view.glsl 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* view.glsl -- Contains everything you need to manage transformations
  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. #include "../math.glsl"
  9. #define V_PROJ_PERSP 0
  10. #define V_PROJ_ORTHO 1
  11. struct View {
  12. vec3 position;
  13. mat4 view;
  14. mat4 invView;
  15. mat4 proj;
  16. mat4 invProj;
  17. mat4 viewProj;
  18. int projMode;
  19. float aspect;
  20. float near;
  21. float far;
  22. };
  23. layout(std140) uniform ViewBlock {
  24. View uView;
  25. };
  26. vec3 V_GetViewPosition(vec2 texCoord, float linearDepth)
  27. {
  28. vec2 ndc = texCoord * 2.0 - 1.0;
  29. if (uView.projMode == V_PROJ_ORTHO) {
  30. vec2 xyScale = vec2(1.0 / uView.proj[0][0], 1.0 / uView.proj[1][1]);
  31. return vec3(ndc * xyScale, -linearDepth);
  32. }
  33. float tanHalfFov = 1.0 / uView.proj[1][1];
  34. vec3 viewRay = vec3(ndc.x * tanHalfFov * uView.aspect, ndc.y * tanHalfFov, -1.0);
  35. return viewRay * linearDepth;
  36. }
  37. vec3 V_GetViewPosition(sampler2D texLinearDepth, vec2 texCoord)
  38. {
  39. float linearDepth = texture(texLinearDepth, texCoord).r;
  40. return V_GetViewPosition(texCoord, linearDepth);
  41. }
  42. vec3 V_GetViewPosition(sampler2D texLinearDepth, ivec2 pixCoord)
  43. {
  44. vec2 texCoord = (vec2(pixCoord) + 0.5) / vec2(textureSize(texLinearDepth, 0));
  45. float linearDepth = texelFetch(texLinearDepth, pixCoord, 0).r;
  46. return V_GetViewPosition(texCoord, linearDepth);
  47. }
  48. vec3 V_GetWorldPosition(vec3 viewPosition)
  49. {
  50. return (uView.invView * vec4(viewPosition, 1.0)).xyz;
  51. }
  52. vec3 V_GetWorldPosition(vec2 texCoord, float linearDepth)
  53. {
  54. vec3 viewPosition = V_GetViewPosition(texCoord, linearDepth);
  55. return V_GetWorldPosition(viewPosition);
  56. }
  57. vec3 V_GetWorldPosition(sampler2D texLinearDepth, vec2 texCoord)
  58. {
  59. float linearDepth = texture(texLinearDepth, texCoord).r;
  60. return V_GetWorldPosition(texCoord, linearDepth);
  61. }
  62. vec3 V_GetWorldPosition(sampler2D texLinearDepth, ivec2 pixCoord)
  63. {
  64. vec2 texCoord = (vec2(pixCoord) + 0.5) / vec2(textureSize(texLinearDepth, 0));
  65. float linearDepth = texelFetch(texLinearDepth, pixCoord, 0).r;
  66. return V_GetWorldPosition(texCoord, linearDepth);
  67. }
  68. vec3 V_GetViewNormal(vec3 worldNormal)
  69. {
  70. return normalize(mat3(uView.view) * worldNormal);
  71. }
  72. vec3 V_GetViewNormal(vec2 encWorldNormal)
  73. {
  74. vec3 worldNormal = M_DecodeOctahedral(encWorldNormal);
  75. return V_GetViewNormal(worldNormal);
  76. }
  77. vec3 V_GetViewNormal(sampler2D texNormal, vec2 texCoord)
  78. {
  79. vec2 encWorldNormal = texture(texNormal, texCoord).rg;
  80. return V_GetViewNormal(encWorldNormal);
  81. }
  82. vec3 V_GetViewNormal(sampler2D texNormal, ivec2 pixCoord)
  83. {
  84. vec2 encWorldNormal = texelFetch(texNormal, pixCoord, 0).rg;
  85. return V_GetViewNormal(encWorldNormal);
  86. }
  87. vec3 V_GetWorldNormal(sampler2D texNormal, vec2 texCoord)
  88. {
  89. vec2 encWorldNormal = texture(texNormal, texCoord).rg;
  90. return M_DecodeOctahedral(encWorldNormal);
  91. }
  92. vec3 V_GetWorldNormal(sampler2D texNormal, ivec2 pixCoord)
  93. {
  94. vec2 encWorldNormal = texelFetch(texNormal, pixCoord, 0).rg;
  95. return M_DecodeOctahedral(encWorldNormal);
  96. }
  97. vec2 V_ViewToScreen(vec3 viewPosition)
  98. {
  99. vec4 clipPos = uView.proj * vec4(viewPosition, 1.0);
  100. return (clipPos.xy / clipPos.w) * 0.5 + 0.5;
  101. }
  102. vec2 V_WorldToScreen(vec3 worldPosition)
  103. {
  104. vec4 projPos = uView.viewProj * vec4(worldPosition, 1.0);
  105. return (projPos.xy / projPos.w) * 0.5 + 0.5;
  106. }
  107. bool V_OffScreen(vec2 texCoord)
  108. {
  109. return any(lessThan(texCoord, vec2(0.0))) ||
  110. any(greaterThan(texCoord, vec2(1.0)));
  111. }
  112. float V_LinearizeDepth(float depth)
  113. {
  114. if (uView.projMode == V_PROJ_ORTHO) {
  115. return uView.near + depth * (uView.far - uView.near);
  116. }
  117. // Perspective
  118. float near = uView.near, far = uView.far;
  119. return (2.0 * near * far) / (far + near - (depth * 2.0 - 1.0) * (far - near));
  120. }
  121. float V_LinearizeDepth01(float depth)
  122. {
  123. if (uView.projMode == V_PROJ_ORTHO) {
  124. return depth;
  125. }
  126. // Perspective
  127. float near = uView.near, far = uView.far;
  128. float z = (2.0 * near * far) / (far + near - (depth * 2.0 - 1.0) * (far - near));
  129. return (z - near) / (far - near);
  130. }