diff options
author | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-09-12 18:42:13 +0300 |
---|---|---|
committer | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-09-12 18:42:13 +0300 |
commit | 2ea82e86ca60c1c268c6074ecba10524cebd97ed (patch) | |
tree | bf355c2a930f584685f68a833ce620ad15e63a70 /intern/cycles/kernel/geom | |
parent | f80018b5f7497d7ed0fe79783c4cd76f05ec1c7c (diff) |
Shading: Add Vertex Color node.
This patch adds a new Vertex Color node. The node also returns the alpha
of the vertex color layer as an output.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D5767
Diffstat (limited to 'intern/cycles/kernel/geom')
-rw-r--r-- | intern/cycles/kernel/geom/geom_patch.h | 14 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_primitive.h | 21 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_subd_triangle.h | 124 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle.h | 47 |
4 files changed, 168 insertions, 38 deletions
diff --git a/intern/cycles/kernel/geom/geom_patch.h b/intern/cycles/kernel/geom/geom_patch.h index df19199f68e..8b4b91b96c8 100644 --- a/intern/cycles/kernel/geom/geom_patch.h +++ b/intern/cycles/kernel/geom/geom_patch.h @@ -380,15 +380,15 @@ ccl_device float3 patch_eval_float3(KernelGlobals *kg, return val; } -ccl_device float3 patch_eval_uchar4(KernelGlobals *kg, +ccl_device float4 patch_eval_uchar4(KernelGlobals *kg, const ShaderData *sd, int offset, int patch, float u, float v, int channel, - float3 *du, - float3 *dv) + float4 *du, + float4 *dv) { int indices[PATCH_MAX_CONTROL_VERTS]; float weights[PATCH_MAX_CONTROL_VERTS]; @@ -398,14 +398,14 @@ ccl_device float3 patch_eval_uchar4(KernelGlobals *kg, int num_control = patch_eval_control_verts( kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv); - float3 val = make_float3(0.0f, 0.0f, 0.0f); + float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f); if (du) - *du = make_float3(0.0f, 0.0f, 0.0f); + *du = make_float4(0.0f, 0.0f, 0.0f, 0.0f); if (dv) - *dv = make_float3(0.0f, 0.0f, 0.0f); + *dv = make_float4(0.0f, 0.0f, 0.0f, 0.0f); for (int i = 0; i < num_control; i++) { - float3 v = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, offset + indices[i])); + float4 v = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, offset + indices[i])); val += v * weights[i]; if (du) diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h index 7f2b52a24c4..9a91da79f58 100644 --- a/intern/cycles/kernel/geom/geom_primitive.h +++ b/intern/cycles/kernel/geom/geom_primitive.h @@ -162,6 +162,27 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg, } } +ccl_device_inline float4 primitive_attribute_float4(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float4 *dx, + float4 *dy) +{ + if (sd->type & PRIMITIVE_ALL_TRIANGLE) { + if (subd_triangle_patch(kg, sd) == ~0) + return triangle_attribute_float4(kg, sd, desc, dx, dy); + else + return subd_triangle_attribute_float4(kg, sd, desc, dx, dy); + } + else { + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } +} + ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, diff --git a/intern/cycles/kernel/geom/geom_subd_triangle.h b/intern/cycles/kernel/geom/geom_subd_triangle.h index 8d5b3c12833..81bac6e6ee1 100644 --- a/intern/cycles/kernel/geom/geom_subd_triangle.h +++ b/intern/cycles/kernel/geom/geom_subd_triangle.h @@ -382,13 +382,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, float2 p = dpdu * sd->u + dpdv * sd->v + uv[2]; float3 a, dads, dadt; - - if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { - a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); - } - else { - a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); - } + a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); # ifdef __RAY_DIFFERENTIALS__ if (dx || dy) { @@ -460,7 +454,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c; } - else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) { + else if (desc.element == ATTR_ELEMENT_CORNER) { float2 uv[3]; subd_triangle_patch_uv(kg, sd, uv); @@ -469,18 +463,10 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, float3 f0, f1, f2, f3; - if (desc.element == ATTR_ELEMENT_CORNER) { - f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset)); - f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset)); - f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset)); - f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset)); - } - else { - f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)); - f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)); - f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)); - f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)); - } + f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset)); + f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset)); + f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset)); + f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset)); if (subd_triangle_patch_num_corners(kg, patch) != 4) { f1 = (f1 + f0) * 0.5f; @@ -510,4 +496,102 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, } } +ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float4 *dx, + float4 *dy) +{ + int patch = subd_triangle_patch(kg, sd); + +#ifdef __PATCH_EVAL__ + if (desc.flags & ATTR_SUBDIVIDED) { + float2 uv[3]; + subd_triangle_patch_uv(kg, sd, uv); + + float2 dpdu = uv[0] - uv[2]; + float2 dpdv = uv[1] - uv[2]; + + /* p is [s, t] */ + float2 p = dpdu * sd->u + dpdv * sd->v + uv[2]; + + float4 dads, dadt; + + float4 a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); + +# ifdef __RAY_DIFFERENTIALS__ + if (dx || dy) { + float dsdu = dpdu.x; + float dtdu = dpdu.y; + float dsdv = dpdv.x; + float dtdv = dpdv.y; + + if (dx) { + float dudx = sd->du.dx; + float dvdx = sd->dv.dx; + + float dsdx = dsdu * dudx + dsdv * dvdx; + float dtdx = dtdu * dudx + dtdv * dvdx; + + *dx = dads * dsdx + dadt * dtdx; + } + if (dy) { + float dudy = sd->du.dy; + float dvdy = sd->dv.dy; + + float dsdy = dsdu * dudy + dsdv * dvdy; + float dtdy = dtdu * dudy + dtdv * dvdy; + + *dy = dads * dsdy + dadt * dtdy; + } + } +# endif + return a; + } + else +#endif /* __PATCH_EVAL__ */ + if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { + float2 uv[3]; + subd_triangle_patch_uv(kg, sd, uv); + + int corners[4]; + subd_triangle_patch_corners(kg, patch, corners); + + float4 f0 = color_uchar4_to_float4( + kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)); + float4 f1 = color_uchar4_to_float4( + kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)); + float4 f2 = color_uchar4_to_float4( + kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)); + float4 f3 = color_uchar4_to_float4( + kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)); + + if (subd_triangle_patch_num_corners(kg, patch) != 4) { + f1 = (f1 + f0) * 0.5f; + f3 = (f3 + f0) * 0.5f; + } + + float4 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y); + float4 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y); + float4 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y); + +#ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c; + if (dy) + *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c; +#endif + + return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c; + } + else { + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 9938c0ba2c3..fdb7f655f64 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -255,20 +255,13 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; } - else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) { + else if (desc.element == ATTR_ELEMENT_CORNER) { int tri = desc.offset + sd->prim * 3; float3 f0, f1, f2; - if (desc.element == ATTR_ELEMENT_CORNER) { - f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0)); - f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1)); - f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2)); - } - else { - f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 0)); - f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 1)); - f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 2)); - } + f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0)); + f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1)); + f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2)); #ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -289,4 +282,36 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, } } +ccl_device float4 triangle_attribute_float4(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float4 *dx, + float4 *dy) +{ + if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { + int tri = desc.offset + sd->prim * 3; + + float4 f0 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0)); + float4 f1 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1)); + float4 f2 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2)); + +#ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2; + if (dy) + *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2; +#endif + + return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; + } + else { + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } +} + CCL_NAMESPACE_END |