|
@@ -363,57 +363,62 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
|
|
|
ray_pos += (ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) + cam_normal * 1.4) * bias / sdfgi.cascades[cascade].to_cell;
|
|
|
}
|
|
|
float softness = 0.2 + min(1.0, roughness * 5.0) * 4.0; //approximation to roughness so it does not seem like a hard fade
|
|
|
- while (length(ray_pos) < max_distance) {
|
|
|
- for (uint i = 0; i < sdfgi.max_cascades; i++) {
|
|
|
- if (i >= cascade && length(ray_pos) < radius_sizes[i]) {
|
|
|
- cascade = max(i, cascade); //never go down
|
|
|
-
|
|
|
- vec3 pos = ray_pos - sdfgi.cascades[i].position;
|
|
|
- pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
|
|
|
-
|
|
|
- float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.1;
|
|
|
-
|
|
|
- vec4 hit_light = vec4(0.0);
|
|
|
- if (distance < softness) {
|
|
|
- hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb;
|
|
|
- hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
|
|
|
- hit_light.a = clamp(1.0 - (distance / softness), 0.0, 1.0);
|
|
|
- hit_light.rgb *= hit_light.a;
|
|
|
- }
|
|
|
+ uint i = 0;
|
|
|
+ bool found = false;
|
|
|
+ while (true) {
|
|
|
+ if (length(ray_pos) >= max_distance || light_accum.a > 0.99) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!found && i >= cascade && length(ray_pos) < radius_sizes[i]) {
|
|
|
+ uint next_i = min(i + 1, sdfgi.max_cascades - 1);
|
|
|
+ cascade = max(i, cascade); //never go down
|
|
|
|
|
|
- distance /= sdfgi.cascades[i].to_cell;
|
|
|
+ vec3 pos = ray_pos - sdfgi.cascades[i].position;
|
|
|
+ pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
|
|
|
|
|
|
- if (i < (sdfgi.max_cascades - 1)) {
|
|
|
- pos = ray_pos - sdfgi.cascades[i + 1].position;
|
|
|
- pos *= sdfgi.cascades[i + 1].to_cell * pos_to_uvw;
|
|
|
+ float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
|
|
|
|
|
|
- float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.1;
|
|
|
+ vec4 hit_light = vec4(0.0);
|
|
|
+ if (fdistance < softness) {
|
|
|
+ hit_light.rgb = textureLod(sampler3D(light_cascades[i], linear_sampler), pos, 0.0).rgb;
|
|
|
+ hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
|
|
|
+ hit_light.a = clamp(1.0 - (fdistance / softness), 0.0, 1.0);
|
|
|
+ hit_light.rgb *= hit_light.a;
|
|
|
+ }
|
|
|
|
|
|
- vec4 hit_light2 = vec4(0.0);
|
|
|
- if (distance2 < softness) {
|
|
|
- hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb;
|
|
|
- hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
|
|
|
- hit_light2.a = clamp(1.0 - (distance2 / softness), 0.0, 1.0);
|
|
|
- hit_light2.rgb *= hit_light2.a;
|
|
|
- }
|
|
|
+ fdistance /= sdfgi.cascades[i].to_cell;
|
|
|
|
|
|
- float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1];
|
|
|
- float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
|
|
|
+ if (i < (sdfgi.max_cascades - 1)) {
|
|
|
+ pos = ray_pos - sdfgi.cascades[next_i].position;
|
|
|
+ pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw;
|
|
|
|
|
|
- distance2 /= sdfgi.cascades[i + 1].to_cell;
|
|
|
+ float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
|
|
|
|
|
|
- hit_light = mix(hit_light, hit_light2, blend);
|
|
|
- distance = mix(distance, distance2, blend);
|
|
|
+ vec4 hit_light2 = vec4(0.0);
|
|
|
+ if (fdistance2 < softness) {
|
|
|
+ hit_light2.rgb = textureLod(sampler3D(light_cascades[next_i], linear_sampler), pos, 0.0).rgb;
|
|
|
+ hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
|
|
|
+ hit_light2.a = clamp(1.0 - (fdistance2 / softness), 0.0, 1.0);
|
|
|
+ hit_light2.rgb *= hit_light2.a;
|
|
|
}
|
|
|
|
|
|
- light_accum += hit_light;
|
|
|
- ray_pos += ray_dir * distance;
|
|
|
- break;
|
|
|
+ float prev_radius = i == 0 ? 0.0 : radius_sizes[max(0, i - 1)];
|
|
|
+ float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
|
|
|
+
|
|
|
+ fdistance2 /= sdfgi.cascades[next_i].to_cell;
|
|
|
+
|
|
|
+ hit_light = mix(hit_light, hit_light2, blend);
|
|
|
+ fdistance = mix(fdistance, fdistance2, blend);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (light_accum.a > 0.99) {
|
|
|
- break;
|
|
|
+ light_accum += hit_light;
|
|
|
+ ray_pos += ray_dir * fdistance;
|
|
|
+ found = true;
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ if (i == sdfgi.max_cascades) {
|
|
|
+ i = 0;
|
|
|
+ found = false;
|
|
|
}
|
|
|
}
|
|
|
|