Created
November 14, 2018 18:15
-
-
Save prideout/59a57c1dfeb4e8cef5b694e0842dedf9 to your computer and use it in GitHub Desktop.
depth pass and color pass
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 310 es | |
#define TARGET_MOBILE | |
precision highp float; | |
precision highp int; | |
invariant gl_Position; | |
#if defined(TARGET_MOBILE) | |
#define HIGHP highp | |
#define MEDIUMP mediump | |
#else | |
#define HIGHP | |
#define MEDIUMP | |
#endif | |
#define LAYOUT_LOCATION(x) layout(location = x) | |
#define bool2 bvec2 | |
#define bool3 bvec3 | |
#define bool4 bvec4 | |
#define int2 ivec2 | |
#define int3 ivec3 | |
#define int4 ivec4 | |
#define uint2 uvec2 | |
#define uint3 uvec3 | |
#define uint4 uvec4 | |
#define float2 vec2 | |
#define float3 vec3 | |
#define float4 vec4 | |
#define float3x3 mat3 | |
#define float4x4 mat4 | |
#define SHADING_MODEL_LIT | |
#define MATERIAL_HAS_BASE_COLOR | |
#define MATERIAL_HAS_ROUGHNESS | |
#define MATERIAL_HAS_METALLIC | |
#define MATERIAL_HAS_AMBIENT_OCCLUSION | |
#define MATERIAL_HAS_CLEAR_COAT | |
#define MATERIAL_HAS_NORMAL | |
#define SHADING_INTERPOLATION | |
#define HAS_ATTRIBUTE_TANGENTS | |
#define HAS_ATTRIBUTE_UV0 | |
#define LOCATION_POSITION 0 | |
#define LOCATION_TANGENTS 1 | |
#define LOCATION_UV0 3 | |
layout(location = LOCATION_POSITION) in vec4 mesh_position; | |
#if defined(HAS_ATTRIBUTE_TANGENTS) | |
layout(location = LOCATION_TANGENTS) in vec4 mesh_tangents; | |
#endif | |
#if defined(HAS_ATTRIBUTE_COLOR) | |
layout(location = LOCATION_COLOR) in vec4 mesh_color; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV0) | |
layout(location = LOCATION_UV0) in vec2 mesh_uv0; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV1) | |
layout(location = LOCATION_UV1) in vec2 mesh_uv1; | |
#endif | |
#if defined(HAS_ATTRIBUTE_BONE_INDICES) | |
layout(location = LOCATION_BONE_INDICES) in uvec4 mesh_bone_indices; | |
#endif | |
#if defined(HAS_ATTRIBUTE_BONE_WEIGHTS) | |
layout(location = LOCATION_BONE_WEIGHTS) in vec4 mesh_bone_weights; | |
#endif | |
LAYOUT_LOCATION(4) out HIGHP vec3 vertex_worldPosition; | |
#if defined(HAS_ATTRIBUTE_TANGENTS) | |
LAYOUT_LOCATION(5) SHADING_INTERPOLATION out MEDIUMP vec3 vertex_worldNormal; | |
#if defined(MATERIAL_HAS_ANISOTROPY) || defined(MATERIAL_HAS_NORMAL) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL) | |
LAYOUT_LOCATION(6) SHADING_INTERPOLATION out MEDIUMP vec3 vertex_worldTangent; | |
LAYOUT_LOCATION(7) SHADING_INTERPOLATION out MEDIUMP vec3 vertex_worldBitangent; | |
#endif | |
#if defined(GEOMETRIC_SPECULAR_AA_NORMAL) | |
LAYOUT_LOCATION(8) SHADING_INTERPOLATION centroid out vec3 vertex_worldNormalCentroid; | |
#endif | |
#endif | |
#if defined(HAS_ATTRIBUTE_COLOR) | |
LAYOUT_LOCATION(9) out MEDIUMP vec4 vertex_color; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV0) | |
LAYOUT_LOCATION(10) out HIGHP vec2 vertex_uv01; | |
#elif defined(HAS_ATTRIBUTE_UV1) | |
LAYOUT_LOCATION(10) out HIGHP vec4 vertex_uv01; | |
#endif | |
#if defined(HAS_SHADOWING) && defined(HAS_DIRECTIONAL_LIGHTING) | |
LAYOUT_LOCATION(11) out HIGHP vec4 vertex_lightSpacePosition; | |
#endif | |
#define VERTEX_DOMAIN_OBJECT | |
layout(std140) uniform FrameUniforms { | |
mat4 viewFromWorldMatrix; | |
mat4 worldFromViewMatrix; | |
mat4 clipFromViewMatrix; | |
mat4 viewFromClipMatrix; | |
mat4 clipFromWorldMatrix; | |
mat4 lightFromWorldMatrix; | |
vec4 resolution; | |
vec3 cameraPosition; | |
float time; | |
mediump vec4 lightColorIntensity; | |
mediump vec4 sun; | |
mediump vec3 lightDirection; | |
mediump uint fParamsX; | |
mediump vec3 shadowBias; | |
mediump float oneOverFroxelDimensionY; | |
mediump vec4 zParams; | |
mediump uvec2 fParams; | |
mediump vec2 origin; | |
mediump float oneOverFroxelDimension; | |
mediump float iblLuminance; | |
mediump float exposure; | |
mediump float ev100; | |
mediump vec3 iblSH[9]; | |
} frameUniforms; | |
layout(std140) uniform ObjectUniforms { | |
mat4 worldFromModelMatrix; | |
mat3 worldFromModelNormalMatrix; | |
} objectUniforms; | |
layout(std140) uniform MaterialParams { | |
mediump float clearCoat; | |
} materialParams; | |
layout(binding=1) uniform sampler2D materialParams_albedo; | |
layout(binding=2) uniform sampler2D materialParams_roughness; | |
layout(binding=3) uniform sampler2D materialParams_metallic; | |
layout(binding=4) uniform sampler2D materialParams_normal; | |
layout(binding=5) uniform sampler2D materialParams_ao; | |
//------------------------------------------------------------------------------ | |
// Common math | |
//------------------------------------------------------------------------------ | |
/** @public-api */ | |
#define PI 3.14159265359 | |
/** @public-api */ | |
#define HALF_PI 1.570796327 | |
#define MEDIUMP_FLT_MAX 65504.0 | |
#define MEDIUMP_FLT_MIN 0.00006103515625 | |
#ifdef TARGET_MOBILE | |
#define FLT_EPS MEDIUMP_FLT_MIN | |
#define saturateMediump(x) min(x, MEDIUMP_FLT_MAX) | |
#else | |
#define FLT_EPS 1e-5 | |
#define saturateMediump(x) x | |
#endif | |
#define saturate(x) clamp(x, 0.0, 1.0) | |
//------------------------------------------------------------------------------ | |
// Scalar operations | |
//------------------------------------------------------------------------------ | |
/** | |
* Computes x^5 using only multiply operations. | |
* | |
* @public-api | |
*/ | |
float pow5(float x) { | |
float x2 = x * x; | |
return x2 * x2 * x; | |
} | |
/** | |
* Computes x^2 as a single multiplication. | |
* | |
* @public-api | |
*/ | |
float sq(float x) { | |
return x * x; | |
} | |
/** | |
* Returns the maximum component of the specified vector. | |
* | |
* @public-api | |
*/ | |
float max3(const vec3 v) { | |
return max(v.x, max(v.y, v.z)); | |
} | |
//------------------------------------------------------------------------------ | |
// Matrix and quaternion operations | |
//------------------------------------------------------------------------------ | |
/** | |
* Multiplies the specified 3-component vector by the 4x4 matrix (m * v) in | |
* high precision. | |
* | |
* @public-api | |
*/ | |
vec4 mulMat4x4Float3(const HIGHP mat4 m, const HIGHP vec3 v) { | |
return v.x * m[0] + (v.y * m[1] + (v.z * m[2] + m[3])); | |
} | |
/** | |
* Multiplies the specified 3-component vector by the 3x3 matrix (m * v) in | |
* high precision. | |
* | |
* @public-api | |
*/ | |
vec3 mulMat3x3Float3(const HIGHP mat4 m, const HIGHP vec3 v) { | |
return v.x * m[0].xyz + (v.y * m[1].xyz + (v.z * m[2].xyz)); | |
} | |
/** | |
* Extracts the normal vector of the tangent frame encoded in the specified quaternion. | |
*/ | |
void toTangentFrame(const HIGHP vec4 q, out HIGHP vec3 n) { | |
n = vec3( 0.0, 0.0, 1.0) + | |
vec3( 2.0, -2.0, -2.0) * q.x * q.zwx + | |
vec3( 2.0, 2.0, -2.0) * q.y * q.wzy; | |
} | |
/** | |
* Extracts the normal and tangent vectors of the tangent frame encoded in the | |
* specified quaternion. | |
*/ | |
void toTangentFrame(const HIGHP vec4 q, out HIGHP vec3 n, out HIGHP vec3 t) { | |
toTangentFrame(q, n); | |
t = vec3( 1.0, 0.0, 0.0) + | |
vec3(-2.0, 2.0, -2.0) * q.y * q.yxw + | |
vec3(-2.0, 2.0, 2.0) * q.z * q.zwx; | |
} | |
//------------------------------------------------------------------------------ | |
// Uniforms access | |
//------------------------------------------------------------------------------ | |
/** @public-api */ | |
mat4 getViewFromWorldMatrix() { | |
return frameUniforms.viewFromWorldMatrix; | |
} | |
/** @public-api */ | |
mat4 getWorldFromViewMatrix() { | |
return frameUniforms.worldFromViewMatrix; | |
} | |
/** @public-api */ | |
mat4 getClipFromViewMatrix() { | |
return frameUniforms.clipFromViewMatrix; | |
} | |
/** @public-api */ | |
mat4 getViewFromClipMatrix() { | |
return frameUniforms.viewFromClipMatrix; | |
} | |
/** @public-api */ | |
mat4 getClipFromWorldMatrix() { | |
return frameUniforms.clipFromWorldMatrix; | |
} | |
/** @public-api */ | |
vec4 getResolution() { | |
return frameUniforms.resolution; | |
} | |
/** @public-api */ | |
vec3 getWorldCameraPosition() { | |
return frameUniforms.cameraPosition; | |
} | |
/** @public-api */ | |
float getTime() { | |
return frameUniforms.time; | |
} | |
/** @public-api */ | |
float getExposure() { | |
return frameUniforms.exposure; | |
} | |
/** @public-api */ | |
float getEV100() { | |
return frameUniforms.ev100; | |
} | |
//------------------------------------------------------------------------------ | |
// Uniforms access | |
//------------------------------------------------------------------------------ | |
mat4 getLightFromWorldMatrix() { | |
return frameUniforms.lightFromWorldMatrix; | |
} | |
/** @public-api */ | |
mat4 getWorldFromModelMatrix() { | |
return objectUniforms.worldFromModelMatrix; | |
} | |
/** @public-api */ | |
mat3 getWorldFromModelNormalMatrix() { | |
return objectUniforms.worldFromModelNormalMatrix; | |
} | |
//------------------------------------------------------------------------------ | |
// Attributes access | |
//------------------------------------------------------------------------------ | |
#if defined(HAS_SKINNING) | |
vec3 mulBoneNormal(vec3 n, uint i) { | |
vec4 q = bonesUniforms.bones[i + 0u]; | |
vec3 is = bonesUniforms.bones[i + 3u].xyz; | |
// apply the inverse of the non-uniform scales | |
n *= is; | |
// apply the rigid transform (valid only for unit quaternions) | |
n += 2.0 * cross(q.xyz, cross(q.xyz, n) + q.w * n); | |
return n; | |
} | |
vec3 mulBoneVertice(vec3 v, uint i) { | |
vec4 q = bonesUniforms.bones[i + 0u]; | |
vec3 t = bonesUniforms.bones[i + 1u].xyz; | |
vec3 s = bonesUniforms.bones[i + 2u].xyz; | |
// apply the non-uniform scales | |
v *= s; | |
// apply the rigid transform (valid only for unit quaternions) | |
v += 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); | |
// apply the translation | |
v += t; | |
return v; | |
} | |
void skinNormal(inout vec3 n, const uvec4 ids, const vec4 weights) { | |
n = mulBoneNormal(n, ids.x * 4u) * weights.x | |
+ mulBoneNormal(n, ids.y * 4u) * weights.y | |
+ mulBoneNormal(n, ids.z * 4u) * weights.z | |
+ mulBoneNormal(n, ids.w * 4u) * weights.w; | |
} | |
void skinPosition(inout vec3 p, const uvec4 ids, const vec4 weights) { | |
p = mulBoneVertice(p, ids.x * 4u) * weights.x | |
+ mulBoneVertice(p, ids.y * 4u) * weights.y | |
+ mulBoneVertice(p, ids.z * 4u) * weights.z | |
+ mulBoneVertice(p, ids.w * 4u) * weights.w; | |
} | |
#endif | |
/** @public-api */ | |
vec4 getPosition() { | |
return mesh_position; | |
} | |
vec4 getSkinnedPosition() { | |
vec4 pos = getPosition(); | |
#if defined(HAS_SKINNING) | |
skinPosition(pos.xyz, mesh_bone_indices, mesh_bone_weights); | |
#endif | |
return pos; | |
} | |
//------------------------------------------------------------------------------ | |
// Helpers | |
//------------------------------------------------------------------------------ | |
/** | |
* Computes and returns the position in world space of the current vertex. | |
* The world position computation depends on the current vertex domain. This | |
* function optionally applies vertex skinning if needed. | |
* | |
* NOTE: the "transform" and "position" temporaries are necessary to work around | |
* an issue with Adreno drivers (b/110851741). | |
*/ | |
vec4 computeWorldPosition() { | |
#if defined(VERTEX_DOMAIN_OBJECT) | |
mat4 transform = getWorldFromModelMatrix(); | |
vec3 position = getSkinnedPosition().xyz; | |
return mulMat4x4Float3(transform, position); | |
#elif defined(VERTEX_DOMAIN_WORLD) | |
return vec4(getSkinnedPosition().xyz, 1.0); | |
#elif defined(VERTEX_DOMAIN_VIEW) | |
mat4 transform = getWorldFromViewMatrix(); | |
vec3 position = getSkinnedPosition().xyz; | |
return mulMat4x4Float3(transform, position); | |
#else | |
mat4 transform = getWorldFromViewMatrix() * getViewFromClipMatrix(); | |
vec3 position = getSkinnedPosition().xyz; | |
return mulMat4x4Float3(transform, position); | |
#endif | |
} | |
struct MaterialVertexInputs { | |
#ifdef HAS_ATTRIBUTE_COLOR | |
vec4 color; | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV0 | |
vec2 uv0; | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV1 | |
vec2 uv1; | |
#endif | |
#ifdef VARIABLE_CUSTOM0 | |
vec4 VARIABLE_CUSTOM0; | |
#endif | |
#ifdef VARIABLE_CUSTOM1 | |
vec4 VARIABLE_CUSTOM1; | |
#endif | |
#ifdef VARIABLE_CUSTOM2 | |
vec4 VARIABLE_CUSTOM2; | |
#endif | |
#ifdef VARIABLE_CUSTOM3 | |
vec4 VARIABLE_CUSTOM3; | |
#endif | |
#ifdef HAS_ATTRIBUTE_TANGENTS | |
vec3 worldNormal; | |
#endif | |
vec4 worldPosition; | |
}; | |
void initMaterialVertex(out MaterialVertexInputs material) { | |
#ifdef HAS_ATTRIBUTE_COLOR | |
material.color = mesh_color; | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV0 | |
material.uv0 = vec2(mesh_uv0.x, 1.0 - mesh_uv0.y); | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV1 | |
material.uv1 = vec2(mesh_uv1.x, 1.0 - mesh_uv1.y); | |
#endif | |
#ifdef VARIABLE_CUSTOM0 | |
material.VARIABLE_CUSTOM0 = vec4(0.0); | |
#endif | |
#ifdef VARIABLE_CUSTOM1 | |
material.VARIABLE_CUSTOM1 = vec4(0.0); | |
#endif | |
#ifdef VARIABLE_CUSTOM2 | |
material.VARIABLE_CUSTOM2 = vec4(0.0); | |
#endif | |
#ifdef VARIABLE_CUSTOM3 | |
material.VARIABLE_CUSTOM3 = vec4(0.0); | |
#endif | |
material.worldPosition = computeWorldPosition(); | |
} | |
#line 0 | |
void materialVertex(inout MaterialVertexInputs m) { | |
} | |
#line 467 | |
//------------------------------------------------------------------------------ | |
// Shadowing | |
//------------------------------------------------------------------------------ | |
#if defined(HAS_SHADOWING) && defined(HAS_DIRECTIONAL_LIGHTING) | |
/** | |
* Computes the light space position of the specified world space point. | |
* The returned point may contain a bias to attempt to eliminate common | |
* shadowing artifacts such as "acne". To achieve this, the world space | |
* normal at the point must also be passed to this function. | |
*/ | |
vec4 getLightSpacePosition(const vec3 p, const vec3 n) { | |
float NoL = saturate(dot(n, frameUniforms.lightDirection)); | |
#ifdef TARGET_MOBILE | |
float normalBias = 1.0 - NoL * NoL; | |
#else | |
float normalBias = sqrt(1.0 - NoL * NoL); | |
#endif | |
vec3 offsetPosition = p + n * (normalBias * frameUniforms.shadowBias.y); | |
vec4 lightSpacePosition = (getLightFromWorldMatrix() * vec4(offsetPosition, 1.0)); | |
lightSpacePosition.z -= frameUniforms.shadowBias.x; | |
return lightSpacePosition; | |
} | |
#endif | |
void main() { | |
// Initialize the inputs to sensible default values, see common_material.vs | |
MaterialVertexInputs material; | |
initMaterialVertex(material); | |
#if defined(HAS_ATTRIBUTE_TANGENTS) | |
// If the material defines a value for the "normal" property, we need to output | |
// the full orthonormal basis to apply normal mapping | |
#if defined(MATERIAL_HAS_ANISOTROPY) || defined(MATERIAL_HAS_NORMAL) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL) | |
// Extract the normal and tangent in world space from the input quaternion | |
// We encode the orthonormal basis as a quaternion to save space in the attributes | |
toTangentFrame(mesh_tangents, material.worldNormal, vertex_worldTangent); | |
// We don't need to normalize here, even if there's a scale in the matrix | |
// because we ensure the worldFromModelNormalMatrix pre-scales the normal such that | |
// all its components are < 1.0. This precents the bitangent to exceed the range of fp16 | |
// in the fragment shader, where we renormalize after interpolation | |
vertex_worldTangent = objectUniforms.worldFromModelNormalMatrix * vertex_worldTangent; | |
material.worldNormal = objectUniforms.worldFromModelNormalMatrix * material.worldNormal; | |
#if defined(HAS_SKINNING) | |
skinNormal(material.worldNormal, mesh_bone_indices, mesh_bone_weights); | |
skinNormal(vertex_worldTangent, mesh_bone_indices, mesh_bone_weights); | |
#endif | |
// Reconstruct the bitangent from the normal and tangent. We don't bother with | |
// normalization here since we'll do it after interpolation in the fragment stage | |
vertex_worldBitangent = | |
cross(material.worldNormal, vertex_worldTangent) * sign(mesh_tangents.w); | |
#else // MATERIAL_HAS_ANISOTROPY || MATERIAL_HAS_NORMAL | |
// Without anisotropy or normal mapping we only need the normal vector | |
toTangentFrame(mesh_tangents, material.worldNormal); | |
material.worldNormal = objectUniforms.worldFromModelNormalMatrix * material.worldNormal; | |
#if defined(HAS_SKINNING) | |
skinNormal(material.worldNormal, mesh_bone_indices, mesh_bone_weights); | |
#endif | |
#endif // MATERIAL_HAS_ANISOTROPY || MATERIAL_HAS_NORMAL | |
#ifdef GEOMETRIC_SPECULAR_AA_NORMAL | |
vertex_worldNormalCentroid = material.worldNormal; | |
#endif // GEOMETRIC_SPECULAR_AA_NORMAL | |
#endif // HAS_ATTRIBUTE_TANGENTS | |
// Invoke user code | |
materialVertex(material); | |
// Handle built-in interpolated attributes | |
#if defined(HAS_ATTRIBUTE_COLOR) | |
vertex_color = material.color; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV0) | |
vertex_uv01.xy = material.uv0; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV1) | |
vertex_uv01.zw = material.uv1; | |
#endif | |
// Handle user-defined interpolated attributes | |
#if defined(VARIABLE_CUSTOM0) | |
VARIABLE_CUSTOM_AT0 = material.VARIABLE_CUSTOM0; | |
#endif | |
#if defined(VARIABLE_CUSTOM1) | |
VARIABLE_CUSTOM_AT1 = material.VARIABLE_CUSTOM1; | |
#endif | |
#if defined(VARIABLE_CUSTOM2) | |
VARIABLE_CUSTOM_AT2 = material.VARIABLE_CUSTOM2; | |
#endif | |
#if defined(VARIABLE_CUSTOM3) | |
VARIABLE_CUSTOM_AT3 = material.VARIABLE_CUSTOM3; | |
#endif | |
// The world position can be changed by the user in materialVertex() | |
vertex_worldPosition = material.worldPosition.xyz; | |
#ifdef HAS_ATTRIBUTE_TANGENTS | |
vertex_worldNormal = material.worldNormal; | |
#endif | |
#if defined(HAS_SHADOWING) && defined(HAS_DIRECTIONAL_LIGHTING) | |
vertex_lightSpacePosition = getLightSpacePosition(vertex_worldPosition, vertex_worldNormal); | |
#endif | |
#if defined(VERTEX_DOMAIN_DEVICE) | |
// The other vertex domains are handled in initMaterialVertex()->computeWorldPosition() | |
gl_Position = getSkinnedPosition(); | |
#else | |
gl_Position = getClipFromWorldMatrix() * material.worldPosition; | |
#endif | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 310 es | |
#define TARGET_MOBILE | |
precision highp float; | |
precision highp int; | |
invariant gl_Position; | |
#if defined(TARGET_MOBILE) | |
#define HIGHP highp | |
#define MEDIUMP mediump | |
#else | |
#define HIGHP | |
#define MEDIUMP | |
#endif | |
#define LAYOUT_LOCATION(x) layout(location = x) | |
#define bool2 bvec2 | |
#define bool3 bvec3 | |
#define bool4 bvec4 | |
#define int2 ivec2 | |
#define int3 ivec3 | |
#define int4 ivec4 | |
#define uint2 uvec2 | |
#define uint3 uvec3 | |
#define uint4 uvec4 | |
#define float2 vec2 | |
#define float3 vec3 | |
#define float4 vec4 | |
#define float3x3 mat3 | |
#define float4x4 mat4 | |
#define HAS_SHADOWING | |
#define SHADING_MODEL_LIT | |
#define MATERIAL_HAS_BASE_COLOR | |
#define MATERIAL_HAS_ROUGHNESS | |
#define MATERIAL_HAS_METALLIC | |
#define MATERIAL_HAS_AMBIENT_OCCLUSION | |
#define MATERIAL_HAS_CLEAR_COAT | |
#define MATERIAL_HAS_NORMAL | |
#define SHADING_INTERPOLATION | |
#define HAS_ATTRIBUTE_TANGENTS | |
#define HAS_ATTRIBUTE_UV0 | |
#define LOCATION_POSITION 0 | |
#define LOCATION_TANGENTS 1 | |
#define LOCATION_UV0 3 | |
layout(location = LOCATION_POSITION) in vec4 mesh_position; | |
#if defined(HAS_ATTRIBUTE_TANGENTS) | |
layout(location = LOCATION_TANGENTS) in vec4 mesh_tangents; | |
#endif | |
#if defined(HAS_ATTRIBUTE_COLOR) | |
layout(location = LOCATION_COLOR) in vec4 mesh_color; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV0) | |
layout(location = LOCATION_UV0) in vec2 mesh_uv0; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV1) | |
layout(location = LOCATION_UV1) in vec2 mesh_uv1; | |
#endif | |
#if defined(HAS_ATTRIBUTE_BONE_INDICES) | |
layout(location = LOCATION_BONE_INDICES) in uvec4 mesh_bone_indices; | |
#endif | |
#if defined(HAS_ATTRIBUTE_BONE_WEIGHTS) | |
layout(location = LOCATION_BONE_WEIGHTS) in vec4 mesh_bone_weights; | |
#endif | |
LAYOUT_LOCATION(4) out HIGHP vec3 vertex_worldPosition; | |
#if defined(HAS_ATTRIBUTE_TANGENTS) | |
LAYOUT_LOCATION(5) SHADING_INTERPOLATION out MEDIUMP vec3 vertex_worldNormal; | |
#if defined(MATERIAL_HAS_ANISOTROPY) || defined(MATERIAL_HAS_NORMAL) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL) | |
LAYOUT_LOCATION(6) SHADING_INTERPOLATION out MEDIUMP vec3 vertex_worldTangent; | |
LAYOUT_LOCATION(7) SHADING_INTERPOLATION out MEDIUMP vec3 vertex_worldBitangent; | |
#endif | |
#if defined(GEOMETRIC_SPECULAR_AA_NORMAL) | |
LAYOUT_LOCATION(8) SHADING_INTERPOLATION centroid out vec3 vertex_worldNormalCentroid; | |
#endif | |
#endif | |
#if defined(HAS_ATTRIBUTE_COLOR) | |
LAYOUT_LOCATION(9) out MEDIUMP vec4 vertex_color; | |
#endif | |
#if defined(HAS_ATTRIBUTE_UV0) | |
LAYOUT_LOCATION(10) out HIGHP vec2 vertex_uv01; | |
#elif defined(HAS_ATTRIBUTE_UV1) | |
LAYOUT_LOCATION(10) out HIGHP vec4 vertex_uv01; | |
#endif | |
#if defined(HAS_SHADOWING) && defined(HAS_DIRECTIONAL_LIGHTING) | |
LAYOUT_LOCATION(11) out HIGHP vec4 vertex_lightSpacePosition; | |
#endif | |
#define VERTEX_DOMAIN_OBJECT | |
layout(std140) uniform FrameUniforms { | |
mat4 viewFromWorldMatrix; | |
mat4 worldFromViewMatrix; | |
mat4 clipFromViewMatrix; | |
mat4 viewFromClipMatrix; | |
mat4 clipFromWorldMatrix; | |
mat4 lightFromWorldMatrix; | |
vec4 resolution; | |
vec3 cameraPosition; | |
float time; | |
mediump vec4 lightColorIntensity; | |
mediump vec4 sun; | |
mediump vec3 lightDirection; | |
mediump uint fParamsX; | |
mediump vec3 shadowBias; | |
mediump float oneOverFroxelDimensionY; | |
mediump vec4 zParams; | |
mediump uvec2 fParams; | |
mediump vec2 origin; | |
mediump float oneOverFroxelDimension; | |
mediump float iblLuminance; | |
mediump float exposure; | |
mediump float ev100; | |
mediump vec3 iblSH[9]; | |
} frameUniforms; | |
layout(std140) uniform ObjectUniforms { | |
mat4 worldFromModelMatrix; | |
mat3 worldFromModelNormalMatrix; | |
} objectUniforms; | |
layout(std140) uniform MaterialParams { | |
mediump float clearCoat; | |
} materialParams; | |
layout(binding=1) uniform sampler2D materialParams_albedo; | |
layout(binding=2) uniform sampler2D materialParams_roughness; | |
layout(binding=3) uniform sampler2D materialParams_metallic; | |
layout(binding=4) uniform sampler2D materialParams_normal; | |
layout(binding=5) uniform sampler2D materialParams_ao; | |
//------------------------------------------------------------------------------ | |
// Common math | |
//------------------------------------------------------------------------------ | |
/** @public-api */ | |
#define PI 3.14159265359 | |
/** @public-api */ | |
#define HALF_PI 1.570796327 | |
#define MEDIUMP_FLT_MAX 65504.0 | |
#define MEDIUMP_FLT_MIN 0.00006103515625 | |
#ifdef TARGET_MOBILE | |
#define FLT_EPS MEDIUMP_FLT_MIN | |
#define saturateMediump(x) min(x, MEDIUMP_FLT_MAX) | |
#else | |
#define FLT_EPS 1e-5 | |
#define saturateMediump(x) x | |
#endif | |
#define saturate(x) clamp(x, 0.0, 1.0) | |
//------------------------------------------------------------------------------ | |
// Scalar operations | |
//------------------------------------------------------------------------------ | |
/** | |
* Computes x^5 using only multiply operations. | |
* | |
* @public-api | |
*/ | |
float pow5(float x) { | |
float x2 = x * x; | |
return x2 * x2 * x; | |
} | |
/** | |
* Computes x^2 as a single multiplication. | |
* | |
* @public-api | |
*/ | |
float sq(float x) { | |
return x * x; | |
} | |
/** | |
* Returns the maximum component of the specified vector. | |
* | |
* @public-api | |
*/ | |
float max3(const vec3 v) { | |
return max(v.x, max(v.y, v.z)); | |
} | |
//------------------------------------------------------------------------------ | |
// Matrix and quaternion operations | |
//------------------------------------------------------------------------------ | |
/** | |
* Multiplies the specified 3-component vector by the 4x4 matrix (m * v) in | |
* high precision. | |
* | |
* @public-api | |
*/ | |
vec4 mulMat4x4Float3(const HIGHP mat4 m, const HIGHP vec3 v) { | |
return v.x * m[0] + (v.y * m[1] + (v.z * m[2] + m[3])); | |
} | |
/** | |
* Multiplies the specified 3-component vector by the 3x3 matrix (m * v) in | |
* high precision. | |
* | |
* @public-api | |
*/ | |
vec3 mulMat3x3Float3(const HIGHP mat4 m, const HIGHP vec3 v) { | |
return v.x * m[0].xyz + (v.y * m[1].xyz + (v.z * m[2].xyz)); | |
} | |
/** | |
* Extracts the normal vector of the tangent frame encoded in the specified quaternion. | |
*/ | |
void toTangentFrame(const HIGHP vec4 q, out HIGHP vec3 n) { | |
n = vec3( 0.0, 0.0, 1.0) + | |
vec3( 2.0, -2.0, -2.0) * q.x * q.zwx + | |
vec3( 2.0, 2.0, -2.0) * q.y * q.wzy; | |
} | |
/** | |
* Extracts the normal and tangent vectors of the tangent frame encoded in the | |
* specified quaternion. | |
*/ | |
void toTangentFrame(const HIGHP vec4 q, out HIGHP vec3 n, out HIGHP vec3 t) { | |
toTangentFrame(q, n); | |
t = vec3( 1.0, 0.0, 0.0) + | |
vec3(-2.0, 2.0, -2.0) * q.y * q.yxw + | |
vec3(-2.0, 2.0, 2.0) * q.z * q.zwx; | |
} | |
//------------------------------------------------------------------------------ | |
// Uniforms access | |
//------------------------------------------------------------------------------ | |
/** @public-api */ | |
mat4 getViewFromWorldMatrix() { | |
return frameUniforms.viewFromWorldMatrix; | |
} | |
/** @public-api */ | |
mat4 getWorldFromViewMatrix() { | |
return frameUniforms.worldFromViewMatrix; | |
} | |
/** @public-api */ | |
mat4 getClipFromViewMatrix() { | |
return frameUniforms.clipFromViewMatrix; | |
} | |
/** @public-api */ | |
mat4 getViewFromClipMatrix() { | |
return frameUniforms.viewFromClipMatrix; | |
} | |
/** @public-api */ | |
mat4 getClipFromWorldMatrix() { | |
return frameUniforms.clipFromWorldMatrix; | |
} | |
/** @public-api */ | |
vec4 getResolution() { | |
return frameUniforms.resolution; | |
} | |
/** @public-api */ | |
vec3 getWorldCameraPosition() { | |
return frameUniforms.cameraPosition; | |
} | |
/** @public-api */ | |
float getTime() { | |
return frameUniforms.time; | |
} | |
/** @public-api */ | |
float getExposure() { | |
return frameUniforms.exposure; | |
} | |
/** @public-api */ | |
float getEV100() { | |
return frameUniforms.ev100; | |
} | |
//------------------------------------------------------------------------------ | |
// Uniforms access | |
//------------------------------------------------------------------------------ | |
mat4 getLightFromWorldMatrix() { | |
return frameUniforms.lightFromWorldMatrix; | |
} | |
/** @public-api */ | |
mat4 getWorldFromModelMatrix() { | |
return objectUniforms.worldFromModelMatrix; | |
} | |
/** @public-api */ | |
mat3 getWorldFromModelNormalMatrix() { | |
return objectUniforms.worldFromModelNormalMatrix; | |
} | |
//------------------------------------------------------------------------------ | |
// Attributes access | |
//------------------------------------------------------------------------------ | |
#if defined(HAS_SKINNING) | |
vec3 mulBoneNormal(vec3 n, uint i) { | |
vec4 q = bonesUniforms.bones[i + 0u]; | |
vec3 is = bonesUniforms.bones[i + 3u].xyz; | |
// apply the inverse of the non-uniform scales | |
n *= is; | |
// apply the rigid transform (valid only for unit quaternions) | |
n += 2.0 * cross(q.xyz, cross(q.xyz, n) + q.w * n); | |
return n; | |
} | |
vec3 mulBoneVertice(vec3 v, uint i) { | |
vec4 q = bonesUniforms.bones[i + 0u]; | |
vec3 t = bonesUniforms.bones[i + 1u].xyz; | |
vec3 s = bonesUniforms.bones[i + 2u].xyz; | |
// apply the non-uniform scales | |
v *= s; | |
// apply the rigid transform (valid only for unit quaternions) | |
v += 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); | |
// apply the translation | |
v += t; | |
return v; | |
} | |
void skinNormal(inout vec3 n, const uvec4 ids, const vec4 weights) { | |
n = mulBoneNormal(n, ids.x * 4u) * weights.x | |
+ mulBoneNormal(n, ids.y * 4u) * weights.y | |
+ mulBoneNormal(n, ids.z * 4u) * weights.z | |
+ mulBoneNormal(n, ids.w * 4u) * weights.w; | |
} | |
void skinPosition(inout vec3 p, const uvec4 ids, const vec4 weights) { | |
p = mulBoneVertice(p, ids.x * 4u) * weights.x | |
+ mulBoneVertice(p, ids.y * 4u) * weights.y | |
+ mulBoneVertice(p, ids.z * 4u) * weights.z | |
+ mulBoneVertice(p, ids.w * 4u) * weights.w; | |
} | |
#endif | |
/** @public-api */ | |
vec4 getPosition() { | |
return mesh_position; | |
} | |
vec4 getSkinnedPosition() { | |
vec4 pos = getPosition(); | |
#if defined(HAS_SKINNING) | |
skinPosition(pos.xyz, mesh_bone_indices, mesh_bone_weights); | |
#endif | |
return pos; | |
} | |
//------------------------------------------------------------------------------ | |
// Helpers | |
//------------------------------------------------------------------------------ | |
/** | |
* Computes and returns the position in world space of the current vertex. | |
* The world position computation depends on the current vertex domain. This | |
* function optionally applies vertex skinning if needed. | |
* | |
* NOTE: the "transform" and "position" temporaries are necessary to work around | |
* an issue with Adreno drivers (b/110851741). | |
*/ | |
vec4 computeWorldPosition() { | |
#if defined(VERTEX_DOMAIN_OBJECT) | |
mat4 transform = getWorldFromModelMatrix(); | |
vec3 position = getSkinnedPosition().xyz; | |
return mulMat4x4Float3(transform, position); | |
#elif defined(VERTEX_DOMAIN_WORLD) | |
return vec4(getSkinnedPosition().xyz, 1.0); | |
#elif defined(VERTEX_DOMAIN_VIEW) | |
mat4 transform = getWorldFromViewMatrix(); | |
vec3 position = getSkinnedPosition().xyz; | |
return mulMat4x4Float3(transform, position); | |
#else | |
mat4 transform = getWorldFromViewMatrix() * getViewFromClipMatrix(); | |
vec3 position = getSkinnedPosition().xyz; | |
return mulMat4x4Float3(transform, position); | |
#endif | |
} | |
struct MaterialVertexInputs { | |
#ifdef HAS_ATTRIBUTE_COLOR | |
vec4 color; | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV0 | |
vec2 uv0; | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV1 | |
vec2 uv1; | |
#endif | |
#ifdef VARIABLE_CUSTOM0 | |
vec4 VARIABLE_CUSTOM0; | |
#endif | |
#ifdef VARIABLE_CUSTOM1 | |
vec4 VARIABLE_CUSTOM1; | |
#endif | |
#ifdef VARIABLE_CUSTOM2 | |
vec4 VARIABLE_CUSTOM2; | |
#endif | |
#ifdef VARIABLE_CUSTOM3 | |
vec4 VARIABLE_CUSTOM3; | |
#endif | |
#ifdef HAS_ATTRIBUTE_TANGENTS | |
vec3 worldNormal; | |
#endif | |
vec4 worldPosition; | |
}; | |
void initMaterialVertex(out MaterialVertexInputs material) { | |
#ifdef HAS_ATTRIBUTE_COLOR | |
material.color = mesh_color; | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV0 | |
material.uv0 = vec2(mesh_uv0.x, 1.0 - mesh_uv0.y); | |
#endif | |
#ifdef HAS_ATTRIBUTE_UV1 | |
material.uv1 = vec2(mesh_uv1.x, 1.0 - mesh_uv1.y); | |
#endif | |
#ifdef VARIABLE_CUSTOM0 | |
material.VARIABLE_CUSTOM0 = vec4(0.0); | |
#endif | |
#ifdef VARIABLE_CUSTOM1 | |
material.VARIABLE_CUSTOM1 = vec4(0.0); | |
#endif | |
#ifdef VARIABLE_CUSTOM2 | |
material.VARIABLE_CUSTOM2 = vec4(0.0); | |
#endif | |
#ifdef VARIABLE_CUSTOM3 | |
material.VARIABLE_CUSTOM3 = vec4(0.0); | |
#endif | |
material.worldPosition = computeWorldPosition(); | |
} | |
void main() { | |
#if defined(VERTEX_DOMAIN_DEVICE) | |
gl_Position = getSkinnedPosition(); | |
#else | |
MaterialVertexInputs material; | |
initMaterialVertex(material); | |
gl_Position = getClipFromWorldMatrix() * material.worldPosition; | |
#endif | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment