Blender V4.5
shader_data.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/* Functions to initialize ShaderData given.
6 *
7 * Could be from an incoming ray, intersection or sampled position. */
8
9#pragma once
10
11#include "kernel/globals.h"
12
15#include "kernel/geom/object.h"
18
20
22
23/* ShaderData setup from incoming ray */
24
26 ccl_private ShaderData *ccl_restrict sd,
27 const float time)
28{
29#ifdef __OBJECT_MOTION__
30 if (sd->object_flag & SD_OBJECT_MOTION) {
31 sd->ob_tfm_motion = object_fetch_transform_motion(kg, sd->object, time);
32 sd->ob_itfm_motion = transform_inverse(sd->ob_tfm_motion);
33 }
34#endif
35}
36
37/* TODO: break this up if it helps reduce register pressure to load data from
38 * global memory as we write it to shader-data. */
40 ccl_private ShaderData *ccl_restrict sd,
41 const ccl_private Ray *ccl_restrict ray,
43{
44 /* Read intersection data into shader globals.
45 *
46 * TODO: this is redundant, could potentially remove some of this from
47 * ShaderData but would need to ensure that it also works for shadow
48 * shader evaluation. */
49 sd->u = isect->u;
50 sd->v = isect->v;
51 sd->ray_length = isect->t;
52 sd->type = isect->type;
53 sd->object = isect->object;
54 sd->object_flag = kernel_data_fetch(object_flag, sd->object);
55 sd->prim = isect->prim;
56 sd->flag = 0;
57
58 /* Read matrices and time. */
59 sd->time = ray->time;
60
61#ifdef __OBJECT_MOTION__
62 shader_setup_object_transforms(kg, sd, ray->time);
63#endif
64
65 /* Read ray data into shader globals. */
66 sd->wi = -ray->D;
67
68#ifdef __HAIR__
69 if (sd->type & PRIMITIVE_CURVE) {
70 /* curve */
71 curve_shader_setup(kg, sd, ray->P, ray->D, isect->t, isect->prim);
72 }
73 else
74#endif
75#ifdef __POINTCLOUD__
76 if (sd->type & PRIMITIVE_POINT)
77 {
78 /* point */
79 point_shader_setup(kg, sd, isect, ray);
80 }
81 else
82#endif
83 {
84 if (sd->type == PRIMITIVE_TRIANGLE) {
85 /* static triangle */
87 }
88 else {
89 /* motion triangle */
91 }
92
93 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
94 /* instance transform */
95 object_normal_transform_auto(kg, sd, &sd->N);
96 object_normal_transform_auto(kg, sd, &sd->Ng);
97#ifdef __DPDU__
98 object_dir_transform_auto(kg, sd, &sd->dPdu);
99 object_dir_transform_auto(kg, sd, &sd->dPdv);
100#endif
101 }
102 }
103
104 sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
105
106 /* backfacing test */
107 const bool backfacing = (dot(sd->Ng, sd->wi) < 0.0f);
108
109 if (backfacing) {
110 sd->flag |= SD_BACKFACING;
111 sd->Ng = -sd->Ng;
112 sd->N = -sd->N;
113#ifdef __DPDU__
114 sd->dPdu = -sd->dPdu;
115 sd->dPdv = -sd->dPdv;
116#endif
117 }
118
119#ifdef __RAY_DIFFERENTIALS__
120 /* differentials */
121 sd->dP = differential_transfer_compact(ray->dP, ray->D, ray->dD, sd->ray_length);
122 sd->dI = differential_incoming_compact(ray->dD);
123 differential_dudv_compact(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
124#endif
125}
126
127/* ShaderData setup from position sampled on mesh */
128
130 ccl_private ShaderData *ccl_restrict sd,
131 const float3 P,
132 const float3 Ng,
133 const float3 I,
134 const int shader,
135 const int object,
136 const int prim,
137 const float u,
138 const float v,
139 const float t,
140 const float time,
141 const bool object_space,
142 const bool is_lamp)
143{
144 /* vectors */
145 sd->P = P;
146 sd->N = Ng;
147 sd->Ng = Ng;
148 sd->wi = I;
149 sd->shader = shader;
150 if (is_lamp) {
151 sd->type = PRIMITIVE_LAMP;
152 }
153 else if (prim != PRIM_NONE) {
154 sd->type = PRIMITIVE_TRIANGLE;
155 }
156 else {
157 sd->type = PRIMITIVE_NONE;
158 }
159
160 /* primitive */
161 sd->object = object;
162 /* Currently no access to bvh prim index for strand sd->prim. */
163 sd->prim = prim;
164 sd->u = u;
165 sd->v = v;
166 sd->time = time;
167 sd->ray_length = t;
168
169 sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
170 sd->object_flag = 0;
171 if (sd->object != OBJECT_NONE) {
172 sd->object_flag |= kernel_data_fetch(object_flag, sd->object);
173
174#ifdef __OBJECT_MOTION__
175 shader_setup_object_transforms(kg, sd, time);
176#endif
177
178 /* transform into world space */
179 if (object_space) {
180 object_position_transform_auto(kg, sd, &sd->P);
181 object_normal_transform_auto(kg, sd, &sd->Ng);
182 sd->N = sd->Ng;
183 object_dir_transform_auto(kg, sd, &sd->wi);
184 }
185
186 if (sd->type == PRIMITIVE_TRIANGLE) {
187 /* smooth normal */
188 if (sd->shader & SHADER_SMOOTH_NORMAL) {
189 sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
190
191 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
192 object_normal_transform_auto(kg, sd, &sd->N);
193 }
194 }
195
196 /* dPdu/dPdv */
197#ifdef __DPDU__
198 triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
199
200 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
201 object_dir_transform_auto(kg, sd, &sd->dPdu);
202 object_dir_transform_auto(kg, sd, &sd->dPdv);
203 }
204#endif
205 }
206 else {
207#ifdef __DPDU__
208 sd->dPdu = zero_float3();
209 sd->dPdv = zero_float3();
210#endif
211 }
212 }
213 else {
214#ifdef __DPDU__
215 sd->dPdu = zero_float3();
216 sd->dPdv = zero_float3();
217#endif
218 }
219
220 /* backfacing test */
221 if (sd->prim != PRIM_NONE) {
222 const bool backfacing = (dot(sd->Ng, sd->wi) < 0.0f);
223
224 if (backfacing) {
225 sd->flag |= SD_BACKFACING;
226 sd->Ng = -sd->Ng;
227 sd->N = -sd->N;
228#ifdef __DPDU__
229 sd->dPdu = -sd->dPdu;
230 sd->dPdv = -sd->dPdv;
231#endif
232 }
233 }
234
235#ifdef __RAY_DIFFERENTIALS__
236 /* no ray differentials here yet */
237 sd->dP = differential_zero_compact();
238 sd->dI = differential_zero_compact();
239 sd->du = differential_zero();
240 sd->dv = differential_zero();
241#endif
242}
243
244/* ShaderData setup for displacement */
245
247 ccl_private ShaderData *ccl_restrict sd,
248 const int object,
249 const int prim,
250 const float u,
251 const float v)
252{
253 float3 P;
254 float3 Ng;
255 const float3 I = zero_float3();
256 int shader;
257
258 triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
259
260 /* force smooth shading for displacement */
261 shader |= SHADER_SMOOTH_NORMAL;
262
264 sd,
265 P,
266 Ng,
267 I,
268 shader,
269 object,
270 prim,
271 u,
272 v,
273 0.0f,
274 0.5f,
275 !(kernel_data_fetch(object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
276 false);
277
278 /* Assign some incoming direction to avoid division by zero. */
279 sd->wi = sd->N;
280}
281
282/* ShaderData setup for point on curve. */
283
284#ifdef __HAIR__
285ccl_device void shader_setup_from_curve(KernelGlobals kg,
286 ccl_private ShaderData *ccl_restrict sd,
287 const int object,
288 const int prim,
289 const int segment,
290 const float u)
291{
292 /* Primitive */
294 sd->prim = prim;
295 sd->u = u;
296 sd->v = 0.0f;
297 sd->time = 0.5f;
298 sd->ray_length = 0.0f;
299
300 /* Shader */
301 sd->shader = kernel_data_fetch(curves, prim).shader_id;
302 sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
303
304 /* Object */
305 sd->object = object;
306 sd->object_flag = kernel_data_fetch(object_flag, sd->object);
307# ifdef __OBJECT_MOTION__
308 shader_setup_object_transforms(kg, sd, sd->time);
309# endif
310
311 /* Get control points. */
312 const KernelCurve kcurve = kernel_data_fetch(curves, prim);
313
314 const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
315 const int k1 = k0 + 1;
316 const int ka = max(k0 - 1, kcurve.first_key);
317 const int kb = min(k1 + 1, kcurve.first_key + kcurve.num_keys - 1);
318
319 float4 P_curve[4];
320
321 P_curve[0] = kernel_data_fetch(curve_keys, ka);
322 P_curve[1] = kernel_data_fetch(curve_keys, k0);
323 P_curve[2] = kernel_data_fetch(curve_keys, k1);
324 P_curve[3] = kernel_data_fetch(curve_keys, kb);
325
326 /* Interpolate position and tangent. */
327 sd->P = make_float3(catmull_rom_basis_eval(P_curve, sd->u));
328# ifdef __DPDU__
329 sd->dPdu = make_float3(catmull_rom_basis_derivative(P_curve, sd->u));
330# endif
331
332 /* Transform into world space */
333 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
334 object_position_transform_auto(kg, sd, &sd->P);
335# ifdef __DPDU__
336 object_dir_transform_auto(kg, sd, &sd->dPdu);
337# endif
338 }
339
340 /* Pick arbitrary view direction, normals and bitangent to avoid NaNs elsewhere. */
341 sd->wi = normalize(cross(make_float3(0, 1, 0), sd->dPdu));
342 sd->N = sd->wi;
343 sd->Ng = sd->wi;
344# ifdef __DPDU__
345 sd->dPdv = cross(sd->dPdu, sd->Ng);
346# endif
347
348 /* No ray differentials currently. */
349# ifdef __RAY_DIFFERENTIALS__
350 sd->dP = differential_zero_compact();
351 sd->dI = differential_zero_compact();
352 sd->du = differential_zero();
353 sd->dv = differential_zero();
354# endif
355}
356#endif /* __HAIR__ */
357
358/* ShaderData setup from ray into background */
359
361 ccl_private ShaderData *ccl_restrict sd,
362 const float3 ray_P,
363 const float3 ray_D,
364 const float ray_time)
365{
366 /* for NDC coordinates */
367 sd->ray_P = ray_P;
368
369 /* vectors */
370 sd->P = ray_D;
371 sd->N = -ray_D;
372 sd->Ng = -ray_D;
373 sd->wi = -ray_D;
374 sd->shader = kernel_data.background.surface_shader;
375 sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
376 sd->object_flag = 0;
377 sd->time = ray_time;
378 sd->ray_length = FLT_MAX;
379
380 sd->object = OBJECT_NONE;
381 sd->prim = PRIM_NONE;
382 sd->type = PRIMITIVE_NONE;
383 sd->u = 0.0f;
384 sd->v = 0.0f;
385
386#ifdef __DPDU__
387 /* dPdu/dPdv */
388 sd->dPdu = zero_float3();
389 sd->dPdv = zero_float3();
390#endif
391
392#ifdef __RAY_DIFFERENTIALS__
393 /* differentials */
394 sd->dP = differential_zero_compact(); /* TODO: ray->dP */
395 sd->dI = differential_zero_compact();
396 sd->du = differential_zero();
397 sd->dv = differential_zero();
398#endif
399}
400
401/* ShaderData setup from point inside volume */
402
403#ifdef __VOLUME__
404ccl_device_inline void shader_setup_from_volume(KernelGlobals kg,
405 ccl_private ShaderData *ccl_restrict sd,
406 const ccl_private Ray *ccl_restrict ray,
407 const int object)
408{
409
410 /* vectors */
411 sd->P = ray->P + ray->D * ray->tmin;
412 sd->N = -ray->D;
413 sd->Ng = -ray->D;
414 sd->wi = -ray->D;
415 sd->shader = SHADER_NONE;
416 sd->flag = 0;
417 sd->object_flag = 0;
418 sd->time = ray->time;
419 sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
420
421 /* TODO: fill relevant fields for texture coordinates. */
422 sd->object = object;
423 sd->prim = PRIM_NONE;
424 sd->type = PRIMITIVE_VOLUME;
425
426 sd->u = 0.0f;
427 sd->v = 0.0f;
428
429# ifdef __DPDU__
430 /* dPdu/dPdv */
431 sd->dPdu = zero_float3();
432 sd->dPdv = zero_float3();
433# endif
434
435# ifdef __RAY_DIFFERENTIALS__
436 /* differentials */
437 sd->dP = differential_zero_compact(); /* TODO ray->dD */
438 sd->dI = differential_zero_compact();
439 sd->du = differential_zero();
440 sd->dv = differential_zero();
441# endif
442
443 /* for NDC coordinates */
444 sd->ray_P = ray->P;
445}
446#endif /* __VOLUME__ */
447
ATTR_WARN_UNUSED_RESULT const BMVert * v
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define PRIMITIVE_PACK_SEGMENT(type, segment)
#define kernel_data
#define ccl_restrict
#define kernel_data_fetch(name, index)
#define SHADER_NONE
#define PRIM_NONE
#define PRIMITIVE_UNPACK_SEGMENT(type)
#define ccl_device
#define OBJECT_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_forceinline float differential_transfer_compact(const float ray_dP, const float3, const float ray_dD, const float ray_t)
ccl_device_forceinline float differential_incoming_compact(const float dD)
ccl_device differential differential_zero()
ccl_device void differential_dudv_compact(ccl_private differential *du, ccl_private differential *dv, const float3 dPdu, const float3 dPdv, const float dP, const float3 Ng)
ccl_device_forceinline float differential_zero_compact()
ccl_device_inline void triangle_dPdudv(KernelGlobals kg, const int prim, ccl_private float3 *dPdu, ccl_private float3 *dPdv)
ccl_device_inline float3 triangle_smooth_normal(KernelGlobals kg, const float3 Ng, const int prim, const float u, float v)
ccl_device_inline void triangle_point_normal(KernelGlobals kg, const int object, const int prim, const float u, const float v, ccl_private float3 *P, ccl_private float3 *Ng, ccl_private int *shader)
VecBase< float, 4 > float4
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
#define object_normal_transform_auto
#define object_position_transform_auto
#define object_dir_transform_auto
@ SD_BACKFACING
@ PRIMITIVE_LAMP
@ PRIMITIVE_NONE
@ PRIMITIVE_VOLUME
@ PRIMITIVE_CURVE
@ PRIMITIVE_CURVE_THICK
@ PRIMITIVE_TRIANGLE
@ PRIMITIVE_POINT
@ SHADER_SMOOTH_NORMAL
@ SHADER_MASK
@ SD_OBJECT_MOTION
@ SD_OBJECT_TRANSFORM_APPLIED
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
CCL_NAMESPACE_BEGIN ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals kg, ccl_private ShaderData *sd)
#define I
ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float3 P, const float3 Ng, const float3 I, const int shader, const int object, const int prim, const float u, const float v, const float t, const float time, const bool object_space, const bool is_lamp)
ccl_device void shader_setup_from_displace(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const int object, const int prim, const float u, const float v)
ccl_device_inline void shader_setup_from_background(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float3 ray_P, const float3 ray_D, const float ray_time)
ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const ccl_private Ray *ccl_restrict ray, const ccl_private Intersection *ccl_restrict isect)
Definition shader_data.h:39
CCL_NAMESPACE_BEGIN ccl_device void shader_setup_object_transforms(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float time)
Definition shader_data.h:25
#define min(a, b)
Definition sort.cc:36
#define FLT_MAX
Definition stdcycles.h:14
max
Definition text_draw.cc:251
ccl_device_inline Transform transform_inverse(const Transform tfm)
Definition transform.h:492
ccl_device_inline void triangle_shader_setup(KernelGlobals kg, ccl_private ShaderData *sd)