Blender  V2.93
svm_displace.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 /* Bump Node */
20 
21 ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
22 {
23 #ifdef __RAY_DIFFERENTIALS__
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) : sd->N;
29 
30  float3 dPdx = sd->dP.dx;
31  float3 dPdy = sd->dP.dy;
32 
33  if (use_object_space) {
34  object_inverse_normal_transform(kg, sd, &normal_in);
35  object_inverse_dir_transform(kg, sd, &dPdx);
36  object_inverse_dir_transform(kg, sd, &dPdy);
37  }
38 
39  /* get surface tangents from normal */
40  float3 Rx = cross(dPdy, normal_in);
41  float3 Ry = cross(normal_in, dPdx);
42 
43  /* get bump values */
44  uint c_offset, x_offset, y_offset, strength_offset;
45  svm_unpack_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &strength_offset);
46 
47  float h_c = stack_load_float(stack, c_offset);
48  float h_x = stack_load_float(stack, x_offset);
49  float h_y = stack_load_float(stack, y_offset);
50 
51  /* compute surface gradient and determinant */
52  float det = dot(dPdx, Rx);
53  float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry;
54 
55  float absdet = fabsf(det);
56 
57  float strength = stack_load_float(stack, strength_offset);
58  float scale = stack_load_float(stack, scale_offset);
59 
60  if (invert)
61  scale *= -1.0f;
62 
63  strength = max(strength, 0.0f);
64 
65  /* compute and output perturbed normal */
66  float3 normal_out = safe_normalize(absdet * normal_in - scale * signf(det) * surfgrad);
67  if (is_zero(normal_out)) {
68  normal_out = normal_in;
69  }
70  else {
71  normal_out = normalize(strength * normal_out + (1.0f - strength) * normal_in);
72  }
73 
74  if (use_object_space) {
75  object_normal_transform(kg, sd, &normal_out);
76  }
77 
78  normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out);
79 
80  stack_store_float3(stack, node.w, normal_out);
81 #endif
82 }
83 
84 /* Displacement Node */
85 
87  ShaderData *sd,
88  float *stack,
89  uint fac_offset)
90 {
91  float3 dP = stack_load_float3(stack, fac_offset);
92  sd->P += dP;
93 }
94 
95 ccl_device void svm_node_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
96 {
97  uint height_offset, midlevel_offset, scale_offset, normal_offset;
98  svm_unpack_node_uchar4(node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset);
99 
100  float height = stack_load_float(stack, height_offset);
101  float midlevel = stack_load_float(stack, midlevel_offset);
102  float scale = stack_load_float(stack, scale_offset);
103  float3 normal = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N;
104  uint space = node.w;
105 
106  float3 dP = normal;
107 
108  if (space == NODE_NORMAL_MAP_OBJECT) {
109  /* Object space. */
111  dP *= (height - midlevel) * scale;
112  object_dir_transform(kg, sd, &dP);
113  }
114  else {
115  /* World space. */
116  dP *= (height - midlevel) * scale;
117  }
118 
119  stack_store_float3(stack, node.z, dP);
120 }
121 
123  KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
124 {
125  uint4 data_node = read_node(kg, offset);
126  uint space = data_node.x;
127 
128  uint vector_offset, midlevel_offset, scale_offset, displacement_offset;
130  node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset);
131 
132  float3 vector = stack_load_float3(stack, vector_offset);
133  float midlevel = stack_load_float(stack, midlevel_offset);
134  float scale = stack_load_float(stack, scale_offset);
135  float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale;
136 
137  if (space == NODE_NORMAL_MAP_TANGENT) {
138  /* Tangent space. */
139  float3 normal = sd->N;
141 
142  const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
143  float3 tangent;
144  if (attr.offset != ATTR_STD_NOT_FOUND) {
145  tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
146  }
147  else {
148  tangent = normalize(sd->dPdu);
149  }
150 
151  float3 bitangent = normalize(cross(normal, tangent));
152  const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
153  if (attr_sign.offset != ATTR_STD_NOT_FOUND) {
154  float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
155  bitangent *= sign;
156  }
157 
158  dP = tangent * dP.x + normal * dP.y + bitangent * dP.z;
159  }
160 
161  if (space != NODE_NORMAL_MAP_WORLD) {
162  /* Tangent or object space. */
163  object_dir_transform(kg, sd, &dP);
164  }
165 
166  stack_store_float3(stack, displacement_offset, dP);
167 }
168 
MINLINE float signf(float f)
unsigned int uint
Definition: BLI_sys_types.h:83
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
OperationNode * node
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
ccl_device_inline void object_inverse_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
Definition: geom_object.h:190
ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
Definition: geom_object.h:166
ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
Definition: geom_object.h:144
ccl_device_inline void object_dir_transform(KernelGlobals *kg, const ShaderData *sd, float3 *D)
Definition: geom_object.h:178
CCL_NAMESPACE_BEGIN ccl_device_inline float primitive_surface_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
IconTextureDrawCall normal
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(float *stack, uint a)
ccl_device_inline uint4 read_node(KernelGlobals *kg, int *offset)
ccl_device_inline float stack_load_float(float *stack, uint a)
ccl_device_inline void stack_store_float3(float *stack, uint a, float3 f)
ccl_device_forceinline void svm_unpack_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
ccl_device_inline bool stack_valid(uint a)
#define ccl_device
#define CCL_NAMESPACE_END
#define fabsf(x)
#define make_float3(x, y, z)
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
@ ATTR_STD_NOT_FOUND
Definition: kernel_types.h:773
ShaderData
double sign(double arg)
Definition: utility.h:250
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
ccl_device void svm_node_set_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint fac_offset)
Definition: svm_displace.h:86
ccl_device void svm_node_vector_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
Definition: svm_displace.h:122
ccl_device void svm_node_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
Definition: svm_displace.h:95
CCL_NAMESPACE_BEGIN ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
Definition: svm_displace.h:21
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: svm_invert.h:19
@ NODE_NORMAL_MAP_TANGENT
Definition: svm_types.h:470
@ NODE_NORMAL_MAP_WORLD
Definition: svm_types.h:472
@ NODE_NORMAL_MAP_OBJECT
Definition: svm_types.h:471
float max
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 safe_normalize(const float2 &a)
ccl_device_inline bool is_zero(const float2 &a)