Blender  V2.93
svm_tex_coord.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 /* Texture Coordinate Node */
20 
22  KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
23 {
24  float3 data;
25  uint type = node.y;
26  uint out_offset = node.z;
27 
28  switch (type) {
29  case NODE_TEXCO_OBJECT: {
30  data = sd->P;
31  if (node.w == 0) {
32  if (sd->object != OBJECT_NONE) {
34  }
35  }
36  else {
37  Transform tfm;
38  tfm.x = read_node_float(kg, offset);
39  tfm.y = read_node_float(kg, offset);
40  tfm.z = read_node_float(kg, offset);
41  data = transform_point(&tfm, data);
42  }
43  break;
44  }
45  case NODE_TEXCO_NORMAL: {
46  data = sd->N;
48  break;
49  }
50  case NODE_TEXCO_CAMERA: {
51  Transform tfm = kernel_data.cam.worldtocamera;
52 
53  if (sd->object != OBJECT_NONE)
54  data = transform_point(&tfm, sd->P);
55  else
56  data = transform_point(&tfm, sd->P + camera_position(kg));
57  break;
58  }
59  case NODE_TEXCO_WINDOW: {
60  if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
61  kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
62  data = camera_world_to_ndc(kg, sd, sd->ray_P);
63  else
64  data = camera_world_to_ndc(kg, sd, sd->P);
65  data.z = 0.0f;
66  break;
67  }
68  case NODE_TEXCO_REFLECTION: {
69  if (sd->object != OBJECT_NONE)
70  data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
71  else
72  data = sd->I;
73  break;
74  }
76  data = object_dupli_generated(kg, sd->object);
77  break;
78  }
79  case NODE_TEXCO_DUPLI_UV: {
80  data = object_dupli_uv(kg, sd->object);
81  break;
82  }
84  data = sd->P;
85 
86 #ifdef __VOLUME__
87  if (sd->object != OBJECT_NONE)
88  data = volume_normalized_position(kg, sd, data);
89 #endif
90  break;
91  }
92  }
93 
94  stack_store_float3(stack, out_offset, data);
95 }
96 
98  KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
99 {
100 #ifdef __RAY_DIFFERENTIALS__
101  float3 data;
102  uint type = node.y;
103  uint out_offset = node.z;
104 
105  switch (type) {
106  case NODE_TEXCO_OBJECT: {
107  data = sd->P + sd->dP.dx;
108  if (node.w == 0) {
109  if (sd->object != OBJECT_NONE) {
111  }
112  }
113  else {
114  Transform tfm;
115  tfm.x = read_node_float(kg, offset);
116  tfm.y = read_node_float(kg, offset);
117  tfm.z = read_node_float(kg, offset);
118  data = transform_point(&tfm, data);
119  }
120  break;
121  }
122  case NODE_TEXCO_NORMAL: {
123  data = sd->N;
125  break;
126  }
127  case NODE_TEXCO_CAMERA: {
128  Transform tfm = kernel_data.cam.worldtocamera;
129 
130  if (sd->object != OBJECT_NONE)
131  data = transform_point(&tfm, sd->P + sd->dP.dx);
132  else
133  data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg));
134  break;
135  }
136  case NODE_TEXCO_WINDOW: {
137  if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
138  kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
139  data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx);
140  else
141  data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
142  data.z = 0.0f;
143  break;
144  }
145  case NODE_TEXCO_REFLECTION: {
146  if (sd->object != OBJECT_NONE)
147  data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
148  else
149  data = sd->I;
150  break;
151  }
153  data = object_dupli_generated(kg, sd->object);
154  break;
155  }
156  case NODE_TEXCO_DUPLI_UV: {
157  data = object_dupli_uv(kg, sd->object);
158  break;
159  }
161  data = sd->P + sd->dP.dx;
162 
163 # ifdef __VOLUME__
164  if (sd->object != OBJECT_NONE)
165  data = volume_normalized_position(kg, sd, data);
166 # endif
167  break;
168  }
169  }
170 
171  stack_store_float3(stack, out_offset, data);
172 #else
173  svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
174 #endif
175 }
176 
178  KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
179 {
180 #ifdef __RAY_DIFFERENTIALS__
181  float3 data;
182  uint type = node.y;
183  uint out_offset = node.z;
184 
185  switch (type) {
186  case NODE_TEXCO_OBJECT: {
187  data = sd->P + sd->dP.dy;
188  if (node.w == 0) {
189  if (sd->object != OBJECT_NONE) {
191  }
192  }
193  else {
194  Transform tfm;
195  tfm.x = read_node_float(kg, offset);
196  tfm.y = read_node_float(kg, offset);
197  tfm.z = read_node_float(kg, offset);
198  data = transform_point(&tfm, data);
199  }
200  break;
201  }
202  case NODE_TEXCO_NORMAL: {
203  data = sd->N;
205  break;
206  }
207  case NODE_TEXCO_CAMERA: {
208  Transform tfm = kernel_data.cam.worldtocamera;
209 
210  if (sd->object != OBJECT_NONE)
211  data = transform_point(&tfm, sd->P + sd->dP.dy);
212  else
213  data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg));
214  break;
215  }
216  case NODE_TEXCO_WINDOW: {
217  if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
218  kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
219  data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy);
220  else
221  data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
222  data.z = 0.0f;
223  break;
224  }
225  case NODE_TEXCO_REFLECTION: {
226  if (sd->object != OBJECT_NONE)
227  data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
228  else
229  data = sd->I;
230  break;
231  }
233  data = object_dupli_generated(kg, sd->object);
234  break;
235  }
236  case NODE_TEXCO_DUPLI_UV: {
237  data = object_dupli_uv(kg, sd->object);
238  break;
239  }
241  data = sd->P + sd->dP.dy;
242 
243 # ifdef __VOLUME__
244  if (sd->object != OBJECT_NONE)
245  data = volume_normalized_position(kg, sd, data);
246 # endif
247  break;
248  }
249  }
250 
251  stack_store_float3(stack, out_offset, data);
252 #else
253  svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
254 #endif
255 }
256 
257 ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
258 {
259  uint color_offset, strength_offset, normal_offset, space;
260  svm_unpack_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space);
261 
262  float3 color = stack_load_float3(stack, color_offset);
263  color = 2.0f * make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f);
264 
265  bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
266  float3 N;
267 
268  if (space == NODE_NORMAL_MAP_TANGENT) {
269  /* tangent space */
270  if (sd->object == OBJECT_NONE) {
271  /* Fallback to unperturbed normal. */
272  stack_store_float3(stack, normal_offset, sd->N);
273  return;
274  }
275 
276  /* first try to get tangent attribute */
277  const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
278  const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
280 
281  if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND ||
282  attr_normal.offset == ATTR_STD_NOT_FOUND) {
283  /* Fallback to unperturbed normal. */
284  stack_store_float3(stack, normal_offset, sd->N);
285  return;
286  }
287 
288  /* get _unnormalized_ interpolated normal and tangent */
289  float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
290  float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
291  float3 normal;
292 
293  if (sd->shader & SHADER_SMOOTH_NORMAL) {
294  normal = primitive_surface_attribute_float3(kg, sd, attr_normal, NULL, NULL);
295  }
296  else {
297  normal = sd->Ng;
298 
299  /* the normal is already inverted, which is too soon for the math here */
300  if (is_backfacing) {
301  normal = -normal;
302  }
303 
305  }
306 
307  /* apply normal map */
308  float3 B = sign * cross(normal, tangent);
309  N = safe_normalize(color.x * tangent + color.y * B + color.z * normal);
310 
311  /* transform to world space */
313  }
314  else {
315  /* strange blender convention */
317  color.y = -color.y;
318  color.z = -color.z;
319  }
320 
321  /* object, world space */
322  N = color;
323 
326  else
327  N = safe_normalize(N);
328  }
329 
330  /* invert normal for backfacing polygons */
331  if (is_backfacing) {
332  N = -N;
333  }
334 
335  float strength = stack_load_float(stack, strength_offset);
336 
337  if (strength != 1.0f) {
338  strength = max(strength, 0.0f);
339  N = safe_normalize(sd->N + (N - sd->N) * strength);
340  }
341 
342  N = ensure_valid_reflection(sd->Ng, sd->I, N);
343 
344  if (is_zero(N)) {
345  N = sd->N;
346  }
347 
348  stack_store_float3(stack, normal_offset, N);
349 }
350 
351 ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
352 {
353  uint tangent_offset, direction_type, axis;
354  svm_unpack_node_uchar3(node.y, &tangent_offset, &direction_type, &axis);
355 
356  float3 tangent;
357  float3 attribute_value;
358  const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
359  if (desc.offset != ATTR_STD_NOT_FOUND) {
360  if (desc.type == NODE_ATTR_FLOAT2) {
362  attribute_value.x = value.x;
363  attribute_value.y = value.y;
364  attribute_value.z = 0.0f;
365  }
366  else {
367  attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
368  }
369  }
370 
371  if (direction_type == NODE_TANGENT_UVMAP) {
372  /* UV map */
373  if (desc.offset == ATTR_STD_NOT_FOUND) {
374  stack_store_float3(stack, tangent_offset, zero_float3());
375  return;
376  }
377  else {
378  tangent = attribute_value;
379  }
380  }
381  else {
382  /* radial */
383  float3 generated;
384 
385  if (desc.offset == ATTR_STD_NOT_FOUND)
386  generated = sd->P;
387  else
388  generated = attribute_value;
389 
390  if (axis == NODE_TANGENT_AXIS_X)
391  tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
392  else if (axis == NODE_TANGENT_AXIS_Y)
393  tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f));
394  else
395  tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f);
396  }
397 
398  object_normal_transform(kg, sd, &tangent);
399  tangent = cross(sd->N, normalize(cross(tangent, sd->N)));
400  stack_store_float3(stack, tangent_offset, tangent);
401 }
402 
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 GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
OperationNode * node
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, const ShaderData *sd, float3 *P)
Definition: geom_object.h:130
ccl_device_inline void object_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
Definition: geom_object.h:166
ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
Definition: geom_object.h:282
ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N)
Definition: geom_object.h:144
ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
Definition: geom_object.h:270
ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
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 float4 read_node_float(KernelGlobals *kg, int *offset)
ccl_device_inline float stack_load_float(float *stack, uint a)
ccl_device_forceinline void svm_unpack_node_uchar3(uint i, uint *x, uint *y, uint *z)
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 float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P)
ccl_device_inline float3 camera_position(KernelGlobals *kg)
#define kernel_data
#define ccl_device
#define CCL_NAMESPACE_END
#define make_float3(x, y, z)
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
@ SD_BACKFACING
Definition: kernel_types.h:843
@ ATTR_STD_VERTEX_NORMAL
Definition: kernel_types.h:746
@ ATTR_STD_NOT_FOUND
Definition: kernel_types.h:773
@ PATH_RAY_CAMERA
Definition: kernel_types.h:266
#define OBJECT_NONE
Definition: kernel_types.h:59
ShaderData
@ SHADER_SMOOTH_NORMAL
Definition: kernel_types.h:581
@ CAMERA_ORTHOGRAPHIC
Definition: kernel_types.h:610
#define B
double sign(double arg)
Definition: utility.h:250
params N
NodeAttributeType type
Definition: kernel_types.h:783
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_normal_map(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
CCL_NAMESPACE_BEGIN ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
Definition: svm_tex_coord.h:21
ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node, int *offset)
Definition: svm_tex_coord.h:97
@ NODE_TANGENT_AXIS_Y
Definition: svm_types.h:465
@ NODE_TANGENT_AXIS_X
Definition: svm_types.h:464
@ NODE_TEXCO_VOLUME_GENERATED
Definition: svm_types.h:246
@ NODE_TEXCO_REFLECTION
Definition: svm_types.h:243
@ NODE_TEXCO_WINDOW
Definition: svm_types.h:242
@ NODE_TEXCO_OBJECT
Definition: svm_types.h:240
@ NODE_TEXCO_DUPLI_UV
Definition: svm_types.h:245
@ NODE_TEXCO_DUPLI_GENERATED
Definition: svm_types.h:244
@ NODE_TEXCO_CAMERA
Definition: svm_types.h:241
@ NODE_TEXCO_NORMAL
Definition: svm_types.h:239
@ NODE_ATTR_FLOAT2
Definition: svm_types.h:168
@ NODE_TANGENT_UVMAP
Definition: svm_types.h:460
@ NODE_NORMAL_MAP_TANGENT
Definition: svm_types.h:470
@ NODE_NORMAL_MAP_BLENDER_WORLD
Definition: svm_types.h:474
@ NODE_NORMAL_MAP_BLENDER_OBJECT
Definition: svm_types.h:473
@ 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)
ccl_device_inline float3 zero_float3()
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)