//--------------------------------------------------------------------------- //These materials/shaders are part of the NEW InstanceManager implementation //Written by Matias N. Goldberg ("dark_sylinc") //--------------------------------------------------------------------------- #version 300 es precision mediump int; precision mediump float; //Vertex input in vec4 vertex; in vec3 normal; in vec3 tangent; in vec4 uv0; in vec4 blendIndices; in vec4 blendWeights; //Parameters uniform mat4 viewProjMatrix; //uniform mat4x3 worldMatrix3x4Array[80]; #ifdef ST_DUAL_QUATERNION uniform vec4 worldDualQuaternion2x4Array[240]; #else uniform vec4 worldMatrix3x4Array[240]; //240 = 80*3 #endif #if (DEPTH_SHADOWCASTER || DEPTH_SHADOWRECEIVER) uniform vec4 depthRange; #endif #if DEPTH_SHADOWRECEIVER uniform mat4 texViewProjMatrix; #endif //Output #if DEPTH_SHADOWCASTER out vec2 depth; #else out vec2 _uv0; out vec3 oNormal; out vec3 oVPos; #if DEPTH_SHADOWRECEIVER out vec4 oLightSpacePos; #endif #endif vec3 calculateBlendPosition(vec3 position, mat2x4 blendDQ) { vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position); vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw)); blendPosition += trans; return blendPosition; } vec3 calculateBlendNormal(vec3 normal, mat2x4 blendDQ) { return normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal); } //--------------------------------------------- //Main Vertex Shader //--------------------------------------------- void main(void) { vec4 worldPos; vec3 worldNorm; #ifdef ST_DUAL_QUATERNION int idx = int(blendIndices[0]) * 2; mat2x4 blendDQ; blendDQ[0] = worldDualQuaternion2x4Array[idx]; blendDQ[1] = worldDualQuaternion2x4Array[idx + 1]; #ifdef BONE_TWO_WEIGHTS int idx2 = int(blendIndices[1]) * 2; mat2x4 blendDQ2; blendDQ2[0] = worldDualQuaternion2x4Array[idx2]; blendDQ2[1] = worldDualQuaternion2x4Array[idx2 + 1]; //Accurate antipodality handling. For speed increase, remove the following line if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0; //Blend the dual quaternions based on the weights blendDQ *= blendWeights.x; blendDQ += blendWeights.y*blendDQ2; //Normalize the resultant dual quaternion blendDQ /= length(blendDQ[0]); #endif worldPos = vec4(calculateBlendPosition(vertex.xyz, blendDQ), 1.0); worldNorm = calculateBlendNormal(normal, blendDQ); #else mat4 worldMatrix; int idx = int(blendIndices[0]) * 3; worldMatrix[0] = worldMatrix3x4Array[idx]; worldMatrix[1] = worldMatrix3x4Array[idx + 1]; worldMatrix[2] = worldMatrix3x4Array[idx + 2]; worldMatrix[3] = vec4( 0, 0, 0, 1 ); worldPos = vertex * worldMatrix; worldNorm = normal * mat3(worldMatrix); #endif //Transform the position gl_Position = viewProjMatrix * worldPos; #if DEPTH_SHADOWCASTER depth.x = (gl_Position.z - depthRange.x) * depthRange.w; depth.y = depthRange.w; #else _uv0 = uv0.xy; oNormal = worldNorm; oVPos = worldPos.xyz; #if DEPTH_SHADOWRECEIVER oLightSpacePos = texViewProjMatrix * worldPos; oLightSpacePos.z = (oLightSpacePos.z - depthRange.x) * depthRange.w; #endif #endif }