Treat specular less than 0.02 as occlusion
This is a very common hack used in almost all PBR renderers to allow removing specular contribution in dielectric materials
This commit is contained in:
parent
674ccdb244
commit
0c65ed38a6
4 changed files with 11 additions and 5 deletions
|
@ -241,7 +241,7 @@
|
|||
A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness].
|
||||
</member>
|
||||
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5">
|
||||
Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources.
|
||||
Adjusts the strength of specular reflections. Specular reflections are composed of scene reflections and the specular lobe which is the bright spot that is reflected from light sources. When set to [code]0.0[/code], no specular reflections will be visible. This differs from the [constant SPECULAR_DISABLED] [enum SpecularMode] as [constant SPECULAR_DISABLED] only applies to the specular lobe from the light source.
|
||||
[b]Note:[/b] Unlike [member metallic], this is not energy-conserving, so it should be left at [code]0.5[/code] in most cases. See also [member roughness].
|
||||
</member>
|
||||
<member name="metallic_texture" type="Texture2D" setter="set_texture" getter="get_texture">
|
||||
|
|
|
@ -686,7 +686,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
|
|||
#endif // LIGHT_ANISOTROPY_USED
|
||||
// F
|
||||
float cLdotH5 = SchlickFresnel(cLdotH);
|
||||
vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
|
||||
// Calculate Fresnel using cheap approximate specular occlusion term from Filament:
|
||||
// https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion
|
||||
float f90 = clamp(50.0 * f0.g, 0.0, 1.0);
|
||||
vec3 F = f0 + (f90 - f0) * cLdotH5;
|
||||
|
||||
vec3 specular_brdf_NL = cNdotL * D * F * G;
|
||||
|
||||
|
@ -1107,7 +1110,7 @@ void main() {
|
|||
|
||||
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
|
||||
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
|
||||
specular_light *= env.x * f0 + env.y;
|
||||
specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1381,7 +1381,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
|
||||
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
|
||||
|
||||
specular_light *= env.x * f0 + env.y;
|
||||
specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -199,7 +199,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
|
|||
#endif // LIGHT_ANISOTROPY_USED
|
||||
// F
|
||||
float cLdotH5 = SchlickFresnel(cLdotH);
|
||||
vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
|
||||
// Calculate Fresnel using specular occlusion term from Filament:
|
||||
// https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion
|
||||
float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0);
|
||||
vec3 F = f0 + (f90 - f0) * cLdotH5;
|
||||
|
||||
vec3 specular_brdf_NL = cNdotL * D * F * G;
|
||||
|
||||
|
|
Loading…
Reference in a new issue