Skip to content

Instantly share code, notes, and snippets.

@prideout
Created November 14, 2018 18:15
Show Gist options
  • Save prideout/59a57c1dfeb4e8cef5b694e0842dedf9 to your computer and use it in GitHub Desktop.
Save prideout/59a57c1dfeb4e8cef5b694e0842dedf9 to your computer and use it in GitHub Desktop.
depth pass and color pass
#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
}
#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