@@ -915,23 +915,35 @@ 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 mip = sqrt (roughness) * MAX_ROUGHNESS_LOD;
919+ float mip_min = pow (roughness, 2.0 ) * MAX_ROUGHNESS_LOD; // Ensures fully rough materials don't have reflection contact hardening.
918920 if (reflections.data[ref_index].box_project) { // box project
919921
920922 vec3 nrdir = normalize (local_ref_vec);
921923 vec3 rbmax = (box_extents - local_pos) / nrdir;
922924 vec3 rbmin = (- box_extents - local_pos) / nrdir;
923925
924926 vec3 rbminmax = mix (rbmin, rbmax, greaterThan (nrdir, vec3 (0.0 , 0.0 , 0.0 )));
927+ float distance_to_hit_point = min (min (rbminmax.x, rbminmax.y), rbminmax.z);
925928
926- float fa = min (min (rbminmax.x, rbminmax.y), rbminmax.z);
927- vec3 posonbox = local_pos + nrdir * fa;
929+ vec3 posonbox = local_pos + nrdir * distance_to_hit_point;
928930 local_ref_vec = posonbox - reflections.data[ref_index].box_offset;
931+
932+ float fresnel = 1.0 - max (dot (normal, - normalize (vertex)), 0.0 );
933+ fresnel = pow (fresnel, 2.0 );
934+
935+ float reflection_roughness = distance_to_hit_point * (1.0 - fresnel); // Adjust contact hardening strength by viewing angle.
936+ reflection_roughness /= MAX_ROUGHNESS_LOD;
937+ reflection_roughness += ((1.0 - fresnel) * sqrt (roughness)); // Increase roughness when viewing angle is perpendicular to avoid overly sharp reflections on rough surfaces.
938+
939+ float mip_offset = clamp (reflection_roughness, 0.0 , 1.0 ); // Compute new mip level based on the mip offset value (this is mostly arbitrary).
940+ mip = mix (mip_min, mip, mip_offset);
929941 }
930942
931943 vec4 reflection;
932944 float reflection_blend = max (0.0 , blend - reflection_accum.a);
933945
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();
946+ 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();
935947 reflection.rgb *= reflections.data[ref_index].exposure_normalization;
936948 reflection.a = reflection_blend;
937949
0 commit comments