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:
parent
58fc0f759b
commit
c4daf1c4ba
1 changed files with 55 additions and 50 deletions
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue