Fixed a SDFGI reflections bug in Radeon

-Code was using too many conditionals.
-Rewrote it to use less and it now works fine.
This commit is contained in:
reduz 2021-02-06 22:49:33 -03:00
parent 58fc0f759b
commit c4daf1c4ba

View file

@ -363,58 +363,63 @@ 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; 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 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) { uint i = 0;
for (uint i = 0; i < sdfgi.max_cascades; i++) { bool found = false;
if (i >= cascade && length(ray_pos) < radius_sizes[i]) { while (true) {
cascade = max(i, cascade); //never go down if (length(ray_pos) >= max_distance || light_accum.a > 0.99) {
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;
}
distance /= sdfgi.cascades[i].to_cell;
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 distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.1;
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;
}
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);
distance2 /= sdfgi.cascades[i + 1].to_cell;
hit_light = mix(hit_light, hit_light2, blend);
distance = mix(distance, distance2, blend);
}
light_accum += hit_light;
ray_pos += ray_dir * distance;
break;
}
}
if (light_accum.a > 0.99) {
break; 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
vec3 pos = ray_pos - sdfgi.cascades[i].position;
pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).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;
}
fdistance /= sdfgi.cascades[i].to_cell;
if (i < (sdfgi.max_cascades - 1)) {
pos = ray_pos - sdfgi.cascades[next_i].position;
pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw;
float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
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;
}
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);
}
light_accum += hit_light;
ray_pos += ray_dir * fdistance;
found = true;
}
i++;
if (i == sdfgi.max_cascades) {
i = 0;
found = false;
}
} }
vec3 light = light_accum.rgb / max(light_accum.a, 0.00001); vec3 light = light_accum.rgb / max(light_accum.a, 0.00001);