Blender  V3.3
tex_coord.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 
6 #include "kernel/camera/camera.h"
7 #include "kernel/geom/geom.h"
9 
11 
12 /* Texture Coordinate Node */
13 
16  uint32_t path_flag,
17  ccl_private float *stack,
18  uint4 node,
19  int offset)
20 {
21  float3 data;
22  uint type = node.y;
23  uint out_offset = node.z;
24 
25  switch (type) {
26  case NODE_TEXCO_OBJECT: {
27  data = sd->P;
28  if (node.w == 0) {
29  if (sd->object != OBJECT_NONE) {
31  }
32  }
33  else {
34  Transform tfm;
35  tfm.x = read_node_float(kg, &offset);
36  tfm.y = read_node_float(kg, &offset);
37  tfm.z = read_node_float(kg, &offset);
38  data = transform_point(&tfm, data);
39  }
40  break;
41  }
42  case NODE_TEXCO_NORMAL: {
43  data = sd->N;
45  break;
46  }
47  case NODE_TEXCO_CAMERA: {
48  Transform tfm = kernel_data.cam.worldtocamera;
49 
50  if (sd->object != OBJECT_NONE)
51  data = transform_point(&tfm, sd->P);
52  else
53  data = transform_point(&tfm, sd->P + camera_position(kg));
54  break;
55  }
56  case NODE_TEXCO_WINDOW: {
57  if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
58  kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
59  data = camera_world_to_ndc(kg, sd, sd->ray_P);
60  else
61  data = camera_world_to_ndc(kg, sd, sd->P);
62  data.z = 0.0f;
63  break;
64  }
65  case NODE_TEXCO_REFLECTION: {
66  if (sd->object != OBJECT_NONE)
67  data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
68  else
69  data = sd->I;
70  break;
71  }
73  data = object_dupli_generated(kg, sd->object);
74  break;
75  }
76  case NODE_TEXCO_DUPLI_UV: {
77  data = object_dupli_uv(kg, sd->object);
78  break;
79  }
81  data = sd->P;
82 
83 #ifdef __VOLUME__
84  if (sd->object != OBJECT_NONE)
85  data = volume_normalized_position(kg, sd, data);
86 #endif
87  break;
88  }
89  }
90 
91  stack_store_float3(stack, out_offset, data);
92  return offset;
93 }
94 
97  uint32_t path_flag,
98  ccl_private float *stack,
99  uint4 node,
100  int offset)
101 {
102 #ifdef __RAY_DIFFERENTIALS__
103  float3 data;
104  uint type = node.y;
105  uint out_offset = node.z;
106 
107  switch (type) {
108  case NODE_TEXCO_OBJECT: {
109  data = sd->P + sd->dP.dx;
110  if (node.w == 0) {
111  if (sd->object != OBJECT_NONE) {
113  }
114  }
115  else {
116  Transform tfm;
117  tfm.x = read_node_float(kg, &offset);
118  tfm.y = read_node_float(kg, &offset);
119  tfm.z = read_node_float(kg, &offset);
120  data = transform_point(&tfm, data);
121  }
122  break;
123  }
124  case NODE_TEXCO_NORMAL: {
125  data = sd->N;
127  break;
128  }
129  case NODE_TEXCO_CAMERA: {
130  Transform tfm = kernel_data.cam.worldtocamera;
131 
132  if (sd->object != OBJECT_NONE)
133  data = transform_point(&tfm, sd->P + sd->dP.dx);
134  else
135  data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg));
136  break;
137  }
138  case NODE_TEXCO_WINDOW: {
139  if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
140  kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
141  data = camera_world_to_ndc(kg, sd, sd->ray_P);
142  else
143  data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
144  data.z = 0.0f;
145  break;
146  }
147  case NODE_TEXCO_REFLECTION: {
148  if (sd->object != OBJECT_NONE)
149  data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
150  else
151  data = sd->I;
152  break;
153  }
155  data = object_dupli_generated(kg, sd->object);
156  break;
157  }
158  case NODE_TEXCO_DUPLI_UV: {
159  data = object_dupli_uv(kg, sd->object);
160  break;
161  }
163  data = sd->P + sd->dP.dx;
164 
165 # ifdef __VOLUME__
166  if (sd->object != OBJECT_NONE)
167  data = volume_normalized_position(kg, sd, data);
168 # endif
169  break;
170  }
171  }
172 
173  stack_store_float3(stack, out_offset, data);
174  return offset;
175 #else
176  return svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
177 #endif
178 }
179 
182  uint32_t path_flag,
183  ccl_private float *stack,
184  uint4 node,
185  int offset)
186 {
187 #ifdef __RAY_DIFFERENTIALS__
188  float3 data;
189  uint type = node.y;
190  uint out_offset = node.z;
191 
192  switch (type) {
193  case NODE_TEXCO_OBJECT: {
194  data = sd->P + sd->dP.dy;
195  if (node.w == 0) {
196  if (sd->object != OBJECT_NONE) {
198  }
199  }
200  else {
201  Transform tfm;
202  tfm.x = read_node_float(kg, &offset);
203  tfm.y = read_node_float(kg, &offset);
204  tfm.z = read_node_float(kg, &offset);
205  data = transform_point(&tfm, data);
206  }
207  break;
208  }
209  case NODE_TEXCO_NORMAL: {
210  data = sd->N;
212  break;
213  }
214  case NODE_TEXCO_CAMERA: {
215  Transform tfm = kernel_data.cam.worldtocamera;
216 
217  if (sd->object != OBJECT_NONE)
218  data = transform_point(&tfm, sd->P + sd->dP.dy);
219  else
220  data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg));
221  break;
222  }
223  case NODE_TEXCO_WINDOW: {
224  if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
225  kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
226  data = camera_world_to_ndc(kg, sd, sd->ray_P);
227  else
228  data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
229  data.z = 0.0f;
230  break;
231  }
232  case NODE_TEXCO_REFLECTION: {
233  if (sd->object != OBJECT_NONE)
234  data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I;
235  else
236  data = sd->I;
237  break;
238  }
240  data = object_dupli_generated(kg, sd->object);
241  break;
242  }
243  case NODE_TEXCO_DUPLI_UV: {
244  data = object_dupli_uv(kg, sd->object);
245  break;
246  }
248  data = sd->P + sd->dP.dy;
249 
250 # ifdef __VOLUME__
251  if (sd->object != OBJECT_NONE)
252  data = volume_normalized_position(kg, sd, data);
253 # endif
254  break;
255  }
256  }
257 
258  stack_store_float3(stack, out_offset, data);
259  return offset;
260 #else
261  return svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
262 #endif
263 }
264 
267  ccl_private float *stack,
268  uint4 node)
269 {
270  uint color_offset, strength_offset, normal_offset, space;
271  svm_unpack_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space);
272 
273  float3 color = stack_load_float3(stack, color_offset);
274  color = 2.0f * make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f);
275 
276  bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
277  float3 N;
278 
279  if (space == NODE_NORMAL_MAP_TANGENT) {
280  /* tangent space */
281  if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_TRIANGLE) == 0) {
282  /* Fallback to unperturbed normal. */
283  stack_store_float3(stack, normal_offset, sd->N);
284  return;
285  }
286 
287  /* first try to get tangent attribute */
288  const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
289  const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
290 
291  if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND) {
292  /* Fallback to unperturbed normal. */
293  stack_store_float3(stack, normal_offset, sd->N);
294  return;
295  }
296 
297  /* get _unnormalized_ interpolated normal and tangent */
298  float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
299  float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
300  float3 normal;
301 
302  if (sd->shader & SHADER_SMOOTH_NORMAL) {
303  normal = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
304  }
305  else {
306  normal = sd->Ng;
307 
308  /* the normal is already inverted, which is too soon for the math here */
309  if (is_backfacing) {
310  normal = -normal;
311  }
312 
314  }
315 
316  /* apply normal map */
317  float3 B = sign * cross(normal, tangent);
318  N = safe_normalize(color.x * tangent + color.y * B + color.z * normal);
319 
320  /* transform to world space */
321  object_normal_transform(kg, sd, &N);
322  }
323  else {
324  /* strange blender convention */
326  color.y = -color.y;
327  color.z = -color.z;
328  }
329 
330  /* object, world space */
331  N = color;
332 
334  object_normal_transform(kg, sd, &N);
335  else
336  N = safe_normalize(N);
337  }
338 
339  /* invert normal for backfacing polygons */
340  if (is_backfacing) {
341  N = -N;
342  }
343 
344  float strength = stack_load_float(stack, strength_offset);
345 
346  if (strength != 1.0f) {
347  strength = max(strength, 0.0f);
348  N = safe_normalize(sd->N + (N - sd->N) * strength);
349  }
350 
351  if (is_zero(N)) {
352  N = sd->N;
353  }
354 
355  stack_store_float3(stack, normal_offset, N);
356 }
357 
360  ccl_private float *stack,
361  uint4 node)
362 {
363  uint tangent_offset, direction_type, axis;
364  svm_unpack_node_uchar3(node.y, &tangent_offset, &direction_type, &axis);
365 
366  float3 tangent;
367  float3 attribute_value;
368  const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
369  if (desc.offset != ATTR_STD_NOT_FOUND) {
370  if (desc.type == NODE_ATTR_FLOAT2) {
371  float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
372  attribute_value.x = value.x;
373  attribute_value.y = value.y;
374  attribute_value.z = 0.0f;
375  }
376  else {
377  attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
378  }
379  }
380 
381  if (direction_type == NODE_TANGENT_UVMAP) {
382  /* UV map */
383  if (desc.offset == ATTR_STD_NOT_FOUND) {
384  stack_store_float3(stack, tangent_offset, zero_float3());
385  return;
386  }
387  else {
388  tangent = attribute_value;
389  }
390  }
391  else {
392  /* radial */
393  float3 generated;
394 
395  if (desc.offset == ATTR_STD_NOT_FOUND)
396  generated = sd->P;
397  else
398  generated = attribute_value;
399 
400  if (axis == NODE_TANGENT_AXIS_X)
401  tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
402  else if (axis == NODE_TANGENT_AXIS_Y)
403  tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f));
404  else
405  tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f);
406  }
407 
408  object_normal_transform(kg, sd, &tangent);
409  tangent = cross(sd->N, normalize(cross(tangent, sd->N)));
410  stack_store_float3(stack, tangent_offset, tangent);
411 }
412 
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 GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
#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
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
IconTextureDrawCall normal
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
ccl_device_inline float3 camera_position(KernelGlobals kg)
ccl_device_inline float3 camera_world_to_ndc(KernelGlobals kg, ccl_private ShaderData *sd, float3 P)
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_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
ccl_device_inline float3 object_dupli_generated(KernelGlobals kg, int object)
ccl_device_inline void object_inverse_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ccl_device_inline float3 object_dupli_uv(KernelGlobals kg, int object)
ccl_device_inline void object_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ccl_device_inline float4 read_node_float(KernelGlobals kg, ccl_private int *offset)
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_forceinline void svm_unpack_node_uchar3(uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
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)
@ NODE_TANGENT_AXIS_Y
@ NODE_TANGENT_AXIS_X
@ NODE_TEXCO_VOLUME_GENERATED
@ NODE_TEXCO_REFLECTION
@ NODE_TEXCO_WINDOW
@ NODE_TEXCO_OBJECT
@ NODE_TEXCO_DUPLI_UV
@ NODE_TEXCO_DUPLI_GENERATED
@ NODE_TEXCO_CAMERA
@ NODE_TEXCO_NORMAL
@ NODE_ATTR_FLOAT2
@ NODE_TANGENT_UVMAP
@ NODE_NORMAL_MAP_TANGENT
@ NODE_NORMAL_MAP_BLENDER_WORLD
@ NODE_NORMAL_MAP_BLENDER_OBJECT
@ NODE_NORMAL_MAP_OBJECT
@ SD_BACKFACING
Definition: kernel/types.h:738
@ PRIMITIVE_TRIANGLE
Definition: kernel/types.h:551
@ ATTR_STD_NOT_FOUND
Definition: kernel/types.h:647
@ PATH_RAY_CAMERA
Definition: kernel/types.h:194
#define OBJECT_NONE
Definition: kernel/types.h:40
ShaderData
Definition: kernel/types.h:925
@ SHADER_SMOOTH_NORMAL
Definition: kernel/types.h:435
@ CAMERA_ORTHOGRAPHIC
Definition: kernel/types.h:466
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 N
#define B
#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_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float2 *dx, ccl_private float2 *dy)
Definition: primitive.h:52
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
unsigned int uint32_t
Definition: stdint.h:80
NodeAttributeType type
Definition: kernel/types.h:657
float x
Definition: types_float2.h:15
float y
Definition: types_float2.h:15
float z
float y
float x
ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private float *stack, uint4 node, int offset)
Definition: tex_coord.h:180
CCL_NAMESPACE_BEGIN ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private float *stack, uint4 node, int offset)
Definition: tex_coord.h:14
ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private float *stack, uint4 node, int offset)
Definition: tex_coord.h:95
ccl_device_noinline void svm_node_tangent(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition: tex_coord.h:358
ccl_device_noinline void svm_node_normal_map(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition: tex_coord.h:265
float max
ccl_device_inline float3 triangle_smooth_normal_unnormalized(KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v)
Definition: triangle.h:105