Blender V4.3
tex_coord.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#include "kernel/geom/geom.h"
10
12
13/* Texture Coordinate Node */
14
17 uint32_t path_flag,
18 ccl_private float *stack,
19 uint4 node,
20 int offset)
21{
22 float3 data = zero_float3();
23 uint type = node.y;
24 uint out_offset = node.z;
25
26 switch (type) {
27 case NODE_TEXCO_OBJECT: {
28 data = sd->P;
29 if (node.w == 0) {
30 if (sd->object != OBJECT_NONE) {
32 }
33 }
34 else {
35 Transform tfm;
36 tfm.x = read_node_float(kg, &offset);
37 tfm.y = read_node_float(kg, &offset);
38 tfm.z = read_node_float(kg, &offset);
39 data = transform_point(&tfm, data);
40 }
41 break;
42 }
43 case NODE_TEXCO_NORMAL: {
44 data = sd->N;
46 break;
47 }
48 case NODE_TEXCO_CAMERA: {
49 Transform tfm = kernel_data.cam.worldtocamera;
50
51 if (sd->object != OBJECT_NONE)
52 data = transform_point(&tfm, sd->P);
53 else
54 data = transform_point(&tfm, sd->P + camera_position(kg));
55 break;
56 }
57 case NODE_TEXCO_WINDOW: {
58 if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
60 data = camera_world_to_ndc(kg, sd, sd->ray_P);
61 else
62 data = camera_world_to_ndc(kg, sd, sd->P);
63 data.z = 0.0f;
64 break;
65 }
67 if (sd->object != OBJECT_NONE)
68 data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
69 else
70 data = sd->wi;
71 break;
72 }
74 data = object_dupli_generated(kg, sd->object);
75 break;
76 }
78 data = object_dupli_uv(kg, sd->object);
79 break;
80 }
82 data = sd->P;
83
84#ifdef __VOLUME__
85 if (sd->object != OBJECT_NONE)
86 data = volume_normalized_position(kg, sd, data);
87#endif
88 break;
89 }
90 }
91
92 stack_store_float3(stack, out_offset, data);
93 return offset;
94}
95
98 uint32_t path_flag,
99 ccl_private float *stack,
100 uint4 node,
101 int offset)
102{
103#ifdef __RAY_DIFFERENTIALS__
104 float3 data = zero_float3();
105 uint type = node.y;
106 uint out_offset = node.z;
107
108 switch (type) {
109 case NODE_TEXCO_OBJECT: {
110 data = svm_node_bump_P_dx(sd);
111 if (node.w == 0) {
112 if (sd->object != OBJECT_NONE) {
114 }
115 }
116 else {
117 Transform tfm;
118 tfm.x = read_node_float(kg, &offset);
119 tfm.y = read_node_float(kg, &offset);
120 tfm.z = read_node_float(kg, &offset);
121 data = transform_point(&tfm, data);
122 }
123 break;
124 }
125 case NODE_TEXCO_NORMAL: {
126 data = sd->N;
127 object_inverse_normal_transform(kg, sd, &data);
128 break;
129 }
130 case NODE_TEXCO_CAMERA: {
131 Transform tfm = kernel_data.cam.worldtocamera;
132
133 if (sd->object != OBJECT_NONE)
134 data = transform_point(&tfm, svm_node_bump_P_dx(sd));
135 else
136 data = transform_point(&tfm, svm_node_bump_P_dx(sd) + camera_position(kg));
137 break;
138 }
139 case NODE_TEXCO_WINDOW: {
140 if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
142 data = camera_world_to_ndc(kg, sd, sd->ray_P);
143 else
144 data = camera_world_to_ndc(kg, sd, svm_node_bump_P_dx(sd));
145 data.z = 0.0f;
146 break;
147 }
149 if (sd->object != OBJECT_NONE)
150 data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
151 else
152 data = sd->wi;
153 break;
154 }
156 data = object_dupli_generated(kg, sd->object);
157 break;
158 }
159 case NODE_TEXCO_DUPLI_UV: {
160 data = object_dupli_uv(kg, sd->object);
161 break;
162 }
164 data = svm_node_bump_P_dx(sd);
165
166# ifdef __VOLUME__
167 if (sd->object != OBJECT_NONE)
168 data = volume_normalized_position(kg, sd, data);
169# endif
170 break;
171 }
172 }
173
174 stack_store_float3(stack, out_offset, data);
175 return offset;
176#else
177 return svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
178#endif
179}
180
183 uint32_t path_flag,
184 ccl_private float *stack,
185 uint4 node,
186 int offset)
187{
188#ifdef __RAY_DIFFERENTIALS__
189 float3 data = zero_float3();
190 uint type = node.y;
191 uint out_offset = node.z;
192
193 switch (type) {
194 case NODE_TEXCO_OBJECT: {
195 data = svm_node_bump_P_dy(sd);
196 if (node.w == 0) {
197 if (sd->object != OBJECT_NONE) {
199 }
200 }
201 else {
202 Transform tfm;
203 tfm.x = read_node_float(kg, &offset);
204 tfm.y = read_node_float(kg, &offset);
205 tfm.z = read_node_float(kg, &offset);
206 data = transform_point(&tfm, data);
207 }
208 break;
209 }
210 case NODE_TEXCO_NORMAL: {
211 data = sd->N;
212 object_inverse_normal_transform(kg, sd, &data);
213 break;
214 }
215 case NODE_TEXCO_CAMERA: {
216 Transform tfm = kernel_data.cam.worldtocamera;
217
218 if (sd->object != OBJECT_NONE)
219 data = transform_point(&tfm, svm_node_bump_P_dy(sd));
220 else
221 data = transform_point(&tfm, svm_node_bump_P_dy(sd) + camera_position(kg));
222 break;
223 }
224 case NODE_TEXCO_WINDOW: {
225 if ((path_flag & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
227 data = camera_world_to_ndc(kg, sd, sd->ray_P);
228 else
229 data = camera_world_to_ndc(kg, sd, svm_node_bump_P_dy(sd));
230 data.z = 0.0f;
231 break;
232 }
234 if (sd->object != OBJECT_NONE)
235 data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
236 else
237 data = sd->wi;
238 break;
239 }
241 data = object_dupli_generated(kg, sd->object);
242 break;
243 }
244 case NODE_TEXCO_DUPLI_UV: {
245 data = object_dupli_uv(kg, sd->object);
246 break;
247 }
249 data = svm_node_bump_P_dy(sd);
250
251# ifdef __VOLUME__
252 if (sd->object != OBJECT_NONE)
253 data = volume_normalized_position(kg, sd, data);
254# endif
255 break;
256 }
257 }
258
259 stack_store_float3(stack, out_offset, data);
260 return offset;
261#else
262 return svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
263#endif
264}
265
268 ccl_private float *stack,
269 uint4 node)
270{
271 uint color_offset, strength_offset, normal_offset, space;
272 svm_unpack_node_uchar4(node.y, &color_offset, &strength_offset, &normal_offset, &space);
273
274 float3 color = stack_load_float3(stack, color_offset);
275 color = 2.0f * make_float3(color.x - 0.5f, color.y - 0.5f, color.z - 0.5f);
276
277 bool is_backfacing = (sd->flag & SD_BACKFACING) != 0;
278 float3 N;
279 float strength = stack_load_float(stack, strength_offset);
280 if (space == NODE_NORMAL_MAP_TANGENT) {
281 /* tangent space */
282 if (sd->object == OBJECT_NONE || (sd->type & PRIMITIVE_TRIANGLE) == 0) {
283 /* Fallback to unperturbed normal. */
284 stack_store_float3(stack, normal_offset, sd->N);
285 return;
286 }
287
288 /* first try to get tangent attribute */
289 const AttributeDescriptor attr = find_attribute(kg, sd, node.z);
290 const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w);
291
292 if (attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND) {
293 /* Fallback to unperturbed normal. */
294 stack_store_float3(stack, normal_offset, sd->N);
295 return;
296 }
297
298 /* get _unnormalized_ interpolated normal and tangent */
299 float3 tangent = primitive_surface_attribute_float3(kg, sd, attr, NULL, NULL);
300 float sign = primitive_surface_attribute_float(kg, sd, attr_sign, NULL, NULL);
301 float3 normal;
302
303 if (sd->shader & SHADER_SMOOTH_NORMAL) {
304 normal = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
305 }
306 else {
307 normal = sd->Ng;
308
309 /* the normal is already inverted, which is too soon for the math here */
310 if (is_backfacing) {
311 normal = -normal;
312 }
313
314 object_inverse_normal_transform(kg, sd, &normal);
315 }
316 /* Apply strength in the tangent case. */
317 color.x *= strength;
318 color.y *= strength;
319 color.z = mix(1.0f, color.z, saturatef(strength));
320
321 /* apply normal map */
322 float3 B = sign * cross(normal, tangent);
323 N = safe_normalize(color.x * tangent + color.y * B + color.z * normal);
324
325 /* transform to world space */
326 object_normal_transform(kg, sd, &N);
327
328 /* invert normal for backfacing polygons */
329 if (is_backfacing) {
330 N = -N;
331 }
332 }
333 else {
334 /* strange blender convention */
336 color.y = -color.y;
337 color.z = -color.z;
338 }
339
340 /* object, world space */
341 N = color;
342
344 object_normal_transform(kg, sd, &N);
345 }
346 else {
347 N = safe_normalize(N);
348 }
349
350 /* invert normal for backfacing polygons */
351 if (is_backfacing) {
352 N = -N;
353 }
354
355 /* Apply strength in all but tangent space. */
356 if (strength != 1.0f) {
357 strength = max(strength, 0.0f);
358 N = safe_normalize(sd->N + (N - sd->N) * strength);
359 }
360 }
361
362 if (is_zero(N)) {
363 N = sd->N;
364 }
365
366 stack_store_float3(stack, normal_offset, N);
367}
368
371 ccl_private float *stack,
372 uint4 node)
373{
374 uint tangent_offset, direction_type, axis;
375 svm_unpack_node_uchar3(node.y, &tangent_offset, &direction_type, &axis);
376
377 float3 tangent;
378 float3 attribute_value;
379 const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
380 if (desc.offset != ATTR_STD_NOT_FOUND) {
381 if (desc.type == NODE_ATTR_FLOAT2) {
382 float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
383 attribute_value.x = value.x;
384 attribute_value.y = value.y;
385 attribute_value.z = 0.0f;
386 }
387 else {
388 attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
389 }
390 }
391
392 if (direction_type == NODE_TANGENT_UVMAP) {
393 /* UV map */
394 if (desc.offset == ATTR_STD_NOT_FOUND) {
395 stack_store_float3(stack, tangent_offset, zero_float3());
396 return;
397 }
398 else {
399 tangent = attribute_value;
400 }
401 }
402 else {
403 /* radial */
404 float3 generated;
405
406 if (desc.offset == ATTR_STD_NOT_FOUND)
407 generated = sd->P;
408 else
409 generated = attribute_value;
410
411 if (axis == NODE_TANGENT_AXIS_X)
412 tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f));
413 else if (axis == NODE_TANGENT_AXIS_Y)
414 tangent = make_float3(-(generated.z - 0.5f), 0.0f, (generated.x - 0.5f));
415 else
416 tangent = make_float3(-(generated.y - 0.5f), (generated.x - 0.5f), 0.0f);
417 }
418
419 object_normal_transform(kg, sd, &tangent);
420 tangent = cross(sd->N, normalize(cross(tangent, sd->N)));
421 stack_store_float3(stack, tangent_offset, tangent);
422}
423
unsigned int uint
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 Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves 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 Invert a color
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)"
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_private
#define ccl_device_noinline
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
ccl_device_inline float3 triangle_smooth_normal_unnormalized(KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v)
#define mix(a, b, c)
Definition hash.h:36
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_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_forceinline float3 svm_node_bump_P_dx(const ccl_private ShaderData *sd)
ccl_device_forceinline float3 svm_node_bump_P_dy(const ccl_private ShaderData *sd)
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
@ PRIMITIVE_TRIANGLE
@ ATTR_STD_NOT_FOUND
@ PATH_RAY_CAMERA
#define OBJECT_NONE
ShaderData
@ SHADER_SMOOTH_NORMAL
@ CAMERA_ORTHOGRAPHIC
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
#define N
#define B
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_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:53
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
unsigned int uint32_t
Definition stdint.h:80
static bool find_attribute(const std::string &attributes, const char *search_attribute)
NodeAttributeType type
float4 y
Definition transform.h:24
float4 x
Definition transform.h:24
float4 z
Definition transform.h:24
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
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:181
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:15
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:96
ccl_device_noinline void svm_node_tangent(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition tex_coord.h:369
ccl_device_noinline void svm_node_normal_map(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
Definition tex_coord.h:266
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
Definition transform.h:63
float max