Fix #109679: Normal map strength is applied incorrectly #109763
|
@ -33,11 +33,16 @@ shader node_normal_map(float Strength = 1.0,
|
|||
if (getattribute(attr_name, tangent) && getattribute(attr_sign_name, tangent_sign) &&
|
||||
(!is_smooth || getattribute("geom:normal_map_normal", ninterp)))
|
||||
{
|
||||
// apply normal map
|
||||
/* apply normal map */
|
||||
vector B = tangent_sign * cross(ninterp, tangent);
|
||||
|
||||
/* apply strength */
|
||||
mcolor[0] *= Strength;
|
||||
mcolor[1] *= Strength;
|
||||
|
||||
Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
|
||||
|
||||
// transform to world space
|
||||
/* transform to world space */
|
||||
Normal = normalize(transform("object", "world", Normal));
|
||||
}
|
||||
else {
|
||||
|
@ -70,6 +75,6 @@ shader node_normal_map(float Strength = 1.0,
|
|||
Normal = -Normal;
|
||||
}
|
||||
|
||||
if (Strength != 1.0)
|
||||
if (Strength != 1.0 && space != "tangent")
|
||||
Normal = normalize(N + (Normal - N) * max(Strength, 0.0));
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
|||
|
||||
bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
|
||||
float3 N;
|
||||
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
if (space == NODE_NORMAL_MAP_TANGENT) {
|
||||
/* tangent space */
|
||||
if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_TRIANGLE) == 0) {
|
||||
|
@ -313,6 +313,9 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
|||
|
||||
object_inverse_normal_transform(kg, sd, &normal);
|
||||
}
|
||||
/* Apply strength in the tangent case. */
|
||||
color.x *= strength;
|
||||
color.y *= strength;
|
||||
|
||||
/* apply normal map */
|
||||
float3 B = sign * cross(normal, tangent);
|
||||
|
@ -335,6 +338,11 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
|||
object_normal_transform(kg, sd, &N);
|
||||
else
|
||||
N = safe_normalize(N);
|
||||
/* Apply strength in all but tangent space. */
|
||||
if (strength != 1.0f) {
|
||||
strength = max(strength, 0.0f);
|
||||
N = safe_normalize(sd->N + (N - sd->N) * strength);
|
||||
}
|
||||
}
|
||||
|
||||
/* invert normal for backfacing polygons */
|
||||
|
@ -342,13 +350,6 @@ ccl_device_noinline void svm_node_normal_map(KernelGlobals kg,
|
|||
N = -N;
|
||||
}
|
||||
|
||||
float strength = stack_load_float(stack, strength_offset);
|
||||
|
||||
if (strength != 1.0f) {
|
||||
strength = max(strength, 0.0f);
|
||||
N = safe_normalize(sd->N + (N - sd->N) * strength);
|
||||
}
|
||||
|
||||
if (is_zero(N)) {
|
||||
N = sd->N;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#ifdef OBINFO_LIB
|
||||
void node_normal_map(vec4 tangent, vec3 texnormal, out vec3 outnormal)
|
||||
void node_normal_map(vec4 tangent, float strength, vec3 texnormal, out vec3 outnormal)
|
||||
{
|
||||
if (all(equal(tangent, vec4(0.0, 0.0, 0.0, 1.0)))) {
|
||||
outnormal = g_data.Ni;
|
||||
|
@ -9,6 +9,9 @@ void node_normal_map(vec4 tangent, vec3 texnormal, out vec3 outnormal)
|
|||
tangent *= (FrontFacing ? 1.0 : -1.0);
|
||||
vec3 B = tangent.w * cross(g_data.Ni, tangent.xyz) * sign(ObjectInfo.w);
|
||||
|
||||
/* Apply strength here instead of in node_normal_map_mix for tangent space. */
|
||||
texnormal.xy *= strength;
|
||||
|
||||
outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * g_data.Ni;
|
||||
outnormal = normalize(outnormal);
|
||||
}
|
||||
|
@ -26,5 +29,5 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
|
|||
|
||||
void node_normal_map_mix(float strength, vec3 newnormal, out vec3 outnormal)
|
||||
{
|
||||
outnormal = normalize(mix(g_data.N, newnormal, max(strength, 0.0)));
|
||||
outnormal = normalize(mix(g_data.N, newnormal, max(0.0, strength)));
|
||||
}
|
||||
|
|
|
@ -94,12 +94,15 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
|
|||
switch (nm->space) {
|
||||
case SHD_SPACE_TANGENT:
|
||||
GPU_material_flag_set(mat, GPU_MATFLAG_OBJECT_INFO);
|
||||
/* We return directly from the node_normal_map as strength
|
||||
* has already been applied for the tangent case */
|
||||
GPU_link(mat,
|
||||
"node_normal_map",
|
||||
GPU_attribute(mat, CD_TANGENT, nm->uv_map),
|
||||
strength,
|
||||
newnormal,
|
||||
&newnormal);
|
||||
break;
|
||||
&out[0].link);
|
||||
return true;
|
||||
case SHD_SPACE_OBJECT:
|
||||
case SHD_SPACE_BLENDER_OBJECT:
|
||||
GPU_link(mat, "normal_transform_object_to_world", newnormal, &newnormal);
|
||||
|
@ -110,6 +113,7 @@ static int gpu_shader_normal_map(GPUMaterial *mat,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Final step - mix and apply strength for all other than tangent space. */
|
||||
GPU_link(mat, "node_normal_map_mix", strength, newnormal, &out[0].link);
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue