Shader Node Editor: Add Closure to RGB convertion node.
authorClément Foucault <foucault.clem@gmail.com>
Mon, 14 May 2018 11:34:54 +0000 (13:34 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Wed, 16 May 2018 14:58:32 +0000 (16:58 +0200)
Patch D3205 by Kanzaki Wataru

Only implemented in Eevee for now. Collapse a closure to RGBA so we can
do NPR stuff on the resulting color.

Use an emission shader to convert the color back to a closure.

Doing this will break PBR and will kill any SSR and SSS effects the shader
the shader rely on. That said screen space refraction and ambient occlusion
are supported due to the way they are implemented.

release/scripts/startup/nodeitems_builtins.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/draw/engines/eevee/eevee_screen_raytrace.c
source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
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_shaderToRgb.c [new file with mode: 0644]

index 0d283d39af7dc5eea07c5c44a749f9a64279b3d9..135c4b68f18ae89484ba9af2e616633a6bc0ac93 100644 (file)
@@ -253,6 +253,7 @@ shader_node_categories = [
         NodeItem("ShaderNodeMath"),
         NodeItem("ShaderNodeValToRGB"),
         NodeItem("ShaderNodeRGBToBW"),
+        NodeItem("ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll),
         NodeItem("ShaderNodeVectorMath"),
         NodeItem("ShaderNodeSeparateRGB"),
         NodeItem("ShaderNodeCombineRGB"),
index d85f4095eb972be52baa9351f5ede9469eb1f1a8..f3cbcd7b99ff288f880ee163ac08d21c258efc89 100644 (file)
@@ -714,6 +714,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c
 #define SH_NODE_MIX_RGB                103
 #define SH_NODE_VALTORGB       104
 #define SH_NODE_RGBTOBW                105
+#define SH_NODE_SHADERTORGB    106
 //#define SH_NODE_TEXTURE              106
 #define SH_NODE_NORMAL         107
 //#define SH_NODE_GEOMETRY     108
index 3b51ce9366f0ed8c8cdcd74eb9af940b527ed59c..d86b73ab1a9bb4c742f03488605564c5b143cccd 100644 (file)
@@ -3473,6 +3473,7 @@ static void registerShaderNodes(void)
        register_node_type_sh_mix_rgb();
        register_node_type_sh_valtorgb();
        register_node_type_sh_rgbtobw();
+       register_node_type_sh_shadertorgb();
        register_node_type_sh_normal();
        register_node_type_sh_mapping();
        register_node_type_sh_curve_vec();
index 56cc905d701fc66024a13b78674d77ea8ab62250..87395f94fbb7c073676f9dfa3b816f53a9a1a9b9 100644 (file)
@@ -68,9 +68,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
                        datatoc_common_uniforms_lib_glsl,
                        datatoc_bsdf_common_lib_glsl,
                        datatoc_bsdf_sampling_lib_glsl,
+                       datatoc_ambient_occlusion_lib_glsl,
                        datatoc_octahedron_lib_glsl,
                        datatoc_lightprobe_lib_glsl,
-                       datatoc_ambient_occlusion_lib_glsl,
                        datatoc_raytrace_lib_glsl,
                        datatoc_effect_ssr_frag_glsl);
 
index 6c21d7d6fef1fb72bfb32bbdf7fdbb69bcf102e6..0f76f8e1b8cfdb5e5a379a38efc5745441c08503 100644 (file)
@@ -2,12 +2,6 @@
 /* Based on Stochastic Screen Space Reflections
  * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */
 
-#ifndef UTIL_TEX
-#define UTIL_TEX
-uniform sampler2DArray utilTex;
-#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
 #define MAX_MIP 9.0
 
 uniform ivec2 halfresOffset;
@@ -183,40 +177,6 @@ const ivec2 neighbors[32] = ivec2[32](
 
 out vec4 fragColor;
 
-void fallback_cubemap(
-        vec3 N, vec3 V, vec3 W, vec3 viewPosition, float roughness, float roughnessSquared, inout vec4 spec_accum)
-{
-       /* Specular probes */
-       vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
-
-       vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
-       vec3 bent_normal;
-#ifdef SSR_AO
-       float final_ao = occlusion_compute(N, viewPosition, 1.0, rand, bent_normal);
-       final_ao = specular_occlusion(dot(N, V), final_ao, roughness);
-#else
-       const float final_ao = 1.0;
-#endif
-
-       /* Starts at 1 because 0 is world probe */
-       for (int i = 1; i < MAX_PROBE && i < prbNumRenderCube && spec_accum.a < 0.999; ++i) {
-               CubeData cd = probes_data[i];
-
-               float fade = probe_attenuation_cube(cd, W);
-
-               if (fade > 0.0) {
-                       vec3 spec = final_ao * probe_evaluate_cube(float(i), cd, W, spec_dir, roughness);
-                       accumulate_light(spec, fade, spec_accum);
-               }
-       }
-
-       /* World Specular */
-       if (spec_accum.a < 0.999) {
-               vec3 spec = final_ao * probe_evaluate_world_spec(spec_dir, roughness);
-               accumulate_light(spec, 1.0, spec_accum);
-       }
-}
-
 #if 0 /* Finish reprojection with motion vectors */
 vec3 get_motion_vector(vec3 pos)
 {
index 429f6ea92e4c829e09941deea8c3a8a3765f98bd..6c1571d5306c60cd05bfcac5ecc6200b09d88a02 100644 (file)
@@ -72,6 +72,12 @@ struct GridData {
 #define MAX_PLANAR 1
 #endif
 
+#ifndef UTIL_TEX
+#define UTIL_TEX
+uniform sampler2DArray utilTex;
+#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+#endif /* UTIL_TEX */
+
 layout(std140) uniform probe_block {
        CubeData probes_data[MAX_PROBE];
 };
@@ -196,6 +202,40 @@ vec3 probe_evaluate_planar(
        return sample;
 }
 
+void fallback_cubemap(
+        vec3 N, vec3 V, vec3 W, vec3 viewPosition, float roughness, float roughnessSquared, inout vec4 spec_accum)
+{
+       /* Specular probes */
+       vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+
+       vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
+       vec3 bent_normal;
+#ifdef SSR_AO
+       float final_ao = occlusion_compute(N, viewPosition, 1.0, rand, bent_normal);
+       final_ao = specular_occlusion(dot(N, V), final_ao, roughness);
+#else
+       const float final_ao = 1.0;
+#endif
+
+       /* Starts at 1 because 0 is world probe */
+       for (int i = 1; i < MAX_PROBE && i < prbNumRenderCube && spec_accum.a < 0.999; ++i) {
+               CubeData cd = probes_data[i];
+
+               float fade = probe_attenuation_cube(cd, W);
+
+               if (fade > 0.0) {
+                       vec3 spec = final_ao * probe_evaluate_cube(float(i), cd, W, spec_dir, roughness);
+                       accumulate_light(spec, fade, spec_accum);
+               }
+       }
+
+       /* World Specular */
+       if (spec_accum.a < 0.999) {
+               vec3 spec = final_ao * probe_evaluate_world_spec(spec_dir, roughness);
+               accumulate_light(spec, 1.0, spec_accum);
+       }
+}
+
 #ifdef IRRADIANCE_LIB
 vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos)
 {
index 45701f090fa6f7cfa37069089c07638577bef9a1..236eddbb63ff2c26b3705c8245f2f5c8de2a5cd8 100644 (file)
@@ -2544,4 +2544,28 @@ void node_eevee_specular(
        result.ssr_id = int(ssr_id);
 }
 
+void node_shadertorgb(Closure cl, out vec4 outcol, out float outalpha)
+{
+       vec4 spec_accum = vec4(0.0);
+       if (ssrToggle && cl.ssr_id == outputSsrId) {
+               vec3 V = cameraVec;
+               vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec);
+               vec3 N = transform_direction(ViewMatrixInverse, vN);
+               float roughness = cl.ssr_data.a;
+               float roughnessSquared = max(1e-3, roughness * roughness);
+               fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum);
+       }
+
+       outalpha = cl.opacity;
+       outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0);
+
+#   ifdef USE_SSS
+#              ifdef USE_SSS_ALBEDO
+       outcol += (cl.sss_data * cl.sss_albedo);
+#      else
+       outcol += cl.sss_data;
+#              endif
+#      endif
+}
+
 #endif /* VOLUMETRICS */
index efe7db088f8471dac616dc69c9ec4a90bba44dc2..5acd0a9fceaac9c980aae8422758a6378338a99c 100644 (file)
@@ -177,6 +177,7 @@ set(SRC
        shader/nodes/node_shader_light_falloff.c
        shader/nodes/node_shader_light_path.c
        shader/nodes/node_shader_mix_shader.c
+       shader/nodes/node_shader_shaderToRgb.c
        shader/nodes/node_shader_normal_map.c
        shader/nodes/node_shader_object_info.c
        shader/nodes/node_shader_hair_info.c
index e411ceb6a23628c4f1d6def2c90532b5fdecdae2..3d6a8647628b0e26619459af2cc8a528ca6bd46e 100644 (file)
@@ -50,6 +50,7 @@ void register_node_type_sh_rgb(void);
 void register_node_type_sh_mix_rgb(void);
 void register_node_type_sh_valtorgb(void);
 void register_node_type_sh_rgbtobw(void);
+void register_node_type_sh_shadertorgb(void);
 void register_node_type_sh_normal(void);
 void register_node_type_sh_gamma(void);
 void register_node_type_sh_brightcontrast(void);
index 299c3a627eec7bd67a351daf818a14be2d3f9c8b..efb8eb66737f6c3c16ba93e6037be74264dbecbd 100644 (file)
@@ -45,6 +45,7 @@ DefNode( ShaderNode,     SH_NODE_VALUE,           0,                      "VALUE
 DefNode( ShaderNode,     SH_NODE_MIX_RGB,         def_mix_rgb,            "MIX_RGB",        MixRGB,           "MixRGB",            ""              )
 DefNode( ShaderNode,     SH_NODE_VALTORGB,        def_colorramp,          "VALTORGB",       ValToRGB,         "ColorRamp",         ""              )
 DefNode( ShaderNode,     SH_NODE_RGBTOBW,         0,                      "RGBTOBW",        RGBToBW,          "RGB to BW",         ""              )
+DefNode( ShaderNode,     SH_NODE_SHADERTORGB,     0,                      "SHADERTORGB",    ShaderToRGB,      "Shader to RGB",     ""              )
 DefNode( ShaderNode,     SH_NODE_NORMAL,          0,                      "NORMAL",         Normal,           "Normal",            ""              )
 DefNode( ShaderNode,     SH_NODE_GAMMA,           0,                      "GAMMA",          Gamma,            "Gamma",             ""              )
 DefNode( ShaderNode,     SH_NODE_BRIGHTCONTRAST,  0,                      "BRIGHTCONTRAST", BrightContrast,   "Bright Contrast",   ""              )
diff --git a/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c b/source/blender/nodes/shader/nodes/node_shader_shaderToRgb.c
new file mode 100644 (file)
index 0000000..286752f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * ***** 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): Kanzaki Wataru, Kinouti Takahiro
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_shadertorgb_in[] = {
+       {       SOCK_SHADER, 1, N_("Shader")},
+       {       -1, 0, ""       }
+};
+
+static bNodeSocketTemplate sh_node_shadertorgb_out[] = {
+       {       SOCK_RGBA, 0, N_("Color")},
+       {       SOCK_FLOAT, 0, N_("Alpha")},
+       {       -1, 0, ""       }
+};
+
+static int node_shader_gpu_shadertorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+       return GPU_stack_link(mat, node, "node_shadertorgb", in, out);
+}
+
+/* node type definition */
+void register_node_type_sh_shadertorgb(void)
+{
+       static bNodeType ntype;
+
+       sh_node_type_base(&ntype, SH_NODE_SHADERTORGB, "Shader to RGB", NODE_CLASS_CONVERTOR, 0);
+       node_type_compatibility(&ntype, NODE_NEW_SHADING);
+       node_type_socket_templates(&ntype, sh_node_shadertorgb_in, sh_node_shadertorgb_out);
+       node_type_init(&ntype, NULL);
+       node_type_storage(&ntype, "", NULL, NULL);
+       node_type_gpu(&ntype, node_shader_gpu_shadertorgb);
+
+       nodeRegisterType(&ntype);
+}