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