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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2013-12-31 20:33:55 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2013-12-31 20:38:26 +0400
commit9cd2b199994ba48f343a89a270827b2e0ed3221d (patch)
treea90b3f0b2a5a8869b0fb8552a8d660d3d91209c1 /intern
parent6b03f92aa7bdb10cfde99bc30a7337c843bda57c (diff)
Cycles Volume Render: generated texture coordinates for volume render.
This does not support staying fixed while the surface deforms, but for static meshes it should match up with the surface texture coordinates. Implemented as a matrix transform from objects space to mesh texture space. Making this work for deforming surfaces would be quite complicated, you might need something like harmonic coordinates as used in the mesh deform modifier, probably will not be possible anytime soon.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp17
-rw-r--r--intern/cycles/kernel/kernel_primitive.h17
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp32
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp4
-rw-r--r--intern/cycles/kernel/shaders/node_texture_coordinate.osl10
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h90
-rw-r--r--intern/cycles/kernel/svm/svm_types.h6
-rw-r--r--intern/cycles/render/attribute.cpp25
-rw-r--r--intern/cycles/render/attribute.h4
-rw-r--r--intern/cycles/render/graph.cpp4
-rw-r--r--intern/cycles/render/mesh.cpp19
-rw-r--r--intern/cycles/render/nodes.cpp13
13 files changed, 200 insertions, 45 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 0e46903a50c..c761c004fe7 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -348,9 +348,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
}
}
- /* create generated coordinates. todo: we should actually get the orco
- * coordinates from modifiers, for now we use texspace loc/size which
- * is available in the api. */
+ /* create generated coordinates from undeformed coordinates */
if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
@@ -363,6 +361,19 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
generated[i++] = get_float3(v->undeformed_co())*size - loc;
}
+
+ /* for volume objects, create a matrix to transform from object space to
+ * mesh texture space. this does not work with deformations but that can
+ * probably only be done well with a volume grid mapping of coordinates */
+ if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
+ Transform *tfm = attr->data_transform();
+
+ float3 loc, size;
+ mesh_texture_space(b_mesh, loc, size);
+
+ *tfm = transform_translate(-loc)*transform_scale(size);
+ }
}
static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, const vector<uint>& used_shaders)
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
index 5a050c443da..fa450c97cbf 100644
--- a/intern/cycles/kernel/kernel_primitive.h
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -23,7 +23,7 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
{
- if(sd->object == ~0 || sd->prim == ~0)
+ if(sd->object == ~0)
return (int)ATTR_STD_NOT_FOUND;
#ifdef __OSL__
@@ -47,6 +47,9 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id,
*elem = (AttributeElement)attr_map.y;
+ if(sd->prim == ~0 && (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;
}
@@ -76,6 +79,18 @@ ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData
#endif
}
+ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
+{
+ Transform tfm;
+
+ tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0);
+ tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1);
+ tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2);
+ tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3);
+
+ return tfm;
+}
+
ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
{
AttributeElement elem_uv;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 1463ce98d15..00cb73b1e34 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -418,7 +418,8 @@ typedef struct Intersection {
typedef enum AttributeElement {
ATTR_ELEMENT_NONE,
- ATTR_ELEMENT_VALUE,
+ ATTR_ELEMENT_OBJECT,
+ ATTR_ELEMENT_MESH,
ATTR_ELEMENT_FACE,
ATTR_ELEMENT_VERTEX,
ATTR_ELEMENT_CORNER,
@@ -434,6 +435,7 @@ typedef enum AttributeStandard {
ATTR_STD_UV_TANGENT,
ATTR_STD_UV_TANGENT_SIGN,
ATTR_STD_GENERATED,
+ ATTR_STD_GENERATED_TRANSFORM,
ATTR_STD_POSITION_UNDEFORMED,
ATTR_STD_POSITION_UNDISPLACED,
ATTR_STD_MOTION_PRE,
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index d7d3301c0b0..9b2065d8892 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -510,12 +510,22 @@ static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives,
return false;
}
-static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
+static bool set_attribute_matrix(const Transform& tfm, TypeDesc type, void *val)
+{
+ if(type == TypeDesc::TypeMatrix) {
+ Transform transpose = transform_transpose(tfm);
+ memcpy(val, &transpose, sizeof(Transform));
+ return true;
+ }
+
+ return false;
+}
+
+static bool get_mesh_element_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
const TypeDesc& type, bool derivatives, void *val)
{
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
- {
+ attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
float3 fval[3];
fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset,
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
@@ -532,6 +542,18 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OS
}
}
+static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
+ const TypeDesc& type, bool derivatives, void *val)
+{
+ if (attr.type == TypeDesc::TypeMatrix) {
+ Transform tfm = primitive_attribute_matrix(kg, sd, attr.offset);
+ return set_attribute_matrix(tfm, type, val);
+ }
+ else {
+ return false;
+ }
+}
+
static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
{
size_t datasize = attr.value.datasize();
@@ -745,9 +767,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (it != attribute_map.end()) {
const OSLGlobals::Attribute& attr = it->second;
- if (attr.elem != ATTR_ELEMENT_VALUE) {
+ if (attr.elem != ATTR_ELEMENT_OBJECT) {
/* triangle and vertex attributes */
if (prim != ~0)
+ return get_mesh_element_attribute(kg, sd, attr, type, derivatives, val);
+ else
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
}
else {
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 6062996af36..554f647df7c 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -545,6 +545,10 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id,
if (it != attr_map.end()) {
const OSLGlobals::Attribute &osl_attr = it->second;
*elem = osl_attr.elem;
+
+ if(sd->prim == ~0 && (AttributeElement)osl_attr.elem != ATTR_ELEMENT_MESH)
+ return ATTR_STD_NOT_FOUND;
+
/* return result */
return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
}
diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
index 8739b77ca78..fdd0a51013b 100644
--- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
@@ -19,6 +19,7 @@
shader node_texture_coordinate(
normal NormalIn = N,
int is_background = 0,
+ int is_volume = 0,
int from_dupli = 0,
string bump_offset = "center",
@@ -45,6 +46,15 @@ shader node_texture_coordinate(
getattribute("geom:dupli_generated", Generated);
getattribute("geom:dupli_uv", UV);
}
+ else if(is_volume) {
+ Generated = transform("object", P);
+
+ matrix tfm;
+ if(getattribute("geom:generated_transform", tfm))
+ Generated = transform(tfm, Generated);
+
+ getattribute("geom:uv", UV);
+ }
else {
getattribute("geom:generated", Generated);
getattribute("geom:uv", UV);
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 3044cbf81e0..4b1f30e55bb 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -24,21 +24,15 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
switch(type) {
case NODE_TEXCO_OBJECT: {
- if(sd->object != ~0) {
- data = sd->P;
+ data = sd->P;
+ if(sd->object != ~0)
object_inverse_position_transform(kg, sd, &data);
- }
- else
- data = sd->P;
break;
}
case NODE_TEXCO_NORMAL: {
- if(sd->object != ~0) {
- data = sd->N;
+ data = sd->N;
+ if(sd->object != ~0)
object_inverse_normal_transform(kg, sd, &data);
- }
- else
- data = sd->N;
break;
}
case NODE_TEXCO_CAMERA: {
@@ -73,6 +67,22 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
data = object_dupli_uv(kg, sd->object);
break;
}
+ case NODE_TEXCO_VOLUME_GENERATED: {
+ data = sd->P;
+
+ if(sd->object != ~0) {
+ 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);
+ }
+ }
+ break;
+ }
}
stack_store_float3(stack, out_offset, data);
@@ -85,21 +95,15 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
switch(type) {
case NODE_TEXCO_OBJECT: {
- if(sd->object != ~0) {
- data = sd->P + sd->dP.dx;
+ data = sd->P + sd->dP.dx;
+ if(sd->object != ~0)
object_inverse_position_transform(kg, sd, &data);
- }
- else
- data = sd->P + sd->dP.dx;
break;
}
case NODE_TEXCO_NORMAL: {
- if(sd->object != ~0) {
- data = sd->N;
+ data = sd->N;
+ if(sd->object != ~0)
object_inverse_normal_transform(kg, sd, &data);
- }
- else
- data = sd->N;
break;
}
case NODE_TEXCO_CAMERA: {
@@ -134,6 +138,22 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
data = object_dupli_uv(kg, sd->object);
break;
}
+ case NODE_TEXCO_VOLUME_GENERATED: {
+ data = sd->P + sd->dP.dx;
+
+ if(sd->object != ~0) {
+ 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);
+ }
+ }
+ break;
+ }
}
stack_store_float3(stack, out_offset, data);
@@ -149,21 +169,15 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
switch(type) {
case NODE_TEXCO_OBJECT: {
- if(sd->object != ~0) {
- data = sd->P + sd->dP.dy;
+ data = sd->P + sd->dP.dy;
+ if(sd->object != ~0)
object_inverse_position_transform(kg, sd, &data);
- }
- else
- data = sd->P + sd->dP.dy;
break;
}
case NODE_TEXCO_NORMAL: {
- if(sd->object != ~0) {
- data = sd->N;
+ data = sd->N;
+ if(sd->object != ~0)
object_inverse_normal_transform(kg, sd, &data);
- }
- else
- data = sd->N;
break;
}
case NODE_TEXCO_CAMERA: {
@@ -198,6 +212,22 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
data = object_dupli_uv(kg, sd->object);
break;
}
+ case NODE_TEXCO_VOLUME_GENERATED: {
+ data = sd->P + sd->dP.dy;
+
+ if(sd->object != ~0) {
+ 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);
+ }
+ }
+ break;
+ }
}
stack_store_float3(stack, out_offset, data);
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index e6df5fe17b7..9850a058611 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -107,7 +107,8 @@ typedef enum NodeType {
typedef enum NodeAttributeType {
NODE_ATTR_FLOAT = 0,
- NODE_ATTR_FLOAT3
+ NODE_ATTR_FLOAT3,
+ NODE_ATTR_MATRIX
} NodeAttributeType;
typedef enum NodeGeometry {
@@ -173,7 +174,8 @@ typedef enum NodeTexCoord {
NODE_TEXCO_WINDOW,
NODE_TEXCO_REFLECTION,
NODE_TEXCO_DUPLI_GENERATED,
- NODE_TEXCO_DUPLI_UV
+ NODE_TEXCO_DUPLI_UV,
+ NODE_TEXCO_VOLUME_GENERATED
} NodeTexCoord;
typedef enum NodeMix {
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 6640439eca9..61b9cf2f3bc 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -19,6 +19,7 @@
#include "util_debug.h"
#include "util_foreach.h"
+#include "util_transform.h"
CCL_NAMESPACE_BEGIN
@@ -34,7 +35,7 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
/* string and matrix not supported! */
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
- type == TypeDesc::TypeNormal);
+ type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix);
}
void Attribute::reserve(int numverts, int numtris, int numcurves, int numkeys)
@@ -60,10 +61,21 @@ void Attribute::add(const float3& f)
buffer.push_back(data[i]);
}
+void Attribute::add(const Transform& 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)
return sizeof(float);
+ else if(type == TypeDesc::TypeMatrix)
+ return sizeof(Transform);
else
return sizeof(float3);
}
@@ -73,7 +85,8 @@ size_t Attribute::element_size(int numverts, int numtris, int numcurves, int num
size_t size;
switch(element) {
- case ATTR_ELEMENT_VALUE:
+ case ATTR_ELEMENT_OBJECT:
+ case ATTR_ELEMENT_MESH:
size = 1;
break;
case ATTR_ELEMENT_VERTEX:
@@ -151,6 +164,8 @@ const char *Attribute::standard_name(AttributeStandard std)
return "ptex_face_id";
else if(std == ATTR_STD_PTEX_UV)
return "ptex_uv";
+ else if(std == ATTR_STD_GENERATED_TRANSFORM)
+ return "generated_transform";
return "";
}
@@ -256,6 +271,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_PTEX_UV:
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
break;
+ case ATTR_STD_GENERATED_TRANSFORM:
+ attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
+ break;
default:
assert(0);
break;
@@ -274,6 +292,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_CURVE_INTERCEPT:
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY);
break;
+ case ATTR_STD_GENERATED_TRANSFORM:
+ attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
+ break;
default:
assert(0);
break;
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index e17a65914dd..0b8905ae5a3 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -31,6 +31,7 @@ class AttributeSet;
class AttributeRequest;
class AttributeRequestSet;
class Mesh;
+struct Transform;
/* Attribute
*
@@ -57,13 +58,16 @@ public:
char *data() { return (buffer.size())? &buffer[0]: NULL; };
float3 *data_float3() { return (float3*)data(); }
float *data_float() { return (float*)data(); }
+ Transform *data_transform() { return (Transform*)data(); }
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
const float3 *data_float3() const { return (const float3*)data(); }
const float *data_float() const { return (const float*)data(); }
+ const Transform *data_transform() const { return (const Transform*)data(); }
void add(const float& f);
void add(const float3& f);
+ void add(const Transform& f);
static bool same_storage(TypeDesc a, TypeDesc b);
static const char *standard_name(AttributeStandard std);
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index af57470aa89..4256c5ed95b 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -120,8 +120,10 @@ void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
foreach(ShaderInput *input, inputs) {
if(!input->link) {
- if(input->default_value == ShaderInput::TEXTURE_GENERATED)
+ if(input->default_value == ShaderInput::TEXTURE_GENERATED) {
attributes->add(ATTR_STD_GENERATED);
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM); // XXX only for volumes!
+ }
else if(input->default_value == ShaderInput::TEXTURE_UV)
attributes->add(ATTR_STD_UV);
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index ecae35ae5ea..93f24886dc9 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -466,7 +466,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
OSLGlobals::Attribute osl_attr;
osl_attr.type = attr.type();
- osl_attr.elem = ATTR_ELEMENT_VALUE;
+ osl_attr.elem = ATTR_ELEMENT_OBJECT;
osl_attr.value = attr;
osl_attr.offset = 0;
@@ -493,6 +493,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
if(req.triangle_type == TypeDesc::TypeFloat)
osl_attr.type = TypeDesc::TypeFloat;
+ else if(req.triangle_type == TypeDesc::TypeMatrix)
+ osl_attr.type = TypeDesc::TypeMatrix;
else
osl_attr.type = TypeDesc::TypeColor;
@@ -513,6 +515,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
if(req.curve_type == TypeDesc::TypeFloat)
osl_attr.type = TypeDesc::TypeFloat;
+ else if(req.curve_type == TypeDesc::TypeMatrix)
+ osl_attr.type = TypeDesc::TypeMatrix;
else
osl_attr.type = TypeDesc::TypeColor;
@@ -580,6 +584,8 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
if(req.triangle_type == TypeDesc::TypeFloat)
attr_map[index].w = NODE_ATTR_FLOAT;
+ else if(req.triangle_type == TypeDesc::TypeMatrix)
+ attr_map[index].w = NODE_ATTR_MATRIX;
else
attr_map[index].w = NODE_ATTR_FLOAT3;
}
@@ -593,6 +599,8 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
if(req.curve_type == TypeDesc::TypeFloat)
attr_map[index].w = NODE_ATTR_FLOAT;
+ else if(req.curve_type == TypeDesc::TypeMatrix)
+ attr_map[index].w = NODE_ATTR_MATRIX;
else
attr_map[index].w = NODE_ATTR_FLOAT3;
}
@@ -645,6 +653,15 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
for(size_t k = 0; k < size; k++)
attr_float[offset+k] = data[k];
}
+ else if(mattr->type == TypeDesc::TypeMatrix) {
+ Transform *tfm = mattr->data_transform();
+ offset = attr_float3.size();
+
+ attr_float3.resize(attr_float3.size() + size*4);
+
+ for(size_t k = 0; k < size*4; k++)
+ attr_float3[offset+k] = (&tfm->x)[k];
+ }
else {
float3 *data = mattr->data_float3();
offset = attr_float3.size();
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index c6c050cd718..7bd370f6b26 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2193,6 +2193,13 @@ void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attr
}
}
+ if(shader->has_volume) {
+ if(!from_dupli) {
+ if(!output("Generated")->links.empty())
+ attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+ }
+ }
+
ShaderNode::attributes(shader, attributes);
}
@@ -2225,6 +2232,10 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
compiler.stack_assign(out);
compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, out->stack_offset);
}
+ else if(compiler.output_type() == SHADER_TYPE_VOLUME) {
+ compiler.stack_assign(out);
+ compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, out->stack_offset);
+ }
else {
int attr = compiler.attribute(ATTR_STD_GENERATED);
compiler.stack_assign(out);
@@ -2294,6 +2305,8 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler)
if(compiler.background)
compiler.parameter("is_background", true);
+ if(compiler.output_type() == SHADER_TYPE_VOLUME)
+ compiler.parameter("is_volume", true);
compiler.parameter("from_dupli", from_dupli);