Skip to content

Commit 2d34dc6

Browse files
lander-vrCalinou
andcommitted
Add contact hardening and fresnel based roughness to reflection probes reflections when using box projection
Co-authored-by: Calinou <[email protected]>
1 parent 19bb187 commit 2d34dc6

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,23 +915,37 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 ref_vec, vec3 normal,
915915

916916
vec3 local_ref_vec = (reflections.data[ref_index].local_matrix * vec4(ref_vec, 0.0)).xyz;
917917

918+
float distance_to_hit_point = 0.0;
919+
float mip = sqrt(roughness) * MAX_ROUGHNESS_LOD;
920+
float mip_min = pow(roughness, 2.0) * MAX_ROUGHNESS_LOD; // Ensures fully rough materials don't have reflection contact hardening.
918921
if (reflections.data[ref_index].box_project) { //box project
919922

920923
vec3 nrdir = normalize(local_ref_vec);
921924
vec3 rbmax = (box_extents - local_pos) / nrdir;
922925
vec3 rbmin = (-box_extents - local_pos) / nrdir;
923926

924927
vec3 rbminmax = mix(rbmin, rbmax, greaterThan(nrdir, vec3(0.0, 0.0, 0.0)));
928+
distance_to_hit_point = min(min(rbminmax.x, rbminmax.y), rbminmax.z);
925929

926930
float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z);
927931
vec3 posonbox = local_pos + nrdir * fa;
928932
local_ref_vec = posonbox - reflections.data[ref_index].box_offset;
933+
934+
float fresnel = 1.0 - max(dot(normal, -normalize(vertex)), 0.0);
935+
fresnel = pow(fresnel, 2.0);
936+
937+
float reflection_roughness = distance_to_hit_point * (1.0 - fresnel); // Adjust contact hardening strength by viewing angle.
938+
reflection_roughness /= MAX_ROUGHNESS_LOD;
939+
reflection_roughness += ((1.0 - fresnel) * sqrt(roughness)); // Increase roughness when viewing angle is perpendicular to avoid overly sharp reflections on rough surfaces.
940+
941+
float mip_offset = clamp(reflection_roughness, 0.0, 1.0); // Compute new mip level based on the mip offset value (this is mostly arbitrary).
942+
mip = mix(mip_min, mip, mip_offset);
929943
}
930944

931945
vec4 reflection;
932946
float reflection_blend = max(0.0, blend - reflection_accum.a);
933947

934-
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb * sc_luminance_multiplier();
948+
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), mip).rgb * sc_luminance_multiplier();
935949
reflection.rgb *= reflections.data[ref_index].exposure_normalization;
936950
reflection.a = reflection_blend;
937951

0 commit comments

Comments
 (0)