Cycles render engine, initial commit. This is the engine itself, blender modification...
[blender.git] / intern / cycles / kernel / svm / svm_attribute.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 CCL_NAMESPACE_BEGIN
20
21 /* Attribute Node */
22
23 __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
24         uint4 node, NodeAttributeType *type,
25         NodeAttributeType *mesh_type, AttributeElement *elem, uint *offset, uint *out_offset)
26 {
27         if(sd->object != ~0) {
28                 /* find attribute by unique id */
29                 uint id = node.y;
30                 uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
31                 uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
32
33                 while(attr_map.x != id)
34                         attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
35
36                 /* return result */
37                 *elem = (AttributeElement)attr_map.y;
38                 *offset = attr_map.z;
39                 *mesh_type = (NodeAttributeType)attr_map.w;
40         }
41         else {
42                 /* background */
43                 *elem = ATTR_ELEMENT_NONE;
44                 *offset = 0;
45                 *mesh_type = (NodeAttributeType)node.w;
46         }
47
48         *out_offset = node.z;
49         *type = (NodeAttributeType)node.w;
50 }
51
52 __device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
53 {
54         NodeAttributeType type, mesh_type;
55         AttributeElement elem;
56         uint offset, out_offset;
57
58         svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
59
60         /* fetch and store attribute */
61         if(type == NODE_ATTR_FLOAT) {
62                 if(mesh_type == NODE_ATTR_FLOAT) {
63                         float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
64                         stack_store_float(stack, out_offset, f);
65                 }
66                 else {
67                         float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
68                         stack_store_float(stack, out_offset, average(f));
69                 }
70         }
71         else {
72                 if(mesh_type == NODE_ATTR_FLOAT3) {
73                         float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
74                         stack_store_float3(stack, out_offset, f);
75                 }
76                 else {
77                         float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
78                         stack_store_float3(stack, out_offset, make_float3(f, f, f));
79                 }
80         }
81 }
82
83 __device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
84 {
85         NodeAttributeType type, mesh_type;
86         AttributeElement elem;
87         uint offset, out_offset;
88
89         svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
90
91         /* fetch and store attribute */
92         if(type == NODE_ATTR_FLOAT) {
93                 if(mesh_type == NODE_ATTR_FLOAT) {
94                         float dx;
95                         float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
96                         stack_store_float(stack, out_offset, f+dx);
97                 }
98                 else {
99                         float3 dx;
100                         float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
101                         stack_store_float(stack, out_offset, average(f+dx));
102                 }
103         }
104         else {
105                 if(mesh_type == NODE_ATTR_FLOAT3) {
106                         float3 dx;
107                         float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
108                         stack_store_float3(stack, out_offset, f+dx);
109                 }
110                 else {
111                         float dx;
112                         float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
113                         stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
114                 }
115         }
116 }
117
118 __device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
119 {
120         NodeAttributeType type, mesh_type;
121         AttributeElement elem;
122         uint offset, out_offset;
123
124         svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
125
126         /* fetch and store attribute */
127         if(type == NODE_ATTR_FLOAT) {
128                 if(mesh_type == NODE_ATTR_FLOAT) {
129                         float dy;
130                         float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
131                         stack_store_float(stack, out_offset, f+dy);
132                 }
133                 else {
134                         float3 dy;
135                         float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
136                         stack_store_float(stack, out_offset, average(f+dy));
137                 }
138         }
139         else {
140                 if(mesh_type == NODE_ATTR_FLOAT3) {
141                         float3 dy;
142                         float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
143                         stack_store_float3(stack, out_offset, f+dy);
144                 }
145                 else {
146                         float dy;
147                         float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
148                         stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
149                 }
150         }
151 }
152
153 CCL_NAMESPACE_END
154