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