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:
Diffstat (limited to 'source/blender/nodes/shader')
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c8
-rw-r--r--source/blender/nodes/shader/node_shader_util.c19
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_blackbody.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c132
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c59
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_eevee_specular.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c19
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c53
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.c14
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_volume_principled.c14
20 files changed, 305 insertions, 60 deletions
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 919af171756..6f2c7835a3c 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -583,10 +583,9 @@ static void ntree_shader_tag_sss_node(bNodeTree *ntree, bNode *output_node)
nodeChainIter(ntree, output_node, ntree_tag_sss_bsdf_cb, &sss_id, true);
}
-void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, bool *has_surface_output, bool *has_volume_output)
+/* This one needs to work on a local tree. */
+void ntreeGPUMaterialNodes(bNodeTree *localtree, GPUMaterial *mat, bool *has_surface_output, bool *has_volume_output)
{
- /* localize tree to create links for reroute and mute */
- bNodeTree *localtree = ntreeLocalize(ntree);
bNode *output = ntreeShaderOutputNode(localtree, SHD_OUTPUT_EEVEE);
bNodeTreeExec *exec;
@@ -618,9 +617,6 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, bool *has_surface
*has_volume_output = (nodeCountSocketLinks(localtree, volume_sock) > 0);
}
}
-
- ntreeFreeTree(localtree);
- MEM_freeN(localtree);
}
bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key)
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 9190f0d53cd..63c1cac566d 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -253,13 +253,18 @@ void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in
float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0;
if (domin || domax || !(texmap->flag & TEXMAP_UNIT_MATRIX)) {
- GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat);
- GPUNodeLink *tmin = GPU_uniform(texmap->min);
- GPUNodeLink *tmax = GPU_uniform(texmap->max);
- GPUNodeLink *tdomin = GPU_uniform(&domin);
- GPUNodeLink *tdomax = GPU_uniform(&domax);
-
- GPU_link(mat, "mapping", in[0].link, tmat, tmin, tmax, tdomin, tdomax, &in[0].link);
+ static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX};
+ static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
+ GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3;
+
+ tmin = GPU_uniform_buffer((domin) ? texmap->min : min, GPU_VEC3);
+ tmax = GPU_uniform_buffer((domax) ? texmap->max : max, GPU_VEC3);
+ tmat0 = GPU_uniform_buffer((float *)texmap->mat[0], GPU_VEC4);
+ tmat1 = GPU_uniform_buffer((float *)texmap->mat[1], GPU_VEC4);
+ tmat2 = GPU_uniform_buffer((float *)texmap->mat[2], GPU_VEC4);
+ tmat3 = GPU_uniform_buffer((float *)texmap->mat[3], GPU_VEC4);
+
+ GPU_link(mat, "mapping", in[0].link, tmat0, tmat1, tmat2, tmat3, tmin, tmax, &in[0].link);
if (texmap->type == TEXMAP_TYPE_NORMAL)
GPU_link(mat, "texco_norm", in[0].link, &in[0].link);
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
index 76291df41bc..e57f5e0d6cf 100644
--- a/source/blender/nodes/shader/nodes/node_shader_blackbody.c
+++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
@@ -40,12 +40,15 @@ static bNodeSocketTemplate sh_node_blackbody_out[] = {
static int node_shader_gpu_blackbody(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- const int size = 256;
+ const int size = CM_TABLE + 1;
float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
- return GPU_stack_link(mat, node, "node_blackbody", in, out, GPU_texture(size, data));
+ float layer;
+ GPUNodeLink *ramp_texture = GPU_texture_ramp(mat, size, data, &layer);
+
+ return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_uniform(&layer));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
index c1423867d96..6551b20a375 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c
@@ -54,6 +54,8 @@ static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *node, bNode
if (!in[4].link)
GPU_link(mat, "world_normals_get", &in[4].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
+
return GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
index 58a37b0e81d..c1b8c748657 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c
@@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *node, bNodeExec
if (!in[2].link)
GPU_link(mat, "world_normals_get", &in[2].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
+
return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
index 7b060bc68aa..ada6e21356f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
@@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecDa
if (!in[3].link)
GPU_link(mat, "world_normals_get", &in[3].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT);
+
return GPU_stack_link(mat, node, "node_bsdf_glass", in, out, GPU_uniform(&node->ssr_id));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
index c3fb43c0ce8..f56837de261 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c
@@ -51,6 +51,8 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecD
if (!in[2].link)
GPU_link(mat, "world_normals_get", &in[2].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
+
return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_uniform(&node->ssr_id));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
new file mode 100644
index 00000000000..83e4bf1731b
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c
@@ -0,0 +1,132 @@
+/*
+ * ***** 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) 2018 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Stockner, L. E. Segovia
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+/* Color, melanin and absorption coefficient default to approximately same brownish hair. */
+static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.017513f, 0.005763f, 0.002059f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Melanin"), 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Melanin Redness"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_RGBA, 1, N_("Tint"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 1, N_("Absorption Coefficient"), 0.245531f, 0.52f, 1.365f, 0.0f, 0.0f, 1000.0f},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Radial Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+ { SOCK_FLOAT, 1, N_("Offset"), 2.0f * ((float)M_PI) / 180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE},
+ { SOCK_FLOAT, 1, N_("Random Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Random Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { -1, 0, "" },
+};
+
+static bNodeSocketTemplate sh_node_bsdf_hair_principled_out[] = {
+ { SOCK_SHADER, 0, N_("BSDF")},
+ { -1, 0, "" }
+};
+
+/* Initialize the custom Parametrization property to Color. */
+static void node_shader_init_hair_principled(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_PRINCIPLED_HAIR_REFLECTANCE;
+}
+
+/* Triggers (in)visibility of some sockets when changing Parametrization. */
+static void node_shader_update_hair_principled(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *sock;
+ int parametrization = node->custom1;
+
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (STREQ(sock->name, "Color")) {
+ if (parametrization == SHD_PRINCIPLED_HAIR_REFLECTANCE) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ else if (STREQ(sock->name, "Melanin")) {
+ if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ else if (STREQ(sock->name, "Melanin Redness")) {
+ if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ else if (STREQ(sock->name, "Tint")) {
+ if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ else if (STREQ(sock->name, "Absorption Coefficient")) {
+ if (parametrization == SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ else if (STREQ(sock->name, "Random Color")) {
+ if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) {
+ sock->flag &= ~SOCK_UNAVAIL;
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
+ }
+ }
+ }
+}
+
+/* node type definition */
+void register_node_type_sh_bsdf_hair_principled(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_BSDF_HAIR_PRINCIPLED, "Principled Hair BSDF", NODE_CLASS_SHADER, 0);
+ node_type_socket_templates(&ntype, sh_node_bsdf_hair_principled_in, sh_node_bsdf_hair_principled_out);
+ node_type_size_preset(&ntype, NODE_SIZE_LARGE);
+ node_type_init(&ntype, node_shader_init_hair_principled);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_update(&ntype, node_shader_update_hair_principled, NULL);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
index 7f02295d45f..370dcdcc2ea 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -64,22 +64,12 @@ static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
node->custom2 = SHD_SUBSURFACE_BURLEY;
}
+#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
+#define socket_not_one(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f))
+
static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
GPUNodeLink *sss_scale;
-#if 0 /* Old 2.7 glsl viewport */
- // normal
- if (!in[17].link)
- in[17].link = GPU_builtin(GPU_VIEW_NORMAL);
- else
- GPU_link(mat, "direction_transform_m4v3", in[17].link, GPU_builtin(GPU_VIEW_MATRIX), &in[17].link);
-
- // clearcoat normal
- if (!in[18].link)
- in[18].link = GPU_builtin(GPU_VIEW_NORMAL);
- else
- GPU_link(mat, "direction_transform_m4v3", in[18].link, GPU_builtin(GPU_VIEW_MATRIX), &in[18].link);
-#endif
/* Normals */
if (!in[17].link) {
@@ -117,7 +107,48 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeE
GPU_link(mat, "set_rgb", GPU_uniform((float *)one), &sss_scale);
}
- return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION),
+ bool use_diffuse = socket_not_one(4) && socket_not_one(15);
+ bool use_subsurf = socket_not_zero(1) && use_diffuse;
+ bool use_refract = socket_not_one(4) && socket_not_zero(15);
+ bool use_clear = socket_not_zero(12);
+
+ /* Due to the manual effort done per config, we only optimize the most common permutations. */
+ char *node_name;
+ uint flag = 0;
+ if (!use_subsurf && use_diffuse && !use_refract && !use_clear) {
+ static char name[] = "node_bsdf_principled_dielectric";
+ node_name = name;
+ flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY;
+ }
+ else if (!use_subsurf && !use_diffuse && !use_refract && !use_clear) {
+ static char name[] = "node_bsdf_principled_metallic";
+ node_name = name;
+ flag = GPU_MATFLAG_GLOSSY;
+ }
+ else if (!use_subsurf && !use_diffuse && !use_refract && use_clear) {
+ static char name[] = "node_bsdf_principled_clearcoat";
+ node_name = name;
+ flag = GPU_MATFLAG_GLOSSY;
+ }
+ else if (use_subsurf && use_diffuse && !use_refract && !use_clear) {
+ static char name[] = "node_bsdf_principled_subsurface";
+ node_name = name;
+ flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS | GPU_MATFLAG_GLOSSY;
+ }
+ else if (!use_subsurf && !use_diffuse && use_refract && !use_clear && !socket_not_zero(4)) {
+ static char name[] = "node_bsdf_principled_glass";
+ node_name = name;
+ flag = GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT;
+ }
+ else {
+ static char name[] = "node_bsdf_principled";
+ node_name = name;
+ flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY | GPU_MATFLAG_SSS | GPU_MATFLAG_REFRACT;
+ }
+
+ GPU_material_flag_set(mat, flag);
+
+ return GPU_stack_link(mat, node, node_name, in, out, GPU_builtin(GPU_VIEW_POSITION),
GPU_uniform(&node->ssr_id), GPU_uniform(&node->sss_id), sss_scale);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
index 41dd3f8af3c..b59f1c80342 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c
@@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, bNode *node, bNodeE
if (!in[3].link)
GPU_link(mat, "world_normals_get", &in[3].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT);
+
return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
index 2c0949f275c..349db30af14 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c
@@ -45,6 +45,8 @@ static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *node, bNode
if (!in[1].link)
GPU_link(mat, "world_normals_get", &in[1].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
+
return GPU_stack_link(mat, node, "node_bsdf_translucent", in, out);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
index ce331f03d4e..59b831c0dab 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c
@@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *node, bNodeExecD
if (!in[2].link)
GPU_link(mat, "world_normals_get", &in[2].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE);
+
return GPU_stack_link(mat, node, "node_bsdf_velvet", in, out);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index d5932ff233a..21bdc3cd0d8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -62,11 +62,13 @@ static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_curve_vec(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- float *array;
+ float *array, layer;
int size;
curvemapping_table_RGBA(node->storage, &array, &size);
- return GPU_stack_link(mat, node, "curves_vec", in, out, GPU_texture(size, array));
+ GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer);
+
+ return GPU_stack_link(mat, node, "curves_vec", in, out, tex, GPU_uniform(&layer));
}
void register_node_type_sh_curve_vec(void)
@@ -119,12 +121,14 @@ static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- float *array;
+ float *array, layer;
int size;
curvemapping_initialize(node->storage);
curvemapping_table_RGBA(node->storage, &array, &size);
- return GPU_stack_link(mat, node, "curves_rgb", in, out, GPU_texture(size, array));
+ GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer);
+
+ return GPU_stack_link(mat, node, "curves_rgb", in, out, tex, GPU_uniform(&layer));
}
void register_node_type_sh_curve_rgb(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c
index e05b0be1e62..6583dd0cec3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c
+++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c
@@ -67,6 +67,8 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat, bNode *node, bNodeEx
GPU_link(mat, "set_value", GPU_uniform(&one), &in[9].link);
}
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY);
+
return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_uniform(&node->ssr_id));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index a84e88e9551..98dcd58b983 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -88,13 +88,18 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
TexMapping *texmap = node->storage;
float domin = (texmap->flag & TEXMAP_CLIP_MIN) != 0;
float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0;
- GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat);
- GPUNodeLink *tmin = GPU_uniform(texmap->min);
- GPUNodeLink *tmax = GPU_uniform(texmap->max);
- GPUNodeLink *tdomin = GPU_uniform(&domin);
- GPUNodeLink *tdomax = GPU_uniform(&domax);
-
- GPU_stack_link(mat, node, "mapping", in, out, tmat, tmin, tmax, tdomin, tdomax);
+ static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX};
+ static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
+ GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3;
+
+ tmin = GPU_uniform_buffer((domin) ? texmap->min : min, GPU_VEC3);
+ tmax = GPU_uniform_buffer((domax) ? texmap->max : max, GPU_VEC3);
+ tmat0 = GPU_uniform_buffer((float *)texmap->mat[0], GPU_VEC4);
+ tmat1 = GPU_uniform_buffer((float *)texmap->mat[1], GPU_VEC4);
+ tmat2 = GPU_uniform_buffer((float *)texmap->mat[2], GPU_VEC4);
+ tmat3 = GPU_uniform_buffer((float *)texmap->mat[3], GPU_VEC4);
+
+ GPU_stack_link(mat, node, "mapping", in, out, tmat0, tmat1, tmat2, tmat3, tmin, tmax);
if (texmap->type == TEXMAP_TYPE_NORMAL)
GPU_link(mat, "texco_norm", out[0].link, &out[0].link);
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index 3c0fb145987..e4b5aaef72d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -63,11 +63,21 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U
if (in[0].link)
strength = in[0].link;
+ else if (node->original) {
+ bNodeSocket *socket = BLI_findlink(&node->original->inputs, 0);
+ bNodeSocketValueFloat *socket_data = socket->default_value;
+ strength = GPU_uniform_buffer(&socket_data->value, GPU_FLOAT);
+ }
else
strength = GPU_uniform(in[0].vec);
if (in[1].link)
realnorm = in[1].link;
+ else if (node->original) {
+ bNodeSocket *socket = BLI_findlink(&node->original->inputs, 1);
+ bNodeSocketValueRGBA *socket_data = socket->default_value;
+ realnorm = GPU_uniform_buffer(socket_data->value, GPU_VEC3);
+ }
else
realnorm = GPU_uniform(in[1].vec);
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
index 57fb9026595..f8af125eb9e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
@@ -54,6 +54,8 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *node,
if (!in[5].link)
GPU_link(mat, "world_normals_get", &in[5].link);
+ GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS);
+
if (node->sss_id == 1) {
bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2);
bNodeSocketValueRGBA *socket_data = socket->default_value;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 2bbe3617bee..9782df2638f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -55,11 +55,28 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
+ static const char *names[] = {
+ "node_tex_image_linear",
+ "node_tex_image_nearest",
+ "node_tex_image_cubic",
+ "node_tex_image_smart"
+ };
+ static const char *names_box[] = {
+ "tex_box_sample_linear",
+ "tex_box_sample_nearest",
+ "tex_box_sample_cubic",
+ "tex_box_sample_smart"
+ };
+
Image *ima = (Image *)node->id;
ImageUser *iuser = NULL;
NodeTexImage *tex = node->storage;
+ const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX)
+ ? names_box[tex->interpolation]
+ : names[tex->interpolation];
+ bool do_color_correction = false;
- GPUNodeLink *norm;
+ GPUNodeLink *norm, *col1, *col2, *col3;
int isdata = tex->color_space == SHD_COLORSPACE_NONE;
float blend = tex->projection_blend;
@@ -67,6 +84,15 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
if (!ima)
return GPU_stack_link(mat, node, "node_tex_image_empty", in, out);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ if ((tex->color_space == SHD_COLORSPACE_COLOR) &&
+ ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
+ GPU_material_do_color_management(mat))
+ {
+ do_color_correction = true;
+ }
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
if (!in[0].link)
in[0].link = GPU_attribute(CD_MTFACE, "");
@@ -74,7 +100,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
switch (tex->projection) {
case SHD_PROJ_FLAT:
- GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
break;
case SHD_PROJ_BOX:
GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL),
@@ -83,8 +109,20 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
GPU_link(mat, "direction_transform_m4v3", norm,
GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
&norm);
+ GPU_link(mat, gpu_node_name, in[0].link,
+ norm,
+ GPU_image(ima, iuser, isdata),
+ &col1,
+ &col2,
+ &col3);
+ if (do_color_correction) {
+ GPU_link(mat, "srgb_to_linearrgb", col1, &col1);
+ GPU_link(mat, "srgb_to_linearrgb", col2, &col2);
+ GPU_link(mat, "srgb_to_linearrgb", col3, &col3);
+ }
GPU_link(mat, "node_tex_image_box", in[0].link,
norm,
+ col1, col2, col3,
GPU_image(ima, iuser, isdata),
GPU_uniform(&blend),
&out[0].link,
@@ -93,23 +131,18 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
case SHD_PROJ_SPHERE:
GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link);
GPU_link(mat, "point_map_to_sphere", in[0].link, &in[0].link);
- GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
break;
case SHD_PROJ_TUBE:
GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link);
GPU_link(mat, "point_map_to_tube", in[0].link, &in[0].link);
- GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
break;
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if ((tex->color_space == SHD_COLORSPACE_COLOR) &&
- ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat))
- {
+ if (do_color_correction && (tex->projection != SHD_PROJ_BOX)) {
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
- BKE_image_release_ibuf(ima, ibuf, NULL);
return true;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
index b6581cb18cb..5f583e1e29b 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
@@ -65,11 +65,19 @@ static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node)
static int gpu_shader_valtorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- float *array;
+ struct ColorBand *coba = node->storage;
+ float *array, layer;
int size;
- BKE_colorband_evaluate_table_rgba(node->storage, &array, &size);
- return GPU_stack_link(mat, node, "valtorgb", in, out, GPU_texture(size, array));
+ BKE_colorband_evaluate_table_rgba(coba, &array, &size);
+ GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer);
+
+ if (coba->ipotype == COLBAND_INTERP_CONSTANT) {
+ return GPU_stack_link(mat, node, "valtorgb_nearest", in, out, tex, GPU_uniform(&layer));
+ }
+ else {
+ return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_uniform(&layer));
+ }
}
void register_node_type_sh_valtorgb(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
index a88a7ebb21a..c946c42f9af 100644
--- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c
@@ -132,19 +132,19 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNod
}
/* Create blackbody spectrum. */
- GPUNodeLink *spectrummap;
+ const int size = CM_TABLE + 1;
+ float *data, layer;
if (use_blackbody) {
- const int size = 256;
- float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
+ data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture");
blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f);
- spectrummap = GPU_texture(size, data);
}
else {
- float *data = MEM_callocN(sizeof(float) * 4, "blackbody black");
- spectrummap = GPU_texture(1, data);
+ data = MEM_callocN(sizeof(float) * size * 4, "blackbody black");
}
+ GPUNodeLink *spectrummap = GPU_texture_ramp(mat, size, data, &layer);
- return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap);
+ return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap,
+ GPU_uniform(&layer));
}
/* node type definition */