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:
		@@ -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"));
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user