2 * Copyright 2011, Blender Foundation.
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.
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.
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.
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)
27 if(sd->object != ~0) {
28 /* find attribute by unique id */
30 uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
31 uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
33 while(attr_map.x != id)
34 attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
37 *elem = (AttributeElement)attr_map.y;
39 *mesh_type = (NodeAttributeType)attr_map.w;
43 *elem = ATTR_ELEMENT_NONE;
45 *mesh_type = (NodeAttributeType)node.w;
49 *type = (NodeAttributeType)node.w;
52 __device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
54 NodeAttributeType type, mesh_type;
55 AttributeElement elem;
56 uint offset, out_offset;
58 svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
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);
67 float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
68 stack_store_float(stack, out_offset, average(f));
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);
77 float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
78 stack_store_float3(stack, out_offset, make_float3(f, f, f));
83 __device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
85 NodeAttributeType type, mesh_type;
86 AttributeElement elem;
87 uint offset, out_offset;
89 svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
91 /* fetch and store attribute */
92 if(type == NODE_ATTR_FLOAT) {
93 if(mesh_type == NODE_ATTR_FLOAT) {
95 float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
96 stack_store_float(stack, out_offset, f+dx);
100 float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
101 stack_store_float(stack, out_offset, average(f+dx));
105 if(mesh_type == NODE_ATTR_FLOAT3) {
107 float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
108 stack_store_float3(stack, out_offset, f+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));
118 __device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
120 NodeAttributeType type, mesh_type;
121 AttributeElement elem;
122 uint offset, out_offset;
124 svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
126 /* fetch and store attribute */
127 if(type == NODE_ATTR_FLOAT) {
128 if(mesh_type == NODE_ATTR_FLOAT) {
130 float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
131 stack_store_float(stack, out_offset, f+dy);
135 float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
136 stack_store_float(stack, out_offset, average(f+dy));
140 if(mesh_type == NODE_ATTR_FLOAT3) {
142 float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
143 stack_store_float3(stack, out_offset, f+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));