Blender  V3.3
displace.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
7 
9 
10 /* Bump Node */
11 template<uint node_feature_mask>
14  ccl_private float *stack,
15  uint4 node)
16 {
17 #ifdef __RAY_DIFFERENTIALS__
19  {
20  /* get normal input */
21  uint normal_offset, scale_offset, invert, use_object_space;
22  svm_unpack_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space);
23 
24  float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) :
25  sd->N;
26 
27  float3 dPdx = sd->dP.dx;
28  float3 dPdy = sd->dP.dy;
29 
30  if (use_object_space) {
31  object_inverse_normal_transform(kg, sd, &normal_in);
32  object_inverse_dir_transform(kg, sd, &dPdx);
33  object_inverse_dir_transform(kg, sd, &dPdy);
34  }
35 
36  /* get surface tangents from normal */
37  float3 Rx = cross(dPdy, normal_in);
38  float3 Ry = cross(normal_in, dPdx);
39 
40  /* get bump values */
41  uint c_offset, x_offset, y_offset, strength_offset;
42  svm_unpack_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset);
43 
44  float h_c = stack_load_float(stack, c_offset);
45  float h_x = stack_load_float(stack, x_offset);
46  float h_y = stack_load_float(stack, y_offset);
47 
48  /* compute surface gradient and determinant */
49  float det = dot(dPdx, Rx);
50  float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry;
51 
52  float absdet = fabsf(det);
53 
54  float strength = stack_load_float(stack, strength_offset);
55  float scale = stack_load_float(stack, scale_offset);
56 
57  if (invert)
58  scale *= -1.0f;
59 
60  strength = max(strength, 0.0f);
61 
62  /* compute and output perturbed normal */
63  float3 normal_out = safe_normalize(absdet * normal_in - scale * signf(det) * surfgrad);
64  if (is_zero(normal_out)) {
65  normal_out = normal_in;
66  }
67  else {
68  normal_out = normalize(strength * normal_out + (1.0f - strength) * normal_in);
69  }
70 
71  if (use_object_space) {
72  object_normal_transform(kg, sd, &normal_out);
73  }
74 
75  normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out);
76  stack_store_float3(stack, node.w, normal_out);
77  }
78  else
79  {
80  stack_store_float3(stack, node.w, zero_float3());
81  }
82 #endif
83 }
84 
85 /* Displacement Node */
86 
87 template<uint node_feature_mask>
90  ccl_private float *stack,
91  uint fac_offset)
92 {
94  {
95  float3 dP = stack_load_float3(stack, fac_offset);
96  sd->P += dP;
97  }
98 }
99 
100 template<uint node_feature_mask>
103  ccl_private float *stack,
104  uint4 node)
105 {
107  {
108  uint height_offset, midlevel_offset, scale_offset, normal_offset;
110  node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset);
111 
112  float height = stack_load_float(stack, height_offset);
113  float midlevel = stack_load_float(stack, midlevel_offset);
114  float scale = stack_load_float(stack, scale_offset);
115  float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
116  uint space = node.w;
117 
118  float3 dP = normal;
119 
120  if (space == NODE_NORMAL_MAP_OBJECT) {
121  /* Object space. */
122  object_inverse_normal_transform(kg, sd, &dP);
123  dP *= (height - midlevel) * scale;
124  object_dir_transform(kg, sd, &dP);
125  }
126  else {
127  /* World space. */
128  dP *= (height - midlevel) * scale;
129  }
130 
131  stack_store_float3(stack, node.z, dP);
132  }
133  else
134  {
135  stack_store_float3(stack, node.z, zero_float3());
136  }
137 }
138 
139 template<uint node_feature_mask>
141  KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
142 {
143  uint4 data_node = read_node(kg, &offset);
144  uint vector_offset, midlevel_offset, scale_offset, displacement_offset;
146  node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset);
147 
149  {
150  uint space = data_node.x;
151 
152  float3 vector = stack_load_float3(stack, vector_offset);
153  float midlevel = stack_load_float(stack, midlevel_offset);
154  float scale = stack_load_float(stack, scale_offset);
155  float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale;
156 
157  if (space == NODE_NORMAL_MAP_TANGENT) {
158  /* Tangent space. */
159  float3 normal = sd->N;
161 
162  const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
163  float3 tangent;
164  if (attr.offset != ATTR_STD_NOT_FOUND) {
165  tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
166  }
167  else {
168  tangent = normalize(sd->dPdu);
169  }
170 
171  float3 bitangent = safe_normalize(cross(normal, tangent));
172  const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
173  if (attr_sign.offset != ATTR_STD_NOT_FOUND) {
174  float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
175  bitangent *= sign;
176  }
177 
178  dP = tangent * dP.x + normal * dP.y + bitangent * dP.z;
179  }
180 
181  if (space != NODE_NORMAL_MAP_WORLD) {
182  /* Tangent or object space. */
183  object_dir_transform(kg, sd, &dP);
184  }
185 
186  stack_store_float3(stack, displacement_offset, dP);
187  }
188  else
189  {
190  stack_store_float3(stack, displacement_offset, zero_float3());
191  (void)data_node;
192  }
193 
194  return offset;
195 }
196 
MINLINE float signf(float f)
unsigned int uint
Definition: BLI_sys_types.h:67
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
Definition: bsdf_util.h:127
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_noinline
Definition: cuda/compat.h:40
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
OperationNode * node
const KernelGlobalsCPU *ccl_restrict KernelGlobals
CCL_NAMESPACE_BEGIN ccl_device_noinline void svm_node_set_bump(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition: displace.h:12
ccl_device_noinline int svm_node_vector_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
Definition: displace.h:140
ccl_device void svm_node_set_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint fac_offset)
Definition: displace.h:88
ccl_device_noinline void svm_node_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition: displace.h:101
SyclQueue void void size_t num_bytes void
IconTextureDrawCall normal
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: invert.h:8
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg, ccl_private const ShaderData *sd, uint id)
ccl_device_inline void object_inverse_dir_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *D)
ccl_device_inline void object_dir_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *D)
ccl_device_inline void object_inverse_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ccl_device_inline void object_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(ccl_private float *stack, uint a)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *offset)
ccl_device_inline float stack_load_float(ccl_private float *stack, uint a)
ccl_device_forceinline void svm_unpack_node_uchar4(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ccl_device_inline bool stack_valid(uint a)
@ NODE_NORMAL_MAP_TANGENT
@ NODE_NORMAL_MAP_WORLD
@ NODE_NORMAL_MAP_OBJECT
@ ATTR_STD_NOT_FOUND
Definition: kernel/types.h:647
#define IF_KERNEL_NODES_FEATURE(feature)
ShaderData
Definition: kernel/types.h:925
ccl_device_inline float2 safe_normalize(const float2 &a)
Definition: math_float2.h:201
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
#define fabsf(x)
Definition: metal/compat.h:219
#define make_float3(x, y, z)
Definition: metal/compat.h:204
double sign(double arg)
Definition: utility.h:250
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
bool is_zero(const T &a)
ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float3 *dx, ccl_private float3 *dy)
Definition: primitive.h:83
CCL_NAMESPACE_BEGIN ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float *dx, ccl_private float *dy)
Definition: primitive.h:21
float z
float y
float x
uint x
Definition: types_uint4.h:15
float max