-
-
Notifications
You must be signed in to change notification settings - Fork 23.5k
Add contact hardening and fresnel based roughness to reflection probes reflections when using box projection #106292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1666,20 +1666,32 @@ void reflection_process(samplerCube reflection_map, | |
| vec3 ref_normal = normalize(reflect(vertex, normal)); | ||
| ref_normal = (local_matrix * vec4(ref_normal, 0.0)).xyz; | ||
|
|
||
| float mip = sqrt(roughness) * MAX_ROUGHNESS_LOD; | ||
| float mip_min = pow(roughness, 2.0) * MAX_ROUGHNESS_LOD; // Ensures fully rough materials don't have reflection contact hardening. | ||
| if (use_box_project) { //box project | ||
|
|
||
| vec3 nrdir = normalize(ref_normal); | ||
| vec3 rbmax = (box_extents - local_pos) / nrdir; | ||
| vec3 rbmin = (-box_extents - local_pos) / nrdir; | ||
|
|
||
| vec3 rbminmax = mix(rbmin, rbmax, vec3(greaterThan(nrdir, vec3(0.0, 0.0, 0.0)))); | ||
| float distance_to_hit_point = min(min(rbminmax.x, rbminmax.y), rbminmax.z); | ||
|
|
||
| float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); | ||
| vec3 posonbox = local_pos + nrdir * fa; | ||
| vec3 posonbox = local_pos + nrdir * distance_to_hit_point; | ||
| ref_normal = posonbox - box_offset.xyz; | ||
|
|
||
| float fresnel = 1.0 - max(dot(normal, -normalize(vertex)), 0.0); | ||
| fresnel = pow(fresnel, 2.0); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here as well |
||
|
|
||
| float reflection_roughness = distance_to_hit_point / MAX_ROUGHNESS_LOD; // Remap distance to be relative to amount of mips. | ||
| reflection_roughness *= 1.0 - fresnel; | ||
| reflection_roughness += ((1.0 - fresnel) * sqrt(roughness)); // Increase roughness when viewing angle is perpendicular to avoid overly sharp reflections on rough surfaces. | ||
|
|
||
| float mip_offset = clamp(reflection_roughness, 0.0, 1.0); // Compute new mip level based on the mip offset value (this is mostly arbitrary). | ||
| mip = mix(mip_min, mip, mip_offset); | ||
| } | ||
|
|
||
| reflection.rgb = srgb_to_linear(textureLod(reflection_map, ref_normal, roughness * MAX_ROUGHNESS_LOD).rgb); | ||
| reflection.rgb = srgb_to_linear(textureLod(reflection_map, ref_normal, mip).rgb); | ||
|
|
||
| if (exterior) { | ||
| reflection.rgb = mix(skybox, reflection.rgb, blend); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -930,23 +930,35 @@ void reflection_process(uint ref_index, vec3 vertex, hvec3 ref_vec, hvec3 normal | |
|
|
||
| vec3 local_ref_vec = (reflections.data[ref_index].local_matrix * vec4(ref_vec, 0.0)).xyz; | ||
|
|
||
| float mip = sqrt(roughness) * MAX_ROUGHNESS_LOD; | ||
| float mip_min = pow(roughness, 2.0) * MAX_ROUGHNESS_LOD; // Ensures fully rough materials don't have reflection contact hardening. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Squaring roughness doesn't make sense here. Previously we There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is done to prevent fully rough surfaces exhibiting reflections. If we just lerp from In the frostbite implementation this is handled by doing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, I don't trust mobile compilers to realize that the pow can be computed with a single multiplication. |
||
| if (reflections.data[ref_index].box_project) { //box project | ||
|
|
||
| vec3 nrdir = normalize(local_ref_vec); | ||
| vec3 rbmax = (box_extents - local_pos) / nrdir; | ||
| vec3 rbmin = (-box_extents - local_pos) / nrdir; | ||
|
|
||
| vec3 rbminmax = mix(rbmin, rbmax, greaterThan(nrdir, vec3(0.0, 0.0, 0.0))); | ||
| float distance_to_hit_point = min(min(rbminmax.x, rbminmax.y), rbminmax.z); | ||
|
|
||
| float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); | ||
| vec3 posonbox = local_pos + nrdir * fa; | ||
| vec3 posonbox = local_pos + nrdir * distance_to_hit_point; | ||
| local_ref_vec = posonbox - reflections.data[ref_index].box_offset; | ||
|
|
||
| float fresnel = 1.0 - max(dot(normal, -normalize(vertex)), 0.0); | ||
| fresnel = pow(fresnel, 4.0); | ||
|
|
||
| float reflection_roughness = distance_to_hit_point / MAX_ROUGHNESS_LOD; // Remap distance to be relative to amount of mips. | ||
| reflection_roughness *= 1.0 - fresnel; | ||
| reflection_roughness += ((1.0 - fresnel) * sqrt(roughness)); // Increase roughness when viewing angle is perpendicular to avoid overly sharp reflections on rough surfaces. | ||
|
|
||
| float mip_offset = clamp(reflection_roughness, 0.0, 1.0); // Compute new mip level based on the mip offset value (this is mostly arbitrary). | ||
| mip = mix(mip_min, mip, mip_offset); | ||
| } | ||
|
|
||
| hvec4 reflection; | ||
| half reflection_blend = max(half(0.0), blend - reflection_accum.a); | ||
|
|
||
| reflection.rgb = hvec3(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(); | ||
| reflection.rgb = hvec3(textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), mip).rgb) * sc_luminance_multiplier(); | ||
| reflection.rgb *= half(reflections.data[ref_index].exposure_normalization); | ||
| reflection.a = reflection_blend; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would feel better if you avoided the pow function in this case. Sure, some compilers might recognize that this has an integer exponent of two, but I would rather not rely on that.