Blender V4.3
subd_triangle.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 for retrieving attributes on triangles produced from subdivision meshes */
6
7#pragma once
8
10
11/* UV coords of triangle within patch */
12
14 ccl_private const ShaderData *sd,
15 float2 uv[3])
16{
17 uint3 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
18
19 uv[0] = kernel_data_fetch(tri_patch_uv, tri_vindex.x);
20 uv[1] = kernel_data_fetch(tri_patch_uv, tri_vindex.y);
21 uv[2] = kernel_data_fetch(tri_patch_uv, tri_vindex.z);
22}
23
24/* Vertex indices of patch */
25
27{
29
30 indices.x = kernel_data_fetch(patches, patch + 0);
31 indices.y = kernel_data_fetch(patches, patch + 1);
32 indices.z = kernel_data_fetch(patches, patch + 2);
33 indices.w = kernel_data_fetch(patches, patch + 3);
34
35 return indices;
36}
37
38/* Originating face for patch */
39
41{
42 return kernel_data_fetch(patches, patch + 4);
43}
44
45/* Number of corners on originating face */
46
48{
49 return kernel_data_fetch(patches, patch + 5) & 0xffff;
50}
51
52/* Indices of the four corners that are used by the patch */
53
55{
56 uint4 data;
57
58 data.x = kernel_data_fetch(patches, patch + 4);
59 data.y = kernel_data_fetch(patches, patch + 5);
60 data.z = kernel_data_fetch(patches, patch + 6);
61 data.w = kernel_data_fetch(patches, patch + 7);
62
63 int num_corners = data.y & 0xffff;
64
65 if (num_corners == 4) {
66 /* quad */
67 corners[0] = data.z;
68 corners[1] = data.z + 1;
69 corners[2] = data.z + 2;
70 corners[3] = data.z + 3;
71 }
72 else {
73 /* ngon */
74 int c = data.y >> 16;
75
76 corners[0] = data.z + c;
77 corners[1] = data.z + mod(c + 1, num_corners);
78 corners[2] = data.w;
79 corners[3] = data.z + mod(c - 1, num_corners);
80 }
81}
82
83/* Reading attributes on various subdivision triangle elements */
84
86 ccl_private const ShaderData *sd,
87 const AttributeDescriptor desc,
88 ccl_private float *dx,
89 ccl_private float *dy)
90{
91 int patch = subd_triangle_patch(kg, sd->prim);
92
93#ifdef __PATCH_EVAL__
94 if (desc.flags & ATTR_SUBDIVIDED) {
95 float2 uv[3];
96 subd_triangle_patch_uv(kg, sd, uv);
97
98 float2 dpdu = uv[1] - uv[0];
99 float2 dpdv = uv[2] - uv[0];
100
101 /* p is [s, t] */
102 float2 p = dpdu * sd->u + dpdv * sd->v + uv[0];
103
104 float a, dads, dadt;
105 a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
106
107# ifdef __RAY_DIFFERENTIALS__
108 if (dx || dy) {
109 float dsdu = dpdu.x;
110 float dtdu = dpdu.y;
111 float dsdv = dpdv.x;
112 float dtdv = dpdv.y;
113
114 if (dx) {
115 float dudx = sd->du.dx;
116 float dvdx = sd->dv.dx;
117
118 float dsdx = dsdu * dudx + dsdv * dvdx;
119 float dtdx = dtdu * dudx + dtdv * dvdx;
120
121 *dx = dads * dsdx + dadt * dtdx;
122 }
123 if (dy) {
124 float dudy = sd->du.dy;
125 float dvdy = sd->dv.dy;
126
127 float dsdy = dsdu * dudy + dsdv * dvdy;
128 float dtdy = dtdu * dudy + dtdv * dvdy;
129
130 *dy = dads * dsdy + dadt * dtdy;
131 }
132 }
133# endif
134
135 return a;
136 }
137 else
138#endif /* __PATCH_EVAL__ */
139 if (desc.element == ATTR_ELEMENT_FACE) {
140 if (dx)
141 *dx = 0.0f;
142 if (dy)
143 *dy = 0.0f;
144
145 return kernel_data_fetch(attributes_float,
146 desc.offset + subd_triangle_patch_face(kg, patch));
147 }
149 float2 uv[3];
150 subd_triangle_patch_uv(kg, sd, uv);
151
153
154 float f0 = kernel_data_fetch(attributes_float, desc.offset + v.x);
155 float f1 = kernel_data_fetch(attributes_float, desc.offset + v.y);
156 float f2 = kernel_data_fetch(attributes_float, desc.offset + v.z);
157 float f3 = kernel_data_fetch(attributes_float, desc.offset + v.w);
158
159 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
160 f1 = (f1 + f0) * 0.5f;
161 f3 = (f3 + f0) * 0.5f;
162 }
163
164 float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
165 float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
166 float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
167
168#ifdef __RAY_DIFFERENTIALS__
169 if (dx)
170 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
171 if (dy)
172 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
173#endif
174
175 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
176 }
177 else if (desc.element == ATTR_ELEMENT_CORNER) {
178 float2 uv[3];
179 subd_triangle_patch_uv(kg, sd, uv);
180
181 int corners[4];
182 subd_triangle_patch_corners(kg, patch, corners);
183
184 float f0 = kernel_data_fetch(attributes_float, corners[0] + desc.offset);
185 float f1 = kernel_data_fetch(attributes_float, corners[1] + desc.offset);
186 float f2 = kernel_data_fetch(attributes_float, corners[2] + desc.offset);
187 float f3 = kernel_data_fetch(attributes_float, corners[3] + desc.offset);
188
189 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
190 f1 = (f1 + f0) * 0.5f;
191 f3 = (f3 + f0) * 0.5f;
192 }
193
194 float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
195 float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
196 float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
197
198#ifdef __RAY_DIFFERENTIALS__
199 if (dx)
200 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
201 if (dy)
202 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
203#endif
204
205 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
206 }
207 else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
208 if (dx)
209 *dx = 0.0f;
210 if (dy)
211 *dy = 0.0f;
212
213 return kernel_data_fetch(attributes_float, desc.offset);
214 }
215 else {
216 if (dx)
217 *dx = 0.0f;
218 if (dy)
219 *dy = 0.0f;
220
221 return 0.0f;
222 }
223}
224
226 ccl_private const ShaderData *sd,
227 const AttributeDescriptor desc,
230{
231 int patch = subd_triangle_patch(kg, sd->prim);
232
233#ifdef __PATCH_EVAL__
234 if (desc.flags & ATTR_SUBDIVIDED) {
235 float2 uv[3];
236 subd_triangle_patch_uv(kg, sd, uv);
237
238 float2 dpdu = uv[1] - uv[0];
239 float2 dpdv = uv[2] - uv[0];
240
241 /* p is [s, t] */
242 float2 p = dpdu * sd->u + dpdv * sd->v + uv[0];
243
244 float2 a, dads, dadt;
245
246 a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
247
248# ifdef __RAY_DIFFERENTIALS__
249 if (dx || dy) {
250 float dsdu = dpdu.x;
251 float dtdu = dpdu.y;
252 float dsdv = dpdv.x;
253 float dtdv = dpdv.y;
254
255 if (dx) {
256 float dudx = sd->du.dx;
257 float dvdx = sd->dv.dx;
258
259 float dsdx = dsdu * dudx + dsdv * dvdx;
260 float dtdx = dtdu * dudx + dtdv * dvdx;
261
262 *dx = dads * dsdx + dadt * dtdx;
263 }
264 if (dy) {
265 float dudy = sd->du.dy;
266 float dvdy = sd->dv.dy;
267
268 float dsdy = dsdu * dudy + dsdv * dvdy;
269 float dtdy = dtdu * dudy + dtdv * dvdy;
270
271 *dy = dads * dsdy + dadt * dtdy;
272 }
273 }
274# endif
275
276 return a;
277 }
278 else
279#endif /* __PATCH_EVAL__ */
280 if (desc.element == ATTR_ELEMENT_FACE) {
281 if (dx)
282 *dx = make_float2(0.0f, 0.0f);
283 if (dy)
284 *dy = make_float2(0.0f, 0.0f);
285
286 return kernel_data_fetch(attributes_float2,
287 desc.offset + subd_triangle_patch_face(kg, patch));
288 }
290 float2 uv[3];
291 subd_triangle_patch_uv(kg, sd, uv);
292
294
295 float2 f0 = kernel_data_fetch(attributes_float2, desc.offset + v.x);
296 float2 f1 = kernel_data_fetch(attributes_float2, desc.offset + v.y);
297 float2 f2 = kernel_data_fetch(attributes_float2, desc.offset + v.z);
298 float2 f3 = kernel_data_fetch(attributes_float2, desc.offset + v.w);
299
300 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
301 f1 = (f1 + f0) * 0.5f;
302 f3 = (f3 + f0) * 0.5f;
303 }
304
305 float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
306 float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
307 float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
308
309#ifdef __RAY_DIFFERENTIALS__
310 if (dx)
311 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
312 if (dy)
313 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
314#endif
315
316 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
317 }
318 else if (desc.element == ATTR_ELEMENT_CORNER) {
319 float2 uv[3];
320 subd_triangle_patch_uv(kg, sd, uv);
321
322 int corners[4];
323 subd_triangle_patch_corners(kg, patch, corners);
324
325 float2 f0, f1, f2, f3;
326
327 f0 = kernel_data_fetch(attributes_float2, corners[0] + desc.offset);
328 f1 = kernel_data_fetch(attributes_float2, corners[1] + desc.offset);
329 f2 = kernel_data_fetch(attributes_float2, corners[2] + desc.offset);
330 f3 = kernel_data_fetch(attributes_float2, corners[3] + desc.offset);
331
332 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
333 f1 = (f1 + f0) * 0.5f;
334 f3 = (f3 + f0) * 0.5f;
335 }
336
337 float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
338 float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
339 float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
340
341#ifdef __RAY_DIFFERENTIALS__
342 if (dx)
343 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
344 if (dy)
345 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
346#endif
347
348 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
349 }
350 else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
351 if (dx)
352 *dx = make_float2(0.0f, 0.0f);
353 if (dy)
354 *dy = make_float2(0.0f, 0.0f);
355
356 return kernel_data_fetch(attributes_float2, desc.offset);
357 }
358 else {
359 if (dx)
360 *dx = make_float2(0.0f, 0.0f);
361 if (dy)
362 *dy = make_float2(0.0f, 0.0f);
363
364 return make_float2(0.0f, 0.0f);
365 }
366}
367
369 ccl_private const ShaderData *sd,
370 const AttributeDescriptor desc,
373{
374 int patch = subd_triangle_patch(kg, sd->prim);
375
376#ifdef __PATCH_EVAL__
377 if (desc.flags & ATTR_SUBDIVIDED) {
378 float2 uv[3];
379 subd_triangle_patch_uv(kg, sd, uv);
380
381 float2 dpdu = uv[1] - uv[0];
382 float2 dpdv = uv[2] - uv[0];
383
384 /* p is [s, t] */
385 float2 p = dpdu * sd->u + dpdv * sd->v + uv[0];
386
387 float3 a, dads, dadt;
388 a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
389
390# ifdef __RAY_DIFFERENTIALS__
391 if (dx || dy) {
392 float dsdu = dpdu.x;
393 float dtdu = dpdu.y;
394 float dsdv = dpdv.x;
395 float dtdv = dpdv.y;
396
397 if (dx) {
398 float dudx = sd->du.dx;
399 float dvdx = sd->dv.dx;
400
401 float dsdx = dsdu * dudx + dsdv * dvdx;
402 float dtdx = dtdu * dudx + dtdv * dvdx;
403
404 *dx = dads * dsdx + dadt * dtdx;
405 }
406 if (dy) {
407 float dudy = sd->du.dy;
408 float dvdy = sd->dv.dy;
409
410 float dsdy = dsdu * dudy + dsdv * dvdy;
411 float dtdy = dtdu * dudy + dtdv * dvdy;
412
413 *dy = dads * dsdy + dadt * dtdy;
414 }
415 }
416# endif
417
418 return a;
419 }
420 else
421#endif /* __PATCH_EVAL__ */
422 if (desc.element == ATTR_ELEMENT_FACE) {
423 if (dx)
424 *dx = make_float3(0.0f, 0.0f, 0.0f);
425 if (dy)
426 *dy = make_float3(0.0f, 0.0f, 0.0f);
427
428 return kernel_data_fetch(attributes_float3,
429 desc.offset + subd_triangle_patch_face(kg, patch));
430 }
432 float2 uv[3];
433 subd_triangle_patch_uv(kg, sd, uv);
434
436
437 float3 f0 = kernel_data_fetch(attributes_float3, desc.offset + v.x);
438 float3 f1 = kernel_data_fetch(attributes_float3, desc.offset + v.y);
439 float3 f2 = kernel_data_fetch(attributes_float3, desc.offset + v.z);
440 float3 f3 = kernel_data_fetch(attributes_float3, desc.offset + v.w);
441
442 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
443 f1 = (f1 + f0) * 0.5f;
444 f3 = (f3 + f0) * 0.5f;
445 }
446
447 float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
448 float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
449 float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
450
451#ifdef __RAY_DIFFERENTIALS__
452 if (dx)
453 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
454 if (dy)
455 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
456#endif
457
458 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
459 }
460 else if (desc.element == ATTR_ELEMENT_CORNER) {
461 float2 uv[3];
462 subd_triangle_patch_uv(kg, sd, uv);
463
464 int corners[4];
465 subd_triangle_patch_corners(kg, patch, corners);
466
467 float3 f0, f1, f2, f3;
468
469 f0 = kernel_data_fetch(attributes_float3, corners[0] + desc.offset);
470 f1 = kernel_data_fetch(attributes_float3, corners[1] + desc.offset);
471 f2 = kernel_data_fetch(attributes_float3, corners[2] + desc.offset);
472 f3 = kernel_data_fetch(attributes_float3, corners[3] + desc.offset);
473
474 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
475 f1 = (f1 + f0) * 0.5f;
476 f3 = (f3 + f0) * 0.5f;
477 }
478
479 float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
480 float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
481 float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
482
483#ifdef __RAY_DIFFERENTIALS__
484 if (dx)
485 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
486 if (dy)
487 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
488#endif
489
490 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
491 }
492 else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
493 if (dx)
494 *dx = make_float3(0.0f, 0.0f, 0.0f);
495 if (dy)
496 *dy = make_float3(0.0f, 0.0f, 0.0f);
497
498 return kernel_data_fetch(attributes_float3, desc.offset);
499 }
500 else {
501 if (dx)
502 *dx = make_float3(0.0f, 0.0f, 0.0f);
503 if (dy)
504 *dy = make_float3(0.0f, 0.0f, 0.0f);
505
506 return make_float3(0.0f, 0.0f, 0.0f);
507 }
508}
509
511 ccl_private const ShaderData *sd,
512 const AttributeDescriptor desc,
513 ccl_private float4 *dx,
514 ccl_private float4 *dy)
515{
516 int patch = subd_triangle_patch(kg, sd->prim);
517
518#ifdef __PATCH_EVAL__
519 if (desc.flags & ATTR_SUBDIVIDED) {
520 float2 uv[3];
521 subd_triangle_patch_uv(kg, sd, uv);
522
523 float2 dpdu = uv[1] - uv[0];
524 float2 dpdv = uv[2] - uv[0];
525
526 /* p is [s, t] */
527 float2 p = dpdu * sd->u + dpdv * sd->v + uv[0];
528
529 float4 a, dads, dadt;
530 if (desc.type == NODE_ATTR_RGBA) {
531 a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
532 }
533 else {
534 a = patch_eval_float4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
535 }
536
537# ifdef __RAY_DIFFERENTIALS__
538 if (dx || dy) {
539 float dsdu = dpdu.x;
540 float dtdu = dpdu.y;
541 float dsdv = dpdv.x;
542 float dtdv = dpdv.y;
543
544 if (dx) {
545 float dudx = sd->du.dx;
546 float dvdx = sd->dv.dx;
547
548 float dsdx = dsdu * dudx + dsdv * dvdx;
549 float dtdx = dtdu * dudx + dtdv * dvdx;
550
551 *dx = dads * dsdx + dadt * dtdx;
552 }
553 if (dy) {
554 float dudy = sd->du.dy;
555 float dvdy = sd->dv.dy;
556
557 float dsdy = dsdu * dudy + dsdv * dvdy;
558 float dtdy = dtdu * dudy + dtdv * dvdy;
559
560 *dy = dads * dsdy + dadt * dtdy;
561 }
562 }
563# endif
564
565 return a;
566 }
567 else
568#endif /* __PATCH_EVAL__ */
569 if (desc.element == ATTR_ELEMENT_FACE) {
570 if (dx)
571 *dx = zero_float4();
572 if (dy)
573 *dy = zero_float4();
574
575 return kernel_data_fetch(attributes_float4,
576 desc.offset + subd_triangle_patch_face(kg, patch));
577 }
579 float2 uv[3];
580 subd_triangle_patch_uv(kg, sd, uv);
581
583
584 float4 f0 = kernel_data_fetch(attributes_float4, desc.offset + v.x);
585 float4 f1 = kernel_data_fetch(attributes_float4, desc.offset + v.y);
586 float4 f2 = kernel_data_fetch(attributes_float4, desc.offset + v.z);
587 float4 f3 = kernel_data_fetch(attributes_float4, desc.offset + v.w);
588
589 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
590 f1 = (f1 + f0) * 0.5f;
591 f3 = (f3 + f0) * 0.5f;
592 }
593
594 float4 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
595 float4 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
596 float4 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
597
598#ifdef __RAY_DIFFERENTIALS__
599 if (dx)
600 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
601 if (dy)
602 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
603#endif
604
605 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
606 }
607 else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
608 float2 uv[3];
609 subd_triangle_patch_uv(kg, sd, uv);
610
611 int corners[4];
612 subd_triangle_patch_corners(kg, patch, corners);
613
614 float4 f0, f1, f2, f3;
615
616 if (desc.element == ATTR_ELEMENT_CORNER_BYTE) {
618 kernel_data_fetch(attributes_uchar4, corners[0] + desc.offset)));
620 kernel_data_fetch(attributes_uchar4, corners[1] + desc.offset)));
622 kernel_data_fetch(attributes_uchar4, corners[2] + desc.offset)));
624 kernel_data_fetch(attributes_uchar4, corners[3] + desc.offset)));
625 }
626 else {
627 f0 = kernel_data_fetch(attributes_float4, corners[0] + desc.offset);
628 f1 = kernel_data_fetch(attributes_float4, corners[1] + desc.offset);
629 f2 = kernel_data_fetch(attributes_float4, corners[2] + desc.offset);
630 f3 = kernel_data_fetch(attributes_float4, corners[3] + desc.offset);
631 }
632
633 if (subd_triangle_patch_num_corners(kg, patch) != 4) {
634 f1 = (f1 + f0) * 0.5f;
635 f3 = (f3 + f0) * 0.5f;
636 }
637
638 float4 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
639 float4 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
640 float4 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
641
642#ifdef __RAY_DIFFERENTIALS__
643 if (dx)
644 *dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
645 if (dy)
646 *dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
647#endif
648
649 return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
650 }
651 else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
652 if (dx)
653 *dx = zero_float4();
654 if (dy)
655 *dy = zero_float4();
656
657 return kernel_data_fetch(attributes_float4, desc.offset);
658 }
659 else {
660 if (dx)
661 *dx = zero_float4();
662 if (dy)
663 *dy = zero_float4();
664
665 return zero_float4();
666 }
667}
668
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v
local_group_size(16, 16) .push_constant(Type b
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_private
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_forceinline float2 make_float2(const float x, const float y)
static ushort indices[]
#define mix(a, b, c)
Definition hash.h:36
CCL_NAMESPACE_BEGIN ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, int prim)
ccl_device float patch_eval_float(KernelGlobals kg, ccl_private const ShaderData *sd, int offset, int patch, float u, float v, int channel, ccl_private float *du, ccl_private float *dv)
ccl_device float2 patch_eval_float2(KernelGlobals kg, ccl_private const ShaderData *sd, int offset, int patch, float u, float v, int channel, ccl_private float2 *du, ccl_private float2 *dv)
ccl_device float3 patch_eval_float3(KernelGlobals kg, ccl_private const ShaderData *sd, int offset, int patch, float u, float v, int channel, ccl_private float3 *du, ccl_private float3 *dv)
ccl_device float4 patch_eval_float4(KernelGlobals kg, ccl_private const ShaderData *sd, int offset, int patch, float u, float v, int channel, ccl_private float4 *du, ccl_private float4 *dv)
ccl_device float4 patch_eval_uchar4(KernelGlobals kg, ccl_private const ShaderData *sd, int offset, int patch, float u, float v, int channel, ccl_private float4 *du, ccl_private float4 *dv)
@ NODE_ATTR_RGBA
@ ATTR_SUBDIVIDED
ShaderData
@ ATTR_ELEMENT_CORNER_BYTE
@ ATTR_ELEMENT_CORNER
@ ATTR_ELEMENT_OBJECT
@ ATTR_ELEMENT_VERTEX_MOTION
@ ATTR_ELEMENT_VERTEX
@ ATTR_ELEMENT_FACE
@ ATTR_ELEMENT_MESH
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
Definition math_float4.h:15
AttributeElement element
NodeAttributeType type
float x
float y
uint y
Definition types_uint3.h:15
uint z
Definition types_uint3.h:15
uint x
Definition types_uint3.h:15
uint x
Definition types_uint4.h:15
ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float3 *dx, ccl_private float3 *dy)
ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float4 *dx, ccl_private float4 *dy)
ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals kg, int patch)
ccl_device_inline uint subd_triangle_patch_face(KernelGlobals kg, int patch)
ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float *dx, ccl_private float *dy)
ccl_device_inline void subd_triangle_patch_corners(KernelGlobals kg, int patch, int corners[4])
ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals kg, int patch)
ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float2 *dx, ccl_private float2 *dy)
CCL_NAMESPACE_BEGIN ccl_device_inline void subd_triangle_patch_uv(KernelGlobals kg, ccl_private const ShaderData *sd, float2 uv[3])
ccl_device_inline float4 color_uchar4_to_float4(uchar4 c)
Definition util/color.h:56
ccl_device float4 color_srgb_to_linear_v4(float4 c)
Definition util/color.h:327
ccl_device_inline int mod(int x, int m)
Definition util/math.h:520