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