Blender V4.3
displace.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
8
10
11/* Bump Node */
12template<uint node_feature_mask>
15 ccl_private float *stack,
16 uint4 node)
17{
18 uint out_offset, bump_state_offset, dummy;
19 svm_unpack_node_uchar4(node.w, &out_offset, &bump_state_offset, &dummy, &dummy);
20
21#ifdef __RAY_DIFFERENTIALS__
23 {
24 /* get normal input */
25 uint normal_offset, scale_offset, invert, use_object_space;
26 svm_unpack_node_uchar4(node.y, &normal_offset, &scale_offset, &invert, &use_object_space);
27
28 float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) :
29 sd->N;
30
31 /* If we have saved bump state, read the full differential from there.
32 * Just using the compact form in those cases leads to incorrect normals (see #111588). */
34 if (bump_state_offset == SVM_STACK_INVALID) {
35 dP = differential_from_compact(sd->Ng, sd->dP);
36 }
37 else {
38 dP.dx = stack_load_float3(stack, bump_state_offset + 4);
39 dP.dy = stack_load_float3(stack, bump_state_offset + 7);
40 }
41
42 if (use_object_space) {
43 object_inverse_normal_transform(kg, sd, &normal_in);
46 }
47
48 /* get surface tangents from normal */
49 float3 Rx = cross(dP.dy, normal_in);
50 float3 Ry = cross(normal_in, dP.dx);
51
52 /* get bump values */
53 uint c_offset, x_offset, y_offset, strength_offset;
54 svm_unpack_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset);
55
56 float h_c = stack_load_float(stack, c_offset);
57 float h_x = stack_load_float(stack, x_offset);
58 float h_y = stack_load_float(stack, y_offset);
59
60 /* compute surface gradient and determinant */
61 float det = dot(dP.dx, Rx);
62 float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry;
63
64 float absdet = fabsf(det);
65
66 float strength = stack_load_float(stack, strength_offset);
67 float scale = stack_load_float(stack, scale_offset);
68
69 if (invert)
70 scale *= -1.0f;
71
72 strength = max(strength, 0.0f);
73
74 /* compute and output perturbed normal */
75 float3 normal_out = safe_normalize(absdet * normal_in - scale * signf(det) * surfgrad);
76 if (is_zero(normal_out)) {
77 normal_out = normal_in;
78 }
79 else {
80 normal_out = normalize(strength * normal_out + (1.0f - strength) * normal_in);
81 }
82
83 if (use_object_space) {
84 object_normal_transform(kg, sd, &normal_out);
85 }
86
87 stack_store_float3(stack, out_offset, normal_out);
88 }
89 else {
90 stack_store_float3(stack, out_offset, zero_float3());
91 }
92#endif
93}
94
95/* Displacement Node */
96
97template<uint node_feature_mask>
100 ccl_private float *stack,
101 uint fac_offset)
102{
104 {
105 float3 dP = stack_load_float3(stack, fac_offset);
106 sd->P += dP;
107 }
108}
109
110template<uint node_feature_mask>
113 ccl_private float *stack,
114 uint4 node)
115{
117 {
118 uint height_offset, midlevel_offset, scale_offset, normal_offset;
120 node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset);
121
122 float height = stack_load_float(stack, height_offset);
123 float midlevel = stack_load_float(stack, midlevel_offset);
124 float scale = stack_load_float(stack, scale_offset);
125 float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
126 uint space = node.w;
127
128 float3 dP = normal;
129
130 if (space == NODE_NORMAL_MAP_OBJECT) {
131 /* Object space. */
133 dP *= (height - midlevel) * scale;
134 object_dir_transform(kg, sd, &dP);
135 }
136 else {
137 /* World space. */
138 dP *= (height - midlevel) * scale;
139 }
140
141 stack_store_float3(stack, node.z, dP);
142 }
143 else {
144 stack_store_float3(stack, node.z, zero_float3());
145 }
146}
147
148template<uint node_feature_mask>
150 KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
151{
152 uint4 data_node = read_node(kg, &offset);
153 uint vector_offset, midlevel_offset, scale_offset, displacement_offset;
155 node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset);
156
158 {
159 uint space = data_node.x;
160
161 float3 vector = stack_load_float3(stack, vector_offset);
162 float midlevel = stack_load_float(stack, midlevel_offset);
163 float scale = stack_load_float(stack, scale_offset);
164 float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale;
165
166 if (space == NODE_NORMAL_MAP_TANGENT) {
167 /* Tangent space. */
168 float3 normal = sd->N;
169 object_inverse_normal_transform(kg, sd, &normal);
170
171 const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
172 float3 tangent;
173 if (attr.offset != ATTR_STD_NOT_FOUND) {
174 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
175 }
176 else {
177 tangent = normalize(sd->dPdu);
178 }
179
180 float3 bitangent = safe_normalize(cross(normal, tangent));
181 const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
182 if (attr_sign.offset != ATTR_STD_NOT_FOUND) {
183 float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
184 bitangent *= sign;
185 }
186
187 dP = tangent * dP.x + normal * dP.y + bitangent * dP.z;
188 }
189
190 if (space != NODE_NORMAL_MAP_WORLD) {
191 /* Tangent or object space. */
192 object_dir_transform(kg, sd, &dP);
193 }
194
195 stack_store_float3(stack, displacement_offset, dP);
196 }
197 else {
198 stack_store_float3(stack, displacement_offset, zero_float3());
199 (void)data_node;
200 }
201
202 return offset;
203}
204
MINLINE float signf(float f)
unsigned int uint
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_device
#define ccl_private
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
#define fabsf(x)
ccl_device_forceinline differential3 differential_from_compact(const float3 D, const float dD)
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:13
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:149
ccl_device void svm_node_set_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint fac_offset)
Definition displace.h:98
ccl_device_noinline void svm_node_displacement(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition displace.h:111
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
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)
#define SVM_STACK_INVALID
@ NODE_NORMAL_MAP_TANGENT
@ NODE_NORMAL_MAP_WORLD
@ NODE_NORMAL_MAP_OBJECT
@ ATTR_STD_NOT_FOUND
#define IF_KERNEL_NODES_FEATURE(feature)
ShaderData
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float cross(const float2 a, const float2 b)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
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:84
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:22
static bool find_attribute(const std::string &attributes, const char *search_attribute)
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
uint x
Definition types_uint4.h:15
float max