Cycles: add Displacement node.

This converts object space height to world space displacement, to be
linked to the new vector displacement material output.

Differential Revision: https://developer.blender.org/D3015
This commit is contained in:
Brecht Van Lommel 2018-01-13 13:11:03 +01:00
parent 2838cf0dfe
commit 4a5ee1a5a2
16 changed files with 186 additions and 5 deletions

View File

@ -872,6 +872,9 @@ static ShaderNode *add_node(Scene *scene,
bevel->samples = b_bevel_node.samples();
node = bevel;
}
else if(b_node.is_a(&RNA_ShaderNodeDisplacement)) {
node = new DisplacementNode();
}
if(node) {
node->name = b_node.name();

View File

@ -23,6 +23,7 @@ set(SRC_OSL
node_convert_from_point.osl
node_convert_from_vector.osl
node_diffuse_bsdf.osl
node_displacement.osl
node_emission.osl
node_environment_texture.osl
node_fresnel.osl

View File

@ -0,0 +1,29 @@
/*
* Copyright 2011-2013 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stdosl.h"
shader node_displacement(
float Height = 0.0,
float Scale = 1.0,
normal Normal = N,
output vector Displacement = vector(0.0, 0.0, 0.0))
{
Displacement = normalize(transform("object", Normal));
Displacement *= Height * Scale;
Displacement = transform("object", "world", Displacement);
}

View File

@ -267,6 +267,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
case NODE_SET_DISPLACEMENT:
svm_node_set_displacement(kg, sd, stack, node.y);
break;
case NODE_DISPLACEMENT:
svm_node_displacement(kg, sd, stack, node);
break;
# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
# ifdef __TEXTURES__
case NODE_TEX_IMAGE:

View File

@ -22,8 +22,8 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac
{
#ifdef __RAY_DIFFERENTIALS__
/* get normal input */
uint normal_offset, distance_offset, invert, use_object_space;
decode_node_uchar4(node.y, &normal_offset, &distance_offset, &invert, &use_object_space);
uint normal_offset, scale_offset, invert, use_object_space;
decode_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space);
float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
@ -55,15 +55,15 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac
float absdet = fabsf(det);
float strength = stack_load_float(stack, strength_offset);
float distance = stack_load_float(stack, distance_offset);
float scale = stack_load_float(stack, scale_offset);
if(invert)
distance *= -1.0f;
scale *= -1.0f;
strength = max(strength, 0.0f);
/* compute and output perturbed normal */
float3 normal_out = safe_normalize(absdet*normal_in - distance*signf(det)*surfgrad);
float3 normal_out = safe_normalize(absdet*normal_in - scale*signf(det)*surfgrad);
if(is_zero(normal_out)) {
normal_out = normal_in;
}
@ -95,5 +95,22 @@ ccl_device void svm_node_set_displacement(KernelGlobals *kg, ShaderData *sd, flo
sd->P += dP;
}
ccl_device void svm_node_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
uint height_offset, scale_offset, normal_offset, displacement_offset;
decode_node_uchar4(node.y, &height_offset, &scale_offset, &normal_offset, &displacement_offset);
float height = stack_load_float(stack, height_offset);
float scale = stack_load_float(stack, scale_offset);
float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N;
float3 dP = normal;
object_inverse_normal_transform(kg, sd, &dP);
dP *= height * scale;
object_dir_transform(kg, sd, &dP);
stack_store_float3(stack, displacement_offset, dP);
}
CCL_NAMESPACE_END

View File

@ -133,6 +133,7 @@ typedef enum ShaderNodeType {
NODE_ENTER_BUMP_EVAL,
NODE_LEAVE_BUMP_EVAL,
NODE_BEVEL,
NODE_DISPLACEMENT,
} ShaderNodeType;
typedef enum NodeAttributeType {

View File

@ -5644,4 +5644,43 @@ void BevelNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_bevel");
}
/* Displacement */
NODE_DEFINE(DisplacementNode)
{
NodeType* type = NodeType::add("displacement", create, NodeType::SHADER);
SOCKET_IN_FLOAT(height, "Height", 0.0f);
SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL);
SOCKET_OUT_VECTOR(displacement, "Displacement");
return type;
}
DisplacementNode::DisplacementNode()
: ShaderNode(node_type)
{
}
void DisplacementNode::compile(SVMCompiler& compiler)
{
ShaderInput *height_in = input("Height");
ShaderInput *scale_in = input("Scale");
ShaderInput *normal_in = input("Normal");
ShaderOutput *displacement_out = output("Displacement");
compiler.add_node(NODE_DISPLACEMENT,
compiler.encode_uchar4(compiler.stack_assign(height_in),
compiler.stack_assign(scale_in),
compiler.stack_assign_if_linked(normal_in),
compiler.stack_assign(displacement_out)));
}
void DisplacementNode::compile(OSLCompiler& compiler)
{
compiler.add(this, "node_displacement");
}
CCL_NAMESPACE_END

View File

@ -1027,6 +1027,18 @@ public:
int samples;
};
class DisplacementNode : public ShaderNode {
public:
SHADER_NODE_CLASS(DisplacementNode)
virtual int get_feature() {
return NODE_FEATURE_BUMP;
}
float height;
float scale;
float3 normal;
};
CCL_NAMESPACE_END
#endif /* __NODES_H__ */

View File

@ -271,6 +271,7 @@ shader_node_categories = [
ShaderNewNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[
NodeItem("ShaderNodeMapping"),
NodeItem("ShaderNodeBump"),
NodeItem("ShaderNodeDisplacement"),
NodeItem("ShaderNodeNormalMap"),
NodeItem("ShaderNodeNormal"),
NodeItem("ShaderNodeVectorCurve"),

View File

@ -790,6 +790,7 @@ struct ShadeResult;
#define SH_NODE_TEX_POINTDENSITY 192
#define SH_NODE_BSDF_PRINCIPLED 193
#define SH_NODE_BEVEL 197
#define SH_NODE_DISPLACEMENT 198
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1

View File

@ -3589,6 +3589,7 @@ static void registerShaderNodes(void)
register_node_type_sh_attribute();
register_node_type_sh_bevel();
register_node_type_sh_displacement();
register_node_type_sh_geometry();
register_node_type_sh_light_path();
register_node_type_sh_light_falloff();

View File

@ -3816,6 +3816,11 @@ void node_bevel(float radius, vec3 N, out vec3 result)
result = N;
}
void node_displacement(float height, float dist, vec3 N, out vec3 result)
{
result = height * dist * N;
}
/* output */
void node_output_material(vec4 surface, vec4 volume, float displacement, out vec4 result)

View File

@ -193,6 +193,7 @@ set(SRC
shader/nodes/node_shader_subsurface_scattering.c
shader/nodes/node_shader_tangent.c
shader/nodes/node_shader_bevel.c
shader/nodes/node_shader_displacement.c
shader/nodes/node_shader_tex_brick.c
shader/nodes/node_shader_tex_checker.c
shader/nodes/node_shader_tex_coord.c

View File

@ -79,6 +79,7 @@ void register_node_type_sh_tex_pointdensity(void);
void register_node_type_sh_attribute(void);
void register_node_type_sh_bevel(void);
void register_node_type_sh_displacement(void);
void register_node_type_sh_geometry(void);
void register_node_type_sh_light_path(void);
void register_node_type_sh_light_falloff(void);

View File

@ -127,6 +127,7 @@ DefNode( ShaderNode, SH_NODE_UVALONGSTROKE, def_sh_uvalongstroke, "UV
DefNode( ShaderNode, SH_NODE_SEPXYZ, 0, "SEPXYZ", SeparateXYZ, "Separate XYZ", "" )
DefNode( ShaderNode, SH_NODE_COMBXYZ, 0, "COMBXYZ", CombineXYZ, "Combine XYZ", "" )
DefNode( ShaderNode, SH_NODE_BEVEL, def_sh_bevel, "BEVEL", Bevel, "Bevel", "" )
DefNode( ShaderNode, SH_NODE_DISPLACEMENT, 0, "DISPLACEMENT", Displacement, "Displacement", "" )
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )

View File

@ -0,0 +1,65 @@
/*
* ***** 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_displacement_in[] = {
{ SOCK_FLOAT, 0, N_("Height"), 0.00f, 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, "" }
};
static bNodeSocketTemplate sh_node_displacement_out[] = {
{ SOCK_VECTOR, 0, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
static int gpu_shader_displacement(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
if (!in[2].link) {
GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[2].link);
}
return GPU_stack_link(mat, "node_displacement", in, out);
}
/* node type definition */
void register_node_type_sh_displacement(void)
{
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_DISPLACEMENT, "Displacement", NODE_CLASS_OP_VECTOR, 0);
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_gpu(&ntype, gpu_shader_displacement);
nodeRegisterType(&ntype);
}