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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:48 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:48 +0400
commit27043b8e40f74c8b0917850d1aefbd6315fa46a5 (patch)
tree26360d0ab051bb94312e40fef974851f3c20f6e0 /intern/cycles
parent393216a6df934a78f541d98def7a948a89f9b5c8 (diff)
Cycles code internals: add support for mesh voxel grid attributes.
These are internally stored as a 3D image textures, but accessible like e.g. UV coordinates though the attribute node and getattribute(). This is convenient for rendering e.g. smoke objects where data like density is really a property of the mesh, and it avoids having to specify the smoke object in a texture node, instead the material will work with any smoke domain.
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/geom/geom.h1
-rw-r--r--intern/cycles/kernel/geom/geom_attribute.h40
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h36
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h75
-rw-r--r--intern/cycles/kernel/kernel_types.h3
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp4
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h4
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h45
-rw-r--r--intern/cycles/render/attribute.cpp101
-rw-r--r--intern/cycles/render/attribute.h15
-rw-r--r--intern/cycles/render/mesh.cpp7
-rw-r--r--intern/cycles/render/nodes.cpp41
13 files changed, 257 insertions, 116 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index e473b1ab91c..45b4c81610e 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -119,6 +119,7 @@ set(SRC_GEOM_HEADERS
geom/geom_object.h
geom/geom_primitive.h
geom/geom_triangle.h
+ geom/geom_volume.h
)
set(SRC_UTIL_HEADERS
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
index a4e9bdb1c57..9495a2541f9 100644
--- a/intern/cycles/kernel/geom/geom.h
+++ b/intern/cycles/kernel/geom/geom.h
@@ -38,6 +38,7 @@
#include "geom_motion_triangle.h"
#include "geom_motion_curve.h"
#include "geom_curve.h"
+#include "geom_volume.h"
#include "geom_primitive.h"
#include "geom_bvh.h"
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
index cbc1fb4fbf2..63ce31c492f 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -32,35 +32,29 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, ui
if(sd->object == PRIM_NONE)
return (int)ATTR_STD_NOT_FOUND;
-#ifdef __OSL__
- if (kg->osl) {
- return OSLShader::find_attribute(kg, sd, id, elem);
- }
- else
-#endif
- {
- /* for SVM, find attribute by unique id */
- uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+ /* for SVM, find attribute by unique id */
+ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
#ifdef __HAIR__
- attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
+ attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
#endif
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
- while(attr_map.x != id) {
- attr_offset += ATTR_PRIM_TYPES;
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
- }
+ uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+
+ while(attr_map.x != id) {
+ attr_offset += ATTR_PRIM_TYPES;
+ attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ }
- *elem = (AttributeElement)attr_map.y;
-
- if(sd->prim == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
- return ATTR_STD_NOT_FOUND;
+ *elem = (AttributeElement)attr_map.y;
+
+ if(sd->prim == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
+ return ATTR_STD_NOT_FOUND;
- /* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- }
+ /* return result */
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
}
+/* Transform matrix attribute on meshes */
+
ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
{
Transform tfm;
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index d90cc108492..f821e696a07 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -25,26 +25,46 @@ CCL_NAMESPACE_BEGIN
ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
{
-#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_TRIANGLE)
-#endif
+ if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+ }
#ifdef __HAIR__
- else
+ else if(sd->type & PRIMITIVE_ALL_CURVE) {
return curve_attribute_float(kg, sd, elem, offset, dx, dy);
+ }
#endif
+#ifdef __VOLUME__
+ else if(sd->object != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float(kg, sd, elem, offset, dx, dy);
+ }
+#endif
+ else {
+ if(dx) *dx = 0.0f;
+ if(dy) *dy = 0.0f;
+ return 0.0f;
+ }
}
ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
{
-#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_TRIANGLE)
-#endif
+ if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+ }
#ifdef __HAIR__
- else
+ else if(sd->type & PRIMITIVE_ALL_CURVE) {
return curve_attribute_float3(kg, sd, elem, offset, dx, dy);
+ }
+#endif
+#ifdef __VOLUME__
+ else if(sd->object != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) {
+ return volume_attribute_float3(kg, sd, elem, offset, dx, dy);
+ }
#endif
+ else {
+ if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+ if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
}
/* Default UV coordinate */
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
new file mode 100644
index 00000000000..963d6cbee9c
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -0,0 +1,75 @@
+/*
+ * 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
+ */
+
+/* Volume Primitive
+ *
+ * Volumes are just regions inside meshes with the mesh surface as boundaries.
+ * There isn't as much data to access as for surfaces, there is only a position
+ * to do lookups in 3D voxel or procedural textures.
+ *
+ * 3D voxel textures can be assigned as attributes per mesh, which means the
+ * same shader can be used for volume objects with different densities, etc. */
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __VOLUME__
+
+/* Return position normalized to 0..1 in mesh bounds */
+
+ccl_device float3 volume_normalized_position(KernelGlobals *kg, const ShaderData *sd, float3 P)
+{
+ /* todo: optimize this so it's just a single matrix multiplication when
+ * possible (not motion blur), or perhaps even just translation + scale */
+ AttributeElement attr_elem;
+ int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
+
+ object_inverse_position_transform(kg, sd, &P);
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+}
+
+ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float *dx, float *dy)
+{
+ float3 P = volume_normalized_position(kg, sd, sd->P);
+ float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+
+ if(dx) *dx = 0.0f;
+ if(dx) *dy = 0.0f;
+
+ /* todo: support float textures to lower memory usage for single floats */
+ return average(float4_to_float3(r));
+}
+
+ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float3 *dx, float3 *dy)
+{
+ float3 P = volume_normalized_position(kg, sd, sd->P);
+ float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+
+ 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(r);
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 0be83e5cbc1..f7aebd29bbe 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -459,7 +459,8 @@ typedef enum AttributeElement {
ATTR_ELEMENT_CORNER,
ATTR_ELEMENT_CURVE,
ATTR_ELEMENT_CURVE_KEY,
- ATTR_ELEMENT_CURVE_KEY_MOTION
+ ATTR_ELEMENT_CURVE_KEY_MOTION,
+ ATTR_ELEMENT_VOXEL
} AttributeElement;
typedef enum AttributeStandard {
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 65548d65308..d5edd04d8a5 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -768,9 +768,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (attr.elem != ATTR_ELEMENT_OBJECT) {
/* triangle and vertex attributes */
- if (prim != PRIM_NONE)
- return get_mesh_element_attribute(kg, sd, attr, type, derivatives, val);
- else
+ if(!get_mesh_element_attribute(kg, sd, attr, type, derivatives, val))
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
}
else {
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index 2592bbe575f..fd0ea7fef31 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -22,12 +22,12 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
uint4 node, NodeAttributeType *type,
NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset)
{
- if(sd->object != OBJECT_NONE && sd->prim != PRIM_NONE) {
+ if(sd->object != OBJECT_NONE) {
/* find attribute by unique id */
uint id = node.y;
uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
#ifdef __HAIR__
- attr_offset = (sd->type & PRIMITIVE_ALL_TRIANGLE)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+ attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
#endif
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index bddeac0b722..a17e4a25efe 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -70,17 +70,10 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
case NODE_TEXCO_VOLUME_GENERATED: {
data = sd->P;
- if(sd->object != OBJECT_NONE) {
- AttributeElement attr_elem;
- int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
-
- object_inverse_position_transform(kg, sd, &data);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
- data = transform_point(&tfm, data);
- }
- }
+#ifdef __VOLUME__
+ if(sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+#endif
break;
}
}
@@ -141,17 +134,10 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
case NODE_TEXCO_VOLUME_GENERATED: {
data = sd->P + sd->dP.dx;
- if(sd->object != OBJECT_NONE) {
- AttributeElement attr_elem;
- int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
-
- object_inverse_position_transform(kg, sd, &data);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
- data = transform_point(&tfm, data);
- }
- }
+#ifdef __VOLUME__
+ if(sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+#endif
break;
}
}
@@ -215,17 +201,10 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
case NODE_TEXCO_VOLUME_GENERATED: {
data = sd->P + sd->dP.dy;
- if(sd->object != OBJECT_NONE) {
- AttributeElement attr_elem;
- int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
-
- object_inverse_position_transform(kg, sd, &data);
-
- if(attr_offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
- data = transform_point(&tfm, data);
- }
- }
+#ifdef __VOLUME__
+ if(sd->object != OBJECT_NONE)
+ data = volume_normalized_position(kg, sd, data);
+#endif
break;
}
}
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index f524a9fa3bc..cd81c33a28f 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -14,6 +14,7 @@
* limitations under the License
*/
+#include "image.h"
#include "mesh.h"
#include "attribute.h"
@@ -25,6 +26,17 @@ CCL_NAMESPACE_BEGIN
/* Attribute */
+Attribute::~Attribute()
+{
+ /* for voxel data, we need to remove the image from the image manager */
+ if(element == ATTR_ELEMENT_VOXEL) {
+ VoxelAttribute *voxel_data = data_voxel();
+
+ if(voxel_data)
+ voxel_data->manager->remove_image(voxel_data->slot);
+ }
+}
+
void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
{
name = name_;
@@ -75,9 +87,20 @@ void Attribute::add(const Transform& f)
buffer.push_back(data[i]);
}
+void Attribute::add(const VoxelAttribute& f)
+{
+ char *data = (char*)&f;
+ size_t size = sizeof(f);
+
+ for(size_t i = 0; i < size; i++)
+ buffer.push_back(data[i]);
+}
+
size_t Attribute::data_sizeof() const
{
- if(type == TypeDesc::TypeFloat)
+ if(element == ATTR_ELEMENT_VOXEL)
+ return sizeof(VoxelAttribute);
+ else if(type == TypeDesc::TypeFloat)
return sizeof(float);
else if(type == TypeDesc::TypeMatrix)
return sizeof(Transform);
@@ -92,6 +115,7 @@ size_t Attribute::element_size(int numverts, int numtris, int numsteps, int numc
switch(element) {
case ATTR_ELEMENT_OBJECT:
case ATTR_ELEMENT_MESH:
+ case ATTR_ELEMENT_VOXEL:
size = 1;
break;
case ATTR_ELEMENT_VERTEX:
@@ -147,40 +171,55 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
const char *Attribute::standard_name(AttributeStandard std)
{
- if(std == ATTR_STD_VERTEX_NORMAL)
- return "N";
- else if(std == ATTR_STD_FACE_NORMAL)
- return "Ng";
- else if(std == ATTR_STD_UV)
- return "uv";
- else if(std == ATTR_STD_GENERATED)
- return "generated";
- else if(std == ATTR_STD_UV_TANGENT)
- return "tangent";
- else if(std == ATTR_STD_UV_TANGENT_SIGN)
- return "tangent_sign";
- else if(std == ATTR_STD_POSITION_UNDEFORMED)
- return "undeformed";
- else if(std == ATTR_STD_POSITION_UNDISPLACED)
- return "undisplaced";
- else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
- return "motion_P";
- else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
- return "motion_N";
- else if(std == ATTR_STD_PARTICLE)
- return "particle";
- else if(std == ATTR_STD_CURVE_INTERCEPT)
- return "curve_intercept";
- else if(std == ATTR_STD_PTEX_FACE_ID)
- return "ptex_face_id";
- else if(std == ATTR_STD_PTEX_UV)
- return "ptex_uv";
- else if(std == ATTR_STD_GENERATED_TRANSFORM)
- return "generated_transform";
+ switch(std) {
+ case ATTR_STD_VERTEX_NORMAL:
+ return "N";
+ case ATTR_STD_FACE_NORMAL:
+ return "Ng";
+ case ATTR_STD_UV:
+ return "uv";
+ case ATTR_STD_GENERATED:
+ return "generated";
+ case ATTR_STD_GENERATED_TRANSFORM:
+ return "generated_transform";
+ case ATTR_STD_UV_TANGENT:
+ return "tangent";
+ case ATTR_STD_UV_TANGENT_SIGN:
+ return "tangent_sign";
+ case ATTR_STD_POSITION_UNDEFORMED:
+ return "undeformed";
+ case ATTR_STD_POSITION_UNDISPLACED:
+ return "undisplaced";
+ case ATTR_STD_MOTION_VERTEX_POSITION:
+ return "motion_P";
+ case ATTR_STD_MOTION_VERTEX_NORMAL:
+ return "motion_N";
+ case ATTR_STD_PARTICLE:
+ return "particle";
+ case ATTR_STD_CURVE_INTERCEPT:
+ return "curve_intercept";
+ case ATTR_STD_PTEX_FACE_ID:
+ return "ptex_face_id";
+ case ATTR_STD_PTEX_UV:
+ return "ptex_uv";
+ case ATTR_STD_NOT_FOUND:
+ case ATTR_STD_NONE:
+ case ATTR_STD_NUM:
+ return "";
+ }
return "";
}
+AttributeStandard Attribute::name_standard(const char *name)
+{
+ for(AttributeStandard std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
+ if(strcmp(name, Attribute::standard_name(std)) == 0)
+ return std;
+
+ return ATTR_STD_NONE;
+}
+
/* Attribute Set */
AttributeSet::AttributeSet()
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index 5160224f4e3..3dc7b7f7401 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -27,12 +27,20 @@
CCL_NAMESPACE_BEGIN
class Attribute;
-class AttributeSet;
class AttributeRequest;
class AttributeRequestSet;
+class AttributeSet;
+class ImageManager;
class Mesh;
struct Transform;
+/* Attributes for voxels are images */
+
+struct VoxelAttribute {
+ ImageManager *manager;
+ int slot;
+};
+
/* Attribute
*
* Arbitrary data layers on meshes.
@@ -48,6 +56,7 @@ public:
AttributeElement element;
Attribute() {}
+ ~Attribute();
void set(ustring name, TypeDesc type, AttributeElement element);
void reserve(int numverts, int numfaces, int numsteps, int numcurves, int numkeys, bool resize);
@@ -60,19 +69,23 @@ public:
float4 *data_float4() { return (float4*)data(); }
float *data_float() { return (float*)data(); }
Transform *data_transform() { return (Transform*)data(); }
+ VoxelAttribute *data_voxel() { return ( VoxelAttribute*)data(); }
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
const float3 *data_float3() const { return (const float3*)data(); }
const float4 *data_float4() const { return (const float4*)data(); }
const float *data_float() const { return (const float*)data(); }
const Transform *data_transform() const { return (const Transform*)data(); }
+ const VoxelAttribute *data_voxel() const { return (const VoxelAttribute*)data(); }
void add(const float& f);
void add(const float3& f);
void add(const Transform& f);
+ void add(const VoxelAttribute& f);
static bool same_storage(TypeDesc a, TypeDesc b);
static const char *standard_name(AttributeStandard std);
+ static AttributeStandard name_standard(const char *name);
};
/* Attribute Set
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 52cd946456f..2ae15e09efb 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -756,7 +756,12 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
mesh->curves.size(),
mesh->curve_keys.size());
- if(mattr->type == TypeDesc::TypeFloat) {
+ if(mattr->element == ATTR_ELEMENT_VOXEL) {
+ /* store slot in offset value */
+ VoxelAttribute *voxel_data = mattr->data_voxel();
+ offset = voxel_data->slot;
+ }
+ else if(mattr->type == TypeDesc::TypeFloat) {
float *data = mattr->data_float();
offset = attr_float.size();
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index d5e358be161..f10b956a482 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2209,8 +2209,9 @@ void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attr
if(shader->has_volume) {
if(!from_dupli) {
- if(!output("Generated")->links.empty())
+ if(!output("Generated")->links.empty()) {
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
}
}
@@ -2629,7 +2630,7 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
if(!intercept_out->links.empty())
attributes->add(ATTR_STD_CURVE_INTERCEPT);
}
-
+
ShaderNode::attributes(shader, attributes);
}
@@ -3143,15 +3144,22 @@ AttributeNode::AttributeNode()
void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
- if(shader->has_surface) {
- ShaderOutput *color_out = output("Color");
- ShaderOutput *vector_out = output("Vector");
- ShaderOutput *fac_out = output("Fac");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *vector_out = output("Vector");
+ ShaderOutput *fac_out = output("Fac");
- if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty())
+ if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) {
+ AttributeStandard std = Attribute::name_standard(attribute.c_str());
+
+ if(std != ATTR_STD_NONE)
+ attributes->add(std);
+ else
attributes->add(attribute);
}
-
+
+ if(shader->has_volume)
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+
ShaderNode::attributes(shader, attributes);
}
@@ -3161,6 +3169,13 @@ void AttributeNode::compile(SVMCompiler& compiler)
ShaderOutput *vector_out = output("Vector");
ShaderOutput *fac_out = output("Fac");
NodeType attr_node = NODE_ATTR;
+ AttributeStandard std = Attribute::name_standard(attribute.c_str());
+ int attr;
+
+ if(std != ATTR_STD_NONE)
+ attr = compiler.attribute(std);
+ else
+ attr = compiler.attribute(attribute);
if(bump == SHADER_BUMP_DX)
attr_node = NODE_ATTR_BUMP_DX;
@@ -3168,8 +3183,6 @@ void AttributeNode::compile(SVMCompiler& compiler)
attr_node = NODE_ATTR_BUMP_DY;
if(!color_out->links.empty() || !vector_out->links.empty()) {
- int attr = compiler.attribute(attribute);
-
if(!color_out->links.empty()) {
compiler.stack_assign(color_out);
compiler.add_node(attr_node, attr, color_out->stack_offset, NODE_ATTR_FLOAT3);
@@ -3181,8 +3194,6 @@ void AttributeNode::compile(SVMCompiler& compiler)
}
if(!fac_out->links.empty()) {
- int attr = compiler.attribute(attribute);
-
compiler.stack_assign(fac_out);
compiler.add_node(attr_node, attr, fac_out->stack_offset, NODE_ATTR_FLOAT);
}
@@ -3196,8 +3207,12 @@ void AttributeNode::compile(OSLCompiler& compiler)
compiler.parameter("bump_offset", "dy");
else
compiler.parameter("bump_offset", "center");
+
+ if(Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE)
+ compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
+ else
+ compiler.parameter("name", attribute.c_str());
- compiler.parameter("name", attribute.c_str());
compiler.add(this, "node_attribute");
}