diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-08-31 23:38:59 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-08-31 23:38:59 +0400 |
commit | 9e3fa15d4b3e22127471a7451a49b594cf6275a0 (patch) | |
tree | 5891c5922401980fbb0843a60abd45278278f0c5 | |
parent | f0d247748408bd10f49c54d3a28a925e37683c4b (diff) |
Added a bunch of additional particle state attributes to the Cycles particle info node:
* Location: Basically the same as the location from Object Info node for object instances on particles, but in principle there could be additional offsets for dupli objects, so included for completeness.
* Size: Single float scale of the particle. Also directly translates to object scale for current dupli objects, but handy to have as a single float to start with instead of a scale vector (currently not even exposed in Object Info).
* Rotation: This is a quaternion, which are not yet supported by Cycles nodes. The float4 is copied to internal Cycles data and stored in the particles texture data, but the node doesn't have a socket for it yet and the data is not yet written to the stack. Code is just commented out so could be enabled quickly if/when rotation support is added to cycles.
* Velocity: Linear velocity vector of particles.
* Angular Velocity: Angular velocity around principle axes.
The texture data is currently packed tightly into the particles texture, which saves a few bytes, but requires an additional texture lookup for some vector attributes which spread over two float4s. Could also add another float4 to particle size to avoid this.
-rw-r--r-- | intern/cycles/blender/blender_particles.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_object.h | 43 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_geometry.h | 38 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 7 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 51 | ||||
-rw-r--r-- | intern/cycles/render/particles.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/render/particles.h | 5 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_particle_info.c | 7 |
10 files changed, 155 insertions, 14 deletions
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index 337ec36d107..74142f481ed 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -168,6 +168,11 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) pa.index = index; pa.age = b_scene.frame_current() - b_pa->birth_time(); pa.lifetime = b_pa->lifetime(); + pa.location = get_float3(b_pa->location()); + pa.rotation = get_float4(b_pa->rotation()); + pa.size = b_pa->size(); + pa.velocity = get_float3(b_pa->velocity()); + pa.angular_velocity = get_float3(b_pa->angular_velocity()); psys->particles.push_back(pa); } diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index b6609377561..2e9b201c0e2 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -150,6 +150,11 @@ static inline float3 get_float3(BL::Array<float, 4> array) return make_float3(array[0], array[1], array[2]); } +static inline float4 get_float4(BL::Array<float, 4> array) +{ + return make_float4(array[0], array[1], array[2], array[3]); +} + static inline int4 get_int4(BL::Array<int, 4> array) { return make_int4(array[0], array[1], array[2], array[3]); diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 4ff315ca265..222ade504cc 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -172,24 +172,61 @@ __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) __device_inline float particle_index(KernelGlobals *kg, int particle) { int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset); + float4 f = kernel_tex_fetch(__particles, offset + 0); return f.x; } __device float particle_age(KernelGlobals *kg, int particle) { int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset); + float4 f = kernel_tex_fetch(__particles, offset + 0); return f.y; } __device float particle_lifetime(KernelGlobals *kg, int particle) { int offset = particle*PARTICLE_SIZE; - float4 f = kernel_tex_fetch(__particles, offset); + float4 f = kernel_tex_fetch(__particles, offset + 0); return f.z; } +__device float particle_size(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f = kernel_tex_fetch(__particles, offset + 0); + return f.w; +} + +__device float4 particle_rotation(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f = kernel_tex_fetch(__particles, offset + 1); + return f; +} + +__device float3 particle_location(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f = kernel_tex_fetch(__particles, offset + 2); + return make_float3(f.x, f.y, f.z); +} + +__device float3 particle_velocity(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f2 = kernel_tex_fetch(__particles, offset + 2); + float4 f3 = kernel_tex_fetch(__particles, offset + 3); + return make_float3(f2.w, f3.x, f3.y); +} + +__device float3 particle_angular_velocity(KernelGlobals *kg, int particle) +{ + int offset = particle*PARTICLE_SIZE; + float4 f3 = kernel_tex_fetch(__particles, offset + 3); + float4 f4 = kernel_tex_fetch(__particles, offset + 4); + return make_float3(f3.z, f3.w, f4.x); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 30d45ad1118..488c6de3a42 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -33,7 +33,7 @@ CCL_NAMESPACE_BEGIN #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 -#define PARTICLE_SIZE 1 +#define PARTICLE_SIZE 5 #define TIME_INVALID FLT_MAX /* device capabilities */ diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 3cfce1d087a..22741bdb067 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -98,25 +98,47 @@ __device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *sta __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { - float data; - switch(type) { case NODE_INFO_PAR_INDEX: { uint particle_id = object_particle_id(kg, sd->object); - data = particle_index(kg, particle_id); - stack_store_float(stack, out_offset, data); + stack_store_float(stack, out_offset, particle_index(kg, particle_id)); break; } case NODE_INFO_PAR_AGE: { uint particle_id = object_particle_id(kg, sd->object); - data = particle_age(kg, particle_id); - stack_store_float(stack, out_offset, data); + stack_store_float(stack, out_offset, particle_age(kg, particle_id)); break; } case NODE_INFO_PAR_LIFETIME: { uint particle_id = object_particle_id(kg, sd->object); - data = particle_lifetime(kg, particle_id); - stack_store_float(stack, out_offset, data); + stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id)); + break; + } + case NODE_INFO_PAR_LOCATION: { + uint particle_id = object_particle_id(kg, sd->object); + stack_store_float3(stack, out_offset, particle_location(kg, particle_id)); + break; + } + #if 0 /* XXX float4 currently not supported in SVM stack */ + case NODE_INFO_PAR_ROTATION: { + uint particle_id = object_particle_id(kg, sd->object); + stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id)); + break; + } + #endif + case NODE_INFO_PAR_SIZE: { + uint particle_id = object_particle_id(kg, sd->object); + stack_store_float(stack, out_offset, particle_size(kg, particle_id)); + break; + } + case NODE_INFO_PAR_VELOCITY: { + uint particle_id = object_particle_id(kg, sd->object); + stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id)); + break; + } + case NODE_INFO_PAR_ANGULAR_VELOCITY: { + uint particle_id = object_particle_id(kg, sd->object); + stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id)); break; } } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 38232eb9c04..16c726e7faa 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -116,7 +116,12 @@ typedef enum NodeObjectInfo { typedef enum NodeParticleInfo { NODE_INFO_PAR_INDEX, NODE_INFO_PAR_AGE, - NODE_INFO_PAR_LIFETIME + NODE_INFO_PAR_LIFETIME, + NODE_INFO_PAR_LOCATION, + NODE_INFO_PAR_ROTATION, + NODE_INFO_PAR_SIZE, + NODE_INFO_PAR_VELOCITY, + NODE_INFO_PAR_ANGULAR_VELOCITY } NodeParticleInfo; typedef enum NodeLightPath { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index b35fe151bac..3d9055119ed 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1801,6 +1801,13 @@ ParticleInfoNode::ParticleInfoNode() add_output("Index", SHADER_SOCKET_FLOAT); add_output("Age", SHADER_SOCKET_FLOAT); add_output("Lifetime", SHADER_SOCKET_FLOAT); + add_output("Location", SHADER_SOCKET_POINT); + #if 0 /* not yet supported */ + add_output("Rotation", SHADER_SOCKET_QUATERNION); + #endif + add_output("Size", SHADER_SOCKET_FLOAT); + add_output("Velocity", SHADER_SOCKET_VECTOR); + add_output("Angular Velocity", SHADER_SOCKET_VECTOR); } void ParticleInfoNode::attributes(AttributeRequestSet *attributes) @@ -1811,6 +1818,18 @@ void ParticleInfoNode::attributes(AttributeRequestSet *attributes) attributes->add(ATTR_STD_PARTICLE); if(!output("Lifetime")->links.empty()) attributes->add(ATTR_STD_PARTICLE); + if(!output("Location")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); + #if 0 /* not yet supported */ + if(!output("Rotation")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); + #endif + if(!output("Size")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); + if(!output("Velocity")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); + if(!output("Angular Velocity")->links.empty()) + attributes->add(ATTR_STD_PARTICLE); ShaderNode::attributes(attributes); } @@ -1836,6 +1855,38 @@ void ParticleInfoNode::compile(SVMCompiler& compiler) compiler.stack_assign(out); compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, out->stack_offset); } + + out = output("Location"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, out->stack_offset); + } + + #if 0 /* XXX Quaternion data is not yet supported by Cycles */ + out = output("Rotation"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, out->stack_offset); + } + #endif + + out = output("Size"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, out->stack_offset); + } + + out = output("Velocity"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, out->stack_offset); + } + + out = output("Angular Velocity"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, out->stack_offset); + } } void ParticleInfoNode::compile(OSLCompiler& compiler) diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp index 539a2333506..c3e4b9510de 100644 --- a/intern/cycles/render/particles.cpp +++ b/intern/cycles/render/particles.cpp @@ -74,7 +74,11 @@ void ParticleSystemManager::device_update_particles(Device *device, DeviceScene /* pack in texture */ int offset = i*PARTICLE_SIZE; - particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, 0.0f); + particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size); + particles[offset+1] = pa.rotation; + particles[offset+2] = make_float4(pa.location.x, pa.location.y, pa.location.z, pa.velocity.x); + particles[offset+3] = make_float4(pa.velocity.y, pa.velocity.z, pa.angular_velocity.x, pa.angular_velocity.y); + particles[offset+4] = make_float4(pa.angular_velocity.z, 0.0f, 0.0f, 0.0f); i++; diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h index e5481ad4c24..afc8b2b2dcb 100644 --- a/intern/cycles/render/particles.h +++ b/intern/cycles/render/particles.h @@ -35,6 +35,11 @@ struct Particle { int index; float age; float lifetime; + float3 location; + float4 rotation; + float size; + float3 velocity; + float3 angular_velocity; }; class ParticleSystem { diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c index 5be8925b556..ddfcb9476f4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c @@ -31,6 +31,13 @@ static bNodeSocketTemplate outputs[] = { { SOCK_FLOAT, 0, "Index" }, { SOCK_FLOAT, 0, "Age" }, { SOCK_FLOAT, 0, "Lifetime" }, + { SOCK_VECTOR, 0, "Location" }, + #if 0 /* quaternion sockets not yet supported */ + { SOCK_QUATERNION, 0, "Rotation" }, + #endif + { SOCK_FLOAT, 0, "Size" }, + { SOCK_VECTOR, 0, "Velocity" }, + { SOCK_VECTOR, 0, "Angular Velocity" }, { -1, 0, "" } }; |