Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmarSquircleArt <omar.squircleart@gmail.com>2019-09-12 18:42:13 +0300
committerOmarSquircleArt <omar.squircleart@gmail.com>2019-09-12 18:42:13 +0300
commit2ea82e86ca60c1c268c6074ecba10524cebd97ed (patch)
treebf355c2a930f584685f68a833ce620ad15e63a70 /intern/cycles/kernel
parentf80018b5f7497d7ed0fe79783c4cd76f05ec1c7c (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')
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/geom/geom_patch.h14
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h21
-rw-r--r--intern/cycles/kernel/geom/geom_subd_triangle.h124
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h47
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp65
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/shaders/node_vertex_color.osl40
-rw-r--r--intern/cycles/kernel/svm/svm.h10
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h29
-rw-r--r--intern/cycles/kernel/svm/svm_types.h4
-rw-r--r--intern/cycles/kernel/svm/svm_vertex_color.h92
12 files changed, 410 insertions, 38 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 04df49aa058..41e57bb3e43 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -223,6 +223,7 @@ set(SRC_SVM_HEADERS
svm/svm_voxel.h
svm/svm_wave.h
svm/svm_white_noise.h
+ svm/svm_vertex_color.h
)
set(SRC_GEOM_HEADERS
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
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 415de9cd66b..2698ed59e64 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -483,6 +483,65 @@ static bool set_attribute_float3(float3 f, TypeDesc type, bool derivatives, void
return set_attribute_float3(fv, type, derivatives, val);
}
+/* Attributes with the TypeRGBA type descriptor should be retrived and stored
+ * in a float array of size 4 (e.g. node_vertex_color.osl), this array have
+ * a type descriptor TypeFloatArray4. If the storage is not a TypeFloatArray4,
+ * we either store the first three components in a vector, store the average of
+ * the components in a float, or fail the retrival and do nothing. We allow
+ * this for the correct operation of the Attribute node.
+ */
+
+static bool set_attribute_float4(float4 f[3], TypeDesc type, bool derivatives, void *val)
+{
+ float *fval = (float *)val;
+ if (type == TypeFloatArray4) {
+ fval[0] = f[0].x;
+ fval[1] = f[0].y;
+ fval[2] = f[0].z;
+ fval[3] = f[0].w;
+
+ if (derivatives) {
+ fval[4] = f[1].x;
+ fval[5] = f[1].y;
+ fval[6] = f[1].z;
+ fval[7] = f[1].w;
+
+ fval[8] = f[2].x;
+ fval[9] = f[2].y;
+ fval[10] = f[2].z;
+ fval[11] = f[2].w;
+ }
+ return true;
+ }
+ else if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
+ type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
+ fval[0] = f[0].x;
+ fval[1] = f[0].y;
+ fval[2] = f[0].z;
+
+ if (derivatives) {
+ fval[3] = f[1].x;
+ fval[4] = f[1].y;
+ fval[5] = f[1].z;
+
+ fval[6] = f[2].x;
+ fval[7] = f[2].y;
+ fval[8] = f[2].z;
+ }
+ return true;
+ }
+ else if (type == TypeDesc::TypeFloat) {
+ fval[0] = average(float4_to_float3(f[0]));
+
+ if (derivatives) {
+ fval[1] = average(float4_to_float3(f[1]));
+ fval[2] = average(float4_to_float3(f[2]));
+ }
+ return true;
+ }
+ return false;
+}
+
static bool set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val)
{
if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
@@ -629,6 +688,12 @@ static bool get_primitive_attribute(KernelGlobals *kg,
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float(fval, type, derivatives, val);
}
+ else if (attr.type == TypeRGBA) {
+ float4 fval[3];
+ fval[0] = primitive_attribute_float4(
+ kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ return set_attribute_float4(fval, type, derivatives, val);
+ }
else {
return false;
}
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 38ba113a184..f4258da70d3 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -80,6 +80,7 @@ set(SRC_OSL
node_vector_math.osl
node_vector_transform.osl
node_velvet_bsdf.osl
+ node_vertex_color.osl
node_voronoi_texture.osl
node_voxel_texture.osl
node_wavelength.osl
diff --git a/intern/cycles/kernel/shaders/node_vertex_color.osl b/intern/cycles/kernel/shaders/node_vertex_color.osl
new file mode 100644
index 00000000000..1997a690181
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_vertex_color.osl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdosl.h"
+
+shader node_vertex_color(string bump_offset = "center",
+ string layer_name = "",
+ output color Color = 0.0,
+ output float Alpha = 0.0)
+{
+ float vertex_color[4];
+ if (getattribute(layer_name, vertex_color)) {
+ Color = color(vertex_color[0], vertex_color[1], vertex_color[2]);
+ Alpha = vertex_color[3];
+
+ if (bump_offset == "dx") {
+ Color += Dx(Color);
+ Alpha += Dx(Alpha);
+ }
+ else if (bump_offset == "dy") {
+ Color += Dy(Color);
+ Alpha += Dy(Alpha);
+ }
+ } else {
+ warning("%s", "Invalid attribute.");
+ }
+}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 8de66a04963..4fc5e633e3b 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -205,6 +205,7 @@ CCL_NAMESPACE_END
#include "kernel/svm/svm_map_range.h"
#include "kernel/svm/svm_clamp.h"
#include "kernel/svm/svm_white_noise.h"
+#include "kernel/svm/svm_vertex_color.h"
#ifdef __SHADER_RAYTRACE__
# include "kernel/svm/svm_ao.h"
@@ -289,6 +290,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
case NODE_ATTR:
svm_node_attr(kg, sd, stack, node);
break;
+ case NODE_VERTEX_COLOR:
+ svm_node_vertex_color(kg, sd, stack, node.y, node.z, node.w);
+ break;
# if NODES_FEATURE(NODE_FEATURE_BUMP)
case NODE_GEOMETRY_BUMP_DX:
svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
@@ -328,6 +332,12 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
case NODE_ATTR_BUMP_DY:
svm_node_attr_bump_dy(kg, sd, stack, node);
break;
+ case NODE_VERTEX_COLOR_BUMP_DX:
+ svm_node_vertex_color_bump_dx(kg, sd, stack, node.y, node.z, node.w);
+ break;
+ case NODE_VERTEX_COLOR_BUMP_DY:
+ svm_node_vertex_color_bump_dy(kg, sd, stack, node.y, node.z, node.w);
+ break;
case NODE_TEX_COORD_BUMP_DX:
svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset);
break;
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index eaee0f9e4ee..fc7a3ba3f5a 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -69,6 +69,15 @@ ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, u
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
}
}
+ else if (desc.type == NODE_ATTR_RGBA) {
+ float4 f = primitive_attribute_float4(kg, sd, desc, NULL, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, average(float4_to_float3(f)));
+ }
+ else {
+ stack_store_float3(stack, out_offset, float4_to_float3(f));
+ }
+ }
else {
float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
if (type == NODE_ATTR_FLOAT) {
@@ -107,6 +116,16 @@ ccl_device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *
stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
}
}
+ else if (desc.type == NODE_ATTR_RGBA) {
+ float4 dx;
+ float4 f = primitive_attribute_float4(kg, sd, desc, &dx, NULL);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, average(float4_to_float3(f + dx)));
+ }
+ else {
+ stack_store_float3(stack, out_offset, float4_to_float3(f + dx));
+ }
+ }
else {
float3 dx;
float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
@@ -146,6 +165,16 @@ ccl_device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *
stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
}
}
+ else if (desc.type == NODE_ATTR_RGBA) {
+ float4 dy;
+ float4 f = primitive_attribute_float4(kg, sd, desc, NULL, &dy);
+ if (type == NODE_ATTR_FLOAT) {
+ stack_store_float(stack, out_offset, average(float4_to_float3(f + dy)));
+ }
+ else {
+ stack_store_float3(stack, out_offset, float4_to_float3(f + dy));
+ }
+ }
else {
float3 dy;
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 65e2dacedae..a6f2327dada 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -142,12 +142,16 @@ typedef enum ShaderNodeType {
NODE_CLAMP,
NODE_TEXTURE_MAPPING,
NODE_TEX_WHITE_NOISE,
+ NODE_VERTEX_COLOR,
+ NODE_VERTEX_COLOR_BUMP_DX,
+ NODE_VERTEX_COLOR_BUMP_DY,
} ShaderNodeType;
typedef enum NodeAttributeType {
NODE_ATTR_FLOAT = 0,
NODE_ATTR_FLOAT2,
NODE_ATTR_FLOAT3,
+ NODE_ATTR_RGBA,
NODE_ATTR_MATRIX
} NodeAttributeType;
diff --git a/intern/cycles/kernel/svm/svm_vertex_color.h b/intern/cycles/kernel/svm/svm_vertex_color.h
new file mode 100644
index 00000000000..3c105b1cbfa
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_vertex_color.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device void svm_node_vertex_color(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint layer_id,
+ uint color_offset,
+ uint alpha_offset)
+{
+ AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id);
+ if (descriptor.offset != ATTR_STD_NOT_FOUND) {
+ float4 vertex_color = primitive_attribute_float4(kg, sd, descriptor, NULL, NULL);
+ stack_store_float3(stack, color_offset, float4_to_float3(vertex_color));
+ stack_store_float(stack, alpha_offset, vertex_color.w);
+ }
+ else {
+ stack_store_float3(stack, color_offset, make_float3(0.0f, 0.0f, 0.0f));
+ stack_store_float(stack, alpha_offset, 0.0f);
+ }
+}
+
+#ifndef __KERNEL_CUDA__
+ccl_device
+#else
+ccl_device_noinline
+#endif
+ void
+ svm_node_vertex_color_bump_dx(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint layer_id,
+ uint color_offset,
+ uint alpha_offset)
+{
+ AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id);
+ if (descriptor.offset != ATTR_STD_NOT_FOUND) {
+ float4 dx;
+ float4 vertex_color = primitive_attribute_float4(kg, sd, descriptor, &dx, NULL);
+ vertex_color += dx;
+ stack_store_float3(stack, color_offset, float4_to_float3(vertex_color));
+ stack_store_float(stack, alpha_offset, vertex_color.w);
+ }
+ else {
+ stack_store_float3(stack, color_offset, make_float3(0.0f, 0.0f, 0.0f));
+ stack_store_float(stack, alpha_offset, 0.0f);
+ }
+}
+
+#ifndef __KERNEL_CUDA__
+ccl_device
+#else
+ccl_device_noinline
+#endif
+ void
+ svm_node_vertex_color_bump_dy(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint layer_id,
+ uint color_offset,
+ uint alpha_offset)
+{
+ AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id);
+ if (descriptor.offset != ATTR_STD_NOT_FOUND) {
+ float4 dy;
+ float4 vertex_color = primitive_attribute_float4(kg, sd, descriptor, NULL, &dy);
+ vertex_color += dy;
+ stack_store_float3(stack, color_offset, float4_to_float3(vertex_color));
+ stack_store_float(stack, alpha_offset, vertex_color.w);
+ }
+ else {
+ stack_store_float3(stack, color_offset, make_float3(0.0f, 0.0f, 0.0f));
+ stack_store_float(stack, alpha_offset, 0.0f);
+ }
+}
+
+CCL_NAMESPACE_END