diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-01-21 02:40:42 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-02-03 14:20:26 +0300 |
commit | f9ea097a872290d20cd94504adb3172165cb770d (patch) | |
tree | 1560b65cd6b5077e8690b26bb4b2f2ff251ff358 /source/blender/nodes/shader | |
parent | 37beac8eb823bd81b411426bfc8718639577b179 (diff) |
Cycles: add Vector Displacement node and extend Displacement node.
This adds midlevel and object/world space for displacement, and a
vector displacement node with tangent/object/world space, midlevel
and scale.
Note that tangent space vector displacement still is not exactly
compatible with maps created by other software, this will require
changes to the tangent computation.
Differential Revision: https://developer.blender.org/D1734
Diffstat (limited to 'source/blender/nodes/shader')
3 files changed, 121 insertions, 20 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.c index bcd11b758f8..e976eaf143a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_displacement.c +++ b/source/blender/nodes/shader/nodes/node_shader_displacement.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_displacement_in[] = { { SOCK_FLOAT, 0, N_("Height"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } @@ -41,13 +42,30 @@ static bNodeSocketTemplate sh_node_displacement_out[] = { { -1, 0, "" } }; -static int gpu_shader_displacement(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node) { - if (!in[2].link) { - GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[2].link); + node->custom1 = SHD_SPACE_OBJECT; /* space */ + + /* Set default value here for backwards compatibility. */ + for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) { + if (STREQ(sock->name, "Midlevel")) { + ((bNodeSocketValueFloat *)sock->default_value)->value = 0.5f; + } } +} - return GPU_stack_link(mat, "node_displacement", in, out); +static int gpu_shader_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + if (!in[3].link) { + GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[3].link); + } + + if(node->custom1 == SHD_SPACE_OBJECT) { + return GPU_stack_link(mat, "node_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } + else { + return GPU_stack_link(mat, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } } /* node type definition */ @@ -59,6 +77,7 @@ void register_node_type_sh_displacement(void) node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_displacement_in, sh_node_displacement_out); node_type_storage(&ntype, "", NULL, NULL); + node_type_init(&ntype, node_shader_init_displacement); node_type_gpu(&ntype, gpu_shader_displacement); nodeRegisterType(&ntype); 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 36d7522e3e6..7584b5eba4d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -68,7 +68,7 @@ static void node_shader_exec_normal_map( float *N = shi->nmapnorm; int uv_index = 0; switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: if (nm->uv_map[0]) { /* find uv map by name */ for (int i = 0; i < shi->totuv; i++) { @@ -96,8 +96,8 @@ static void node_shader_exec_normal_map( } break; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: if (shi->use_world_space_shading) { mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn); mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); @@ -107,8 +107,8 @@ static void node_shader_exec_normal_map( interp_v3_v3v3(out[0]->vec, N, vecIn, strength); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: if (shi->use_world_space_shading) mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); else @@ -150,10 +150,10 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U /* ******* CYCLES or BLENDER INTERNAL with world space shading flag ******* */ const char *color_to_normal_fnc_name = "color_to_normal_new_shading"; - if (nm->space == SHD_NORMAL_MAP_BLENDER_OBJECT || nm->space == SHD_NORMAL_MAP_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) + if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) color_to_normal_fnc_name = "color_to_blender_normal_new_shading"; switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm); GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); GPU_link(mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link); @@ -161,14 +161,14 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U GPU_link(mat, "direction_transform_m4v3", out[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[0].link); GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); return true; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); break; @@ -184,15 +184,15 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U GPU_link(mat, "vec_math_negate", negnorm, &negnorm); switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); break; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_LOC_TO_VIEW_MATRIX), &realnorm); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_VIEW_MATRIX), &realnorm); break; } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c new file mode 100644 index 00000000000..c40377c3d59 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c @@ -0,0 +1,82 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_vector_displacement_in[] = { + { SOCK_RGBA, 0, N_("Vector"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_vector_displacement_out[] = { + { SOCK_VECTOR, 0, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_init_vector_displacement(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_SPACE_TANGENT; /* space */ +} + +static int gpu_shader_vector_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + if(node->custom1 == SHD_SPACE_TANGENT) { + return GPU_stack_link(mat, + "node_vector_displacement_tangent", + in, + out, + GPU_attribute(CD_TANGENT, ""), + GPU_builtin(GPU_VIEW_NORMAL), + GPU_builtin(GPU_OBJECT_MATRIX), + GPU_builtin(GPU_VIEW_MATRIX)); + } + else if(node->custom1 == SHD_SPACE_OBJECT) { + return GPU_stack_link(mat, "node_vector_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } + else { + return GPU_stack_link(mat, "node_vector_displacement_world", in, out); + } +} + +/* node type definition */ +void register_node_type_sh_vector_displacement(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_vector_displacement_in, sh_node_vector_displacement_out); + node_type_storage(&ntype, "", NULL, NULL); + node_type_init(&ntype, node_shader_init_vector_displacement); + node_type_gpu(&ntype, gpu_shader_vector_displacement); + + nodeRegisterType(&ntype); +} |