diffuse.vsh 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Uniforms
  2. uniform mat4 u_worldViewProjectionMatrix; // Matrix to transform a position to clip space.
  3. uniform mat4 u_inverseTransposeWorldViewMatrix; // Matrix to transform a normal to view space.
  4. // Inputs
  5. attribute vec4 a_position; // Vertex Position (x, y, z, w)
  6. attribute vec3 a_normal; // Vertex Normal (x, y, z)
  7. attribute vec2 a_texCoord; // Vertex Texture Coordinate (u, v)
  8. // Outputs
  9. varying vec3 v_normalVector; // NormalVector in view space.
  10. varying vec2 v_texCoord; // Texture coordinate (u, v).
  11. varying vec3 v_cameraDirection; // Camera direction
  12. #if defined(SKINNING)
  13. attribute vec4 a_blendWeights;
  14. attribute vec4 a_blendIndices;
  15. // 32 4x3 matrices as an array of floats
  16. uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
  17. // Common vectors.
  18. vec4 _skinnedPosition;
  19. vec3 _skinnedNormal;
  20. void skinPosition(float blendWeight, int matrixIndex)
  21. {
  22. vec4 tmp;
  23. tmp.x = dot(a_position, u_matrixPalette[matrixIndex]);
  24. tmp.y = dot(a_position, u_matrixPalette[matrixIndex + 1]);
  25. tmp.z = dot(a_position, u_matrixPalette[matrixIndex + 2]);
  26. tmp.w = a_position.w;
  27. _skinnedPosition += blendWeight * tmp;
  28. }
  29. vec4 getPosition()
  30. {
  31. _skinnedPosition = vec4(0.0);
  32. // Transform position to view space using
  33. // matrix palette with four matrices used to transform a vertex.
  34. float blendWeight = a_blendWeights[0];
  35. int matrixIndex = int (a_blendIndices[0]) * 3;
  36. skinPosition(blendWeight, matrixIndex);
  37. blendWeight = a_blendWeights[1];
  38. matrixIndex = int(a_blendIndices[1]) * 3;
  39. skinPosition(blendWeight, matrixIndex);
  40. blendWeight = a_blendWeights[2];
  41. matrixIndex = int(a_blendIndices[2]) * 3;
  42. skinPosition(blendWeight, matrixIndex);
  43. blendWeight = a_blendWeights[3];
  44. matrixIndex = int(a_blendIndices[3]) * 3;
  45. skinPosition(blendWeight, matrixIndex);
  46. return _skinnedPosition;
  47. }
  48. void skinNormal(float blendWeight, int matrixIndex)
  49. {
  50. vec3 tmp;
  51. tmp.x = dot(a_normal, u_matrixPalette[matrixIndex].xyz);
  52. tmp.y = dot(a_normal, u_matrixPalette[matrixIndex + 1].xyz);
  53. tmp.z = dot(a_normal, u_matrixPalette[matrixIndex + 2].xyz);
  54. _skinnedNormal += blendWeight * tmp;
  55. }
  56. vec3 getNormal()
  57. {
  58. _skinnedNormal = vec3(0.0);
  59. // Transform normal to view space using
  60. // matrix palette with four matrices used to transform a vertex.
  61. float blendWeight = a_blendWeights[0];
  62. int matrixIndex = int (a_blendIndices[0]) * 3;
  63. skinNormal(blendWeight, matrixIndex);
  64. blendWeight = a_blendWeights[1];
  65. matrixIndex = int(a_blendIndices[1]) * 3;
  66. skinNormal(blendWeight, matrixIndex);
  67. blendWeight = a_blendWeights[2];
  68. matrixIndex = int(a_blendIndices[2]) * 3;
  69. skinNormal(blendWeight, matrixIndex);
  70. blendWeight = a_blendWeights[3];
  71. matrixIndex = int(a_blendIndices[3]) * 3;
  72. skinNormal(blendWeight, matrixIndex);
  73. return _skinnedNormal;
  74. }
  75. #else
  76. vec4 getPosition()
  77. {
  78. return a_position;
  79. }
  80. vec3 getNormal()
  81. {
  82. return a_normal;
  83. }
  84. #endif
  85. #if defined(POINT_LIGHT)
  86. uniform mat4 u_worldViewMatrix; // Matrix to tranform a position to view space.
  87. uniform vec3 u_pointLightPosition; // Position
  88. uniform float u_pointLightRange; // Inverse of light range.
  89. varying vec4 v_vertexToPointLightDirection; // Light direction w.r.t current vertex.
  90. void applyLight(vec4 position)
  91. {
  92. // World space position.
  93. vec4 positionWorldViewSpace = u_worldViewMatrix * position;
  94. // Compute the light direction.
  95. vec3 lightDirection = u_pointLightPosition - positionWorldViewSpace.xyz;
  96. vec4 vertexToPointLightDirection;
  97. vertexToPointLightDirection.xyz = lightDirection;
  98. // Attenuation
  99. vertexToPointLightDirection.w = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
  100. // Output light direction.
  101. v_vertexToPointLightDirection = vertexToPointLightDirection;
  102. }
  103. #elif defined(SPOT_LIGHT)
  104. uniform mat4 u_worldViewMatrix; // Matrix to tranform a position to view space.
  105. uniform vec3 u_spotLightPosition; // Position
  106. uniform float u_spotLightRangeInverse; // Inverse of light range.
  107. varying vec3 v_vertexToSpotLightDirection; // Light direction w.r.t current vertex.
  108. varying float v_spotLightAttenuation; // Attenuation of spot light.
  109. void applyLight(vec4 position)
  110. {
  111. // World space position.
  112. vec4 positionWorldViewSpace = u_worldViewMatrix * position;
  113. // Compute the light direction with light position and the vertex position.
  114. vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
  115. // Attenuation
  116. v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
  117. // Output light direction.
  118. v_vertexToSpotLightDirection = lightDirection;
  119. }
  120. #else
  121. void applyLight(vec4 position)
  122. {
  123. }
  124. #endif
  125. void main()
  126. {
  127. vec4 position = getPosition();
  128. vec3 normal = getNormal();
  129. // Transform position to clip space.
  130. gl_Position = u_worldViewProjectionMatrix * position;
  131. // Transform normal to view space.
  132. mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
  133. u_inverseTransposeWorldViewMatrix[1].xyz,
  134. u_inverseTransposeWorldViewMatrix[2].xyz);
  135. v_normalVector = inverseTransposeWorldViewMatrix * normal;
  136. // Apply light.
  137. applyLight(position);
  138. // Pass on the texture coordinates to Fragment shader.
  139. v_texCoord = a_texCoord;
  140. }