Shaders: add emission strength input to Principled BSDF node

This impacts I/O add-ons. OBJ, FBX and Collada have been updated, glTF not yet.

Differential Revision: https://developer.blender.org/D4971
This commit is contained in:
Alex Strand 2020-09-09 11:36:57 +02:00 committed by Brecht Van Lommel
parent 65fd005312
commit b248ec9776
Notes: blender-bot 2023-02-13 21:16:49 +01:00
Referenced by commit c866075dfb, Fix T81580: No doversion for Emission Strength
Referenced by commit 940ef1a4e8, EEVEE: Fixed Compilation Error
Referenced by issue #82213, Normal Node Is Connecting To Alpha   Case from: Sketchfab Plugin   |   2.91.0 BETA  |  Bad Import! |  Normal\Alpha\Nodes |
Referenced by issue #81580, Keyframed Principled Shader "Alpha" Values in older files get mapped to "Emission Strength" in 2.91
Referenced by issue #80458, Reliable GPU hang on common Intel cards (Linux)
8 changed files with 81 additions and 24 deletions

View File

@ -2755,6 +2755,7 @@ NODE_DEFINE(PrincipledBsdfNode)
SOCKET_IN_FLOAT(transmission_roughness, "Transmission Roughness", 0.0f);
SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
SOCKET_IN_COLOR(emission, "Emission", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 1.0f);
SOCKET_IN_FLOAT(alpha, "Alpha", 1.0f);
SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
SOCKET_IN_NORMAL(clearcoat_normal,
@ -2781,7 +2782,9 @@ void PrincipledBsdfNode::expand(ShaderGraph *graph)
ShaderOutput *principled_out = output("BSDF");
ShaderInput *emission_in = input("Emission");
if (emission_in->link || emission != make_float3(0.0f, 0.0f, 0.0f)) {
ShaderInput *emission_strength_in = input("Emission Strength");
if ((emission_in->link || emission != make_float3(0.0f, 0.0f, 0.0f)) &&
(emission_strength_in->link || emission_strength != 0.0f)) {
/* Create add closure and emission. */
AddClosureNode *add = graph->create_node<AddClosureNode>();
EmissionNode *emission_node = graph->create_node<EmissionNode>();
@ -2790,7 +2793,7 @@ void PrincipledBsdfNode::expand(ShaderGraph *graph)
graph->add(add);
graph->add(emission_node);
emission_node->strength = 1.0f;
graph->relink(emission_strength_in, emission_node->input("Strength"));
graph->relink(emission_in, emission_node->input("Color"));
graph->relink(principled_out, new_out);
graph->connect(emission_node->output("Emission"), add->input("Closure1"));

View File

@ -580,6 +580,7 @@ class PrincipledBsdfNode : public BsdfBaseNode {
ClosureType distribution, distribution_orig;
ClosureType subsurface_method;
float3 emission;
float emission_strength;
float alpha;
bool has_integrator_dependency();

View File

@ -505,7 +505,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
@_set_check
def emission_color_set(self, color):
if self.use_nodes and self.node_principled_bsdf is not None:
color = values_clamp(color, 0.0, 1.0)
color = values_clamp(color, 0.0, 1000000.0)
color = rgb_to_rgba(color)
self.node_principled_bsdf.inputs["Emission"].default_value = color
@ -523,6 +523,31 @@ class PrincipledBSDFWrapper(ShaderWrapper):
emission_color_texture = property(emission_color_texture_get)
def emission_strength_get(self):
if not self.use_nodes or self.node_principled_bsdf is None:
return 1.0
return self.node_principled_bsdf.inputs["Emission Strength"].default_value
@_set_check
def emission_strength_set(self, value):
value = values_clamp(value, 0.0, 1000000.0)
if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Emission Strength"].default_value = value
emission_strength = property(emission_strength_get, emission_strength_set)
def emission_strength_texture_get(self):
if not self.use_nodes or self.node_principled_bsdf is None:
return None
return ShaderImageTextureWrapper(
self, self.node_principled_bsdf,
self.node_principled_bsdf.inputs["Emission Strength"],
grid_row_diff=-1,
colorspace_name='Non-Color',
)
emission_strength_texture = property(emission_strength_texture_get)
# --------------------------------------------------------------------
# Normal map.

View File

@ -54,6 +54,7 @@ void node_bsdf_principled(vec4 base_color,
float transmission,
float transmission_roughness,
vec4 emission,
float emission_strength,
float alpha,
vec3 N,
vec3 CN,
@ -134,7 +135,7 @@ void node_bsdf_principled(vec4 base_color,
result.radiance += render_pass_glossy_mask(spec_col, out_spec);
/* Coarse approx. */
result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@ -161,6 +162,7 @@ void node_bsdf_principled_dielectric(vec4 base_color,
float transmission,
float transmission_roughness,
vec4 emission,
float emission_strength,
float alpha,
vec3 N,
vec3 CN,
@ -193,7 +195,7 @@ void node_bsdf_principled_dielectric(vec4 base_color,
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
result.radiance += render_pass_diffuse_mask(diffuse, out_diff * diffuse);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@ -218,6 +220,7 @@ void node_bsdf_principled_metallic(vec4 base_color,
float transmission,
float transmission_roughness,
vec4 emission,
float emission_strength,
float alpha,
vec3 N,
vec3 CN,
@ -238,7 +241,7 @@ void node_bsdf_principled_metallic(vec4 base_color,
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@ -263,6 +266,7 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
float transmission,
float transmission_roughness,
vec4 emission,
float emission_strength,
float alpha,
vec3 N,
vec3 CN,
@ -295,7 +299,7 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(vec3(spec_col), out_spec);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@ -321,6 +325,7 @@ void node_bsdf_principled_subsurface(vec4 base_color,
float transmission,
float transmission_roughness,
vec4 emission,
float emission_strength,
float alpha,
vec3 N,
vec3 CN,
@ -365,7 +370,7 @@ void node_bsdf_principled_subsurface(vec4 base_color,
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@ -394,6 +399,7 @@ void node_bsdf_principled_glass(vec4 base_color,
float transmission,
float transmission_roughness,
vec4 emission,
float emission_strength,
float alpha,
vec3 N,
vec3 CN,
@ -436,7 +442,7 @@ void node_bsdf_principled_glass(vec4 base_color,
result = CLOSURE_DEFAULT;
result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
result.radiance += render_pass_glossy_mask(spec_col, out_spec * spec_col);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance += render_pass_emission_mask(emission.rgb * emission_strength);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);

View File

@ -323,6 +323,11 @@ void MaterialNode::set_emission(COLLADAFW::ColorOrTexture &cot)
add_link(texture_node, 0, shader_node, 0);
}
}
bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Emission Strength");
if (socket) {
*(float *)socket->default_value = 1.0f;
}
}
void MaterialNode::set_opacity(COLLADAFW::ColorOrTexture &cot)

View File

@ -1326,13 +1326,29 @@ COLLADASW::ColorOrTexture bc_get_base_color(Material *ma)
COLLADASW::ColorOrTexture bc_get_emission(Material *ma)
{
Color default_color = {0, 0, 0, 1};
Color default_color = {0, 0, 0, 1}; /* default black */
bNode *shader = bc_get_master_shader(ma);
if (ma->use_nodes && shader) {
return bc_get_cot_from_shader(shader, "Emission", default_color);
if (!(ma->use_nodes && shader)) {
return bc_get_cot(default_color);
}
return bc_get_cot(default_color); /* default black */
double emission_strength = 0.0;
bc_get_float_from_shader(shader, emission_strength, "Emission Strength");
if (emission_strength == 0.0) {
return bc_get_cot(default_color);
}
COLLADASW::ColorOrTexture cot = bc_get_cot_from_shader(shader, "Emission", default_color);
/* Multiply in emission strength. If using texture, emission strength is not
* supported. */
COLLADASW::Color col = cot.getColor();
cot.getColor().set(emission_strength * col.getRed(),
emission_strength * col.getGreen(),
emission_strength * col.getBlue(),
col.getAlpha());
return cot;
}
COLLADASW::ColorOrTexture bc_get_ambient(Material *ma)
@ -1393,7 +1409,7 @@ double bc_get_reflectivity(Material *ma)
return reflectivity;
}
double bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid)
bool bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid)
{
bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, nodeid.c_str());
if (socket) {

View File

@ -384,7 +384,7 @@ double bc_get_alpha(Material *ma);
double bc_get_ior(Material *ma);
double bc_get_shininess(Material *ma);
double bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid);
bool bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid);
COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader,
std::string nodeid,
Color &default_color,

View File

@ -49,6 +49,7 @@ static bNodeSocketTemplate sh_node_bsdf_principled_in[] = {
{SOCK_FLOAT, N_("Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Transmission Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_RGBA, N_("Emission"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{SOCK_FLOAT, N_("Emission Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
{SOCK_FLOAT, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{SOCK_VECTOR,
@ -89,26 +90,26 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
GPUNodeLink *sss_scale;
/* Normals */
if (!in[19].link) {
GPU_link(mat, "world_normals_get", &in[19].link);
}
/* Clearcoat Normals */
if (!in[20].link) {
GPU_link(mat, "world_normals_get", &in[20].link);
}
/* Clearcoat Normals */
if (!in[21].link) {
GPU_link(mat, "world_normals_get", &in[21].link);
}
#if 0 /* Not used at the moment. */
/* Tangents */
if (!in[21].link) {
if (!in[22].link) {
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
GPU_link(mat, "tangent_orco_z", orco, &in[21].link);
GPU_link(mat, "tangent_orco_z", orco, &in[22].link);
GPU_link(mat,
"node_tangent",
GPU_builtin(GPU_WORLD_NORMAL),
in[21].link,
in[22].link,
GPU_builtin(GPU_OBJECT_MATRIX),
&in[21].link);
&in[22].link);
}
#endif