-#version 300 es
// Original Code
// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/glTF-WebGL-PBR/shaders/pbr-vert.glsl
#define MORPH defined(MORPH_POSITION) || defined(MORPH_NORMAL) || defined(MORPH_TANGENT)
+// These lines in the shader may be replaced with actual definitions by the model loader,
+// if they are needed. Note, some shader compilers have problems with spurious ";", so
+// the macro invocations don't have a trailing ";". The replacement strings in the model
+// loader will provide it instead.
+#define ADD_EXTRA_SKINNING_ATTRIBUTES
+#define ADD_EXTRA_WEIGHTS
+
#ifdef HIGHP
precision highp float;
#else
precision mediump float;
#endif
-in vec3 aPosition;
-in vec2 aTexCoord;
-in vec3 aNormal;
+INPUT vec3 aPosition;
+INPUT vec2 aTexCoord;
+INPUT vec3 aNormal;
#ifdef VEC4_TANGENT
-in vec4 aTangent;
+INPUT vec4 aTangent;
#else
-in vec3 aTangent;
+INPUT vec3 aTangent;
#endif
-in vec4 aVertexColor;
+INPUT vec4 aVertexColor;
+
+#ifdef SL_VERSION_LOW
+INPUT float aVertexID;
+#endif
+
+#ifdef SKINNING
+INPUT vec4 aJoints0;
+INPUT vec4 aWeights0;
+ADD_EXTRA_SKINNING_ATTRIBUTES
+#endif
#ifdef MORPH
- uniform highp sampler2D sBlendShapeGeometry;
+uniform highp sampler2D sBlendShapeGeometry;
+#ifdef SL_VERSION_LOW
+uniform int uBlendShapeGeometryWidth;
+uniform int uBlendShapeGeometryHeight;
+#endif
#endif
-out mediump vec2 vUV;
-out lowp mat3 vTBN;
-out lowp vec4 vColor;
-out highp vec3 vPositionToCamera;
+OUTPUT mediump vec2 vUV;
+OUTPUT lowp mat3 vTBN;
+OUTPUT lowp vec4 vColor;
+OUTPUT highp vec3 vPositionToCamera;
uniform highp mat4 uViewMatrix;
uniform mat3 uNormalMatrix;
uniform mat4 uProjection;
#ifdef SKINNING
- in vec4 aJoints;
- in vec4 aWeights;
- #define MAX_BONES 80
- uniform mat4 uBone[MAX_BONES];
- uniform mediump vec3 uYDirection;
+
+#ifdef SL_VERSION_LOW
+#define MAX_BONES 80
+uniform mat4 uBone[MAX_BONES];
+#else
+#define MAX_BONES 256
+layout(std140) uniform Bones
+{
+ mat4 uBone[MAX_BONES];
+};
+#endif
+
+uniform mediump vec3 uYDirection;
#endif
#ifdef MORPH
-#define MAX_BLEND_SHAPE_NUMBER 128
+#define MAX_BLEND_SHAPE_NUMBER 256
uniform int uNumberOfBlendShapes; ///< Total number of blend shapes loaded.
uniform highp float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER]; ///< The weight of each blend shape.
#ifdef MORPH_VERSION_2_0
// Shadow
uniform lowp int uIsShadowEnabled;
uniform highp mat4 uShadowLightViewProjectionMatrix;
-out highp vec3 positionFromLightView;
+OUTPUT highp vec3 positionFromLightView;
void main()
{
highp vec3 tangent = aTangent.xyz;
#ifdef MORPH
+#ifdef SL_VERSION_LOW
+ int width = uBlendShapeGeometryWidth;
+#else
int width = textureSize( sBlendShapeGeometry, 0 ).x;
+#endif
highp int blendShapeBufferOffset = 0;
+#ifdef SL_VERSION_LOW
+ highp float blendShapeWidth = float(uBlendShapeGeometryWidth);
+ highp float blendShapeHeight = float(uBlendShapeGeometryHeight);
+ highp float invertBlendShapeWidth = 1.0 / blendShapeWidth;
+ highp float invertBlendShapeHeight = 1.0 / blendShapeHeight;
+#endif
+
for( int index = 0; index < uNumberOfBlendShapes; ++index )
{
highp vec3 diff = vec3(0.0);
highp int vertexId = 0;
highp int x = 0;
highp int y = 0;
+ highp float weight = clamp(uBlendShapeWeight[index], 0.0, 1.0);
#ifdef MORPH_POSITION
// Calculate the index to retrieve the geometry from the texture.
+#ifdef SL_VERSION_LOW
+ vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+ y = vertexId / width;
+ x = vertexId - y * width;
+#else
vertexId = gl_VertexID + blendShapeBufferOffset;
x = vertexId % width;
y = vertexId / width;
+#endif
// Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.
- if( 0.0 != uBlendShapeWeight[index] )
+ if(0.0 != weight)
{
#ifdef MORPH_VERSION_2_0
highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor;
highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
#endif
- diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#ifdef SL_VERSION_LOW
+ highp float floatX = float(x) + 0.5;
+ highp float floatY = float(y) + 0.5;
+ diff = weight * unnormalizeFactor * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
+ diff = weight * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
}
position.xyz += diff;
#ifdef MORPH_NORMAL
// Calculate the index to retrieve the normal from the texture.
+#ifdef SL_VERSION_LOW
+ vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+ y = vertexId / width;
+ x = vertexId - y * width;
+#else
vertexId = gl_VertexID + blendShapeBufferOffset;
x = vertexId % width;
y = vertexId / width;
+#endif
// Retrieves the blend shape normal from the texture, unnormalizes it and multiply by the weight.
- if( 0.0 != uBlendShapeWeight[index] )
+ if(0.0 != weight)
{
- diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#ifdef SL_VERSION_LOW
+ highp float floatX = float(x) + 0.5;
+ highp float floatY = float(y) + 0.5;
+ diff = weight * 2.0 * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
+ diff = weight * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
}
normal += diff.xyz;
#ifdef MORPH_TANGENT
// Calculate the index to retrieve the tangent from the texture.
+#ifdef SL_VERSION_LOW
+ vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+ y = vertexId / width;
+ x = vertexId - y * width;
+#else
vertexId = gl_VertexID + blendShapeBufferOffset;
x = vertexId % width;
y = vertexId / width;
+#endif
// Retrieves the blend shape tangent from the texture, unnormalizes it and multiply by the weight.
- if( 0.0 != uBlendShapeWeight[index] )
+ if(0.0 != weight)
{
- diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#ifdef SL_VERSION_LOW
+ highp float floatX = float(x) + 0.5;
+ highp float floatY = float(y) + 0.5;
+ diff = weight * 2.0 * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
+ diff = weight * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
}
tangent += diff.xyz;
#endif
+
+
+
#ifdef SKINNING
- highp mat4 bone = uBone[int(aJoints.x)] * aWeights.x +
- uBone[int(aJoints.y)] * aWeights.y +
- uBone[int(aJoints.z)] * aWeights.z +
- uBone[int(aJoints.w)] * aWeights.w;
+ highp mat4 bone =
+ uBone[int(aJoints0.x)] * aWeights0.x +
+ uBone[int(aJoints0.y)] * aWeights0.y +
+ uBone[int(aJoints0.z)] * aWeights0.z +
+ uBone[int(aJoints0.w)] * aWeights0.w;
+
+ ADD_EXTRA_WEIGHTS
+
position = bone * position;
normal = uYDirection * (bone * vec4(normal, 0.0)).xyz;
tangent = uYDirection * (bone * vec4(tangent, 0.0)).xyz;
#else
highp vec4 positionW = uModelMatrix * position;
#endif
+
highp vec4 positionV = uViewMatrix * positionW;
+#ifdef SL_VERSION_LOW
+ highp vec3 i0 = uViewMatrix[0].xyz;
+ highp vec3 i1 = uViewMatrix[1].xyz;
+ highp vec3 i2 = uViewMatrix[2].xyz;
+
+ vPositionToCamera = mat3(vec3(i0.x, i1.x, i2.x), vec3(i0.y, i1.y, i2.y), vec3(i0.z, i1.z, i2.z)) * -vec3(positionV.xyz / positionV.w);
+#else
vPositionToCamera = transpose(mat3(uViewMatrix)) * -vec3(positionV.xyz / positionV.w);
+#endif
normal = normalize(normal);
tangent = normalize(tangent);