Cycles: Make object flag names more obvious that hey are object and not shader
[blender.git] / intern / cycles / kernel / geom / geom_motion_triangle_shader.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 /* Motion Triangle Primitive
18  *
19  * These are stored as regular triangles, plus extra positions and normals at
20  * times other than the frame center. Computing the triangle vertex positions
21  * or normals at a given ray time is a matter of interpolation of the two steps
22  * between which the ray time lies.
23  *
24  * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
25  * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
26  */
27
28 CCL_NAMESPACE_BEGIN
29
30 /* Setup of motion triangle specific parts of ShaderData, moved into this one
31  * function to more easily share computation of interpolated positions and
32  * normals */
33
34 /* return 3 triangle vertex normals */
35 ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg,
36                                                       ShaderData *sd, const
37                                                       Intersection *isect,
38                                                       const Ray *ray,
39                                                       bool subsurface)
40 {
41         /* Get shader. */
42         ccl_fetch(sd, shader) = kernel_tex_fetch(__tri_shader, ccl_fetch(sd, prim));
43         /* Get motion info. */
44         /* TODO(sergey): This logic is really similar to motion_triangle_vertices(),
45          * can we de-duplicate something here?
46          */
47         int numsteps, numverts;
48         object_motion_info(kg, ccl_fetch(sd, object), &numsteps, &numverts, NULL);
49         /* Figure out which steps we need to fetch and their interpolation factor. */
50         int maxstep = numsteps*2;
51         int step = min((int)(ccl_fetch(sd, time)*maxstep), maxstep-1);
52         float t = ccl_fetch(sd, time)*maxstep - step;
53         /* Find attribute. */
54         AttributeElement elem;
55         int offset = find_attribute_motion(kg, ccl_fetch(sd, object),
56                                            ATTR_STD_MOTION_VERTEX_POSITION,
57                                            &elem);
58         kernel_assert(offset != ATTR_STD_NOT_FOUND);
59         /* Fetch vertex coordinates. */
60         float3 verts[3], next_verts[3];
61         uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
62         motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
63         motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_verts);
64         /* Interpolate between steps. */
65         verts[0] = (1.0f - t)*verts[0] + t*next_verts[0];
66         verts[1] = (1.0f - t)*verts[1] + t*next_verts[1];
67         verts[2] = (1.0f - t)*verts[2] + t*next_verts[2];
68         /* Compute refined position. */
69 #ifdef __SUBSURFACE__
70         if(subsurface) {
71                 ccl_fetch(sd, P) = motion_triangle_refine_subsurface(kg,
72                                                                      sd,
73                                                                      isect,
74                                                                      ray,
75                                                                      verts);
76         }
77         else
78 #endif  /*  __SUBSURFACE__*/
79         {
80                 ccl_fetch(sd, P) = motion_triangle_refine(kg, sd, isect, ray, verts);
81         }
82         /* Compute face normal. */
83         float3 Ng;
84         if(ccl_fetch(sd, flag) & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
85                 Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0]));
86         }
87         else {
88                 Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
89         }
90         ccl_fetch(sd, Ng) = Ng;
91         ccl_fetch(sd, N) = Ng;
92         /* Compute derivatives of P w.r.t. uv. */
93 #ifdef __DPDU__
94         ccl_fetch(sd, dPdu) = (verts[0] - verts[2]);
95         ccl_fetch(sd, dPdv) = (verts[1] - verts[2]);
96 #endif
97         /* Compute smooth normal. */
98         if(ccl_fetch(sd, shader) & SHADER_SMOOTH_NORMAL) {
99                 /* Find attribute. */
100                 AttributeElement elem;
101                 int offset = find_attribute_motion(kg,
102                                                    ccl_fetch(sd, object),
103                                                    ATTR_STD_MOTION_VERTEX_NORMAL,
104                                                    &elem);
105                 kernel_assert(offset != ATTR_STD_NOT_FOUND);
106                 /* Fetch vertex coordinates. */
107                 float3 normals[3], next_normals[3];
108                 motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
109                 motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step+1, next_normals);
110                 /* Interpolate between steps. */
111                 normals[0] = (1.0f - t)*normals[0] + t*next_normals[0];
112                 normals[1] = (1.0f - t)*normals[1] + t*next_normals[1];
113                 normals[2] = (1.0f - t)*normals[2] + t*next_normals[2];
114                 /* Interpolate between vertices. */
115                 float u = ccl_fetch(sd, u);
116                 float v = ccl_fetch(sd, v);
117                 float w = 1.0f - u - v;
118                 ccl_fetch(sd, N) = (u*normals[0] + v*normals[1] + w*normals[2]);
119         }
120 }
121
122 CCL_NAMESPACE_END
123