647840dc696924bff0859266791a567fa39f84b0
[blender.git] / intern / cycles / kernel / geom / geom_subd_triangle.h
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
19 CCL_NAMESPACE_BEGIN
20
21 /* Patch index for triangle, -1 if not subdivision triangle */
22
23 ccl_device_inline uint subd_triangle_patch(KernelGlobals *kg, const ShaderData *sd)
24 {
25         return (ccl_fetch(sd, prim) != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, ccl_fetch(sd, prim)) : ~0;
26 }
27
28 /* UV coords of triangle within patch */
29
30 ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg, const ShaderData *sd, float2 uv[3])
31 {
32         uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
33
34         uv[0] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.x);
35         uv[1] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.y);
36         uv[2] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.z);
37 }
38
39 /* Vertex indices of patch */
40
41 ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals *kg, int patch)
42 {
43         uint4 indices;
44
45         indices.x = kernel_tex_fetch(__patches, patch+0);
46         indices.y = kernel_tex_fetch(__patches, patch+1);
47         indices.z = kernel_tex_fetch(__patches, patch+2);
48         indices.w = kernel_tex_fetch(__patches, patch+3);
49
50         return indices;
51 }
52
53 /* Originating face for patch */
54
55 ccl_device_inline uint subd_triangle_patch_face(KernelGlobals *kg, int patch)
56 {
57         return kernel_tex_fetch(__patches, patch+4);
58 }
59
60 /* Number of corners on originating face */
61
62 ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals *kg, int patch)
63 {
64         return kernel_tex_fetch(__patches, patch+5) & 0xffff;
65 }
66
67 /* Indices of the four corners that are used by the patch */
68
69 ccl_device_inline void subd_triangle_patch_corners(KernelGlobals *kg, int patch, int corners[4])
70 {
71         uint4 data;
72
73         data.x = kernel_tex_fetch(__patches, patch+4);
74         data.y = kernel_tex_fetch(__patches, patch+5);
75         data.z = kernel_tex_fetch(__patches, patch+6);
76         data.w = kernel_tex_fetch(__patches, patch+7);
77
78         int num_corners = data.y & 0xffff;
79
80         if(num_corners == 4) {
81                 /* quad */
82                 corners[0] = data.z;
83                 corners[1] = data.z+1;
84                 corners[2] = data.z+2;
85                 corners[3] = data.z+3;
86         }
87         else {
88                 /* ngon */
89                 int c = data.y >> 16;
90
91                 corners[0] = data.z + c;
92                 corners[1] = data.z + mod(c+1, num_corners);
93                 corners[2] = data.w;
94                 corners[3] = data.z + mod(c-1, num_corners);
95         }
96 }
97
98 /* Reading attributes on various subdivision triangle elements */
99
100 ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
101 {
102         int patch = subd_triangle_patch(kg, sd);
103
104 #ifdef __PATCH_EVAL__
105         if(desc.flags & ATTR_SUBDIVIDED) {
106                 float2 uv[3];
107                 subd_triangle_patch_uv(kg, sd, uv);
108
109                 float2 dpdu = uv[0] - uv[2];
110                 float2 dpdv = uv[1] - uv[2];
111
112                 /* p is [s, t] */
113                 float2 p = dpdu * ccl_fetch(sd, u) + dpdv * ccl_fetch(sd, v) + uv[2];
114
115                 float a, dads, dadt;
116                 a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
117
118 #ifdef __RAY_DIFFERENTIALS__
119                 if(dx || dy) {
120                         float dsdu = dpdu.x;
121                         float dtdu = dpdu.y;
122                         float dsdv = dpdv.x;
123                         float dtdv = dpdv.y;
124
125                         if(dx) {
126                                 float dudx = ccl_fetch(sd, du).dx;
127                                 float dvdx = ccl_fetch(sd, dv).dx;
128
129                                 float dsdx = dsdu*dudx + dsdv*dvdx;
130                                 float dtdx = dtdu*dudx + dtdv*dvdx;
131
132                                 *dx = dads*dsdx + dadt*dtdx;
133                         }
134                         if(dy) {
135                                 float dudy = ccl_fetch(sd, du).dy;
136                                 float dvdy = ccl_fetch(sd, dv).dy;
137
138                                 float dsdy = dsdu*dudy + dsdv*dvdy;
139                                 float dtdy = dtdu*dudy + dtdv*dvdy;
140
141                                 *dy = dads*dsdy + dadt*dtdy;
142                         }
143                 }
144 #endif
145
146                 return a;
147         }
148         else
149 #endif /* __PATCH_EVAL__ */
150         if(desc.element == ATTR_ELEMENT_FACE) {
151                 if(dx) *dx = 0.0f;
152                 if(dy) *dy = 0.0f;
153
154                 return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
155         }
156         else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
157                 float2 uv[3];
158                 subd_triangle_patch_uv(kg, sd, uv);
159
160                 uint4 v = subd_triangle_patch_indices(kg, patch);
161
162                 float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x);
163                 float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y);
164                 float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z);
165                 float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w);
166
167                 if(subd_triangle_patch_num_corners(kg, patch) != 4) {
168                         f1 = (f1+f0)*0.5f;
169                         f3 = (f3+f0)*0.5f;
170                 }
171
172                 float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
173                 float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
174                 float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
175
176 #ifdef __RAY_DIFFERENTIALS__
177                 if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
178                 if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
179 #endif
180
181                 return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
182         }
183         else if(desc.element == ATTR_ELEMENT_CORNER) {
184                 float2 uv[3];
185                 subd_triangle_patch_uv(kg, sd, uv);
186
187                 int corners[4];
188                 subd_triangle_patch_corners(kg, patch, corners);
189
190                 float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset);
191                 float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset);
192                 float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset);
193                 float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset);
194
195                 if(subd_triangle_patch_num_corners(kg, patch) != 4) {
196                         f1 = (f1+f0)*0.5f;
197                         f3 = (f3+f0)*0.5f;
198                 }
199
200                 float a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
201                 float b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
202                 float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
203
204 #ifdef __RAY_DIFFERENTIALS__
205                 if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
206                 if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
207 #endif
208
209                 return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
210         }
211         else {
212                 if(dx) *dx = 0.0f;
213                 if(dy) *dy = 0.0f;
214
215                 return 0.0f;
216         }
217 }
218
219 ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
220 {
221         int patch = subd_triangle_patch(kg, sd);
222
223 #ifdef __PATCH_EVAL__
224         if(desc.flags & ATTR_SUBDIVIDED) {
225                 float2 uv[3];
226                 subd_triangle_patch_uv(kg, sd, uv);
227
228                 float2 dpdu = uv[0] - uv[2];
229                 float2 dpdv = uv[1] - uv[2];
230
231                 /* p is [s, t] */
232                 float2 p = dpdu * ccl_fetch(sd, u) + dpdv * ccl_fetch(sd, v) + uv[2];
233
234                 float3 a, dads, dadt;
235
236                 if(desc.element == ATTR_ELEMENT_CORNER_BYTE) {
237                         a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
238                 }
239                 else {
240                         a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
241                 }
242
243 #ifdef __RAY_DIFFERENTIALS__
244                 if(dx || dy) {
245                         float dsdu = dpdu.x;
246                         float dtdu = dpdu.y;
247                         float dsdv = dpdv.x;
248                         float dtdv = dpdv.y;
249
250                         if(dx) {
251                                 float dudx = ccl_fetch(sd, du).dx;
252                                 float dvdx = ccl_fetch(sd, dv).dx;
253
254                                 float dsdx = dsdu*dudx + dsdv*dvdx;
255                                 float dtdx = dtdu*dudx + dtdv*dvdx;
256
257                                 *dx = dads*dsdx + dadt*dtdx;
258                         }
259                         if(dy) {
260                                 float dudy = ccl_fetch(sd, du).dy;
261                                 float dvdy = ccl_fetch(sd, dv).dy;
262
263                                 float dsdy = dsdu*dudy + dsdv*dvdy;
264                                 float dtdy = dtdu*dudy + dtdv*dvdy;
265
266                                 *dy = dads*dsdy + dadt*dtdy;
267                         }
268                 }
269 #endif
270
271                 return a;
272         }
273         else
274 #endif /* __PATCH_EVAL__ */
275         if(desc.element == ATTR_ELEMENT_FACE) {
276                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
277                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
278
279                 return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch)));
280         }
281         else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
282                 float2 uv[3];
283                 subd_triangle_patch_uv(kg, sd, uv);
284
285                 uint4 v = subd_triangle_patch_indices(kg, patch);
286
287                 float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x));
288                 float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y));
289                 float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z));
290                 float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w));
291
292                 if(subd_triangle_patch_num_corners(kg, patch) != 4) {
293                         f1 = (f1+f0)*0.5f;
294                         f3 = (f3+f0)*0.5f;
295                 }
296
297                 float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
298                 float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
299                 float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
300
301 #ifdef __RAY_DIFFERENTIALS__
302                 if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
303                 if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
304 #endif
305
306                 return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
307         }
308         else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
309                 float2 uv[3];
310                 subd_triangle_patch_uv(kg, sd, uv);
311
312                 int corners[4];
313                 subd_triangle_patch_corners(kg, patch, corners);
314
315                 float3 f0, f1, f2, f3;
316
317                 if(desc.element == ATTR_ELEMENT_CORNER) {
318                         f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset));
319                         f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset));
320                         f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset));
321                         f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset));
322                 }
323                 else {
324                         f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset));
325                         f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset));
326                         f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset));
327                         f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset));
328                 }
329
330                 if(subd_triangle_patch_num_corners(kg, patch) != 4) {
331                         f1 = (f1+f0)*0.5f;
332                         f3 = (f3+f0)*0.5f;
333                 }
334
335                 float3 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
336                 float3 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
337                 float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
338
339 #ifdef __RAY_DIFFERENTIALS__
340                 if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
341                 if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
342 #endif
343
344                 return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
345         }
346         else {
347                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
348                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
349
350                 return make_float3(0.0f, 0.0f, 0.0f);
351         }
352 }
353
354 CCL_NAMESPACE_END
355