Fix T65298 Eevee: Principled BSDF doesn't use specular with metals
This does add some more register pressure as it passes a new vec3 down the shading function. But for now we care more about accuracy than efficiency.
This commit is contained in:
@@ -644,19 +644,19 @@ vec3 F_schlick(vec3 f0, float cos_theta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fresnel approximation for LTC area lights (not MRP) */
|
/* Fresnel approximation for LTC area lights (not MRP) */
|
||||||
vec3 F_area(vec3 f0, vec2 lut)
|
vec3 F_area(vec3 f0, vec3 f90, vec2 lut)
|
||||||
{
|
{
|
||||||
/* Unreal specular matching : if specular color is below 2% intensity,
|
/* Unreal specular matching : if specular color is below 2% intensity,
|
||||||
* treat as shadowning */
|
* treat as shadowning */
|
||||||
return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y + lut.x * f0;
|
return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fresnel approximation for IBL */
|
/* Fresnel approximation for IBL */
|
||||||
vec3 F_ibl(vec3 f0, vec2 lut)
|
vec3 F_ibl(vec3 f0, vec3 f90, vec2 lut)
|
||||||
{
|
{
|
||||||
/* Unreal specular matching : if specular color is below 2% intensity,
|
/* Unreal specular matching : if specular color is below 2% intensity,
|
||||||
* treat as shadowning */
|
* treat as shadowning */
|
||||||
return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y + lut.x * f0;
|
return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * lut.y * f90 + lut.x * f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GGX */
|
/* GGX */
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ Closure nodetree_exec(void)
|
|||||||
vec3 dielectric = vec3(0.034) * specular * 2.0;
|
vec3 dielectric = vec3(0.034) * specular * 2.0;
|
||||||
vec3 albedo = mix(basecol, vec3(0.0), metallic);
|
vec3 albedo = mix(basecol, vec3(0.0), metallic);
|
||||||
vec3 f0 = mix(dielectric, basecol, metallic);
|
vec3 f0 = mix(dielectric, basecol, metallic);
|
||||||
|
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
|
||||||
vec3 out_diff, out_spec, ssr_spec;
|
vec3 out_diff, out_spec, ssr_spec;
|
||||||
eevee_closure_default(N, albedo, f0, 1, roughness, 1.0, out_diff, out_spec, ssr_spec);
|
eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, out_diff, out_spec, ssr_spec);
|
||||||
|
|
||||||
Closure result = Closure(out_spec + out_diff * albedo,
|
Closure result = Closure(out_spec + out_diff * albedo,
|
||||||
1.0,
|
1.0,
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ void CLOSURE_NAME(vec3 N
|
|||||||
#ifdef CLOSURE_GLOSSY
|
#ifdef CLOSURE_GLOSSY
|
||||||
,
|
,
|
||||||
vec3 f0,
|
vec3 f0,
|
||||||
|
vec3 f90,
|
||||||
int ssr_id
|
int ssr_id
|
||||||
#endif
|
#endif
|
||||||
#if defined(CLOSURE_GLOSSY) || defined(CLOSURE_REFRACTION)
|
#if defined(CLOSURE_GLOSSY) || defined(CLOSURE_REFRACTION)
|
||||||
@@ -264,12 +265,12 @@ void CLOSURE_NAME(vec3 N
|
|||||||
|
|
||||||
#ifdef CLOSURE_GLOSSY
|
#ifdef CLOSURE_GLOSSY
|
||||||
vec2 brdf_lut_lights = texture(utilTex, vec3(lut_uv, 1.0)).ba;
|
vec2 brdf_lut_lights = texture(utilTex, vec3(lut_uv, 1.0)).ba;
|
||||||
out_spec *= F_area(f0, brdf_lut_lights.xy);
|
out_spec *= F_area(f0, f90, brdf_lut_lights.xy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CLOSURE_CLEARCOAT
|
#ifdef CLOSURE_CLEARCOAT
|
||||||
vec2 brdf_lut_lights_clear = texture(utilTex, vec3(lut_uv_clear, 1.0)).ba;
|
vec2 brdf_lut_lights_clear = texture(utilTex, vec3(lut_uv_clear, 1.0)).ba;
|
||||||
out_spec_clear *= F_area(vec3(0.04), brdf_lut_lights_clear.xy);
|
out_spec_clear *= F_area(vec3(0.04), vec3(1.0), brdf_lut_lights_clear.xy);
|
||||||
out_spec += out_spec_clear * C_intensity;
|
out_spec += out_spec_clear * C_intensity;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -454,7 +455,7 @@ void CLOSURE_NAME(vec3 N
|
|||||||
|
|
||||||
/* This factor is outputted to be used by SSR in order
|
/* This factor is outputted to be used by SSR in order
|
||||||
* to match the intensity of the regular reflections. */
|
* to match the intensity of the regular reflections. */
|
||||||
ssr_spec = F_ibl(f0, brdf_lut);
|
ssr_spec = F_ibl(f0, f90, brdf_lut);
|
||||||
float spec_occlu = specular_occlusion(NV, final_ao, roughness);
|
float spec_occlu = specular_occlusion(NV, final_ao, roughness);
|
||||||
|
|
||||||
/* The SSR pass recompute the occlusion to not apply it to the SSR */
|
/* The SSR pass recompute the occlusion to not apply it to the SSR */
|
||||||
@@ -475,7 +476,8 @@ void CLOSURE_NAME(vec3 N
|
|||||||
NV = dot(C_N, V);
|
NV = dot(C_N, V);
|
||||||
vec2 C_uv = lut_coords(NV, C_roughness);
|
vec2 C_uv = lut_coords(NV, C_roughness);
|
||||||
vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
|
vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg;
|
||||||
vec3 C_fresnel = F_ibl(vec3(0.04), C_brdf_lut) * specular_occlusion(NV, final_ao, C_roughness);
|
vec3 C_fresnel = F_ibl(vec3(0.04), vec3(1.0), C_brdf_lut) *
|
||||||
|
specular_occlusion(NV, final_ao, C_roughness);
|
||||||
|
|
||||||
out_spec += C_spec_accum.rgb * C_fresnel * C_intensity;
|
out_spec += C_spec_accum.rgb * C_fresnel * C_intensity;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1241,7 +1241,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
|
|||||||
{
|
{
|
||||||
N = normalize(N);
|
N = normalize(N);
|
||||||
vec3 out_spec, ssr_spec;
|
vec3 out_spec, ssr_spec;
|
||||||
eevee_closure_glossy(N, vec3(1.0), int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
|
eevee_closure_glossy(N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
|
||||||
vec3 vN = mat3(ViewMatrix) * N;
|
vec3 vN = mat3(ViewMatrix) * N;
|
||||||
result = CLOSURE_DEFAULT;
|
result = CLOSURE_DEFAULT;
|
||||||
result.radiance = out_spec * color.rgb;
|
result.radiance = out_spec * color.rgb;
|
||||||
@@ -1269,7 +1269,7 @@ void node_bsdf_glass(
|
|||||||
vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb :
|
vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb :
|
||||||
color.rgb; /* Simulate 2 transmission event */
|
color.rgb; /* Simulate 2 transmission event */
|
||||||
eevee_closure_glass(
|
eevee_closure_glass(
|
||||||
N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
|
N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
|
||||||
out_refr *= refr_color;
|
out_refr *= refr_color;
|
||||||
out_spec *= color.rgb;
|
out_spec *= color.rgb;
|
||||||
float fresnel = F_eta(ior, dot(N, cameraVec));
|
float fresnel = F_eta(ior, dot(N, cameraVec));
|
||||||
@@ -1339,12 +1339,15 @@ void node_bsdf_principled(vec4 base_color,
|
|||||||
vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
|
vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
|
||||||
f0 = mix(f0, spec_col, transmission);
|
f0 = mix(f0, spec_col, transmission);
|
||||||
|
|
||||||
|
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
|
||||||
|
|
||||||
vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
|
vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
|
||||||
|
|
||||||
float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface;
|
float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface;
|
||||||
eevee_closure_principled(N,
|
eevee_closure_principled(N,
|
||||||
mixed_ss_base_color,
|
mixed_ss_base_color,
|
||||||
f0,
|
f0,
|
||||||
|
f90,
|
||||||
int(ssr_id),
|
int(ssr_id),
|
||||||
roughness,
|
roughness,
|
||||||
CN,
|
CN,
|
||||||
@@ -1428,7 +1431,8 @@ void node_bsdf_principled_dielectric(vec4 base_color,
|
|||||||
float NV = dot(N, cameraVec);
|
float NV = dot(N, cameraVec);
|
||||||
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
|
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
|
||||||
|
|
||||||
eevee_closure_default(N, diffuse, f0, int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec);
|
eevee_closure_default(
|
||||||
|
N, diffuse, f0, vec3(1.0), int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec);
|
||||||
|
|
||||||
vec3 vN = mat3(ViewMatrix) * N;
|
vec3 vN = mat3(ViewMatrix) * N;
|
||||||
result = CLOSURE_DEFAULT;
|
result = CLOSURE_DEFAULT;
|
||||||
@@ -1471,7 +1475,9 @@ void node_bsdf_principled_metallic(vec4 base_color,
|
|||||||
N = normalize(N);
|
N = normalize(N);
|
||||||
vec3 out_spec, ssr_spec;
|
vec3 out_spec, ssr_spec;
|
||||||
|
|
||||||
eevee_closure_glossy(N, base_color.rgb, int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
|
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
|
||||||
|
|
||||||
|
eevee_closure_glossy(N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
|
||||||
|
|
||||||
vec3 vN = mat3(ViewMatrix) * N;
|
vec3 vN = mat3(ViewMatrix) * N;
|
||||||
result = CLOSURE_DEFAULT;
|
result = CLOSURE_DEFAULT;
|
||||||
@@ -1514,8 +1520,11 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
|
|||||||
vec3 out_spec, ssr_spec;
|
vec3 out_spec, ssr_spec;
|
||||||
N = normalize(N);
|
N = normalize(N);
|
||||||
|
|
||||||
|
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
|
||||||
|
|
||||||
eevee_closure_clearcoat(N,
|
eevee_closure_clearcoat(N,
|
||||||
base_color.rgb,
|
base_color.rgb,
|
||||||
|
f90,
|
||||||
int(ssr_id),
|
int(ssr_id),
|
||||||
roughness,
|
roughness,
|
||||||
CN,
|
CN,
|
||||||
@@ -1578,9 +1587,12 @@ void node_bsdf_principled_subsurface(vec4 base_color,
|
|||||||
float NV = dot(N, cameraVec);
|
float NV = dot(N, cameraVec);
|
||||||
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
|
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
|
||||||
|
|
||||||
|
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
|
||||||
|
|
||||||
eevee_closure_skin(N,
|
eevee_closure_skin(N,
|
||||||
mixed_ss_base_color,
|
mixed_ss_base_color,
|
||||||
f0,
|
f0,
|
||||||
|
f90,
|
||||||
int(ssr_id),
|
int(ssr_id),
|
||||||
roughness,
|
roughness,
|
||||||
1.0,
|
1.0,
|
||||||
@@ -1647,7 +1659,7 @@ void node_bsdf_principled_glass(vec4 base_color,
|
|||||||
f0 = mix(vec3(1.0), base_color.rgb, specular_tint);
|
f0 = mix(vec3(1.0), base_color.rgb, specular_tint);
|
||||||
|
|
||||||
eevee_closure_glass(
|
eevee_closure_glass(
|
||||||
N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
|
N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
|
||||||
|
|
||||||
vec3 refr_color = base_color.rgb;
|
vec3 refr_color = base_color.rgb;
|
||||||
refr_color *= (refractionDepth > 0.0) ? refr_color :
|
refr_color *= (refractionDepth > 0.0) ? refr_color :
|
||||||
@@ -3527,6 +3539,7 @@ void node_eevee_specular(vec4 diffuse,
|
|||||||
eevee_closure_default_clearcoat(normal,
|
eevee_closure_default_clearcoat(normal,
|
||||||
diffuse.rgb,
|
diffuse.rgb,
|
||||||
specular.rgb,
|
specular.rgb,
|
||||||
|
vec3(1.0),
|
||||||
int(ssr_id),
|
int(ssr_id),
|
||||||
roughness,
|
roughness,
|
||||||
clearcoat_normal,
|
clearcoat_normal,
|
||||||
|
|||||||
Reference in New Issue
Block a user