HDR: Safer divisions
This commit is contained in:
parent
dd97ee58db
commit
7b5255eac4
6 changed files with 14 additions and 8 deletions
|
@ -240,7 +240,7 @@ float get_ray_end(vec3 ray_origin, vec3 ray_dir, float t_max)
|
||||||
// Handle the camera being underground
|
// Handle the camera being underground
|
||||||
float earth_radius = min(ray_altitude, get_earth_radius());
|
float earth_radius = min(ray_altitude, get_earth_radius());
|
||||||
float atmos_dist = ray_sphere_intersection(ray_origin, ray_dir, get_atmosphere_radius());
|
float atmos_dist = ray_sphere_intersection(ray_origin, ray_dir, get_atmosphere_radius());
|
||||||
float ground_dist = ray_sphere_intersection(ray_origin, ray_dir, earth_radius);
|
float ground_dist = ray_sphere_intersection(ray_origin, ray_dir, earth_radius + 1e-3);
|
||||||
float t_d;
|
float t_d;
|
||||||
if (ray_altitude < get_atmosphere_radius()) {
|
if (ray_altitude < get_atmosphere_radius()) {
|
||||||
// We are inside the atmosphere
|
// We are inside the atmosphere
|
||||||
|
|
|
@ -68,7 +68,7 @@ void main()
|
||||||
|
|
||||||
ray_dir = ray_end - ray_origin;
|
ray_dir = ray_end - ray_origin;
|
||||||
t_max = length(ray_dir);
|
t_max = length(ray_dir);
|
||||||
ray_dir /= t_max;
|
ray_dir /= max(t_max, 1e-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 transmittance;
|
vec4 transmittance;
|
||||||
|
|
|
@ -80,12 +80,13 @@ int getIndex(int counter)
|
||||||
return int(texture(fg_ClusteredIndices, coords).r);
|
return int(texture(fg_ClusteredIndices, coords).r);
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_square_falloff_attenuation(vec3 to_light, float inv_range)
|
float get_square_falloff_attenuation(vec3 to_light, float range)
|
||||||
{
|
{
|
||||||
|
float inv_range = 1.0 / max(range, 1e-5);
|
||||||
float dd = dot(to_light, to_light);
|
float dd = dot(to_light, to_light);
|
||||||
float factor = dd * inv_range * inv_range;
|
float factor = dd * inv_range * inv_range;
|
||||||
float smooth_factor = max(1.0 - factor * factor, 0.0);
|
float smooth_factor = max(1.0 - factor * factor, 0.0);
|
||||||
return (smooth_factor * smooth_factor) / max(dd, 0.0001);
|
return (smooth_factor * smooth_factor) / max(dd, 1e-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_spot_angle_attenuation(vec3 l, vec3 light_dir,
|
float get_spot_angle_attenuation(vec3 l, vec3 light_dir,
|
||||||
|
@ -124,7 +125,7 @@ vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0
|
||||||
vec3 L = normalize(to_light);
|
vec3 L = normalize(to_light);
|
||||||
|
|
||||||
float attenuation = get_square_falloff_attenuation(
|
float attenuation = get_square_falloff_attenuation(
|
||||||
to_light, 1.0 / light.range);
|
to_light, light.range);
|
||||||
if (attenuation <= 0.0)
|
if (attenuation <= 0.0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -144,7 +145,7 @@ vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0
|
||||||
vec3 L = normalize(to_light);
|
vec3 L = normalize(to_light);
|
||||||
|
|
||||||
float attenuation = get_square_falloff_attenuation(
|
float attenuation = get_square_falloff_attenuation(
|
||||||
to_light, 1.0 / light.range);
|
to_light, light.range);
|
||||||
attenuation *= get_spot_angle_attenuation(
|
attenuation *= get_spot_angle_attenuation(
|
||||||
L, light.direction, light.cos_cutoff, light.exponent);
|
L, light.direction, light.cos_cutoff, light.exponent);
|
||||||
if (attenuation <= 0.0)
|
if (attenuation <= 0.0)
|
||||||
|
|
|
@ -26,6 +26,10 @@ float safe_sqrt(float x) {
|
||||||
return sqrt(max(x, 0.0));
|
return sqrt(max(x, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float safe_asin(float x) {
|
||||||
|
return asin(clamp(x, -1.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
float safe_acos(float x) {
|
float safe_acos(float x) {
|
||||||
return acos(clamp(x, -1.0, 1.0));
|
return acos(clamp(x, -1.0, 1.0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ const float SUN_SIN_HALF_ANGULAR_DIAMETER = 0.0047560042817014138; // sin(radian
|
||||||
float M_PI();
|
float M_PI();
|
||||||
float sqr(float x);
|
float sqr(float x);
|
||||||
float saturate(float x);
|
float saturate(float x);
|
||||||
|
float safe_asin(float x);
|
||||||
// atmos_spectral.glsl
|
// atmos_spectral.glsl
|
||||||
vec4 get_sun_spectral_irradiance();
|
vec4 get_sun_spectral_irradiance();
|
||||||
vec3 linear_srgb_from_spectral_samples(vec4 L);
|
vec3 linear_srgb_from_spectral_samples(vec4 L);
|
||||||
|
@ -51,7 +52,7 @@ void main()
|
||||||
vec3 frag_ray_dir = normalize(ray_dir);
|
vec3 frag_ray_dir = normalize(ray_dir);
|
||||||
float azimuth = atan(frag_ray_dir.y, frag_ray_dir.x) / M_PI() * 0.5 + 0.5;
|
float azimuth = atan(frag_ray_dir.y, frag_ray_dir.x) / M_PI() * 0.5 + 0.5;
|
||||||
// Undo the non-linear transformation from the sky-view LUT
|
// Undo the non-linear transformation from the sky-view LUT
|
||||||
float l = asin(frag_ray_dir.z);
|
float l = safe_asin(frag_ray_dir.z);
|
||||||
float elev = sqrt(abs(l) / (M_PI() * 0.5)) * sign(l) * 0.5 + 0.5;
|
float elev = sqrt(abs(l) / (M_PI() * 0.5)) * sign(l) * 0.5 + 0.5;
|
||||||
|
|
||||||
vec4 sky_radiance = texture(sky_view_tex, vec2(azimuth, elev));
|
vec4 sky_radiance = texture(sky_view_tex, vec2(azimuth, elev));
|
||||||
|
|
|
@ -87,7 +87,7 @@ vec3 surface_eval_analytical(
|
||||||
float G = G1_Smith_GGX(NdotV, a2) * G1_Smith_GGX(NdotL, a2);
|
float G = G1_Smith_GGX(NdotV, a2) * G1_Smith_GGX(NdotL, a2);
|
||||||
float D = D_GGX(NdotH, a2);
|
float D = D_GGX(NdotH, a2);
|
||||||
|
|
||||||
vec3 f_specular = (F * a2) / (D * G);
|
vec3 f_specular = (F * a2) / max(D * G, 1e-5);
|
||||||
vec3 f_diffuse = (vec3(1.0) - F) * c_diff * M_1_PI();
|
vec3 f_diffuse = (vec3(1.0) - F) * c_diff * M_1_PI();
|
||||||
vec3 bsdf = f_diffuse + f_specular;
|
vec3 bsdf = f_diffuse + f_specular;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue