Commit: fd254892bb11b4afdf7e44f7d8d8a2b53996715f
Author: Mai Lavelle
Date:   Wed Jun 8 08:14:19 2016 -0400
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBfd254892bb11b4afdf7e44f7d8d8a2b53996715f

Read subdivision attributes in kernel

We can now store and retrieve attributes for subdivision meshes, tho in some
places behavior of attributes may not be entirely correct yet.

===================================================================

M       intern/cycles/kernel/geom/geom_attribute.h
M       intern/cycles/kernel/geom/geom_primitive.h
M       intern/cycles/kernel/geom/geom_triangle.h
M       intern/cycles/kernel/svm/svm_attribute.h
M       intern/cycles/util/util_math.h

===================================================================

diff --git a/intern/cycles/kernel/geom/geom_attribute.h 
b/intern/cycles/kernel/geom/geom_attribute.h
index c7364e9..9ec81f8 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -25,6 +25,8 @@ CCL_NAMESPACE_BEGIN
  * Lookup of attributes is different between OSL and SVM, as OSL is ustring
  * based while for SVM we use integer ids. */
 
+ccl_device_inline int subd_triangle_patch(KernelGlobals *kg, const ShaderData 
*sd);
+
 /* Find attribute based on ID */
 
 ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, 
uint id, AttributeElement *elem)
@@ -37,6 +39,9 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, const 
ShaderData *sd, ui
 #ifdef __HAIR__
        attr_offset = (ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)? attr_offset 
+ ATTR_PRIM_CURVE: attr_offset;
 #endif
+       if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE && 
subd_triangle_patch(kg, sd) != ~0) {
+               attr_offset += ATTR_PRIM_SUBD;
+       }
        uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
        
        while(attr_map.x != id) {
diff --git a/intern/cycles/kernel/geom/geom_primitive.h 
b/intern/cycles/kernel/geom/geom_primitive.h
index b1b1e91..44734d1 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -26,7 +26,10 @@ CCL_NAMESPACE_BEGIN
 ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData 
*sd, AttributeElement elem, int offset, float *dx, float *dy)
 {
        if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE) {
-               return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+               if(subd_triangle_patch(kg, sd) == ~0)
+                       return triangle_attribute_float(kg, sd, elem, offset, 
dx, dy);
+               else
+                       return subd_triangle_attribute_float(kg, sd, elem, 
offset, dx, dy);
        }
 #ifdef __HAIR__
        else if(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE) {
@@ -48,7 +51,10 @@ ccl_device float primitive_attribute_float(KernelGlobals 
*kg, const ShaderData *
 ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const 
ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
 {
        if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE) {
-               return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+               if(subd_triangle_patch(kg, sd) == ~0)
+                       return triangle_attribute_float3(kg, sd, elem, offset, 
dx, dy);
+               else
+                       return subd_triangle_attribute_float3(kg, sd, elem, 
offset, dx, dy);
        }
 #ifdef __HAIR__
        else if(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE) {
diff --git a/intern/cycles/kernel/geom/geom_triangle.h 
b/intern/cycles/kernel/geom/geom_triangle.h
index 995dfac..ede5023 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -205,4 +205,202 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals 
*kg, const ShaderData
        }
 }
 
+ccl_device_inline int subd_triangle_patch(KernelGlobals *kg, const ShaderData 
*sd)
+{
+       return __float_as_int(kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, 
prim)).w);
+}
+
+ccl_device_inline void subd_triangle_patch_uv(KernelGlobals *kg, const 
ShaderData *sd, float2 uv[3])
+{
+       float4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
+
+       uv[0].x = kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)).w;
+       uv[0].y = kernel_tex_fetch(__tri_vnormal, 
__float_as_int(tri_vindex.x)).w;
+
+       uv[1].x = kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)).w;
+       uv[1].y = kernel_tex_fetch(__tri_vnormal, 
__float_as_int(tri_vindex.y)).w;
+
+       uv[2].x = kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)).w;
+       uv[2].y = kernel_tex_fetch(__tri_vnormal, 
__float_as_int(tri_vindex.z)).w;
+}
+
+ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals *kg, const 
ShaderData *sd)
+{
+       int patch = subd_triangle_patch(kg, sd);
+       return kernel_tex_fetch(__patches, patch);
+}
+
+ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const 
ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
+{
+       if(elem == ATTR_ELEMENT_FACE) {
+               if(dx) *dx = 0.0f;
+               if(dy) *dy = 0.0f;
+
+               return kernel_tex_fetch(__attributes_float, offset + 
subd_triangle_patch(kg, sd));
+       }
+       else if(elem == ATTR_ELEMENT_VERTEX || elem == 
ATTR_ELEMENT_VERTEX_MOTION) {
+               float2 uv[3];
+               subd_triangle_patch_uv(kg, sd, uv);
+               uint4 v = subd_triangle_patch_indices(kg, sd);
+
+               float a, b, c;
+
+               float f0 = kernel_tex_fetch(__attributes_float, offset + v.x);
+               float f1 = kernel_tex_fetch(__attributes_float, offset + v.y);
+               float f2 = kernel_tex_fetch(__attributes_float, offset + v.z);
+
+               if(v.w != ~0) {
+                       float f3 = kernel_tex_fetch(__attributes_float, offset 
+ v.w);
+
+                       a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, 
uv[0].x), uv[0].y);
+                       b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, 
uv[1].x), uv[1].y);
+                       c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, 
uv[2].x), uv[2].y);
+               }
+               else {
+                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
+                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
+                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               }
+
+#ifdef __RAY_DIFFERENTIALS__
+               if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
+               if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - 
(ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
+#endif
+
+               return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - 
ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
+       }
+       else if(elem == ATTR_ELEMENT_CORNER) {
+               int patch = offset + subd_triangle_patch(kg, sd)*4;
+
+               float2 uv[3];
+               subd_triangle_patch_uv(kg, sd, uv);
+               uint4 v = subd_triangle_patch_indices(kg, sd);
+
+               float a, b, c;
+
+               float f0 = kernel_tex_fetch(__attributes_float, patch + 0);
+               float f1 = kernel_tex_fetch(__attributes_float, patch + 1);
+               float f2 = kernel_tex_fetch(__attributes_float, patch + 2);
+
+               if(v.w != ~0) {
+                       float f3 = kernel_tex_fetch(__attributes_float, patch + 
3);
+
+                       a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, 
uv[0].x), uv[0].y);
+                       b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, 
uv[1].x), uv[1].y);
+                       c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, 
uv[2].x), uv[2].y);
+               }
+               else {
+                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
+                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
+                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               }
+
+#ifdef __RAY_DIFFERENTIALS__
+               if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
+               if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - 
(ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
+#endif
+
+               return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - 
ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
+       }
+       else {
+               if(dx) *dx = 0.0f;
+               if(dy) *dy = 0.0f;
+
+               return 0.0f;
+       }
+}
+
+ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const 
ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
+{
+       if(elem == ATTR_ELEMENT_FACE) {
+               if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+               if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+               return float4_to_float3(kernel_tex_fetch(__attributes_float3, 
offset + subd_triangle_patch(kg, sd)));
+       }
+       else if(elem == ATTR_ELEMENT_VERTEX || elem == 
ATTR_ELEMENT_VERTEX_MOTION) {
+               float2 uv[3];
+               subd_triangle_patch_uv(kg, sd, uv);
+               uint4 v = subd_triangle_patch_indices(kg, sd);
+
+               float3 a, b, c;
+
+               float3 f0 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.x));
+               float3 f1 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.y));
+               float3 f2 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.z));
+
+               if(v.w != ~0) {
+                       float3 f3 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w));
+
+                       a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, 
uv[0].x), uv[0].y);
+                       b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, 
uv[1].x), uv[1].y);
+                       c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, 
uv[2].x), uv[2].y);
+               }
+               else {
+                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
+                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
+                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               }
+
+#ifdef __RAY_DIFFERENTIALS__
+               if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
+               if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - 
(ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
+#endif
+
+               return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - 
ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
+       }
+       else if(elem == ATTR_ELEMENT_CORNER || elem == 
ATTR_ELEMENT_CORNER_BYTE) {
+               int patch = offset + subd_triangle_patch(kg, sd)*4;
+
+               float2 uv[3];
+               subd_triangle_patch_uv(kg, sd, uv);
+               uint4 v = subd_triangle_patch_indices(kg, sd);
+
+               float3 a, b, c;
+               float3 f0, f1, f2, f3;
+
+               if(elem == ATTR_ELEMENT_CORNER) {
+                       f0 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 0));
+                       f1 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 1));
+                       f2 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 2));
+               }
+               else {
+                       f0 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 0));
+                       f1 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 1));
+                       f2 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 2));
+               }
+
+               if(v.w != ~0) {
+                       if(elem == ATTR_ELEMENT_CORNER) {
+                               f3 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, patch + 3));
+                       }
+                       else {
+                               f3 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, patch + 3));
+                       }
+
+                       a = interp(interp(f0, f1, uv[0].x), interp(f3, f2, 
uv[0].x), uv[0].y);
+                       b = interp(interp(f0, f1, uv[1].x), interp(f3, f2, 
uv[1].x), uv[1].y);
+                       c = interp(interp(f0, f1, uv[2].x), interp(f3, f2, 
uv[2].x), uv[2].y);
+               }
+               else {
+                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
+                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
+                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               }
+
+#ifdef __RAY_DIFFERENTIALS__
+               if(dx) *dx = ccl_fetch(sd, du).dx

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to