Implement Eevee output node system
authorLuca Rood <dev@lucarood.com>
Mon, 19 Jun 2017 14:31:10 +0000 (16:31 +0200)
committerLuca Rood <dev@lucarood.com>
Tue, 20 Jun 2017 16:39:49 +0000 (18:39 +0200)
This makes Eevee consistent with Cycles, by having a single output node,
and multiple shader nodes that connect to it.

Note that node systems for Eevee saved before this will be missing the
output node, and thus will show an invalid material. This is easily
resolved by connecting the shader output to a new output node.

release/scripts/startup/nodeitems_builtins.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/editors/space_node/node_edit.c
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_shader.h
source/blender/nodes/NOD_static_types.h
source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c [new file with mode: 0644]
source/blender/nodes/shader/nodes/node_shader_output_metallic.c
source/blender/nodes/shader/nodes/node_shader_output_specular.c

index 2e2684a0524bd7b9f62c4bace0339b080abf188e..59bf93696bc2a52e3aa9232d27e1f5a21209e577 100644 (file)
@@ -219,6 +219,7 @@ shader_node_categories = [
         NodeItem("ShaderNodeOutputMetallic", poll=object_shader_nodes_poll),
         NodeItem("ShaderNodeOutputSpecular", poll=object_shader_nodes_poll),
         NodeItem("ShaderNodeOutputMaterial", poll=object_shader_nodes_poll),
+        NodeItem("ShaderNodeOutputEeveeMaterial", poll=object_shader_nodes_poll),
         NodeItem("ShaderNodeOutputLamp", poll=object_shader_nodes_poll),
         NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
         NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
index bda762b73b60b9875071a5ee5200d96a3eb2dc17..44846a129617abc266a30e2d55e712f05c1415b3 100644 (file)
@@ -796,6 +796,7 @@ struct ShadeResult;
 #define SH_NODE_BSDF_PRINCIPLED         193
 #define SH_NODE_OUTPUT_METALLIC                        194
 #define SH_NODE_OUTPUT_SPECULAR                        195
+#define SH_NODE_OUTPUT_EEVEE_MATERIAL  196
 
 /* custom defines options for Material node */
 #define SH_NODE_MAT_DIFF   1
index 5555068db37f734d0819fcdb076545a9db56e675..8d512f15949af9809012a154c56487fddc4dcefb 100644 (file)
@@ -3592,6 +3592,7 @@ static void registerShaderNodes(void)
        register_node_type_sh_output_material();
        register_node_type_sh_output_metallic();
        register_node_type_sh_output_specular();
+       register_node_type_sh_output_eevee_material();
        register_node_type_sh_output_world();
        register_node_type_sh_output_linestyle();
 
index c70cbeef52fb22e92935ef631dade8637ca406a6..9ad40ea802ed3d759be00c2dcf8a74a0a7b3dcab 100644 (file)
@@ -399,14 +399,10 @@ void ED_node_shader_default(const bContext *C, ID *id)
                        ma->nodetree = ntree;
 
                        if (BKE_scene_uses_blender_eevee(scene)) {
-                               out = nodeAddStaticNode(C, ntree, SH_NODE_OUTPUT_METALLIC);
-                               out->locx = 300.0f; out->locy = 300.0f;
-                               nodeSetActive(ntree, out);
-                               ntreeUpdateTree(CTX_data_main(C), ntree);
-                               return;
+                               output_type = SH_NODE_OUTPUT_EEVEE_MATERIAL;
+                               shader_type = SH_NODE_OUTPUT_METALLIC;
                        }
-
-                       if (BKE_scene_use_new_shading_nodes(scene)) {
+                       else if (BKE_scene_use_new_shading_nodes(scene)) {
                                output_type = SH_NODE_OUTPUT_MATERIAL;
                                shader_type = SH_NODE_BSDF_DIFFUSE;
                        }
index 7595a3cf6b7de82285aaa184188a41629146b6b4..f423e541dc28a2bbb6ea755789bd2b6715bb00c8 100644 (file)
@@ -3893,6 +3893,12 @@ void node_output_specular(
 {
        result = vec4(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp);
 }
+
+void node_output_eevee_material(vec4 Surface, out vec4 result)
+{
+       result = Surface;
+}
+
 #endif
 
 /* ********************** matcap style render ******************** */
index b57e33e85c7a4ad3e8124f5d582fa562654e0ec5..690011ec2aadb98c878f4442032761935c780580 100644 (file)
@@ -188,6 +188,7 @@ set(SRC
        shader/nodes/node_shader_output_material.c
        shader/nodes/node_shader_output_metallic.c
        shader/nodes/node_shader_output_specular.c
+       shader/nodes/node_shader_output_eevee_material.c
        shader/nodes/node_shader_output_world.c
        shader/nodes/node_shader_output_linestyle.c
        shader/nodes/node_shader_particle_info.c
index c05c1a551446d662e4a87d6a35f244d07d9ac01b..ffa255478ff87bbb51a3c1abe49801c5717861b8 100644 (file)
@@ -122,6 +122,7 @@ void register_node_type_sh_output_lamp(void);
 void register_node_type_sh_output_material(void);
 void register_node_type_sh_output_metallic(void);
 void register_node_type_sh_output_specular(void);
+void register_node_type_sh_output_eevee_material(void);
 void register_node_type_sh_output_world(void);
 void register_node_type_sh_output_linestyle(void);
 
index f4c7926603377e2cebc041202c909b1ffe420e33..c4c99fdb256860e71153447f7588faead80087cd 100644 (file)
@@ -67,8 +67,9 @@ DefNode( ShaderNode,     SH_NODE_COMBRGB,         0,                      "COMBR
 DefNode( ShaderNode,     SH_NODE_HUE_SAT,         0,                      "HUE_SAT",        HueSaturation,    "Hue/Saturation",    ""              )
 
 DefNode( ShaderNode,     SH_NODE_OUTPUT_MATERIAL,    def_sh_output,          "OUTPUT_MATERIAL",    OutputMaterial,   "Material Output",   ""       )
-DefNode( ShaderNode,     SH_NODE_OUTPUT_METALLIC,    def_sh_output,          "OUTPUT_METALLIC",    OutputMetallic,   "Material Metallic Output", "")
-DefNode( ShaderNode,     SH_NODE_OUTPUT_SPECULAR,    def_sh_output,          "OUTPUT_SPECULAR",    OutputSpecular,   "Material Specular Output", "")
+DefNode( ShaderNode,     SH_NODE_OUTPUT_METALLIC,    0,                      "OUTPUT_METALLIC",    OutputMetallic,   "Material Metallic Output", "")
+DefNode( ShaderNode,     SH_NODE_OUTPUT_SPECULAR,    0,                      "OUTPUT_SPECULAR",    OutputSpecular,   "Material Specular Output", "")
+DefNode( ShaderNode,     SH_NODE_OUTPUT_EEVEE_MATERIAL, def_sh_output,       "OUTPUT_EEVEE_MATERIAL", OutputEeveeMaterial, "Eevee Material Output", "")
 DefNode( ShaderNode,     SH_NODE_OUTPUT_LAMP,        def_sh_output,          "OUTPUT_LAMP",        OutputLamp,       "Lamp Output",       ""       )
 DefNode( ShaderNode,     SH_NODE_OUTPUT_WORLD,       def_sh_output,          "OUTPUT_WORLD",       OutputWorld,      "World Output",      ""       )
 DefNode( ShaderNode,     SH_NODE_OUTPUT_LINESTYLE,   def_sh_output_linestyle,"OUTPUT_LINESTYLE",   OutputLineStyle,  "Line Style Output", ""       )
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c b/source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c
new file mode 100644 (file)
index 0000000..dcb7ada
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+#include "BKE_scene.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_output_eevee_material_in[] = {
+       {       SOCK_SHADER, 1, N_("Surface")},
+       {       -1, 0, ""       }
+};
+
+static int node_shader_gpu_output_eevee_material(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+       GPUNodeLink *outlink;
+
+       GPU_stack_link(mat, "node_output_eevee_material", in, out, &outlink);
+       GPU_material_output_link(mat, outlink);
+
+       return true;
+}
+
+
+/* node type definition */
+void register_node_type_sh_output_eevee_material(void)
+{
+       static bNodeType ntype;
+
+       sh_node_type_base(&ntype, SH_NODE_OUTPUT_EEVEE_MATERIAL, "Eevee Material Output", NODE_CLASS_OUTPUT, 0);
+       node_type_compatibility(&ntype, NODE_NEW_SHADING);
+       node_type_socket_templates(&ntype, sh_node_output_eevee_material_in, NULL);
+       node_type_init(&ntype, NULL);
+       node_type_storage(&ntype, "", NULL, NULL);
+       node_type_gpu(&ntype, node_shader_gpu_output_eevee_material);
+
+       /* Do not allow muting output node. */
+       node_type_internal_links(&ntype, NULL);
+
+       nodeRegisterType(&ntype);
+}
index b8182acfc7f3d2b57b4f4e27f5ea9bba59374a8a..cb2c06268d24031b30e88297c05bc48460b1a750 100644 (file)
@@ -44,9 +44,13 @@ static bNodeSocketTemplate sh_node_output_metallic_in[] = {
        {       -1, 0, ""       }
 };
 
+static bNodeSocketTemplate sh_node_output_metallic_out[] = {
+       {       SOCK_SHADER, 0, N_("BSDF")},
+       {       -1, 0, ""       }
+};
+
 static int node_shader_gpu_output_metallic(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
 {
-       GPUNodeLink *outlink;
        static float one = 1.0f;
 
        /* Normals */
@@ -64,10 +68,7 @@ static int node_shader_gpu_output_metallic(GPUMaterial *mat, bNode *UNUSED(node)
                GPU_link(mat, "set_value", GPU_uniform(&one), &in[10].link);
        }
 
-       GPU_stack_link(mat, "node_output_metallic", in, out, &outlink);
-       GPU_material_output_link(mat, outlink);
-
-       return true;
+       return GPU_stack_link(mat, "node_output_metallic", in, out);
 }
 
 
@@ -76,15 +77,12 @@ void register_node_type_sh_output_metallic(void)
 {
        static bNodeType ntype;
 
-       sh_node_type_base(&ntype, SH_NODE_OUTPUT_METALLIC, "Metallic Material Output", NODE_CLASS_OUTPUT, 0);
+       sh_node_type_base(&ntype, SH_NODE_OUTPUT_METALLIC, "Metallic Material Output", NODE_CLASS_SHADER, 0);
        node_type_compatibility(&ntype, NODE_NEW_SHADING);
-       node_type_socket_templates(&ntype, sh_node_output_metallic_in, NULL);
+       node_type_socket_templates(&ntype, sh_node_output_metallic_in, sh_node_output_metallic_out);
        node_type_init(&ntype, NULL);
        node_type_storage(&ntype, "", NULL, NULL);
        node_type_gpu(&ntype, node_shader_gpu_output_metallic);
 
-       /* Do not allow muting output node. */
-       node_type_internal_links(&ntype, NULL);
-
        nodeRegisterType(&ntype);
 }
index 25bcf9642f9ffcdb02bd775ac14dc02b4b0d8929..218a4357205c45a65fad66c5afbe44c30ca2ea24 100644 (file)
@@ -43,9 +43,13 @@ static bNodeSocketTemplate sh_node_output_specular_in[] = {
        {       -1, 0, ""       }
 };
 
+static bNodeSocketTemplate sh_node_output_specular_out[] = {
+       {       SOCK_SHADER, 0, N_("BSDF")},
+       {       -1, 0, ""       }
+};
+
 static int node_shader_gpu_output_specular(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
 {
-       GPUNodeLink *outlink;
        static float one = 1.0f;
 
        /* Normals */
@@ -63,10 +67,7 @@ static int node_shader_gpu_output_specular(GPUMaterial *mat, bNode *UNUSED(node)
                GPU_link(mat, "set_value", GPU_uniform(&one), &in[9].link);
        }
 
-       GPU_stack_link(mat, "node_output_specular", in, out, &outlink);
-       GPU_material_output_link(mat, outlink);
-
-       return true;
+       return GPU_stack_link(mat, "node_output_specular", in, out);
 }
 
 
@@ -75,15 +76,12 @@ void register_node_type_sh_output_specular(void)
 {
        static bNodeType ntype;
 
-       sh_node_type_base(&ntype, SH_NODE_OUTPUT_SPECULAR, "Specular Material Output", NODE_CLASS_OUTPUT, 0);
+       sh_node_type_base(&ntype, SH_NODE_OUTPUT_SPECULAR, "Specular Material Output", NODE_CLASS_SHADER, 0);
        node_type_compatibility(&ntype, NODE_NEW_SHADING);
-       node_type_socket_templates(&ntype, sh_node_output_specular_in, NULL);
+       node_type_socket_templates(&ntype, sh_node_output_specular_in, sh_node_output_specular_out);
        node_type_init(&ntype, NULL);
        node_type_storage(&ntype, "", NULL, NULL);
        node_type_gpu(&ntype, node_shader_gpu_output_specular);
 
-       /* Do not allow muting output node. */
-       node_type_internal_links(&ntype, NULL);
-
        nodeRegisterType(&ntype);
 }