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
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-05-02 20:25:25 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-05-03 13:08:56 +0300
commita7404958148f1030483c7d6238ebf48abc26cf24 (patch)
treecd06f232a263ac3bfc7233e12a6d09a5a0a60d7e /source/blender
parent54bde8244578fc2002efa394b482ff3ff47f43fd (diff)
Eevee: Add "uber" Shader Output Nodes.
Include Metallic and Specular workflow. Clearcoat and are not implemented yet.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/intern/node.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c53
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h1
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl31
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_shader.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_metallic.c90
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_specular.c89
12 files changed, 260 insertions, 25 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 219bca0a1a9..42d62297243 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -794,6 +794,8 @@ struct ShadeResult;
#define SH_NODE_UVALONGSTROKE 191
#define SH_NODE_TEX_POINTDENSITY 192
#define SH_NODE_BSDF_PRINCIPLED 193
+#define SH_NODE_OUTPUT_METALLIC 194
+#define SH_NODE_OUTPUT_SPECULAR 195
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 4b7dcc1b9b5..7c382bccfc9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3588,6 +3588,8 @@ static void registerShaderNodes(void)
register_node_type_sh_output_lamp();
register_node_type_sh_output_material();
+ register_node_type_sh_output_metallic();
+ register_node_type_sh_output_specular();
register_node_type_sh_output_world();
register_node_type_sh_output_linestyle();
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 01849678366..6572abde728 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -490,20 +490,8 @@ static void EEVEE_cache_init(void *vedata)
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
psl->material_pass = DRW_pass_create("Material Shader Pass", state);
-
- /* NOTE : this shading grp does not contain any geom, it's just here to setup uniforms & textures. */
- stl->g_data->material_lit_grp = DRW_shgroup_create(e_data.default_lit, psl->material_pass);
- DRW_shgroup_uniform_block(stl->g_data->material_lit_grp, "light_block", stl->light_ubo, 0);
- DRW_shgroup_uniform_block(stl->g_data->material_lit_grp, "shadow_block", stl->shadow_ubo, 1);
- DRW_shgroup_uniform_int(stl->g_data->material_lit_grp, "light_count", &stl->lamps->num_light, 1);
- DRW_shgroup_uniform_float(stl->g_data->material_lit_grp, "lodMax", &stl->probes->lodmax, 1);
- DRW_shgroup_uniform_vec3(stl->g_data->material_lit_grp, "shCoefs[0]", (float *)stl->probes->shcoefs, 9);
- DRW_shgroup_uniform_vec3(stl->g_data->material_lit_grp, "cameraPos", e_data.camera_pos, 1);
- DRW_shgroup_uniform_texture(stl->g_data->material_lit_grp, "ltcMat", e_data.ltc_mat, 0);
- DRW_shgroup_uniform_texture(stl->g_data->material_lit_grp, "brdfLut", e_data.brdf_lut, 1);
- DRW_shgroup_uniform_texture(stl->g_data->material_lit_grp, "probeFiltered", txl->probe_pool, 2);
- /* NOTE : Adding Shadow Map textures uniform in EEVEE_cache_finish */
}
+
{
/* Final pass : Map HDR color to LDR color.
* Write result to the default color buffer */
@@ -522,6 +510,7 @@ static void EEVEE_cache_init(void *vedata)
static void EEVEE_cache_populate(void *vedata, Object *ob)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
struct Batch *geom = DRW_cache_object_surface_get(ob);
@@ -558,6 +547,16 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
if (shgrp) {
DRW_shgroup_call_add(shgrp, mat_geom[i], ob->obmat);
+
+ DRW_shgroup_uniform_block(shgrp, "light_block", stl->light_ubo, 0);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", stl->shadow_ubo, 1);
+ DRW_shgroup_uniform_int(shgrp, "light_count", &stl->lamps->num_light, 1);
+ DRW_shgroup_uniform_float(shgrp, "lodMax", &stl->probes->lodmax, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "shCoefs[0]", (float *)stl->probes->shcoefs, 9);
+ DRW_shgroup_uniform_vec3(shgrp, "cameraPos", e_data.camera_pos, 1);
+ DRW_shgroup_uniform_texture(shgrp, "ltcMat", e_data.ltc_mat, 0);
+ DRW_shgroup_uniform_texture(shgrp, "brdfLut", e_data.brdf_lut, 1);
+ DRW_shgroup_uniform_texture(shgrp, "probeFiltered", txl->probe_pool, 2);
}
else {
/* Shader failed : pink color */
@@ -599,8 +598,23 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
}
}
+typedef struct eevee_bind_shadow_data {
+ struct GPUTexture *shadow_depth_map_pool;
+ struct GPUTexture *shadow_depth_cube_pool;
+ struct GPUTexture *shadow_depth_cascade_pool;
+} eevee_bind_shadow_data;
+
+static void eevee_bind_shadow(void *data, DRWShadingGroup *shgrp)
+{
+ eevee_bind_shadow_data *shdw_data = data;
+ DRW_shgroup_uniform_texture(shgrp, "shadowMaps", shdw_data->shadow_depth_map_pool, 3);
+ DRW_shgroup_uniform_texture(shgrp, "shadowCubes", shdw_data->shadow_depth_cube_pool, 4);
+ DRW_shgroup_uniform_texture(shgrp, "shadowCascades", shdw_data->shadow_depth_cascade_pool, 5);
+}
+
static void EEVEE_cache_finish(void *vedata)
{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl;
@@ -608,13 +622,14 @@ static void EEVEE_cache_finish(void *vedata)
EEVEE_lights_cache_finish(stl, txl, fbl);
/* Shadows binding */
- DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "shadowMaps", txl->shadow_depth_map_pool, 4);
- DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "shadowCubes", txl->shadow_depth_cube_pool, 5);
- DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "shadowCascades", txl->shadow_depth_cascade_pool, 6);
+ eevee_bind_shadow_data data;
+
+ data.shadow_depth_map_pool = txl->shadow_depth_map_pool;
+ data.shadow_depth_cube_pool = txl->shadow_depth_cube_pool;
+ data.shadow_depth_cascade_pool = txl->shadow_depth_cascade_pool;
- DRW_shgroup_uniform_texture(stl->g_data->material_lit_grp, "shadowMaps", txl->shadow_depth_map_pool, 4);
- DRW_shgroup_uniform_texture(stl->g_data->material_lit_grp, "shadowCubes", txl->shadow_depth_cube_pool, 5);
- DRW_shgroup_uniform_texture(stl->g_data->material_lit_grp, "shadowCascades", txl->shadow_depth_cascade_pool, 6);
+ DRW_pass_foreach_shgroup(psl->default_pass, eevee_bind_shadow, &data);
+ DRW_pass_foreach_shgroup(psl->material_pass, eevee_bind_shadow, &data);
}
static void EEVEE_draw_scene(void *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index ee8e8598725..3876ab44d95 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -175,7 +175,6 @@ typedef struct EEVEE_LampEngineData {
typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *default_lit_grp;
- struct DRWShadingGroup *material_lit_grp;
struct DRWShadingGroup *shadow_shgrp;
struct DRWShadingGroup *depth_shgrp;
struct DRWShadingGroup *depth_shgrp_cull;
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
index 8d4a1e6d523..57622aa716b 100644
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -9,5 +9,5 @@ void main()
{
float roughness = 1.0 - float(hardness) / 511.0;
roughness *= roughness;
- FragColor = vec4(eevee_surface_lit(worldNormal, diffuse_col, specular_col, roughness), 1.0);
+ FragColor = vec4(eevee_surface_lit(worldNormal, diffuse_col, specular_col, roughness, 1.0), 1.0);
}
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 9b8963ef798..0d96b7768dc 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -231,7 +231,7 @@ float light_common(inout LightData ld, inout ShadingData sd)
return vis;
}
-vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness)
+vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, float ao)
{
ShadingData sd;
sd.N = normalize(world_normal);
@@ -243,6 +243,7 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness)
sd.spec_dominant_dir = get_specular_dominant_dir(sd.N, sd.R, roughness);
vec3 radiance = vec3(0.0);
+ vec3 indirect_radiance = vec3(0.0);
/* Analitic Lights */
for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
@@ -264,9 +265,9 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness)
vec2 uv = ltc_coords(dot(sd.N, sd.V), sqrt(roughness));
vec2 brdf_lut = texture(brdfLut, uv).rg;
vec3 Li = textureLod(probeFiltered, sd.spec_dominant_dir, roughness * lodMax).rgb;
- radiance += Li * brdf_lut.y + f0 * Li * brdf_lut.x;
+ indirect_radiance += Li * brdf_lut.y + f0 * Li * brdf_lut.x;
- radiance += spherical_harmonics(sd.N, shCoefs) * albedo;
+ indirect_radiance += spherical_harmonics(sd.N, shCoefs) * albedo;
- return radiance;
+ return radiance + indirect_radiance * ao;
} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 8bfbd07bce8..1da213b4103 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -3828,6 +3828,37 @@ void node_output_world(vec4 surface, vec4 volume, out vec4 result)
result = surface;
}
+void convert_metallic_to_specular(vec4 basecol, float metallic, float specular_fac, out vec4 diffuse, out vec4 f0)
+{
+ vec4 dielectric = vec4(0.034) * specular_fac * 2.0;
+ diffuse = mix(basecol, vec4(0.0), metallic);
+ f0 = mix(dielectric, basecol, metallic);
+}
+
+void world_normals_get(out vec3 N)
+{
+ N = gl_FrontFacing ? worldNormal : -worldNormal;
+}
+
+void node_output_metallic(
+ vec4 basecol, float metallic, float specular, float roughness, vec4 emissive, float transp, vec3 normal,
+ float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+ float occlusion, out vec4 result)
+{
+ vec4 diffuse, f0;
+ convert_metallic_to_specular(basecol, metallic, specular, diffuse, f0);
+
+ result = vec4(eevee_surface_lit(normal, diffuse.rgb, f0.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp);
+}
+
+void node_output_specular(
+ vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
+ float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+ float occlusion, out vec4 result)
+{
+ result = vec4(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp);
+}
+
/* ********************** matcap style render ******************** */
void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 3596a2aa12d..697b649a298 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -186,6 +186,8 @@ set(SRC
shader/nodes/node_shader_hair_info.c
shader/nodes/node_shader_output_lamp.c
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_world.c
shader/nodes/node_shader_output_linestyle.c
shader/nodes/node_shader_particle_info.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 804c1897a27..c05c1a55144 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -120,6 +120,8 @@ void register_node_type_sh_uvalongstroke(void);
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_world(void);
void register_node_type_sh_output_linestyle(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index e754d063397..7d9f8149ad0 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -67,6 +67,8 @@ 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_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_metallic.c b/source/blender/nodes/shader/nodes/node_shader_output_metallic.c
new file mode 100644
index 00000000000..b8182acfc7f
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output_metallic.c
@@ -0,0 +1,90 @@
+/*
+ * ***** 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): Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_output_metallic_in[] = {
+ { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 1, N_("Emissive Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Clear Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Clear Coat Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Clear Coat Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Ambient Occlusion"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { -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 */
+ if (!in[6].link) {
+ GPU_link(mat, "world_normals_get", &in[6].link);
+ }
+
+ /* Clearcoat Normals */
+ if (!in[9].link) {
+ GPU_link(mat, "world_normals_get", &in[9].link);
+ }
+
+ /* Occlusion */
+ if (!in[10].link) {
+ 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;
+}
+
+
+/* node type definition */
+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);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_output_metallic_in, NULL);
+ 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);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_specular.c b/source/blender/nodes/shader/nodes/node_shader_output_specular.c
new file mode 100644
index 00000000000..25bcf9642f9
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output_specular.c
@@ -0,0 +1,89 @@
+/*
+ * ***** 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): Clément Foucault.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_output_specular_in[] = {
+ { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f},
+ { SOCK_RGBA, 1, N_("Specular"), 0.03f, 0.03f, 0.03f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 1, N_("Emissive Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Clear Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Clear Coat Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Clear Coat Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Ambient Occlusion"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { -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 */
+ if (!in[5].link) {
+ GPU_link(mat, "world_normals_get", &in[5].link);
+ }
+
+ /* Clearcoat Normals */
+ if (!in[8].link) {
+ GPU_link(mat, "world_normals_get", &in[8].link);
+ }
+
+ /* Occlusion */
+ if (!in[9].link) {
+ 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;
+}
+
+
+/* node type definition */
+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);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_output_specular_in, NULL);
+ 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);
+}