Blender V2.61 - r43446

kernel_triangle.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 /* Point on triangle for Moller-Trumbore triangles */
00022 __device_inline float3 triangle_point_MT(KernelGlobals *kg, int tri_index, float u, float v)
00023 {
00024     /* load triangle vertices */
00025     float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
00026 
00027     float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
00028     float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
00029     float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
00030 
00031     /* compute point */
00032     float t = 1.0f - u - v;
00033     return (u*v0 + v*v1 + t*v2);
00034 }
00035 
00036 /* Sample point on triangle */
00037 __device_inline float3 triangle_sample_MT(KernelGlobals *kg, int tri_index, float randu, float randv)
00038 {
00039     /* compute point */
00040     randu = sqrtf(randu);
00041 
00042     float u = 1.0f - randu;
00043     float v = randv*randu;
00044 
00045     return triangle_point_MT(kg, tri_index, u, v);
00046 }
00047 
00048 /* Normal for Moller-Trumbore triangles */
00049 __device_inline float3 triangle_normal_MT(KernelGlobals *kg, int tri_index, int *shader)
00050 {
00051 #if 0
00052     /* load triangle vertices */
00053     float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
00054 
00055     float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
00056     float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
00057     float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
00058 
00059     /* compute normal */
00060     return normalize(cross(v2 - v0, v1 - v0));
00061 #else
00062     float4 Nm = kernel_tex_fetch(__tri_normal, tri_index);
00063     *shader = __float_as_int(Nm.w);
00064     return make_float3(Nm.x, Nm.y, Nm.z);
00065 #endif
00066 }
00067 
00068 __device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int tri_index, float u, float v)
00069 {
00070     /* load triangle vertices */
00071     float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
00072 
00073     float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.x)));
00074     float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.y)));
00075     float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, __float_as_int(tri_vindex.z)));
00076 
00077     return normalize((1.0f - u - v)*n2 + u*n0 + v*n1);
00078 }
00079 
00080 __device_inline void triangle_dPdudv(KernelGlobals *kg, float3 *dPdu, float3 *dPdv, int tri)
00081 {
00082     /* fetch triangle vertex coordinates */
00083     float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri));
00084 
00085     float3 p0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
00086     float3 p1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
00087     float3 p2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
00088 
00089     /* compute derivatives of P w.r.t. uv */
00090     *dPdu = (p0 - p2);
00091     *dPdv = (p1 - p2);
00092 }
00093 
00094 /* attributes */
00095 
00096 __device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
00097 {
00098     if(elem == ATTR_ELEMENT_FACE) {
00099         if(dx) *dx = 0.0f;
00100         if(dy) *dy = 0.0f;
00101 
00102         return kernel_tex_fetch(__attributes_float, offset + sd->prim);
00103     }
00104     else if(elem == ATTR_ELEMENT_VERTEX) {
00105         float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
00106 
00107         float f0 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.x));
00108         float f1 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.y));
00109         float f2 = kernel_tex_fetch(__attributes_float, offset + __float_as_int(tri_vindex.z));
00110 
00111 #ifdef __RAY_DIFFERENTIALS__
00112         if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
00113         if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
00114 #endif
00115 
00116         return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
00117     }
00118     else if(elem == ATTR_ELEMENT_CORNER) {
00119         int tri = offset + sd->prim*3;
00120         float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
00121         float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
00122         float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
00123 
00124 #ifdef __RAY_DIFFERENTIALS__
00125         if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
00126         if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
00127 #endif
00128 
00129         return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
00130     }
00131     else {
00132         if(dx) *dx = 0.0f;
00133         if(dy) *dy = 0.0f;
00134 
00135         return 0.0f;
00136     }
00137 }
00138 
00139 __device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
00140 {
00141     if(elem == ATTR_ELEMENT_FACE) {
00142         if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
00143         if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
00144 
00145         return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
00146     }
00147     else if(elem == ATTR_ELEMENT_VERTEX) {
00148         float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
00149 
00150         float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.x)));
00151         float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.y)));
00152         float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + __float_as_int(tri_vindex.z)));
00153 
00154 #ifdef __RAY_DIFFERENTIALS__
00155         if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
00156         if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
00157 #endif
00158 
00159         return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
00160     }
00161     else if(elem == ATTR_ELEMENT_CORNER) {
00162         int tri = offset + sd->prim*3;
00163         float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
00164         float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
00165         float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
00166 
00167 #ifdef __RAY_DIFFERENTIALS__
00168         if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
00169         if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
00170 #endif
00171 
00172         return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
00173     }
00174     else {
00175         if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
00176         if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
00177 
00178         return make_float3(0.0f, 0.0f, 0.0f);
00179     }
00180 }
00181 
00182 CCL_NAMESPACE_END
00183