Merge branch 'blender-v4.0-release'

This commit is contained in:
Lukas Stockner 2023-10-31 05:48:58 +01:00
commit d15013b583
7 changed files with 123 additions and 63 deletions

View File

@ -36,7 +36,18 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
normal Tangent = normalize(dPdu), normal Tangent = normalize(dPdu),
output closure color BSDF = 0) output closure color BSDF = 0)
{ {
float CLOSURE_WEIGHT_CUTOFF = 1e-5;
/* Clamping to match SVM */
float metallic = clamp(Metallic, 0.0, 1.0);
float transmission = clamp(TransmissionWeight, 0.0, 1.0);
float subsurface_weight = clamp(SubsurfaceWeight, 0.0, 1.0);
color specular_tint = max(SpecularTint, color(0.0)); color specular_tint = max(SpecularTint, color(0.0));
float coat_weight = max(CoatWeight, 0.0);
color coat_tint = max(CoatTint, color(0.0));
float sheen_weight = max(SheenWeight, 0.0);
color base_color = max(BaseColor, color(0.0));
color clamped_base_color = min(base_color, color(1.0));
float r2 = clamp(Roughness, 0.0, 1.0); float r2 = clamp(Roughness, 0.0, 1.0);
r2 = r2 * r2; r2 = r2 * r2;
@ -53,8 +64,8 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal); T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
} }
if (Metallic < 1.0 && TransmissionWeight < 1.0) { if (metallic < 1.0 && TransmissionWeight < 1.0) {
float eta = IOR; float eta = max(IOR, 1e-5);
float f0 = F0_from_ior(eta); float f0 = F0_from_ior(eta);
if (SpecularIORLevel != 0.5) { if (SpecularIORLevel != 0.5) {
f0 *= 2.0 * max(SpecularIORLevel, 0.0); f0 *= 2.0 * max(SpecularIORLevel, 0.0);
@ -64,22 +75,21 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
} }
} }
BSDF = BaseColor * diffuse(Normal); BSDF = base_color * diffuse(Normal);
if (SubsurfaceWeight > 1e-5) { if (subsurface_weight > CLOSURE_WEIGHT_CUTOFF) {
float subsurface_weight = min(SubsurfaceWeight, 1.0); vector radius = max(SubsurfaceScale * SubsurfaceRadius, vector(0.0));
vector radius = SubsurfaceScale * SubsurfaceRadius;
float subsurface_ior = (subsurface_method == "random_walk_skin") ? SubsurfaceIOR : eta; float subsurface_ior = (subsurface_method == "random_walk_skin") ? SubsurfaceIOR : eta;
closure color SubsurfBSDF = bssrdf(subsurface_method, closure color SubsurfBSDF = bssrdf(subsurface_method,
Normal, Normal,
SubsurfaceScale * SubsurfaceRadius, radius,
BaseColor, clamped_base_color,
"roughness", "roughness",
r2, r2,
"ior", "ior",
subsurface_ior, subsurface_ior,
"anisotropy", "anisotropy",
SubsurfaceAnisotropy); SubsurfaceAnisotropy);
BSDF = mix(BSDF, BaseColor * SubsurfBSDF, subsurface_weight); BSDF = mix(BSDF, clamped_base_color * SubsurfBSDF, subsurface_weight);
} }
if (eta != 1.0) { if (eta != 1.0) {
@ -95,38 +105,45 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
} }
closure color TransmissionBSDF = 0; closure color TransmissionBSDF = 0;
if (Metallic < 1.0 && TransmissionWeight > 0.0) { if (metallic < 1.0 && TransmissionWeight > CLOSURE_WEIGHT_CUTOFF) {
float eta = max(IOR, 1e-5); float eta = max(IOR, 1e-5);
eta = backfacing() ? 1.0 / eta : eta; eta = backfacing() ? 1.0 / eta : eta;
color F0 = F0_from_ior(eta) * specular_tint; color F0 = F0_from_ior(eta) * specular_tint;
color F90 = color(1.0); color F90 = color(1.0);
TransmissionBSDF = generalized_schlick_bsdf( TransmissionBSDF = generalized_schlick_bsdf(Normal,
Normal, vector(0.0), color(1.0), sqrt(BaseColor), r2, r2, F0, F90, -eta, distribution), vector(0.0),
BSDF = mix(BSDF, TransmissionBSDF, clamp(TransmissionWeight, 0.0, 1.0)); color(1.0),
sqrt(clamped_base_color),
r2,
r2,
F0,
F90,
-eta,
distribution),
BSDF = mix(BSDF, TransmissionBSDF, transmission);
} }
closure color MetallicBSDF = 0; closure color MetallicBSDF = 0;
if (Metallic > 0.0) { if (metallic > CLOSURE_WEIGHT_CUTOFF) {
color F0 = BaseColor; color F0 = clamped_base_color;
color F82 = specular_tint; color F82 = min(specular_tint, color(1.0));
MetallicBSDF = microfacet_f82_tint(distribution, Normal, T, alpha_x, alpha_y, F0, F82); MetallicBSDF = microfacet_f82_tint(distribution, Normal, T, alpha_x, alpha_y, F0, F82);
BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0)); BSDF = mix(BSDF, MetallicBSDF, metallic);
} }
if (EmissionStrength > 0.0 && EmissionColor != color(0.0)) { if (EmissionStrength != 0.0 && EmissionColor != color(0.0)) {
BSDF += EmissionStrength * EmissionColor * emission(); BSDF += EmissionStrength * EmissionColor * emission();
} }
if (CoatWeight > 1e-5) { if (coat_weight > CLOSURE_WEIGHT_CUTOFF) {
float coat_ior = max(CoatIOR, 1.0); float coat_ior = max(CoatIOR, 1.0);
float coat_weight = clamp(CoatWeight, 0.0, 1.0);
if (CoatTint != color(1.0)) { if (CoatTint != color(1.0)) {
float coat_neta = 1.0 / coat_ior; float coat_neta = 1.0 / coat_ior;
float cosNI = dot(I, CoatNormal); float cosNI = dot(I, CoatNormal);
float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI)); float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI));
BSDF *= mix(color(1.0), pow(CoatTint, 1.0 / cosNT), coat_weight); BSDF *= mix(color(1.0), pow(CoatTint, 1.0 / cosNT), clamp(coat_weight, 0.0, 1.0));
} }
float coat_r2 = clamp(CoatRoughness, 0.0, 1.0); float coat_r2 = clamp(CoatRoughness, 0.0, 1.0);
coat_r2 = coat_r2 * coat_r2; coat_r2 = coat_r2 * coat_r2;
@ -136,10 +153,10 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
BSDF = layer(coat_weight * CoatBSDF, BSDF); BSDF = layer(coat_weight * CoatBSDF, BSDF);
} }
if (SheenWeight > 1e-5) { if (SheenWeight > CLOSURE_WEIGHT_CUTOFF) {
normal sheen_normal = normalize(mix(Normal, CoatNormal, clamp(CoatWeight, 0.0, 1.0))); normal sheen_normal = normalize(mix(Normal, CoatNormal, clamp(coat_weight, 0.0, 1.0)));
closure color SheenBSDF = sheen(sheen_normal, clamp(SheenRoughness, 0.0, 1.0)); closure color SheenBSDF = sheen(sheen_normal, clamp(SheenRoughness, 0.0, 1.0));
BSDF = layer(clamp(SheenWeight, 0.0, 1.0) * SheenTint * SheenBSDF, BSDF); BSDF = layer(sheen_weight * max(SheenTint, color(0.0)) * SheenBSDF, BSDF);
} }
BSDF = mix(transparent(), BSDF, clamp(Alpha, 0.0, 1.0)); BSDF = mix(transparent(), BSDF, clamp(Alpha, 0.0, 1.0));

View File

@ -109,18 +109,18 @@ ccl_device
// get Disney principled parameters // get Disney principled parameters
float metallic = saturatef(param1); float metallic = saturatef(param1);
float subsurface_weight = saturatef(param2); float subsurface_weight = saturatef(param2);
float specular_ior_level = fmaxf(stack_load_float(stack, specular_ior_level_offset), 0.0f); float specular_ior_level = max(stack_load_float(stack, specular_ior_level_offset), 0.0f);
float roughness = saturatef(stack_load_float(stack, roughness_offset)); float roughness = saturatef(stack_load_float(stack, roughness_offset));
Spectrum specular_tint = rgb_to_spectrum( Spectrum specular_tint = rgb_to_spectrum(
max(stack_load_float3(stack, specular_tint_offset), zero_float3())); max(stack_load_float3(stack, specular_tint_offset), zero_float3()));
float anisotropic = saturatef(stack_load_float(stack, anisotropic_offset)); float anisotropic = saturatef(stack_load_float(stack, anisotropic_offset));
float sheen_weight = saturatef(stack_load_float(stack, sheen_weight_offset)); float sheen_weight = max(stack_load_float(stack, sheen_weight_offset), 0.0f);
float3 sheen_tint = stack_load_float3(stack, sheen_tint_offset); float3 sheen_tint = max(stack_load_float3(stack, sheen_tint_offset), zero_float3());
float sheen_roughness = saturatef(stack_load_float(stack, sheen_roughness_offset)); float sheen_roughness = saturatef(stack_load_float(stack, sheen_roughness_offset));
float coat_weight = saturatef(stack_load_float(stack, coat_weight_offset)); float coat_weight = fmaxf(stack_load_float(stack, coat_weight_offset), 0.0f);
float coat_roughness = saturatef(stack_load_float(stack, coat_roughness_offset)); float coat_roughness = saturatef(stack_load_float(stack, coat_roughness_offset));
float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f); float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f);
float3 coat_tint = stack_load_float3(stack, coat_tint_offset); float3 coat_tint = max(stack_load_float3(stack, coat_tint_offset), zero_float3());
float transmission_weight = saturatef(stack_load_float(stack, transmission_weight_offset)); float transmission_weight = saturatef(stack_load_float(stack, transmission_weight_offset));
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset); float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
float ior = fmaxf(stack_load_float(stack, eta_offset), 1e-5f); float ior = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
@ -140,6 +140,8 @@ ccl_device
make_float3(__uint_as_float(data_base_color.y), make_float3(__uint_as_float(data_base_color.y),
__uint_as_float(data_base_color.z), __uint_as_float(data_base_color.z),
__uint_as_float(data_base_color.w)); __uint_as_float(data_base_color.w));
base_color = max(base_color, zero_float3());
const float3 clamped_base_color = min(base_color, one_float3());
// get the subsurface scattering data // get the subsurface scattering data
uint4 data_subsurf = read_node(kg, &offset); uint4 data_subsurf = read_node(kg, &offset);
@ -157,7 +159,7 @@ ccl_device
float emission_strength = stack_valid(emission_strength_offset) ? float emission_strength = stack_valid(emission_strength_offset) ?
stack_load_float(stack, emission_strength_offset) : stack_load_float(stack, emission_strength_offset) :
__uint_as_float(data_alpha_emission.z); __uint_as_float(data_alpha_emission.z);
float3 emission = stack_load_float3(stack, emission_offset) * fmaxf(emission_strength, 0.0f); float3 emission = stack_load_float3(stack, emission_offset) * emission_strength;
Spectrum weight = closure_weight * mix_weight; Spectrum weight = closure_weight * mix_weight;
@ -283,8 +285,8 @@ ccl_device
bsdf->alpha_x = alpha_x; bsdf->alpha_x = alpha_x;
bsdf->alpha_y = alpha_y; bsdf->alpha_y = alpha_y;
fresnel->f0 = rgb_to_spectrum(base_color); fresnel->f0 = rgb_to_spectrum(clamped_base_color);
const Spectrum f82 = specular_tint; const Spectrum f82 = min(specular_tint, one_spectrum());
/* setup bsdf */ /* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf); sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
@ -316,7 +318,7 @@ ccl_device
fresnel->f90 = one_spectrum(); fresnel->f90 = one_spectrum();
fresnel->exponent = -ior; fresnel->exponent = -ior;
fresnel->reflection_tint = one_spectrum(); fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = sqrt(rgb_to_spectrum(base_color)); fresnel->transmission_tint = sqrt(rgb_to_spectrum(clamped_base_color));
/* setup bsdf */ /* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
@ -375,16 +377,18 @@ ccl_device
/* Diffuse/Subsurface component */ /* Diffuse/Subsurface component */
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
ccl_private Bssrdf *bssrdf = bssrdf_alloc( ccl_private Bssrdf *bssrdf = bssrdf_alloc(
sd, rgb_to_spectrum(base_color) * subsurface_weight * weight); sd, rgb_to_spectrum(clamped_base_color) * subsurface_weight * weight);
if (bssrdf) { if (bssrdf) {
float3 subsurface_radius = stack_load_float3(stack, data_subsurf.y); float3 subsurface_radius = stack_load_float3(stack, data_subsurf.y);
float subsurface_scale = stack_load_float(stack, data_subsurf.z); float subsurface_scale = stack_load_float(stack, data_subsurf.z);
bssrdf->radius = rgb_to_spectrum(subsurface_radius * subsurface_scale); bssrdf->radius = rgb_to_spectrum(max(subsurface_radius * subsurface_scale, zero_float3()));
bssrdf->albedo = rgb_to_spectrum(base_color); bssrdf->albedo = rgb_to_spectrum(clamped_base_color);
bssrdf->N = maybe_ensure_valid_specular_reflection(sd, N); bssrdf->N = maybe_ensure_valid_specular_reflection(sd, N);
bssrdf->alpha = sqr(roughness); bssrdf->alpha = sqr(roughness);
/* IOR is clamped to [1.01..3.8] inside bssrdf_setup */
bssrdf->ior = eta; bssrdf->ior = eta;
/* Anisotropy is clamped to [0.0..0.9] inside bssrdf_setup */
bssrdf->anisotropy = stack_load_float(stack, data_subsurf.w); bssrdf->anisotropy = stack_load_float(stack, data_subsurf.w);
if (subsurface_method == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) { if (subsurface_method == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) {
bssrdf->ior = stack_load_float(stack, data_subsurf.x); bssrdf->ior = stack_load_float(stack, data_subsurf.x);

View File

@ -7392,6 +7392,11 @@ def km_3d_view_tool_edit_armature_extrude_to_cursor(params):
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [ {"items": [
("armature.click_extrude", {"type": params.tool_mouse, "value": 'PRESS', **params.tool_modifier}, None), ("armature.click_extrude", {"type": params.tool_mouse, "value": 'PRESS', **params.tool_modifier}, None),
# Support LMB click-drag for RMB key-map.
*(([] if (params.select_mouse == 'LEFTMOUSE') else [
("transform.translate", {"type": params.tool_mouse, "value": 'CLICK_DRAG'},
{"properties": [("release_confirm", True)]})
])),
]}, ]},
) )
@ -7477,6 +7482,11 @@ def km_3d_view_tool_edit_mesh_extrude_to_cursor(params):
{"items": [ {"items": [
# No need for `tool_modifier` since this takes all input. # No need for `tool_modifier` since this takes all input.
("mesh.dupli_extrude_cursor", {"type": params.tool_mouse, "value": 'PRESS'}, None), ("mesh.dupli_extrude_cursor", {"type": params.tool_mouse, "value": 'PRESS'}, None),
# Support LMB click-drag for RMB key-map.
*(([] if (params.select_mouse == 'LEFTMOUSE') else [
("transform.translate", {"type": params.tool_mouse, "value": 'CLICK_DRAG'},
{"properties": [("release_confirm", True)]})
])),
]}, ]},
) )
@ -7771,6 +7781,11 @@ def km_3d_view_tool_edit_curve_extrude_to_cursor(params):
{"items": [ {"items": [
# No need for `tool_modifier` since this takes all input. # No need for `tool_modifier` since this takes all input.
("curve.vertex_add", {"type": params.tool_mouse, "value": 'PRESS'}, None), ("curve.vertex_add", {"type": params.tool_mouse, "value": 'PRESS'}, None),
# Support LMB click-drag for RMB key-map.
*(([] if (params.select_mouse == 'LEFTMOUSE') else [
("transform.translate", {"type": params.tool_mouse, "value": 'CLICK_DRAG'},
{"properties": [("release_confirm", True)]})
])),
]}, ]},
) )

View File

@ -225,7 +225,6 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv
ARegion *region; ARegion *region;
View3D *v3d; View3D *v3d;
float tvec[3], oldcurs[3], mval_f[2]; float tvec[3], oldcurs[3], mval_f[2];
int retv;
scene = CTX_data_scene(C); scene = CTX_data_scene(C);
region = CTX_wm_region(C); region = CTX_wm_region(C);
@ -240,12 +239,16 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv
copy_v3_v3(cursor->location, tvec); copy_v3_v3(cursor->location, tvec);
/* extrude to the where new cursor is and store the operation result */ /* extrude to the where new cursor is and store the operation result */
retv = armature_click_extrude_exec(C, op); int retval = armature_click_extrude_exec(C, op);
/* restore previous 3d cursor position */ /* restore previous 3d cursor position */
copy_v3_v3(cursor->location, oldcurs); copy_v3_v3(cursor->location, oldcurs);
return retv; /* Support dragging to move after extrude, see: #114282. */
if (retval & OPERATOR_FINISHED) {
retval |= OPERATOR_PASS_THROUGH;
}
return WM_operator_flag_only_pass_through_on_press(retval, event);
} }
void ARMATURE_OT_click_extrude(wmOperatorType *ot) void ARMATURE_OT_click_extrude(wmOperatorType *ot)

View File

@ -5703,7 +5703,12 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_float_set_array(op->ptr, "location", location); RNA_float_set_array(op->ptr, "location", location);
} }
return add_vertex_exec(C, op); /* Support dragging to move after extrude, see: #114282. */
int retval = add_vertex_exec(C, op);
if (retval & OPERATOR_FINISHED) {
retval |= OPERATOR_PASS_THROUGH;
}
return WM_operator_flag_only_pass_through_on_press(retval, event);
} }
void CURVE_OT_vertex_add(wmOperatorType *ot) void CURVE_OT_vertex_add(wmOperatorType *ot)

View File

@ -914,7 +914,9 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
} }
MEM_freeN(objects); MEM_freeN(objects);
return OPERATOR_FINISHED; /* Support dragging to move after extrude, see: #114282. */
const int retval = OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
return WM_operator_flag_only_pass_through_on_press(retval, event);
} }
void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)

View File

@ -63,22 +63,36 @@ void node_bsdf_principled(vec4 base_color,
out Closure result) out Closure result)
{ {
/* Match cycles. */ /* Match cycles. */
metallic = clamp(metallic, 0.0, 1.0); metallic = saturate(metallic);
roughness = clamp(roughness, 0.0, 1.0); roughness = saturate(roughness);
ior = max(ior, 1e-5); ior = max(ior, 1e-5);
transmission_weight = clamp(transmission_weight, 0.0, 1.0); alpha = saturate(alpha);
subsurface_weight = clamp(subsurface_weight, 0.0, 1.0); subsurface_weight = saturate(subsurface_weight);
/* Not used by EEVEE */
/* subsurface_anisotropy = clamp(subsurface_anisotropy, 0.0, 0.9); */
/* subsurface_ior = clamp(subsurface_ior, 1.01, 3.8); */
specular_ior_level = max(specular_ior_level, 0.0); specular_ior_level = max(specular_ior_level, 0.0);
specular_tint = max(specular_tint, vec4(0.0)); specular_tint = max(specular_tint, vec4(0.0));
/* Not used by EEVEE */ /* Not used by EEVEE */
/* anisotropic = clamp(anisotropic, 0.0, 1.0) */ /* anisotropic = saturate(anisotropic); */
coat_weight = clamp(coat_weight, 0.0, 1.0); transmission_weight = saturate(transmission_weight);
coat_roughness = clamp(coat_roughness, 0.0, 1.0); coat_weight = max(coat_weight, 0.0);
coat_roughness = saturate(coat_roughness);
coat_ior = max(coat_ior, 1.0); coat_ior = max(coat_ior, 1.0);
sheen_weight = clamp(sheen_weight, 0.0, 1.0); coat_tint = max(coat_tint, vec4(0.0));
sheen_roughness = clamp(sheen_roughness, 0.0, 1.0); sheen_weight = max(sheen_weight, 0.0);
emission_strength = max(emission_strength, 0.0); sheen_roughness = saturate(sheen_roughness);
alpha = clamp(alpha, 0.0, 1.0); sheen_tint = max(sheen_tint, vec4(0.0));
base_color = max(base_color, vec4(0.0));
vec4 clamped_base_color = min(base_color, vec4(1.0));
vec4 diffuse_sss_base_color = base_color;
if (subsurface_weight > 0.0) {
/* Subsurface Scattering materials behave unpredictably with values greater than 1.0 in Cycles.
* So it's clamped there and we clamp here for consistency with Cycles. */
diffuse_sss_base_color = mix(diffuse_sss_base_color, clamped_base_color, subsurface_weight);
}
N = safe_normalize(N); N = safe_normalize(N);
CN = safe_normalize(CN); CN = safe_normalize(CN);
@ -100,7 +114,7 @@ void node_bsdf_principled(vec4 base_color,
vec3 sheen_color = sheen_weight * sheen_tint.rgb * principled_sheen(NV, sheen_roughness); vec3 sheen_color = sheen_weight * sheen_tint.rgb * principled_sheen(NV, sheen_roughness);
diffuse_data.color = weight * sheen_color; diffuse_data.color = weight * sheen_color;
/* Attenuate lower layers */ /* Attenuate lower layers */
weight *= (1.0 - math_reduce_max(sheen_color)); weight *= max((1.0 - math_reduce_max(sheen_color)), 0.0);
} }
else { else {
diffuse_data.color = vec3(0.0); diffuse_data.color = vec3(0.0);
@ -117,13 +131,13 @@ void node_bsdf_principled(vec4 base_color,
float reflectance = bsdf_lut(coat_NV, coat_data.roughness, coat_ior, false).x; float reflectance = bsdf_lut(coat_NV, coat_data.roughness, coat_ior, false).x;
coat_data.weight = weight * coat_weight * reflectance; coat_data.weight = weight * coat_weight * reflectance;
/* Attenuate lower layers */ /* Attenuate lower layers */
weight *= (1.0 - reflectance * coat_weight); weight *= max((1.0 - reflectance * coat_weight), 0.0);
if (!all(equal(coat_tint.rgb, vec3(1.0)))) { if (!all(equal(coat_tint.rgb, vec3(1.0)))) {
float coat_neta = 1.0 / coat_ior; float coat_neta = 1.0 / coat_ior;
float NT = sqrt_fast(1.0 - coat_neta * coat_neta * (1 - NV * NV)); float NT = sqrt_fast(1.0 - coat_neta * coat_neta * (1 - NV * NV));
/* Tint lower layers. */ /* Tint lower layers. */
coat_tint.rgb = mix(vec3(1.0), pow(coat_tint.rgb, vec3(1.0 / NT)), coat_weight); coat_tint.rgb = mix(vec3(1.0), pow(coat_tint.rgb, vec3(1.0 / NT)), saturate(coat_weight));
} }
} }
else { else {
@ -142,13 +156,13 @@ void node_bsdf_principled(vec4 base_color,
reflection_data.roughness = roughness; reflection_data.roughness = roughness;
vec3 reflection_tint = specular_tint.rgb; vec3 reflection_tint = specular_tint.rgb;
if (metallic > 0.0) { if (metallic > 0.0) {
vec3 F0 = base_color.rgb; vec3 F0 = clamped_base_color.rgb;
vec3 F82 = reflection_tint; vec3 F82 = min(reflection_tint, vec3(1.0));
vec3 metallic_brdf; vec3 metallic_brdf;
brdf_f82_tint_lut(F0, F82, NV, roughness, do_multiscatter != 0.0, metallic_brdf); brdf_f82_tint_lut(F0, F82, NV, roughness, do_multiscatter != 0.0, metallic_brdf);
reflection_data.color = weight * metallic * metallic_brdf; reflection_data.color = weight * metallic * metallic_brdf;
/* Attenuate lower layers */ /* Attenuate lower layers */
weight *= (1.0 - metallic); weight *= max((1.0 - metallic), 0.0);
} }
else { else {
reflection_data.color = vec3(0.0); reflection_data.color = vec3(0.0);
@ -165,7 +179,7 @@ void node_bsdf_principled(vec4 base_color,
vec3 reflectance, transmittance; vec3 reflectance, transmittance;
bsdf_lut(F0, bsdf_lut(F0,
F90, F90,
base_color.rgb, clamped_base_color.rgb,
NV, NV,
roughness, roughness,
ior, ior,
@ -178,7 +192,7 @@ void node_bsdf_principled(vec4 base_color,
refraction_data.weight = weight * transmission_weight; refraction_data.weight = weight * transmission_weight;
refraction_data.color = transmittance * coat_tint.rgb; refraction_data.color = transmittance * coat_tint.rgb;
/* Attenuate lower layers */ /* Attenuate lower layers */
weight *= (1.0 - transmission_weight); weight *= max((1.0 - transmission_weight), 0.0);
} }
else { else {
refraction_data.weight = 0.0; refraction_data.weight = 0.0;
@ -205,14 +219,14 @@ void node_bsdf_principled(vec4 base_color,
reflection_data.color += weight * reflectance; reflection_data.color += weight * reflectance;
/* Attenuate lower layers */ /* Attenuate lower layers */
weight *= (1.0 - math_reduce_max(reflectance)); weight *= max((1.0 - math_reduce_max(reflectance)), 0.0);
} }
/* Diffuse component */ /* Diffuse component */
if (true) { if (true) {
diffuse_data.sss_radius = subsurface_radius * subsurface_scale; diffuse_data.sss_radius = max(subsurface_radius * subsurface_scale, vec3(0.0));
diffuse_data.sss_id = uint(do_sss); diffuse_data.sss_id = uint(do_sss);
diffuse_data.color += weight * base_color.rgb * coat_tint.rgb; diffuse_data.color += weight * diffuse_sss_base_color.rgb * coat_tint.rgb;
} }
/* Adjust the weight of picking the closure. */ /* Adjust the weight of picking the closure. */