Cycles: switch to squared roughness convention for all nodes.

This was already done for the Principled BSDF to be compatible with typical
baked roughness maps in PBR workflows.
This commit is contained in:
Brecht Van Lommel 2018-03-10 16:09:22 +01:00
parent 8a76f8dac3
commit 7613ffc944
Notes: blender-bot 2023-06-26 11:58:59 +02:00
Referenced by issue #62692, Cycles transparency shader
Referenced by issue #56264, Roughness (at least for glossy shader node) is broken if you link in files saved in older blender versions
11 changed files with 99 additions and 34 deletions

View File

@ -17,6 +17,7 @@
# <pep8 compliant>
import bpy
import math
from bpy.app.handlers import persistent
@ -138,6 +139,56 @@ def displacement_principled_nodes(node):
if node.subsurface_method != 'RANDOM_WALK':
node.subsurface_method = 'BURLEY'
def square_roughness_node_insert(material, nodetree, traversed):
if nodetree in traversed:
return
traversed.add(nodetree)
roughness_node_types = {
'ShaderNodeBsdfAnisotropic',
'ShaderNodeBsdfGlass',
'ShaderNodeBsdfGlossy',
'ShaderNodeBsdfRefraction'}
# Update default values
for node in nodetree.nodes:
if node.bl_idname == 'ShaderNodeGroup':
square_roughness_node_insert(material, node.node_tree, traversed)
elif node.bl_idname in roughness_node_types:
roughness_input = node.inputs['Roughness']
roughness_input.default_value = math.sqrt(max(roughness_input.default_value, 0.0))
# Gather roughness links to replace
roughness_links = []
for link in nodetree.links:
if link.to_node.bl_idname in roughness_node_types and \
link.to_socket.identifier == 'Roughness':
roughness_links.append(link)
# Replace links with sqrt node
for link in roughness_links:
from_node = link.from_node
from_socket = link.from_socket
to_node = link.to_node
to_socket = link.to_socket
nodetree.links.remove(link)
node = nodetree.nodes.new(type='ShaderNodeMath')
node.operation = 'POWER'
node.location[0] = 0.5 * (from_node.location[0] + to_node.location[0]);
node.location[1] = 0.5 * (from_node.location[1] + to_node.location[1]);
nodetree.links.new(from_socket, node.inputs[0])
node.inputs[1].default_value = 0.5
nodetree.links.new(node.outputs['Value'], to_socket)
def square_roughness_nodes_insert():
traversed = set()
for material in bpy.data.materials:
if check_is_new_shading_material(material):
square_roughness_node_insert(material, material.node_tree, traversed)
def mapping_node_order_flip(node):
"""
@ -376,3 +427,7 @@ def do_versions(self):
cmat.displacement_method = 'BUMP'
foreach_cycles_node(displacement_principled_nodes)
if bpy.data.version <= (2, 79, 3):
# Switch to squared roughness convention
square_roughness_nodes_insert()

View File

@ -33,27 +33,28 @@ shader node_anisotropic_bsdf(
T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
/* compute roughness */
float RoughnessU, RoughnessV;
float roughness = Roughness * Roughness;
float roughness_u, roughness_v;
float aniso = clamp(Anisotropy, -0.99, 0.99);
if (aniso < 0.0) {
RoughnessU = Roughness / (1.0 + aniso);
RoughnessV = Roughness * (1.0 + aniso);
roughness_u = roughness / (1.0 + aniso);
roughness_v = roughness * (1.0 + aniso);
}
else {
RoughnessU = Roughness * (1.0 - aniso);
RoughnessV = Roughness / (1.0 - aniso);
roughness_u = roughness * (1.0 - aniso);
roughness_v = roughness / (1.0 - aniso);
}
if (distribution == "sharp")
BSDF = Color * reflection(Normal);
else if (distribution == "beckmann")
BSDF = Color * microfacet_beckmann_aniso(Normal, T, RoughnessU, RoughnessV);
BSDF = Color * microfacet_beckmann_aniso(Normal, T, roughness_u, roughness_v);
else if (distribution == "GGX")
BSDF = Color * microfacet_ggx_aniso(Normal, T, RoughnessU, RoughnessV);
BSDF = Color * microfacet_ggx_aniso(Normal, T, roughness_u, roughness_v);
else if (distribution == "Multiscatter GGX")
BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, RoughnessU, RoughnessV, Color);
BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
else
BSDF = Color * ashikhmin_shirley(Normal, T, RoughnessU, RoughnessV);
BSDF = Color * ashikhmin_shirley(Normal, T, roughness_u, roughness_v);
}

View File

@ -29,16 +29,17 @@ shader node_glass_bsdf(
float eta = backfacing() ? 1.0 / f : f;
float cosi = dot(I, Normal);
float Fr = fresnel_dielectric_cos(cosi, eta);
float roughness = Roughness * Roughness;
if (distribution == "sharp")
BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta));
else if (distribution == "beckmann")
BSDF = Color * (Fr * microfacet_beckmann(Normal, Roughness) +
(1.0 - Fr) * microfacet_beckmann_refraction(Normal, Roughness, eta));
BSDF = Color * (Fr * microfacet_beckmann(Normal, roughness) +
(1.0 - Fr) * microfacet_beckmann_refraction(Normal, roughness, eta));
else if (distribution == "Multiscatter GGX")
BSDF = Color * microfacet_multi_ggx_glass(Normal, Roughness, eta, Color);
BSDF = Color * microfacet_multi_ggx_glass(Normal, roughness, eta, Color);
else if (distribution == "GGX")
BSDF = Color * (Fr * microfacet_ggx(Normal, Roughness) +
(1.0 - Fr) * microfacet_ggx_refraction(Normal, Roughness, eta));
BSDF = Color * (Fr * microfacet_ggx(Normal, roughness) +
(1.0 - Fr) * microfacet_ggx_refraction(Normal, roughness, eta));
}

View File

@ -24,16 +24,18 @@ shader node_glossy_bsdf(
normal Normal = N,
output closure color BSDF = 0)
{
float roughness = Roughness * Roughness;
if (distribution == "sharp")
BSDF = Color * reflection(Normal);
else if (distribution == "beckmann")
BSDF = Color * microfacet_beckmann(Normal, Roughness);
BSDF = Color * microfacet_beckmann(Normal, roughness);
else if (distribution == "GGX")
BSDF = Color * microfacet_ggx(Normal, Roughness);
BSDF = Color * microfacet_ggx(Normal, roughness);
else if (distribution == "Multiscatter GGX")
BSDF = Color * microfacet_multi_ggx(Normal, Roughness, Color);
BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color);
else
BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), Roughness, Roughness);
BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), roughness, roughness);
}

View File

@ -26,12 +26,13 @@ shader node_refraction_bsdf(
{
float f = max(IOR, 1e-5);
float eta = backfacing() ? 1.0 / f : f;
float roughness = Roughness * Roughness;
if (distribution == "sharp")
BSDF = Color * refraction(Normal, eta);
else if (distribution == "beckmann")
BSDF = Color * microfacet_beckmann_refraction(Normal, Roughness, eta);
BSDF = Color * microfacet_beckmann_refraction(Normal, roughness, eta);
else if (distribution == "GGX")
BSDF = Color * microfacet_ggx_refraction(Normal, Roughness, eta);
BSDF = Color * microfacet_ggx_refraction(Normal, roughness, eta);
}

View File

@ -468,10 +468,12 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
break;
}
float roughness = sqr(param1);
bsdf->N = N;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = param1;
bsdf->alpha_y = param1;
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
bsdf->ior = 0.0f;
bsdf->extra = NULL;
@ -525,8 +527,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sd->flag |= bsdf_refraction_setup(bsdf);
}
else {
bsdf->alpha_x = param1;
bsdf->alpha_y = param1;
float roughness = sqr(param1);
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
bsdf->ior = eta;
if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
@ -557,7 +560,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
/* fresnel */
float cosNO = dot(N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
float roughness = param1;
float roughness = sqr(param1);
/* reflection */
#ifdef __CAUSTICS_TRICKS__
@ -611,8 +614,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->extra = extra;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = param1;
bsdf->alpha_y = param1;
float roughness = sqr(param1);
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
float eta = fmaxf(param2, 1e-5f);
bsdf->ior = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
@ -648,7 +652,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
/* compute roughness */
float roughness = param1;
float roughness = sqr(param1);
float anisotropy = clamp(param2, -0.99f, 0.99f);
if(anisotropy < 0.0f) {

View File

@ -1858,7 +1858,7 @@ NODE_DEFINE(AnisotropicBsdfNode)
SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.2f);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.5f);
SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
@ -1918,7 +1918,7 @@ NODE_DEFINE(GlossyBsdfNode)
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.2f);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
SOCKET_OUT_CLOSURE(BSDF, "BSDF");

View File

@ -28,7 +28,7 @@
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 279
#define BLENDER_SUBVERSION 3
#define BLENDER_SUBVERSION 4
/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 6

View File

@ -2599,7 +2599,8 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
vec3 light_specular = gl_LightSource[i].specular.rgb;
/* we mix in some diffuse so low roughness still shows up */
float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness);
float r2 = roughness * roughness;
float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / r2);
bsdf += 0.5 * max(dot(N, light_position), 0.0);
L += light_specular * bsdf;
}

View File

@ -31,7 +31,7 @@
static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Anisotropy"), 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Rotation"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},

View File

@ -31,7 +31,7 @@
static bNodeSocketTemplate sh_node_bsdf_glossy_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ -1, 0, "" }
};