deferred_light.glsl 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. uniform sampler2D gbufferD;
  2. uniform sampler2D gbuffer0;
  3. uniform sampler2D gbuffer1;
  4. #ifdef _Voxel
  5. uniform sampler3D voxels;
  6. #endif
  7. uniform vec4 envmap_data; // angle, sin(angle), cos(angle), strength
  8. uniform vec4 shirr[7];
  9. uniform sampler2D senvmap_brdf;
  10. uniform sampler2D senvmap_radiance;
  11. #ifdef SPIRV
  12. uniform float envmap_num_mipmaps;
  13. #else
  14. uniform int envmap_num_mipmaps;
  15. #endif
  16. uniform sampler2D ssaotex;
  17. uniform vec2 camera_proj;
  18. uniform vec3 eye;
  19. uniform vec3 eye_look;
  20. uniform vec3 point_pos;
  21. uniform vec3 point_col;
  22. #ifdef _Voxel
  23. uniform float cone_offset;
  24. uniform float cone_aperture;
  25. #endif
  26. uniform vec3 light_area0;
  27. uniform vec3 light_area1;
  28. uniform vec3 light_area2;
  29. uniform vec3 light_area3;
  30. uniform sampler2D sltc_mat;
  31. uniform sampler2D sltc_mag;
  32. #include "gbuffer.glsl"
  33. #include "brdf.glsl"
  34. #include "math.glsl"
  35. #include "shirr.glsl"
  36. #ifdef _Voxel
  37. #include "conetrace.glsl"
  38. #endif
  39. in vec2 tex_coord;
  40. in vec3 view_ray;
  41. out vec4 frag_color;
  42. const float LUT_SIZE = 64.0;
  43. const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE;
  44. const float LUT_BIAS = 0.5 / LUT_SIZE;
  45. float integrate_edge(vec3 v1, vec3 v2) {
  46. float cos_theta = dot(v1, v2);
  47. float theta = acos(cos_theta);
  48. float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0);
  49. return res;
  50. }
  51. float ltc_evaluate(vec3 N, vec3 V, float dotnv, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) {
  52. // Construct orthonormal basis around N
  53. vec3 T1, T2;
  54. T1 = normalize(V - N * dotnv);
  55. T2 = cross(N, T1);
  56. // Rotate area light in (T1, T2, R) basis
  57. Minv = mul(transpose(mat3(T1, T2, N)), Minv);
  58. // Polygon (allocate 5 vertices for clipping)
  59. vec3 L0 = mul((points0 - P), Minv);
  60. vec3 L1 = mul((points1 - P), Minv);
  61. vec3 L2 = mul((points2 - P), Minv);
  62. vec3 L3 = mul((points3 - P), Minv);
  63. vec3 L4 = vec3(0.0, 0.0, 0.0);
  64. int n = 0;
  65. // Detect clipping config
  66. int config = 0;
  67. if (L0.z > 0.0) config += 1;
  68. if (L1.z > 0.0) config += 2;
  69. if (L2.z > 0.0) config += 4;
  70. if (L3.z > 0.0) config += 8;
  71. // Clip
  72. if (config == 0) {
  73. // Clip all
  74. }
  75. else if (config == 1) { // V1 clip V2 V3 V4
  76. n = 3;
  77. L1 = -L1.z * L0 + L0.z * L1;
  78. L2 = -L3.z * L0 + L0.z * L3;
  79. }
  80. else if (config == 2) { // V2 clip V1 V3 V4
  81. n = 3;
  82. L0 = -L0.z * L1 + L1.z * L0;
  83. L2 = -L2.z * L1 + L1.z * L2;
  84. }
  85. else if (config == 3) { // V1 V2 clip V3 V4
  86. n = 4;
  87. L2 = -L2.z * L1 + L1.z * L2;
  88. L3 = -L3.z * L0 + L0.z * L3;
  89. }
  90. else if (config == 4) { // V3 clip V1 V2 V4
  91. n = 3;
  92. L0 = -L3.z * L2 + L2.z * L3;
  93. L1 = -L1.z * L2 + L2.z * L1;
  94. }
  95. else if (config == 5) { // V1 V3 clip V2 V4) impossible
  96. n = 0;
  97. }
  98. else if (config == 6) { // V2 V3 clip V1 V4
  99. n = 4;
  100. L0 = -L0.z * L1 + L1.z * L0;
  101. L3 = -L3.z * L2 + L2.z * L3;
  102. }
  103. else if (config == 7) { // V1 V2 V3 clip V4
  104. n = 5;
  105. L4 = -L3.z * L0 + L0.z * L3;
  106. L3 = -L3.z * L2 + L2.z * L3;
  107. }
  108. else if (config == 8) { // V4 clip V1 V2 V3
  109. n = 3;
  110. L0 = -L0.z * L3 + L3.z * L0;
  111. L1 = -L2.z * L3 + L3.z * L2;
  112. L2 = L3;
  113. }
  114. else if (config == 9) { // V1 V4 clip V2 V3
  115. n = 4;
  116. L1 = -L1.z * L0 + L0.z * L1;
  117. L2 = -L2.z * L3 + L3.z * L2;
  118. }
  119. else if (config == 10) { // V2 V4 clip V1 V3) impossible
  120. n = 0;
  121. }
  122. else if (config == 11) { // V1 V2 V4 clip V3
  123. n = 5;
  124. L4 = L3;
  125. L3 = -L2.z * L3 + L3.z * L2;
  126. L2 = -L2.z * L1 + L1.z * L2;
  127. }
  128. else if (config == 12) { // V3 V4 clip V1 V2
  129. n = 4;
  130. L1 = -L1.z * L2 + L2.z * L1;
  131. L0 = -L0.z * L3 + L3.z * L0;
  132. }
  133. else if (config == 13) { // V1 V3 V4 clip V2
  134. n = 5;
  135. L4 = L3;
  136. L3 = L2;
  137. L2 = -L1.z * L2 + L2.z * L1;
  138. L1 = -L1.z * L0 + L0.z * L1;
  139. }
  140. else if (config == 14) { // V2 V3 V4 clip V1
  141. n = 5;
  142. L4 = -L0.z * L3 + L3.z * L0;
  143. L0 = -L0.z * L1 + L1.z * L0;
  144. }
  145. else if (config == 15) { // V1 V2 V3 V4
  146. n = 4;
  147. }
  148. if (n == 0) return 0.0;
  149. if (n == 3) L3 = L0;
  150. if (n == 4) L4 = L0;
  151. // Project onto sphere
  152. L0 = normalize(L0);
  153. L1 = normalize(L1);
  154. L2 = normalize(L2);
  155. L3 = normalize(L3);
  156. L4 = normalize(L4);
  157. // Integrate
  158. float sum = 0.0;
  159. sum += integrate_edge(L0, L1);
  160. sum += integrate_edge(L1, L2);
  161. sum += integrate_edge(L2, L3);
  162. if (n >= 4) sum += integrate_edge(L3, L4);
  163. if (n == 5) sum += integrate_edge(L4, L0);
  164. return max(0.0, -sum);
  165. }
  166. vec3 sample_light(const vec3 p, const vec3 n, const vec3 v, const float dotnv, const vec3 lp, const vec3 light_col,
  167. const vec3 albedo, const float rough, const vec3 f0, const float occ
  168. #ifdef _Voxel
  169. , sampler3D voxels, vec3 voxpos
  170. #endif
  171. ) {
  172. vec3 ld = lp - p;
  173. vec3 l = normalize(ld);
  174. float dotnl = max(0.0, dot(n, l));
  175. float theta = acos(dotnv);
  176. vec2 tuv = vec2(rough, theta / (0.5 * PI));
  177. tuv = tuv * LUT_SCALE + LUT_BIAS;
  178. vec4 t = textureLod(sltc_mat, tuv, 0.0);
  179. mat3 inv = mat3(
  180. vec3(1.0, 0.0, t.y),
  181. vec3(0.0, t.z, 0.0),
  182. vec3(t.w, 0.0, t.x));
  183. float ltcspec = ltc_evaluate(n, v, dotnv, p, inv, light_area0, light_area1, light_area2, light_area3);
  184. ltcspec *= textureLod(sltc_mag, tuv, 0.0).a;
  185. mat3 m1 = mat3(
  186. vec3(1.0, 0.0, 0.0),
  187. vec3(0.0, 1.0, 0.0),
  188. vec3(0.0, 0.0, 1.0));
  189. float ltcdiff = ltc_evaluate(n, v, dotnv, p, m1, light_area0, light_area1, light_area2, light_area3);
  190. vec3 direct = albedo * ltcdiff + ltcspec * 0.05;
  191. direct *= attenuate(distance(p, lp));
  192. direct *= light_col;
  193. direct *= clamp(dotnl + 2.0 * occ * occ - 1.0, 0.0, 1.0); // Micro shadowing
  194. #ifdef _Voxel
  195. float voxshadow = 1.0 - trace_shadow(voxels, voxpos, l);
  196. direct *= vec3(voxshadow, voxshadow, voxshadow);
  197. #endif
  198. return direct;
  199. }
  200. void main() {
  201. vec4 g0 = textureLod(gbuffer0, tex_coord, 0.0); // Normal.xy, roughness, metallic/matid
  202. vec3 n;
  203. n.z = 1.0 - abs(g0.x) - abs(g0.y);
  204. n.xy = n.z >= 0.0 ? g0.xy : octahedron_wrap(g0.xy);
  205. n = normalize(n);
  206. float roughness = g0.b;
  207. float metallic;
  208. uint matid;
  209. unpack_f32_i16(g0.a, metallic, matid);
  210. vec4 g1 = textureLod(gbuffer1, tex_coord, 0.0); // Basecolor.rgb, occ
  211. float occ = g1.a;
  212. vec3 albedo = surface_albedo(g1.rgb, metallic); // g1.rgb - basecolor
  213. vec3 f0 = surface_f0(g1.rgb, metallic);
  214. float depth = textureLod(gbufferD, tex_coord, 0.0).r * 2.0 - 1.0;
  215. vec3 p = get_pos(eye, eye_look, normalize(view_ray), depth, camera_proj);
  216. vec3 v = normalize(eye - p);
  217. float dotnv = max(0.0, dot(n, v));
  218. occ = mix(1.0, occ, dotnv); // AO Fresnel
  219. vec2 env_brdf = texelFetch(senvmap_brdf, ivec2(vec2(roughness, 1.0 - dotnv) * 256.0), 0).xy;
  220. // Envmap
  221. vec3 envl = sh_irradiance(vec3(n.x * envmap_data.z - n.y * envmap_data.y, n.x * envmap_data.y + n.y * envmap_data.z, n.z), shirr);
  222. envl /= PI;
  223. vec3 reflection_world = reflect(-v, n);
  224. float lod = mip_from_roughness(roughness, float(envmap_num_mipmaps));
  225. vec3 prefiltered_color = textureLod(senvmap_radiance, envmap_equirect(reflection_world, envmap_data.x), lod).rgb;
  226. envl.rgb *= albedo;
  227. // Indirect specular
  228. envl.rgb += prefiltered_color * (f0 * env_brdf.x + env_brdf.y) * 1.5;
  229. envl.rgb *= envmap_data.w * occ;
  230. #ifdef _Voxel
  231. vec3 voxpos = p / voxelgi_half_extents;
  232. float voxao = 1.0 - trace_ao(voxpos, n, voxels);
  233. envl.rgb *= vec3(voxao, voxao, voxao);
  234. #endif
  235. frag_color.rgb = envl;
  236. frag_color.rgb *= textureLod(ssaotex, tex_coord, 0.0).r;
  237. if (matid == uint(1)) { // Emission
  238. frag_color.rgb += g1.rgb; // materialid
  239. albedo = vec3(0.0, 0.0, 0.0);
  240. }
  241. frag_color.rgb += sample_light(p, n, v, dotnv, point_pos, point_col, albedo, roughness, f0, occ
  242. #ifdef _Voxel
  243. , voxels, voxpos
  244. #endif
  245. );
  246. frag_color.a = 1.0; // Mark as opaque
  247. }