Blender V2.61 - r43446

svm_attribute.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 CCL_NAMESPACE_BEGIN
00020 
00021 /* Attribute Node */
00022 
00023 __device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
00024     uint4 node, NodeAttributeType *type,
00025     NodeAttributeType *mesh_type, AttributeElement *elem, uint *offset, uint *out_offset)
00026 {
00027     if(sd->object != ~0) {
00028         /* find attribute by unique id */
00029         uint id = node.y;
00030         uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
00031         uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
00032 
00033         while(attr_map.x != id)
00034             attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
00035 
00036         /* return result */
00037         *elem = (AttributeElement)attr_map.y;
00038         *offset = attr_map.z;
00039         *mesh_type = (NodeAttributeType)attr_map.w;
00040     }
00041     else {
00042         /* background */
00043         *elem = ATTR_ELEMENT_NONE;
00044         *offset = 0;
00045         *mesh_type = (NodeAttributeType)node.w;
00046     }
00047 
00048     *out_offset = node.z;
00049     *type = (NodeAttributeType)node.w;
00050 }
00051 
00052 __device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
00053 {
00054     NodeAttributeType type, mesh_type;
00055     AttributeElement elem;
00056     uint offset, out_offset;
00057 
00058     svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
00059 
00060     /* fetch and store attribute */
00061     if(type == NODE_ATTR_FLOAT) {
00062         if(mesh_type == NODE_ATTR_FLOAT) {
00063             float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
00064             stack_store_float(stack, out_offset, f);
00065         }
00066         else {
00067             float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
00068             stack_store_float(stack, out_offset, average(f));
00069         }
00070     }
00071     else {
00072         if(mesh_type == NODE_ATTR_FLOAT3) {
00073             float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, NULL);
00074             stack_store_float3(stack, out_offset, f);
00075         }
00076         else {
00077             float f = triangle_attribute_float(kg, sd, elem, offset, NULL, NULL);
00078             stack_store_float3(stack, out_offset, make_float3(f, f, f));
00079         }
00080     }
00081 }
00082 
00083 __device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
00084 {
00085     NodeAttributeType type, mesh_type;
00086     AttributeElement elem;
00087     uint offset, out_offset;
00088 
00089     svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
00090 
00091     /* fetch and store attribute */
00092     if(type == NODE_ATTR_FLOAT) {
00093         if(mesh_type == NODE_ATTR_FLOAT) {
00094             float dx;
00095             float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
00096             stack_store_float(stack, out_offset, f+dx);
00097         }
00098         else {
00099             float3 dx;
00100             float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
00101             stack_store_float(stack, out_offset, average(f+dx));
00102         }
00103     }
00104     else {
00105         if(mesh_type == NODE_ATTR_FLOAT3) {
00106             float3 dx;
00107             float3 f = triangle_attribute_float3(kg, sd, elem, offset, &dx, NULL);
00108             stack_store_float3(stack, out_offset, f+dx);
00109         }
00110         else {
00111             float dx;
00112             float f = triangle_attribute_float(kg, sd, elem, offset, &dx, NULL);
00113             stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
00114         }
00115     }
00116 }
00117 
00118 __device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
00119 {
00120     NodeAttributeType type, mesh_type;
00121     AttributeElement elem;
00122     uint offset, out_offset;
00123 
00124     svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset);
00125 
00126     /* fetch and store attribute */
00127     if(type == NODE_ATTR_FLOAT) {
00128         if(mesh_type == NODE_ATTR_FLOAT) {
00129             float dy;
00130             float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
00131             stack_store_float(stack, out_offset, f+dy);
00132         }
00133         else {
00134             float3 dy;
00135             float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
00136             stack_store_float(stack, out_offset, average(f+dy));
00137         }
00138     }
00139     else {
00140         if(mesh_type == NODE_ATTR_FLOAT3) {
00141             float3 dy;
00142             float3 f = triangle_attribute_float3(kg, sd, elem, offset, NULL, &dy);
00143             stack_store_float3(stack, out_offset, f+dy);
00144         }
00145         else {
00146             float dy;
00147             float f = triangle_attribute_float(kg, sd, elem, offset, NULL, &dy);
00148             stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
00149         }
00150     }
00151 }
00152 
00153 CCL_NAMESPACE_END
00154