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:
authorCampbell Barton <ideasman42@gmail.com>2018-06-08 09:10:35 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-06-08 09:10:35 +0300
commit908b6960c01ffb1665af56ff6f03aaa3eac5366a (patch)
treedb609864fbe601073212b4c37541a7965ea96ea5 /source/blender/nodes/shader
parentd352a0adc5dadd0bfdc3b1b1ac76d92be689966b (diff)
parenta25c11fd8d602236f36c34c342453149bdc1d909 (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/nodes/shader')
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c52
-rw-r--r--source/blender/nodes/shader/node_shader_util.c20
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_brightness.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bump.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.c42
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_fresnel.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geom.c163
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.c8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c374
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mixRgb.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output.c97
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_world.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_squeeze.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c166
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectMath.c24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectTransform.c8
28 files changed, 915 insertions, 115 deletions
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index a5d8031f2f3..fcb21982661 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -82,7 +82,7 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
-
+
if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
if (ob) {
*r_from = &ob->id;
@@ -136,11 +136,11 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
{
bNode *node, *node_next;
-
+
/* replace muted nodes and reroute nodes by internal links */
for (node = localtree->nodes.first; node; node = node_next) {
node_next = node->next;
-
+
if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
nodeInternalRelink(localtree, node);
nodeFreeNode(localtree, node);
@@ -161,9 +161,9 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
static void update(bNodeTree *ntree)
{
ntreeSetOutput(ntree);
-
+
ntree_update_reroute_nodes(ntree);
-
+
if (ntree->update & NTREE_UPDATE_NODES) {
/* clean up preview cache, in case nodes have been removed */
BKE_node_preview_remove_unused(ntree);
@@ -175,13 +175,13 @@ bNodeTreeType *ntreeType_Shader;
void register_node_tree_type_sh(void)
{
bNodeTreeType *tt = ntreeType_Shader = MEM_callocN(sizeof(bNodeTreeType), "shader node tree type");
-
+
tt->type = NTREE_SHADER;
strcpy(tt->idname, "ShaderNodeTree");
strcpy(tt->ui_name, "Shader Editor");
tt->ui_icon = 0; /* defined in drawnode.c */
strcpy(tt->ui_description, "Shader nodes");
-
+
tt->foreach_nodeclass = foreach_nodeclass;
tt->localize = localize;
tt->local_sync = local_sync;
@@ -189,9 +189,9 @@ void register_node_tree_type_sh(void)
tt->update = update;
tt->poll = shader_tree_poll;
tt->get_from_context = shader_get_from_context;
-
+
tt->ext.srna = &RNA_ShaderNodeTree;
-
+
ntreeTypeAdd(tt);
}
@@ -622,19 +622,19 @@ bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNod
{
bNodeTreeExec *exec;
bNode *node;
-
+
/* ensures only a single output node is enabled */
ntreeSetOutput(ntree);
-
+
/* common base initialization */
exec = ntree_exec_begin(context, ntree, parent_key);
-
+
/* allocate the thread stack listbase array */
exec->threadstack = MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array");
-
+
for (node = exec->nodetree->nodes.first; node; node = node->next)
node->need_exec = 1;
-
+
return exec;
}
@@ -642,22 +642,22 @@ bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
{
bNodeExecContext context;
bNodeTreeExec *exec;
-
+
/* XXX hack: prevent exec data from being generated twice.
* this should be handled by the renderer!
*/
if (ntree->execdata)
return ntree->execdata;
-
+
context.previews = ntree->previews;
-
+
exec = ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
-
+
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
* which only store the ntree pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
-
+
return exec;
}
@@ -665,18 +665,18 @@ void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
{
bNodeThreadStack *nts;
int a;
-
+
if (exec->threadstack) {
for (a = 0; a < BLENDER_MAX_THREADS; a++) {
for (nts = exec->threadstack[a].first; nts; nts = nts->next)
if (nts->stack) MEM_freeN(nts->stack);
BLI_freelistN(&exec->threadstack[a]);
}
-
+
MEM_freeN(exec->threadstack);
exec->threadstack = NULL;
}
-
+
ntree_exec_end(exec);
}
@@ -686,7 +686,7 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec)
/* exec may get freed, so assign ntree */
bNodeTree *ntree = exec->nodetree;
ntreeShaderEndExecTree_internal(exec);
-
+
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
ntree->execdata = NULL;
}
@@ -699,7 +699,7 @@ bool ntreeShaderExecTree(bNodeTree *ntree, int thread)
bNodeThreadStack *nts = NULL;
bNodeTreeExec *exec = ntree->execdata;
int compat;
-
+
/* ensure execdata is only initialized once */
if (!exec) {
BLI_thread_lock(LOCK_NODES);
@@ -709,11 +709,11 @@ bool ntreeShaderExecTree(bNodeTree *ntree, int thread)
exec = ntree->execdata;
}
-
+
nts = ntreeGetThreadStack(exec, thread);
compat = ntreeExecThreadNodes(exec, nts, &scd, thread);
ntreeReleaseThreadStack(nts);
-
+
/* if compat is zero, it has been using non-compatible nodes */
return compat;
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 43e940d6d0a..a4b2c155675 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -45,7 +45,7 @@ int sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
{
node_type_base(ntype, type, name, nclass, flag);
-
+
ntype->poll = sh_node_poll_default;
ntype->insert_link = node_insert_link_default;
ntype->update_internal_links = node_update_internal_links_default;
@@ -56,11 +56,11 @@ void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, shor
void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
{
const float *from = ns->vec;
-
+
if (type_in == SOCK_FLOAT) {
if (ns->sockettype == SOCK_FLOAT)
*in = *from;
- else
+ else
*in = (from[0] + from[1] + from[2]) / 3.0f;
}
else if (type_in == SOCK_VECTOR) {
@@ -94,7 +94,7 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
{
memset(gs, 0, sizeof(*gs));
-
+
if (ns == NULL) {
/* node_get_stack() will generate NULL bNodeStack pointers for unknown/unsuported types of sockets... */
zero_v4(gs->vec);
@@ -107,7 +107,7 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
else {
nodestack_get_vec(gs->vec, type, ns);
gs->link = ns->data;
-
+
if (type == SOCK_FLOAT)
gs->type = GPU_FLOAT;
else if (type == SOCK_VECTOR)
@@ -140,10 +140,10 @@ static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeS
{
bNodeSocket *sock;
int i;
-
+
for (sock = sockets->first, i = 0; sock; sock = sock->next, i++)
node_gpu_stack_from_data(&gs[i], sock->type, ns[i]);
-
+
gs[i].end = true;
}
@@ -192,7 +192,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
if (activetexnode)
return activetexnode;
-
+
if (hasgroup) {
/* node active texture node in this tree, look inside groups */
for (node = ntree->nodes.first; node; node = node->next) {
@@ -203,7 +203,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
}
}
}
-
+
return inactivenode;
}
@@ -222,7 +222,7 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs, sh
for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
node = nodeexec->node;
-
+
do_it = false;
/* for groups, only execute outputs for edited group */
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_brightness.c b/source/blender/nodes/shader/nodes/node_shader_brightness.c
index d795575c86a..bb95ed2d32c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_brightness.c
+++ b/source/blender/nodes/shader/nodes/node_shader_brightness.c
@@ -50,13 +50,13 @@ static int gpu_shader_brightcontrast(GPUMaterial *mat, bNode *node, bNodeExecDat
void register_node_type_sh_brightcontrast(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, 0);
node_type_compatibility(&ntype, NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_brightcontrast_in, sh_node_brightcontrast_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, gpu_shader_brightcontrast);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c
index 6098aefc5e1..6274d132bc7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bump.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bump.c
@@ -31,7 +31,7 @@
#include "node_shader_util.h"
-/* **************** BUMP ******************** */
+/* **************** BUMP ******************** */
static bNodeSocketTemplate sh_node_bump_in[] = {
{ SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Distance"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index 134319cb352..24de03dbda4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -50,7 +50,7 @@ static void copy_stack(bNodeStack *to, bNodeStack *from)
copy_v4_v4(to->vec, from->vec);
to->data = from->data;
to->datatype = from->datatype;
-
+
/* tag as copy to prevent freeing */
to->is_copy = 1;
}
@@ -63,7 +63,7 @@ static void move_stack(bNodeStack *to, bNodeStack *from)
to->data = from->data;
to->datatype = from->datatype;
to->is_copy = from->is_copy;
-
+
from->data = NULL;
from->is_copy = 0;
}
@@ -75,20 +75,20 @@ static void *group_initexec(bNodeExecContext *context, bNode *node, bNodeInstanc
{
bNodeTree *ngroup = (bNodeTree *)node->id;
bNodeTreeExec *exec;
-
+
if (!ngroup)
return NULL;
-
+
/* initialize the internal node tree execution */
exec = ntreeShaderBeginExecTree_internal(context, ngroup, key);
-
+
return exec;
}
static void group_freeexec(void *nodedata)
{
bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata;
-
+
if (gexec)
ntreeShaderEndExecTree_internal(gexec);
}
@@ -102,7 +102,7 @@ static void group_copy_inputs(bNode *gnode, bNodeStack **in, bNodeStack *gstack)
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_INPUT) {
for (sock = node->outputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -123,7 +123,7 @@ static void group_move_outputs(bNode *gnode, bNodeStack **out, bNodeStack *gstac
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
for (sock = node->inputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -140,10 +140,10 @@ static void group_execute(void *data, int thread, struct bNode *node, bNodeExecD
{
bNodeTreeExec *exec = execdata->data;
bNodeThreadStack *nts;
-
+
if (!exec)
return;
-
+
/* XXX same behavior as trunk: all nodes inside group are executed.
* it's stupid, but just makes it work. compo redesign will do this better.
*/
@@ -152,13 +152,13 @@ static void group_execute(void *data, int thread, struct bNode *node, bNodeExecD
for (inode = exec->nodetree->nodes.first; inode; inode = inode->next)
inode->need_exec = 1;
}
-
+
nts = ntreeGetThreadStack(exec, thread);
-
+
group_copy_inputs(node, in, nts->stack);
ntreeExecThreadNodes(exec, nts, data, thread);
group_move_outputs(node, out, nts->stack);
-
+
ntreeReleaseThreadStack(nts);
}
@@ -169,7 +169,7 @@ static void group_gpu_copy_inputs(bNode *gnode, GPUNodeStack *in, bNodeStack *gs
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_INPUT) {
for (sock = node->outputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -192,7 +192,7 @@ static void group_gpu_move_outputs(bNode *gnode, GPUNodeStack *out, bNodeStack *
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
for (sock = node->inputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -210,10 +210,10 @@ static void group_gpu_move_outputs(bNode *gnode, GPUNodeStack *out, bNodeStack *
static int gpu_group_execute(GPUMaterial *mat, bNode *node, bNodeExecData *execdata, GPUNodeStack *in, GPUNodeStack *out)
{
bNodeTreeExec *exec = execdata->data;
-
+
if (!node->id)
return 0;
-
+
group_gpu_copy_inputs(node, in, exec->stack);
#if 0 /* XXX NODE_GROUP_EDIT is deprecated, depends on node space */
ntreeExecGPUNodes(exec, mat, (node->flag & NODE_GROUP_EDIT));
@@ -221,14 +221,14 @@ static int gpu_group_execute(GPUMaterial *mat, bNode *node, bNodeExecData *execd
ntreeExecGPUNodes(exec, mat, 0, NODE_NEW_SHADING | NODE_OLD_SHADING);
#endif
group_gpu_move_outputs(node, out, exec->stack);
-
+
return 1;
}
void register_node_type_sh_group(void)
{
static bNodeType ntype;
-
+
/* NB: cannot use sh_node_type_base for node group, because it would map the node type
* to the shared NODE_GROUP integer type id.
*/
@@ -241,7 +241,7 @@ void register_node_type_sh_group(void)
ntype.ext.srna = RNA_struct_find("ShaderNodeGroup");
BLI_assert(ntype.ext.srna != NULL);
RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
-
+
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, NULL, NULL);
node_type_size(&ntype, 140, 60, 400);
@@ -249,6 +249,6 @@ void register_node_type_sh_group(void)
node_type_update(&ntype, NULL, node_group_verify);
node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
node_type_gpu(&ntype, gpu_group_execute);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 5dfeb883915..4f3dc92ad02 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -48,7 +48,7 @@ static bNodeSocketTemplate sh_node_curve_vec_out[] = {
static void node_shader_exec_curve_vec(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
-
+
/* stack order input: vec */
/* stack order output: vec */
nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
@@ -102,7 +102,7 @@ static void node_shader_exec_curve_rgb(void *UNUSED(data), int UNUSED(thread), b
{
float vec[3];
float fac;
-
+
/* stack order input: vec */
/* stack order output: vec */
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
index 599d0533c27..072abed6c16 100644
--- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c
+++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
@@ -47,7 +47,7 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *node, bNodeExecData
else {
GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link);
}
-
+
return GPU_stack_link(mat, node, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.c b/source/blender/nodes/shader/nodes/node_shader_gamma.c
index 2aedba58f2c..e536d198ed0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.c
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.c
@@ -60,7 +60,7 @@ static int node_shader_gpu_gamma(GPUMaterial *mat, bNode *node, bNodeExecData *U
void register_node_type_sh_gamma(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_gamma_in, sh_node_gamma_out);
@@ -68,6 +68,6 @@ void register_node_type_sh_gamma(void)
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_gamma);
node_type_gpu(&ntype, node_shader_gpu_gamma);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c
new file mode 100644
index 00000000000..0a51ee8dc68
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_geom.c
@@ -0,0 +1,163 @@
+/*
+ * ***** 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 *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_geom.c
+ * \ingroup shdnodes
+ */
+
+
+#include "node_shader_util.h"
+
+#include "DNA_customdata_types.h"
+
+/* **************** GEOMETRY ******************** */
+
+/* output socket type definition */
+static bNodeSocketTemplate sh_node_geom_out[] = {
+ { SOCK_VECTOR, 0, N_("Global")},
+ { SOCK_VECTOR, 0, N_("Local")},
+ { SOCK_VECTOR, 0, N_("View")},
+ { SOCK_VECTOR, 0, N_("Orco")},
+ { SOCK_VECTOR, 0, N_("UV")},
+ { SOCK_VECTOR, 0, N_("Normal")},
+ { SOCK_RGBA, 0, N_("Vertex Color")},
+ { SOCK_FLOAT, 0, N_("Vertex Alpha")},
+ { SOCK_FLOAT, 0, N_("Front/Back")},
+ { -1, 0, "" }
+};
+
+/* node execute callback */
+static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out)
+{
+ if (data) {
+ ShadeInput *shi = ((ShaderCallData *)data)->shi;
+ NodeGeometry *ngeo = (NodeGeometry *)node->storage;
+ ShadeInputUV *suv = &shi->uv[shi->actuv];
+ static float defaultvcol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ int i;
+
+ if (ngeo->uvname[0]) {
+ /* find uv map by name */
+ for (i = 0; i < shi->totuv; i++) {
+ if (STREQ(shi->uv[i].name, ngeo->uvname)) {
+ suv = &shi->uv[i];
+ break;
+ }
+ }
+ }
+
+ /* out: global, local, view, orco, uv, normal, vertex color */
+ copy_v3_v3(out[GEOM_OUT_GLOB]->vec, shi->gl);
+ copy_v3_v3(out[GEOM_OUT_LOCAL]->vec, shi->co);
+ copy_v3_v3(out[GEOM_OUT_VIEW]->vec, shi->view);
+ copy_v3_v3(out[GEOM_OUT_ORCO]->vec, shi->lo);
+ copy_v3_v3(out[GEOM_OUT_UV]->vec, suv->uv);
+ copy_v3_v3(out[GEOM_OUT_NORMAL]->vec, shi->vno);
+
+ if (shi->use_world_space_shading) {
+ negate_v3(out[GEOM_OUT_NORMAL]->vec);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[GEOM_OUT_NORMAL]->vec);
+ }
+ if (shi->totcol) {
+ /* find vertex color layer by name */
+ ShadeInputCol *scol = &shi->col[0];
+
+ if (ngeo->colname[0]) {
+ for (i = 0; i < shi->totcol; i++) {
+ if (STREQ(shi->col[i].name, ngeo->colname)) {
+ scol = &shi->col[i];
+ break;
+ }
+ }
+ }
+
+ srgb_to_linearrgb_v3_v3(out[GEOM_OUT_VCOL]->vec, scol->col);
+ out[GEOM_OUT_VCOL]->vec[3] = scol->col[3];
+ out[GEOM_OUT_VCOL_ALPHA]->vec[0] = scol->col[3];
+ }
+ else {
+ memcpy(out[GEOM_OUT_VCOL]->vec, defaultvcol, sizeof(defaultvcol));
+ out[GEOM_OUT_VCOL_ALPHA]->vec[0] = 1.0f;
+ }
+
+ if (shi->osatex) {
+ out[GEOM_OUT_GLOB]->data = shi->dxgl;
+ out[GEOM_OUT_GLOB]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_LOCAL]->data = shi->dxco;
+ out[GEOM_OUT_LOCAL]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_VIEW]->data = &shi->dxview;
+ out[GEOM_OUT_VIEW]->datatype = NS_OSA_VALUES;
+ out[GEOM_OUT_ORCO]->data = shi->dxlo;
+ out[GEOM_OUT_ORCO]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_UV]->data = suv->dxuv;
+ out[GEOM_OUT_UV]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_NORMAL]->data = shi->dxno;
+ out[GEOM_OUT_NORMAL]->datatype = NS_OSA_VECTORS;
+ }
+
+ /* front/back, normal flipping was stored */
+ out[GEOM_OUT_FRONTBACK]->vec[0] = (shi->flippednor) ? 0.0f : 1.0f;
+ }
+}
+
+static void node_shader_init_geometry(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->storage = MEM_callocN(sizeof(NodeGeometry), "NodeGeometry");
+}
+
+static int gpu_shader_geom(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ NodeGeometry *ngeo = (NodeGeometry *)node->storage;
+ GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+ GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, ngeo->uvname);
+ GPUNodeLink *mcol = GPU_attribute(CD_MCOL, ngeo->colname);
+
+ bool ret = GPU_stack_link(mat, "geom", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), orco, mtface, mcol);
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", out[5].link, &out[5].link);
+ ret &= GPU_link(mat, "direction_transform_m4v3", out[5].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[5].link);
+ }
+ return ret;
+}
+
+/* node type definition */
+void register_node_type_sh_geom(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_GEOMETRY, "Geometry", NODE_CLASS_INPUT, 0);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, NULL, sh_node_geom_out);
+ node_type_init(&ntype, node_shader_init_geometry);
+ node_type_storage(&ntype, "NodeGeometry", node_free_standard_storage, node_copy_standard_storage);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_geom);
+ node_type_gpu(&ntype, gpu_shader_geom);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
index 0e82c962f53..07f1e9e3233 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
@@ -52,7 +52,7 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat
{
if (fac != 0.0f && (hue != 0.5f || sat != 1.0f || val != 1.0f)) {
float col[3], hsv[3], mfac = 1.0f - fac;
-
+
rgb_to_hsv(in[0], in[1], in[2], hsv, hsv + 1, hsv + 2);
hsv[0] += (hue - 0.5f);
if (hsv[0] > 1.0f) hsv[0] -= 1.0f; else if (hsv[0] < 0.0f) hsv[0] += 1.0f;
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c
index c5765ae492b..b1805946f65 100644
--- a/source/blender/nodes/shader/nodes/node_shader_invert.c
+++ b/source/blender/nodes/shader/nodes/node_shader_invert.c
@@ -34,7 +34,7 @@
-/* **************** INVERT ******************** */
+/* **************** INVERT ******************** */
static bNodeSocketTemplate sh_node_invert_in[] = {
{ SOCK_FLOAT, 1, N_("Fac"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
@@ -46,18 +46,18 @@ static bNodeSocketTemplate sh_node_invert_out[] = {
{ -1, 0, "" }
};
-static void node_shader_exec_invert(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in,
+static void node_shader_exec_invert(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in,
bNodeStack **out)
{
float col[3], icol[3], fac;
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
nodestack_get_vec(col, SOCK_VECTOR, in[1]);
-
+
icol[0] = 1.0f - col[0];
icol[1] = 1.0f - col[1];
icol[2] = 1.0f - col[2];
-
+
/* if fac, blend result against original input */
if (fac < 1.0f)
interp_v3_v3v3(out[0]->vec, col, icol, fac);
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index 42d957977e3..fdbf23618ef 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -56,7 +56,7 @@ static void node_shader_exec_mapping(void *UNUSED(data), int UNUSED(thread), bNo
{
TexMapping *texmap = node->storage;
float *vec = out[0]->vec;
-
+
/* stack order input: vector */
/* stack order output: vector */
nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
@@ -105,7 +105,7 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
void register_node_type_sh_mapping(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_mapping_in, sh_node_mapping_out);
@@ -114,6 +114,6 @@ void register_node_type_sh_mapping(void)
node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage);
node_type_exec(&ntype, node_shader_initexec_mapping, NULL, node_shader_exec_mapping);
node_type_gpu(&ntype, gpu_shader_mapping);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
new file mode 100644
index 00000000000..8a73ddc1194
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -0,0 +1,374 @@
+/*
+ * ***** 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 *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_material.c
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.h"
+
+/* **************** MATERIAL ******************** */
+
+static bNodeSocketTemplate sh_node_material_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_material_out[] = {
+ { SOCK_RGBA, 0, N_("Color")},
+ { SOCK_FLOAT, 0, N_("Alpha")},
+ { SOCK_VECTOR, 0, N_("Normal")},
+ { -1, 0, "" }
+};
+
+/* **************** EXTENDED MATERIAL ******************** */
+
+static bNodeSocketTemplate sh_node_material_ext_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
+ { SOCK_RGBA, 1, N_("Mirror"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Ambient"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Emit"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("SpecTra"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Reflectivity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Alpha"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("Translucency"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_material_ext_out[] = {
+ { SOCK_RGBA, 0, N_("Color")},
+ { SOCK_FLOAT, 0, N_("Alpha")},
+ { SOCK_VECTOR, 0, N_("Normal")},
+ { SOCK_RGBA, 0, N_("Diffuse")},
+ { SOCK_RGBA, 0, N_("Spec")},
+ { SOCK_RGBA, 0, N_("AO")},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+{
+ if (data && node->id) {
+ ShadeResult shrnode;
+ ShadeInput *shi;
+ ShaderCallData *shcd = data;
+ float col[4];
+ bNodeSocket *sock;
+ char hasinput[NUM_MAT_IN] = {'\0'};
+ int i, mode;
+
+ /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily
+ * the constant input stack values (e.g. in case material node is inside a group).
+ * we just want to know if a node input uses external data or the material setting.
+ * this is an ugly hack, but so is this node as a whole.
+ */
+ for (sock = node->inputs.first, i = 0; sock; sock = sock->next, ++i)
+ hasinput[i] = (sock->link != NULL);
+
+ shi = shcd->shi;
+ shi->mat = (Material *)node->id;
+
+ /* copy all relevant material vars, note, keep this synced with render_types.h */
+ memcpy(&shi->r, &shi->mat->r, 23 * sizeof(float));
+ shi->har = shi->mat->har;
+
+ /* write values */
+ if (hasinput[MAT_IN_COLOR])
+ nodestack_get_vec(&shi->r, SOCK_VECTOR, in[MAT_IN_COLOR]);
+
+ if (hasinput[MAT_IN_SPEC])
+ nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]);
+
+ if (hasinput[MAT_IN_REFL])
+ nodestack_get_vec(&shi->refl, SOCK_FLOAT, in[MAT_IN_REFL]);
+
+ /* retrieve normal */
+ if (hasinput[MAT_IN_NORMAL]) {
+ nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]);
+ if (shi->use_world_space_shading) {
+ negate_v3(shi->vn);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), shi->vn);
+ }
+ normalize_v3(shi->vn);
+ }
+ else
+ copy_v3_v3(shi->vn, shi->vno);
+
+ /* custom option to flip normal */
+ if (node->custom1 & SH_NODE_MAT_NEG) {
+ negate_v3(shi->vn);
+ }
+
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ if (hasinput[MAT_IN_MIR])
+ nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
+ if (hasinput[MAT_IN_AMB])
+ nodestack_get_vec(&shi->amb, SOCK_FLOAT, in[MAT_IN_AMB]);
+ if (hasinput[MAT_IN_EMIT])
+ nodestack_get_vec(&shi->emit, SOCK_FLOAT, in[MAT_IN_EMIT]);
+ if (hasinput[MAT_IN_SPECTRA])
+ nodestack_get_vec(&shi->spectra, SOCK_FLOAT, in[MAT_IN_SPECTRA]);
+ if (hasinput[MAT_IN_RAY_MIRROR])
+ nodestack_get_vec(&shi->ray_mirror, SOCK_FLOAT, in[MAT_IN_RAY_MIRROR]);
+ if (hasinput[MAT_IN_ALPHA])
+ nodestack_get_vec(&shi->alpha, SOCK_FLOAT, in[MAT_IN_ALPHA]);
+ if (hasinput[MAT_IN_TRANSLUCENCY])
+ nodestack_get_vec(&shi->translucency, SOCK_FLOAT, in[MAT_IN_TRANSLUCENCY]);
+ }
+
+ /* make alpha output give results even if transparency is only enabled on
+ * the material linked in this not and not on the parent material */
+ mode = shi->mode;
+ if (shi->mat->mode & MA_TRANSP)
+ shi->mode |= MA_TRANSP;
+
+ shi->nodes = 1; /* temp hack to prevent trashadow recursion */
+ node_shader_lamp_loop(shi, &shrnode); /* clears shrnode */
+ shi->nodes = 0;
+
+ shi->mode = mode;
+
+ /* write to outputs */
+ if (node->custom1 & SH_NODE_MAT_DIFF) {
+ copy_v3_v3(col, shrnode.combined);
+ if (!(node->custom1 & SH_NODE_MAT_SPEC)) {
+ sub_v3_v3(col, shrnode.spec);
+ }
+ }
+ else if (node->custom1 & SH_NODE_MAT_SPEC) {
+ copy_v3_v3(col, shrnode.spec);
+ }
+ else
+ col[0] = col[1] = col[2] = 0.0f;
+
+ col[3] = shrnode.alpha;
+
+ if (shi->do_preview)
+ BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage);
+
+ copy_v3_v3(out[MAT_OUT_COLOR]->vec, col);
+ out[MAT_OUT_ALPHA]->vec[0] = shrnode.alpha;
+
+ if (node->custom1 & SH_NODE_MAT_NEG) {
+ shi->vn[0] = -shi->vn[0];
+ shi->vn[1] = -shi->vn[1];
+ shi->vn[2] = -shi->vn[2];
+ }
+
+ copy_v3_v3(out[MAT_OUT_NORMAL]->vec, shi->vn);
+
+ if (shi->use_world_space_shading) {
+ negate_v3(out[MAT_OUT_NORMAL]->vec);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[MAT_OUT_NORMAL]->vec);
+ }
+ /* Extended material options */
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ /* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside
+ * a node tree :( */
+ copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diffshad);
+ copy_v3_v3(out[MAT_OUT_SPEC]->vec, shrnode.spec);
+ copy_v3_v3(out[MAT_OUT_AO]->vec, shrnode.ao);
+ }
+
+ /* copy passes, now just active node */
+ if (node->flag & NODE_ACTIVE_ID) {
+ float combined[4], alpha;
+
+ copy_v4_v4(combined, shcd->shr->combined);
+ alpha = shcd->shr->alpha;
+
+ *(shcd->shr) = shrnode;
+
+ copy_v4_v4(shcd->shr->combined, combined);
+ shcd->shr->alpha = alpha;
+ }
+ }
+}
+
+
+static void node_shader_init_material(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SH_NODE_MAT_DIFF | SH_NODE_MAT_SPEC;
+}
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUMaterial *mat, GPUNodeStack *in)
+{
+ if (in->link) {
+ return in->link;
+ }
+ else {
+ GPUNodeLink *result = NULL;
+
+ /* note GPU_uniform() is only intended to be used as a parameter to
+ * GPU_link(), returning it directly results in leaks or double frees */
+ if (in->type == GPU_FLOAT)
+ GPU_link(mat, "set_value", GPU_uniform(in->vec), &result);
+ else if (in->type == GPU_VEC3)
+ GPU_link(mat, "set_rgb", GPU_uniform(in->vec), &result);
+ else if (in->type == GPU_VEC4)
+ GPU_link(mat, "set_rgba", GPU_uniform(in->vec), &result);
+ else
+ BLI_assert(0);
+
+ return result;
+ }
+}
+
+static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (node->id) {
+ GPUShadeInput shi;
+ GPUShadeResult shr;
+ bNodeSocket *sock;
+ char hasinput[NUM_MAT_IN] = {'\0'};
+ int i;
+
+ /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily
+ * the constant input stack values (e.g. in case material node is inside a group).
+ * we just want to know if a node input uses external data or the material setting.
+ */
+ for (sock = node->inputs.first, i = 0; sock; sock = sock->next, ++i)
+ hasinput[i] = (sock->link != NULL);
+
+ GPU_shadeinput_set(mat, (Material *)node->id, &shi);
+
+ /* write values */
+ if (hasinput[MAT_IN_COLOR])
+ shi.rgb = gpu_get_input_link(mat, &in[MAT_IN_COLOR]);
+
+ if (hasinput[MAT_IN_SPEC])
+ shi.specrgb = gpu_get_input_link(mat, &in[MAT_IN_SPEC]);
+
+ if (hasinput[MAT_IN_REFL])
+ shi.refl = gpu_get_input_link(mat, &in[MAT_IN_REFL]);
+
+ /* retrieve normal */
+ if (hasinput[MAT_IN_NORMAL]) {
+ GPUNodeLink *tmp;
+ shi.vn = gpu_get_input_link(mat, &in[MAT_IN_NORMAL]);
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+ GPU_link(mat, "direction_transform_m4v3", shi.vn, GPU_builtin(GPU_VIEW_MATRIX), &shi.vn);
+ }
+ GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp);
+ }
+
+ /* custom option to flip normal */
+ if (node->custom1 & SH_NODE_MAT_NEG)
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ if (hasinput[MAT_IN_MIR])
+ shi.mir = gpu_get_input_link(mat, &in[MAT_IN_MIR]);
+ if (hasinput[MAT_IN_AMB])
+ shi.amb = gpu_get_input_link(mat, &in[MAT_IN_AMB]);
+ if (hasinput[MAT_IN_EMIT])
+ shi.emit = gpu_get_input_link(mat, &in[MAT_IN_EMIT]);
+ if (hasinput[MAT_IN_SPECTRA])
+ shi.spectra = gpu_get_input_link(mat, &in[MAT_IN_SPECTRA]);
+ if (hasinput[MAT_IN_ALPHA])
+ shi.alpha = gpu_get_input_link(mat, &in[MAT_IN_ALPHA]);
+ }
+
+ GPU_shaderesult_set(&shi, &shr); /* clears shr */
+
+ /* write to outputs */
+ if (node->custom1 & SH_NODE_MAT_DIFF) {
+ out[MAT_OUT_COLOR].link = shr.combined;
+
+ if (!(node->custom1 & SH_NODE_MAT_SPEC)) {
+ GPUNodeLink *link;
+ GPU_link(mat, "vec_math_sub", shr.combined, shr.spec, &out[MAT_OUT_COLOR].link, &link);
+ }
+ }
+ else if (node->custom1 & SH_NODE_MAT_SPEC) {
+ out[MAT_OUT_COLOR].link = shr.spec;
+ }
+ else
+ GPU_link(mat, "set_rgb_zero", &out[MAT_OUT_COLOR].link);
+
+ GPU_link(mat, "mtex_alpha_to_col", out[MAT_OUT_COLOR].link, shr.alpha, &out[MAT_OUT_COLOR].link);
+
+ out[MAT_OUT_ALPHA].link = shr.alpha; //
+
+ if (node->custom1 & SH_NODE_MAT_NEG)
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+ out[MAT_OUT_NORMAL].link = shi.vn;
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", out[MAT_OUT_NORMAL].link, &out[MAT_OUT_NORMAL].link);
+ GPU_link(mat, "direction_transform_m4v3", out[MAT_OUT_NORMAL].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[MAT_OUT_NORMAL].link);
+ }
+
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ out[MAT_OUT_DIFFUSE].link = shr.diff;
+ out[MAT_OUT_SPEC].link = shr.spec;
+ GPU_link(mat, "set_rgb_one", &out[MAT_OUT_AO].link);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void register_node_type_sh_material(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_MATERIAL, "Material", NODE_CLASS_INPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_material_in, sh_node_material_out);
+ node_type_init(&ntype, node_shader_init_material);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_material);
+ node_type_gpu(&ntype, gpu_shader_material);
+
+ nodeRegisterType(&ntype);
+}
+
+
+void register_node_type_sh_material_ext(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_MATERIAL_EXT, "Extended Material", NODE_CLASS_INPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_material_ext_in, sh_node_material_ext_out);
+ node_type_init(&ntype, node_shader_init_material);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_material);
+ node_type_gpu(&ntype, gpu_shader_material);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index 2be70b66b36..bf594325119 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -33,7 +33,7 @@
#include "node_shader_util.h"
-/* **************** SCALAR MATH ******************** */
+/* **************** SCALAR MATH ******************** */
static bNodeSocketTemplate sh_node_math_in[] = {
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
@@ -45,15 +45,15 @@ static bNodeSocketTemplate sh_node_math_out[] = {
{ -1, 0, "" }
};
-static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
+static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float a, b, r = 0.0f;
-
+
nodestack_get_vec(&a, SOCK_FLOAT, in[0]);
nodestack_get_vec(&b, SOCK_FLOAT, in[1]);
-
+
switch (node->custom1) {
-
+
case NODE_MATH_ADD:
r = a + b;
break;
@@ -147,7 +147,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
}
else {
float y_mod_1 = fabsf(fmodf(b, 1.0f));
-
+
/* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
r = powf(a, floorf(b + 0.5f));
diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
index 37ec4d46226..054b02b220d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
@@ -54,7 +54,7 @@ static void node_shader_exec_mix_rgb(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
CLAMP(fac, 0.0f, 1.0f);
-
+
nodestack_get_vec(col, SOCK_VECTOR, in[1]);
nodestack_get_vec(vec, SOCK_VECTOR, in[2]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c
index 4bca5add106..265f6ac6fab 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal.c
@@ -48,12 +48,12 @@ static bNodeSocketTemplate sh_node_normal_out[] = {
static void node_shader_exec_normal(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
-
+
/* stack order input: normal */
/* stack order output: normal, value */
-
+
nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
-
+
/* render normals point inside... the widget points outside */
out[1]->vec[0] = -dot_v3v3(vec, out[0]->vec);
}
@@ -67,12 +67,12 @@ static int gpu_shader_normal(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSE
void register_node_type_sh_normal(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_normal_in, sh_node_normal_out);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_normal);
node_type_gpu(&ntype, gpu_shader_normal);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c
new file mode 100644
index 00000000000..5b1a68b4bf9
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output.c
@@ -0,0 +1,97 @@
+/*
+ * ***** 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 *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_output.c
+ * \ingroup shdnodes
+ */
+
+
+#include "node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+static bNodeSocketTemplate sh_node_output_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_output(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
+{
+ if (data) {
+ ShadeInput *shi = ((ShaderCallData *)data)->shi;
+ float col[4];
+
+ /* stack order input sockets: col, alpha, normal */
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+ nodestack_get_vec(col + 3, SOCK_FLOAT, in[1]);
+
+ if (shi->do_preview) {
+ BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage);
+ node->lasty = shi->ys;
+ }
+
+ if (node->flag & NODE_DO_OUTPUT) {
+ ShadeResult *shr = ((ShaderCallData *)data)->shr;
+
+ copy_v4_v4(shr->combined, col);
+ shr->alpha = col[3];
+
+ // copy_v3_v3(shr->nor, in[3]->vec);
+ }
+ }
+}
+
+static int gpu_shader_output(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+
+#if 0
+ if (in[1].hasinput)
+ GPU_material_enable_alpha(mat);
+#endif
+
+ GPU_stack_link(mat, "output_node", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return 1;
+}
+
+void register_node_type_sh_output(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_output_in, NULL);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_output);
+ node_type_gpu(&ntype, gpu_shader_output);
+
+ /* 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_world.c b/source/blender/nodes/shader/nodes/node_shader_output_world.c
index 17b4bfb6de6..2c115bdda20 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_world.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_world.c
@@ -56,7 +56,7 @@ void register_node_type_sh_output_world(void)
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_output_world);
-
+
/* Do not allow muting output node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
index 19f31f77989..148f8e99c8f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
@@ -48,7 +48,7 @@ static void node_shader_exec_sephsv(void *UNUSED(data), int UNUSED(thread), bNod
{
float col[3];
nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
+
rgb_to_hsv(col[0], col[1], col[2],
&out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
}
@@ -90,7 +90,7 @@ static void node_shader_exec_combhsv(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(&h, SOCK_FLOAT, in[0]);
nodestack_get_vec(&s, SOCK_FLOAT, in[1]);
nodestack_get_vec(&v, SOCK_FLOAT, in[2]);
-
+
hsv_to_rgb(h, s, v, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
index 3f866af5de4..bd914399a28 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
@@ -48,7 +48,7 @@ static void node_shader_exec_seprgb(void *UNUSED(data), int UNUSED(thread), bNod
{
float col[3];
nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
+
out[0]->vec[0] = col[0];
out[1]->vec[0] = col[1];
out[2]->vec[0] = col[2];
@@ -92,7 +92,7 @@ static void node_shader_exec_combrgb(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(&r, SOCK_FLOAT, in[0]);
nodestack_get_vec(&g, SOCK_FLOAT, in[1]);
nodestack_get_vec(&b, SOCK_FLOAT, in[2]);
-
+
out[0]->vec[0] = r;
out[0]->vec[1] = g;
out[0]->vec[2] = b;
diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
index 2175a7c564f..e46494efd34 100644
--- a/source/blender/nodes/shader/nodes/node_shader_squeeze.c
+++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
@@ -32,7 +32,7 @@
#include "node_shader_util.h"
-/* **************** VALUE SQUEEZE ******************** */
+/* **************** VALUE SQUEEZE ******************** */
static bNodeSocketTemplate sh_node_squeeze_in[] = {
{ SOCK_FLOAT, 1, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Width"), 1.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
@@ -48,7 +48,7 @@ static bNodeSocketTemplate sh_node_squeeze_out[] = {
static void node_shader_exec_squeeze(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
-
+
nodestack_get_vec(vec, SOCK_FLOAT, in[0]);
nodestack_get_vec(vec + 1, SOCK_FLOAT, in[1]);
nodestack_get_vec(vec + 2, SOCK_FLOAT, in[2]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
index c919f8efa4e..67fe6d08ffd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
@@ -54,7 +54,7 @@ static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
NodeTexBrick *tex = MEM_callocN(sizeof(NodeTexBrick), "NodeTexBrick");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
-
+
tex->offset = 0.5f;
tex->squash = 1.0f;
tex->offset_freq = 2;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index 111a9cbfbc0..360b28d768a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -49,7 +49,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *node, bNodeExecDat
GPUMatType type = GPU_Material_get_type(mat);
GPU_link(mat, "generated_from_orco", orco, &orco);
-
+
if (type == GPU_MATERIAL_TYPE_WORLD) {
return GPU_stack_link(mat, node, "node_tex_coord_background", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
@@ -59,7 +59,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *node, bNodeExecDat
else {
return GPU_stack_link(mat, node, "node_tex_coord", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 378da163f64..d441a674838 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -66,20 +66,20 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
if (!in[0].link) {
GPUMatType type = GPU_Material_get_type(mat);
-
+
if (type == GPU_MATERIAL_TYPE_MESH)
in[0].link = GPU_builtin(GPU_VIEW_POSITION);
else
GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
}
-
+
node_shader_gpu_tex_mapping(mat, node, in, out);
if (tex->projection == SHD_PROJ_EQUIRECTANGULAR)
GPU_stack_link(mat, node, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata));
else
GPU_stack_link(mat, node, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata));
-
+
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
GPU_material_do_color_management(mat))
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
new file mode 100644
index 00000000000..737ec7d1c4b
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -0,0 +1,166 @@
+/*
+ * ***** 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 *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_texture.c
+ * \ingroup shdnodes
+ */
+
+#include "DNA_texture_types.h"
+
+#include "node_shader_util.h"
+
+#include "GPU_material.h"
+
+/* **************** TEXTURE ******************** */
+static bNodeSocketTemplate sh_node_texture_in[] = {
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, /* no limit */
+ { -1, 0, "" }
+};
+static bNodeSocketTemplate sh_node_texture_out[] = {
+ { SOCK_FLOAT, 0, N_("Value"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_RGBA, 0, N_("Color"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_VECTOR, 0, N_("Normal"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_texture(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+{
+ if (data && node->id) {
+ ShadeInput *shi = ((ShaderCallData *)data)->shi;
+ TexResult texres;
+ bNodeSocket *sock_vector = node->inputs.first;
+ float vec[3], nor[3] = {0.0f, 0.0f, 0.0f};
+ int retval;
+ short which_output = node->custom1;
+
+ short thread = shi->thread;
+
+ /* out: value, color, normal */
+
+ /* we should find out if a normal as output is needed, for now we do all */
+ texres.nor = nor;
+ texres.tr = texres.tg = texres.tb = 0.0f;
+
+ /* don't use in[0]->hasinput, see material node for explanation */
+ if (sock_vector->link) {
+ nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
+
+ if (in[0]->datatype == NS_OSA_VECTORS) {
+ float *fp = in[0]->data;
+ retval = multitex_nodes((Tex *)node->id, vec, fp, fp + 3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+ else if (in[0]->datatype == NS_OSA_VALUES) {
+ const float *fp = in[0]->data;
+ float dxt[3], dyt[3];
+
+ dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f;
+ dyt[0] = fp[1]; dyt[1] = dyt[2] = 0.0f;
+ retval = multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+ else
+ retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+ else {
+ copy_v3_v3(vec, shi->lo);
+ retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+
+ /* stupid exception */
+ if ( ((Tex *)node->id)->type == TEX_STUCCI) {
+ texres.tin = 0.5f + 0.7f * texres.nor[0];
+ CLAMP(texres.tin, 0.0f, 1.0f);
+ }
+
+ /* intensity and color need some handling */
+ if (texres.talpha)
+ out[0]->vec[0] = texres.ta;
+ else
+ out[0]->vec[0] = texres.tin;
+
+ if ((retval & TEX_RGB) == 0) {
+ copy_v3_fl(out[1]->vec, out[0]->vec[0]);
+ out[1]->vec[3] = 1.0f;
+ }
+ else {
+ copy_v3_v3(out[1]->vec, &texres.tr);
+ out[1]->vec[3] = 1.0f;
+ }
+
+ copy_v3_v3(out[2]->vec, nor);
+
+ if (shi->do_preview) {
+ BKE_node_preview_set_pixel(execdata->preview, out[1]->vec, shi->xs, shi->ys, shi->do_manage);
+ }
+
+ }
+}
+
+static int gpu_shader_texture(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ Tex *tex = (Tex *)node->id;
+
+ if (tex && tex->ima && (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)) {
+ if (tex->type == TEX_IMAGE) {
+ GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, false);
+ GPU_stack_link(mat, "texture_image", in, out, texlink);
+ }
+ else { /* TEX_ENVMAP */
+ if (!in[0].link)
+ in[0].link = GPU_uniform(in[0].vec);
+ if (!GPU_material_use_world_space_shading(mat))
+ GPU_link(mat, "direction_transform_m4v3", in[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[0].link);
+ GPU_link(mat, "mtex_cube_map_refl_from_refldir",
+ GPU_cube_map(tex->ima, &tex->iuser, false), in[0].link, &out[0].link, &out[1].link);
+ GPU_link(mat, "color_to_normal", out[1].link, &out[2].link);
+ }
+
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
+ if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
+ GPU_material_do_color_management(mat))
+ {
+ GPU_link(mat, "srgb_to_linearrgb", out[1].link, &out[1].link);
+ }
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
+
+ return true;
+ }
+
+ return false;
+}
+
+void register_node_type_sh_texture(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_texture_in, sh_node_texture_out);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_texture);
+ node_type_gpu(&ntype, gpu_shader_texture);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
index 5041741beb1..a1879df3a18 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
@@ -48,7 +48,7 @@ static void node_shader_exec_valtorgb(void *UNUSED(data), int UNUSED(thread), bN
{
/* stack order in: fac */
/* stack order out: col, alpha */
-
+
if (node->storage) {
float fac;
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
index 2b060806819..ca5291e6041 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
@@ -31,7 +31,7 @@
#include "node_shader_util.h"
-/* **************** VECTOR MATH ******************** */
+/* **************** VECTOR MATH ******************** */
static bNodeSocketTemplate sh_node_vect_math_in[] = {
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
@@ -44,32 +44,32 @@ static bNodeSocketTemplate sh_node_vect_math_out[] = {
{ -1, 0, "" }
};
-static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
-{
+static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
+{
float vec1[3], vec2[3];
-
+
nodestack_get_vec(vec1, SOCK_VECTOR, in[0]);
nodestack_get_vec(vec2, SOCK_VECTOR, in[1]);
-
+
if (node->custom1 == 0) { /* Add */
out[0]->vec[0] = vec1[0] + vec2[0];
out[0]->vec[1] = vec1[1] + vec2[1];
out[0]->vec[2] = vec1[2] + vec2[2];
-
+
out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[1]) + fabsf(out[0]->vec[2])) / 3.0f;
}
else if (node->custom1 == 1) { /* Subtract */
out[0]->vec[0] = vec1[0] - vec2[0];
out[0]->vec[1] = vec1[1] - vec2[1];
out[0]->vec[2] = vec1[2] - vec2[2];
-
+
out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[1]) + fabsf(out[0]->vec[2])) / 3.0f;
}
else if (node->custom1 == 2) { /* Average */
out[0]->vec[0] = vec1[0] + vec2[0];
out[0]->vec[1] = vec1[1] + vec2[1];
out[0]->vec[2] = vec1[2] + vec2[2];
-
+
out[1]->vec[0] = normalize_v3(out[0]->vec);
}
else if (node->custom1 == 3) { /* Dot product */
@@ -79,7 +79,7 @@ static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), b
out[0]->vec[0] = (vec1[1] * vec2[2]) - (vec1[2] * vec2[1]);
out[0]->vec[1] = (vec1[2] * vec2[0]) - (vec1[0] * vec2[2]);
out[0]->vec[2] = (vec1[0] * vec2[1]) - (vec1[1] * vec2[0]);
-
+
out[1]->vec[0] = normalize_v3(out[0]->vec);
}
else if (node->custom1 == 5) { /* Normalize */
@@ -93,10 +93,10 @@ static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), b
out[0]->vec[1] = vec2[1];
out[0]->vec[2] = vec2[2];
}
-
+
out[1]->vec[0] = normalize_v3(out[0]->vec);
}
-
+
}
static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -132,7 +132,7 @@ static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, bNodeExecData *UN
default:
return false;
}
-
+
return true;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
index 8183b6c45cb..d0b16dd5886 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
@@ -28,10 +28,10 @@
/** \file blender/nodes/shader/nodes/node_shader_vectTransform.c
* \ingroup shdnodes
*/
-
+
#include "../node_shader_util.h"
-/* **************** Vector Transform ******************** */
+/* **************** Vector Transform ******************** */
static bNodeSocketTemplate sh_node_vect_transform_in[] = {
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ -1, 0, "" }
@@ -45,10 +45,10 @@ static bNodeSocketTemplate sh_node_vect_transform_out[] = {
static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeShaderVectTransform *vect = MEM_callocN(sizeof(NodeShaderVectTransform), "NodeShaderVectTransform");
-
+
/* Convert World into Object Space per default */
vect->convert_to = 1;
-
+
node->storage = vect;
}