summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl')
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl26
1 files changed, 20 insertions, 6 deletions
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
index 28f4dc59ec..1d46f59408 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
@@ -21,24 +21,38 @@ void main() {
vec2 uv = ((vec2(id.xy) * 2.0 + 1.0) / (params.face_size) - 1.0);
vec3 N = texelCoordToVec(uv, id.z);
- //vec4 color = color_interp;
-
if (params.use_direct_write) {
imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0));
} else {
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
+ float solid_angle_texel = 4.0 * M_PI / (6.0 * params.face_size * params.face_size);
+ float roughness2 = params.roughness * params.roughness;
+ float roughness4 = roughness2 * roughness2;
+ vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ mat3 T;
+ T[0] = normalize(cross(UpVector, N));
+ T[1] = cross(N, T[0]);
+ T[2] = N;
+
for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) {
vec2 xi = Hammersley(sampleNum, params.sample_count);
- vec3 H = ImportanceSampleGGX(xi, params.roughness, N);
- vec3 V = N;
- vec3 L = (2.0 * dot(V, H) * H - V);
+ vec3 H = T * ImportanceSampleGGX(xi, roughness4);
+ float NdotH = dot(N, H);
+ vec3 L = (2.0 * NdotH * H - N);
float ndotl = clamp(dot(N, L), 0.0, 1.0);
if (ndotl > 0.0) {
- sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
+ float D = DistributionGGX(NdotH, roughness4);
+ float pdf = D * NdotH / (4.0 * NdotH) + 0.0001;
+
+ float solid_angle_sample = 1.0 / (float(params.sample_count) * pdf + 0.0001);
+
+ float mipLevel = params.roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel);
+
+ sum.rgb += textureLod(source_cube, L, mipLevel).rgb * ndotl;
sum.a += ndotl;
}
}