scene.vert 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /* scene.vert -- Common vertex shader for all scene render paths.
  2. *
  3. * Copyright (c) 2025-2026 Le Juez Victor
  4. *
  5. * This software is provided 'as-is', without any express or implied warranty.
  6. * For conditions of distribution and use, see accompanying LICENSE file.
  7. */
  8. #version 330 core
  9. /* === Constants === */
  10. #define BILLBOARD_NONE 0
  11. #define BILLBOARD_FRONT 1
  12. #define BILLBOARD_Y_AXIS 2
  13. /* === Includes === */
  14. #include "../include/blocks/light.glsl"
  15. #include "../include/blocks/view.glsl"
  16. #include "../include/math.glsl"
  17. /* === Attributes === */
  18. layout(location = 0) in vec3 aPosition;
  19. layout(location = 1) in vec2 aTexCoord;
  20. layout(location = 2) in vec3 aNormal;
  21. layout(location = 3) in vec4 aColor;
  22. layout(location = 4) in vec4 aTangent;
  23. layout(location = 5) in ivec4 aBoneIDs;
  24. layout(location = 6) in vec4 aWeights;
  25. layout(location = 10) in vec3 iPosition;
  26. layout(location = 11) in vec4 iRotation;
  27. layout(location = 12) in vec3 iScale;
  28. layout(location = 13) in vec4 iColor;
  29. layout(location = 14) in vec4 iCustom;
  30. /* === Uniforms === */
  31. uniform sampler1D uBoneMatricesTex;
  32. uniform mat4 uMatModel;
  33. uniform mat4 uMatNormal;
  34. uniform vec4 uAlbedoColor;
  35. uniform vec3 uEmissionColor;
  36. uniform float uEmissionEnergy;
  37. uniform vec2 uTexCoordOffset;
  38. uniform vec2 uTexCoordScale;
  39. uniform bool uInstancing;
  40. uniform bool uSkinning;
  41. uniform int uBillboard;
  42. #if defined(UNLIT) || defined(DEPTH) || defined(DEPTH_CUBE) || defined(PROBE)
  43. uniform mat4 uMatInvView; // inv view only for billboard modes
  44. uniform mat4 uMatViewProj;
  45. #endif // UNLIT || DEPTH || DEPTH_CUBE || PROBE
  46. /* === Varyings === */
  47. smooth out vec3 vPosition;
  48. smooth out vec2 vTexCoord;
  49. flat out vec3 vEmission;
  50. smooth out vec4 vColor;
  51. smooth out mat3 vTBN;
  52. #if defined(GEOMETRY)
  53. smooth out float vLinearDepth;
  54. #endif // GEOMETRY
  55. #if defined(FORWARD) || defined(PROBE)
  56. smooth out vec4 vPosLightSpace[NUM_FORWARD_LIGHTS];
  57. #endif // FORWARD || PROBE
  58. #if defined(DECAL)
  59. smooth out mat4 vDecalProjection;
  60. smooth out mat3 vDecalAxes;
  61. #endif // DECAL
  62. /* === Helper Functions === */
  63. mat4 BoneMatrix(int boneID)
  64. {
  65. int baseIndex = 4 * boneID;
  66. vec4 row0 = texelFetch(uBoneMatricesTex, baseIndex + 0, 0);
  67. vec4 row1 = texelFetch(uBoneMatricesTex, baseIndex + 1, 0);
  68. vec4 row2 = texelFetch(uBoneMatricesTex, baseIndex + 2, 0);
  69. vec4 row3 = texelFetch(uBoneMatricesTex, baseIndex + 3, 0);
  70. return transpose(mat4(row0, row1, row2, row3));
  71. }
  72. mat4 SkinMatrix(ivec4 boneIDs, vec4 weights)
  73. {
  74. return weights.x * BoneMatrix(boneIDs.x) +
  75. weights.y * BoneMatrix(boneIDs.y) +
  76. weights.z * BoneMatrix(boneIDs.z) +
  77. weights.w * BoneMatrix(boneIDs.w);
  78. }
  79. #if defined(DECAL)
  80. mat4 MatrixTransform(vec3 translation, vec4 quat, vec3 scale)
  81. {
  82. float xx = quat.x * quat.x;
  83. float yy = quat.y * quat.y;
  84. float zz = quat.z * quat.z;
  85. float xy = quat.x * quat.y;
  86. float xz = quat.x * quat.z;
  87. float yz = quat.y * quat.z;
  88. float wx = quat.w * quat.x;
  89. float wy = quat.w * quat.y;
  90. float wz = quat.w * quat.z;
  91. return mat4(
  92. scale.x * (1.0 - 2.0 * (yy + zz)), scale.x * 2.0 * (xy + wz), scale.x * 2.0 * (xz - wy), 0.0,
  93. scale.y * 2.0 * (xy - wz), scale.y * (1.0 - 2.0 * (xx + zz)), scale.y * 2.0 * (yz + wx), 0.0,
  94. scale.z * 2.0 * (xz + wy), scale.z * 2.0 * (yz - wx), scale.z * (1.0 - 2.0 * (xx + yy)), 0.0,
  95. translation.x, translation.y, translation.z, 1.0
  96. );
  97. }
  98. #endif
  99. void BillboardFront(inout vec3 position, inout vec3 normal, inout vec3 tangent, vec3 center, mat4 invView)
  100. {
  101. vec3 right = invView[0].xyz;
  102. vec3 up = invView[1].xyz;
  103. vec3 forward = invView[2].xyz;
  104. vec3 localPos = position - center;
  105. vec3 localNormal = normal;
  106. vec3 localTangent = tangent;
  107. position = center + localPos.x*right + localPos.y*up + localPos.z*forward;
  108. normal = localNormal.x*right + localNormal.y*up + localNormal.z*forward;
  109. tangent = localTangent.x*right + localTangent.y*up + localTangent.z*forward;
  110. }
  111. void BillboardYAxis(inout vec3 position, inout vec3 normal, inout vec3 tangent, vec3 center, mat4 invView)
  112. {
  113. vec3 cameraPos = vec3(invView[3]);
  114. vec3 upVector = vec3(0, 1, 0);
  115. vec3 look = normalize(cameraPos - center);
  116. vec3 right = normalize(cross(upVector, look));
  117. vec3 front = normalize(cross(right, upVector));
  118. vec3 localPos = position - center;
  119. vec3 localNormal = normal;
  120. vec3 localTangent = tangent;
  121. position = center + localPos.x*right + localPos.y*upVector + localPos.z*front;
  122. normal = localNormal.x*right + localNormal.y*upVector + localNormal.z*front;
  123. tangent = localTangent.x*right + localTangent.y*upVector + localTangent.z*front;
  124. }
  125. /* === User override === */
  126. #include "../include/user/scene.vert"
  127. /* === Main program === */
  128. void main()
  129. {
  130. SceneVertex();
  131. #if defined(DECAL)
  132. mat4 finalMatModel = uMatModel;
  133. #endif // DECAL
  134. vec3 billboardCenter = vec3(uMatModel[3]);
  135. vec3 localPosition = POSITION;
  136. vec3 localNormal = NORMAL;
  137. vec3 localTangent = TANGENT.xyz;
  138. if (uSkinning) {
  139. mat4 sMatModel = SkinMatrix(aBoneIDs, aWeights);
  140. mat3 sMatNormal = mat3(transpose(inverse(sMatModel)));
  141. localPosition = vec3(sMatModel * vec4(localPosition, 1.0));
  142. localNormal = sMatNormal * localNormal;
  143. localTangent = sMatNormal * localTangent;
  144. }
  145. vec3 finalPosition = vec3(uMatModel * vec4(localPosition, 1.0));
  146. vec3 finalNormal = mat3(uMatNormal) * localNormal;
  147. vec3 finalTangent = mat3(uMatNormal) * localTangent;
  148. if (uInstancing) {
  149. billboardCenter += INSTANCE_POSITION;
  150. finalPosition = finalPosition * INSTANCE_SCALE;
  151. finalPosition = M_Rotate3D(finalPosition, INSTANCE_ROTATION);
  152. finalPosition = finalPosition + INSTANCE_POSITION;
  153. finalNormal = M_Rotate3D(finalNormal, INSTANCE_ROTATION);
  154. finalTangent = M_Rotate3D(finalTangent, INSTANCE_ROTATION);
  155. #if defined(DECAL)
  156. mat4 iMatModel = MatrixTransform(INSTANCE_POSITION, INSTANCE_ROTATION, INSTANCE_SCALE);
  157. finalMatModel = iMatModel * finalMatModel;
  158. #endif // DECAL
  159. }
  160. #if defined(UNLIT) || defined(DEPTH) || defined(DEPTH_CUBE) || defined(PROBE)
  161. if (uBillboard == BILLBOARD_FRONT) {
  162. BillboardFront(finalPosition, finalNormal, finalTangent, billboardCenter, uMatInvView);
  163. }
  164. else if (uBillboard == BILLBOARD_Y_AXIS) {
  165. BillboardYAxis(finalPosition, finalNormal, finalTangent, billboardCenter, uMatInvView);
  166. }
  167. #else
  168. if (uBillboard == BILLBOARD_FRONT) {
  169. BillboardFront(finalPosition, finalNormal, finalTangent, billboardCenter, uView.invView);
  170. }
  171. else if (uBillboard == BILLBOARD_Y_AXIS) {
  172. BillboardYAxis(finalPosition, finalNormal, finalTangent, billboardCenter, uView.invView);
  173. }
  174. #endif
  175. vec3 T = normalize(finalTangent);
  176. vec3 N = normalize(finalNormal);
  177. vec3 B = normalize(cross(N, T) * TANGENT.w);
  178. vPosition = finalPosition;
  179. vTexCoord = TEXCOORD;
  180. vEmission = EMISSION;
  181. vColor = COLOR * INSTANCE_COLOR;
  182. vTBN = mat3(T, B, N);
  183. #if defined(GEOMETRY)
  184. vLinearDepth = -(uView.view * vec4(vPosition, 1.0)).z;
  185. #endif // GEOMETRY
  186. #if defined(FORWARD) || defined(PROBE)
  187. for (int i = 0; i < uNumLights; i++) {
  188. vPosLightSpace[i] = uLights[i].viewProj * vec4(vPosition, 1.0);
  189. }
  190. #endif // FORWARD || PROBE
  191. #if defined(UNLIT) || defined(DEPTH) || defined(DEPTH_CUBE) || defined(PROBE)
  192. gl_Position = uMatViewProj * vec4(vPosition, 1.0);
  193. #else
  194. gl_Position = uView.viewProj * vec4(vPosition, 1.0);
  195. #endif
  196. #if defined(DECAL)
  197. vDecalProjection = inverse(finalMatModel) * uView.invView;
  198. vDecalAxes[0] = normalize(finalMatModel[0].xyz);
  199. vDecalAxes[1] = normalize(finalMatModel[1].xyz);
  200. vDecalAxes[2] = normalize(finalMatModel[2].xyz);
  201. #endif // DECAL
  202. }