Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-12 15:39:30 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-13 16:56:11 +0300
commit8f71a84496a95528303fbe0bb7c1406060353425 (patch)
treeebebb3cb4dd35b83a7f4aba960f616fffdc36800 /intern
parent21854575a4ede7d0c16fbe31ac90e66493f607fe (diff)
Cycles/Eevee: add Emission and Alpha inputs to Principled BSDF
This makes it easier to set up materials with emission and transparency. Importers/exporters and add-ons are recommended to now use these rather than creating separate transparent BSDF and emission nodes.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/render/graph.cpp37
-rw-r--r--intern/cycles/render/graph.h9
-rw-r--r--intern/cycles/render/nodes.cpp46
-rw-r--r--intern/cycles/render/nodes.h3
4 files changed, 94 insertions, 1 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index e5fd39f08b7..9203c4468d2 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -127,6 +127,12 @@ ShaderOutput *ShaderNode::output(ustring name)
return NULL;
}
+void ShaderNode::remove_input(ShaderInput *input)
+{
+ assert(input->link == NULL);
+ inputs.erase(remove(inputs.begin(), inputs.end(), input), inputs.end());
+}
+
void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
foreach (ShaderInput *input, inputs) {
@@ -297,6 +303,28 @@ void ShaderGraph::disconnect(ShaderInput *to)
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
+void ShaderGraph::relink(ShaderInput *from, ShaderInput *to)
+{
+ ShaderOutput *out = from->link;
+ if (out) {
+ disconnect(from);
+ connect(out, to);
+ }
+ to->parent->copy_value(to->socket_type, *(from->parent), from->socket_type);
+}
+
+void ShaderGraph::relink(ShaderOutput *from, ShaderOutput *to)
+{
+ /* Copy because disconnect modifies this list. */
+ vector<ShaderInput *> outputs = from->links;
+
+ foreach (ShaderInput *sock, outputs) {
+ disconnect(sock);
+ if (to)
+ connect(to, sock);
+ }
+}
+
void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to)
{
simplified = false;
@@ -320,6 +348,7 @@ void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to)
void ShaderGraph::simplify(Scene *scene)
{
if (!simplified) {
+ expand();
default_inputs(scene->shader_manager->use_osl());
clean(scene);
refine_bump_nodes();
@@ -780,6 +809,14 @@ void ShaderGraph::clean(Scene *scene)
nodes = newnodes;
}
+void ShaderGraph::expand()
+{
+ /* Call expand on all nodes, to generate additional nodes. */
+ foreach (ShaderNode *node, nodes) {
+ node->expand(this);
+ }
+}
+
void ShaderGraph::default_inputs(bool do_osl)
{
/* nodes can specify default texture coordinates, for now we give
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index b1aa5cf3168..cade04de374 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -147,6 +147,7 @@ class ShaderNode : public Node {
virtual ~ShaderNode();
void create_inputs_outputs(const NodeType *type);
+ void remove_input(ShaderInput *input);
ShaderInput *input(const char *name);
ShaderOutput *output(const char *name);
@@ -158,6 +159,11 @@ class ShaderNode : public Node {
virtual void compile(SVMCompiler &compiler) = 0;
virtual void compile(OSLCompiler &compiler) = 0;
+ /* Expand node into additional nodes. */
+ virtual void expand(ShaderGraph * /* graph */)
+ {
+ }
+
/* ** Node optimization ** */
/* Check whether the node can be replaced with single constant. */
virtual void constant_fold(const ConstantFolder & /*folder*/)
@@ -322,6 +328,8 @@ class ShaderGraph {
void connect(ShaderOutput *from, ShaderInput *to);
void disconnect(ShaderOutput *from);
void disconnect(ShaderInput *to);
+ void relink(ShaderInput *from, ShaderInput *to);
+ void relink(ShaderOutput *from, ShaderOutput *to);
void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
void remove_proxy_nodes();
@@ -346,6 +354,7 @@ class ShaderGraph {
void break_cycles(ShaderNode *node, vector<bool> &visited, vector<bool> &on_stack);
void bump_from_displacement(bool use_object_space);
void refine_bump_nodes();
+ void expand();
void default_inputs(bool do_osl);
void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 6e86643cc2b..86cc2030d1b 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2427,6 +2427,8 @@ NODE_DEFINE(PrincipledBsdfNode)
SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
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(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,
"Clearcoat Normal",
@@ -2447,6 +2449,48 @@ PrincipledBsdfNode::PrincipledBsdfNode() : BsdfBaseNode(node_type)
distribution_orig = NBUILTIN_CLOSURES;
}
+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)) {
+ /* Create add closure and emission. */
+ AddClosureNode *add = new AddClosureNode();
+ EmissionNode *emission_node = new EmissionNode();
+ ShaderOutput *new_out = add->output("Closure");
+
+ graph->add(add);
+ graph->add(emission_node);
+
+ emission_node->strength = 1.0f;
+ graph->relink(emission_in, emission_node->input("Color"));
+ graph->relink(principled_out, new_out);
+ graph->connect(emission_node->output("Emission"), add->input("Closure1"));
+ graph->connect(principled_out, add->input("Closure2"));
+
+ principled_out = new_out;
+ }
+
+ ShaderInput *alpha_in = input("Alpha");
+ if (alpha_in->link || alpha != 1.0f) {
+ /* Create mix and transparent BSDF for alpha transparency. */
+ MixClosureNode *mix = new MixClosureNode();
+ TransparentBsdfNode *transparent = new TransparentBsdfNode();
+
+ graph->add(mix);
+ graph->add(transparent);
+
+ graph->relink(alpha_in, mix->input("Fac"));
+ graph->relink(principled_out, mix->output("Closure"));
+ graph->connect(transparent->output("BSDF"), mix->input("Closure1"));
+ graph->connect(principled_out, mix->input("Closure2"));
+ }
+
+ remove_input(emission_in);
+ remove_input(alpha_in);
+}
+
bool PrincipledBsdfNode::has_surface_bssrdf()
{
ShaderInput *subsurface_in = input("Subsurface");
@@ -2627,7 +2671,7 @@ NODE_DEFINE(TransparentBsdfNode)
{
NodeType *type = NodeType::add("transparent_bsdf", create, NodeType::SHADER);
- SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
+ SOCKET_IN_COLOR(color, "Color", make_float3(1.0f, 1.0f, 1.0f));
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
SOCKET_OUT_CLOSURE(BSDF, "BSDF");
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 88fa728ecd1..3dd84ad8dca 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -487,6 +487,7 @@ class PrincipledBsdfNode : public BsdfBaseNode {
public:
SHADER_NODE_CLASS(PrincipledBsdfNode)
+ void expand(ShaderGraph *graph);
bool has_surface_bssrdf();
bool has_bssrdf_bump();
void compile(SVMCompiler &compiler,
@@ -515,6 +516,8 @@ class PrincipledBsdfNode : public BsdfBaseNode {
float surface_mix_weight;
ClosureType distribution, distribution_orig;
ClosureType subsurface_method;
+ float3 emission;
+ float alpha;
bool has_integrator_dependency();
void attributes(Shader *shader, AttributeRequestSet *attributes);