Cycles: restore Particle Info Index for now, keep it next to Random.

It seems to be useful still in cases where the particle are distributed in
a particular order or pattern, to colorize them along with that. This isn't
really well defined, but might as well avoid breaking backwards compatibility
for now.
This commit is contained in:
Brecht Van Lommel 2018-02-14 17:02:28 +01:00
parent f6107af4cf
commit b5fe00d1ac
15 changed files with 47 additions and 18 deletions

View File

@ -352,11 +352,11 @@ ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)
/* Particle data from which object was instanced */
ccl_device_inline float particle_random(KernelGlobals *kg, int particle)
ccl_device_inline uint particle_index(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.x;
return __float_as_uint(f.x);
}
ccl_device float particle_age(KernelGlobals *kg, int particle)

View File

@ -82,6 +82,7 @@ ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated");
ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv");
ustring OSLRenderServices::u_material_index("material:index");
ustring OSLRenderServices::u_object_random("object:random");
ustring OSLRenderServices::u_particle_index("particle:index");
ustring OSLRenderServices::u_particle_random("particle:random");
ustring OSLRenderServices::u_particle_age("particle:age");
ustring OSLRenderServices::u_particle_lifetime("particle:lifetime");
@ -652,11 +653,17 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD
}
/* Particle Attributes */
else if(name == u_particle_random) {
else if(name == u_particle_index) {
int particle_id = object_particle_id(kg, sd->object);
float f = particle_random(kg, particle_id);
float f = particle_index(kg, particle_id);
return set_attribute_float(f, type, derivatives, val);
}
else if(name == u_particle_random) {
int particle_id = object_particle_id(kg, sd->object);
float f = hash_int_01(particle_index(kg, particle_id));
return set_attribute_float(f, type, derivatives, val);
}
else if(name == u_particle_age) {
int particle_id = object_particle_id(kg, sd->object);
float f = particle_age(kg, particle_id);

View File

@ -146,6 +146,7 @@ public:
static ustring u_geom_dupli_uv;
static ustring u_material_index;
static ustring u_object_random;
static ustring u_particle_index;
static ustring u_particle_random;
static ustring u_particle_age;
static ustring u_particle_lifetime;

View File

@ -17,6 +17,7 @@
#include "stdosl.h"
shader node_particle_info(
output float Index = 0.0,
output float Random = 0.0,
output float Age = 0.0,
output float Lifetime = 0.0,
@ -25,6 +26,7 @@ shader node_particle_info(
output vector Velocity = point(0.0, 0.0, 0.0),
output vector AngularVelocity = point(0.0, 0.0, 0.0))
{
getattribute("particle:index", Index);
getattribute("particle:random", Random);
getattribute("particle:age", Age);
getattribute("particle:lifetime", Lifetime);

View File

@ -114,9 +114,15 @@ ccl_device void svm_node_particle_info(KernelGlobals *kg,
uint out_offset)
{
switch(type) {
case NODE_INFO_PAR_INDEX: {
int particle_id = object_particle_id(kg, sd->object);
stack_store_float(stack, out_offset, particle_index(kg, particle_id));
break;
}
case NODE_INFO_PAR_RANDOM: {
int particle_id = object_particle_id(kg, sd->object);
stack_store_float(stack, out_offset, particle_random(kg, particle_id));
float random = hash_int_01(particle_index(kg, particle_id));
stack_store_float(stack, out_offset, random);
break;
}
case NODE_INFO_PAR_AGE: {

View File

@ -160,6 +160,7 @@ typedef enum NodeObjectInfo {
} NodeObjectInfo;
typedef enum NodeParticleInfo {
NODE_INFO_PAR_INDEX,
NODE_INFO_PAR_RANDOM,
NODE_INFO_PAR_AGE,
NODE_INFO_PAR_LIFETIME,

View File

@ -3463,6 +3463,7 @@ NODE_DEFINE(ParticleInfoNode)
{
NodeType* type = NodeType::add("particle_info", create, NodeType::SHADER);
SOCKET_OUT_FLOAT(random, "Index");
SOCKET_OUT_FLOAT(random, "Random");
SOCKET_OUT_FLOAT(age, "Age");
SOCKET_OUT_FLOAT(lifetime, "Lifetime");
@ -3484,6 +3485,8 @@ ParticleInfoNode::ParticleInfoNode()
void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if(!output("Index")->links.empty())
attributes->add(ATTR_STD_PARTICLE);
if(!output("Random")->links.empty())
attributes->add(ATTR_STD_PARTICLE);
if(!output("Age")->links.empty())
@ -3510,6 +3513,11 @@ void ParticleInfoNode::compile(SVMCompiler& compiler)
{
ShaderOutput *out;
out = output("Index");
if(!out->links.empty()) {
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out));
}
out = output("Random");
if(!out->links.empty()) {
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out));

View File

@ -80,8 +80,7 @@ void ParticleSystemManager::device_update_particles(Device *, DeviceScene *dscen
Particle& pa = psys->particles[k];
int offset = i*PARTICLE_SIZE;
float random = hash_int_01(pa.index);
particles[offset] = make_float4(random, pa.age, pa.lifetime, pa.size);
particles[offset] = make_float4(__uint_as_float(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);

View File

@ -344,10 +344,9 @@ void GPU_zenith_update_color(float color[3]);
struct GPUParticleInfo
{
float scalprops[4];
float location[3];
float location[4];
float velocity[3];
float angular_velocity[3];
int random_id;
};
#ifdef WITH_OPENSUBDIV

View File

@ -1884,12 +1884,14 @@ static int gpu_get_particle_info(GPUParticleInfo *pi)
if (ind >= 0) {
ParticleData *p = &dob->particle_system->particles[ind];
pi->scalprops[0] = BLI_hash_int_01(ind);
pi->scalprops[0] = ind;
pi->scalprops[1] = GMS.gscene->r.cfra - p->time;
pi->scalprops[2] = p->lifetime;
pi->scalprops[3] = p->size;
copy_v3_v3(pi->location, p->state.co);
pi->location[3] = BLI_hash_int_01(ind);
copy_v3_v3(pi->velocity, p->state.vel);
copy_v3_v3(pi->angular_velocity, p->state.ave);
return 1;

View File

@ -452,7 +452,7 @@ void GPU_material_bind_uniforms(
GPU_shader_uniform_vector(shader, material->partscalarpropsloc, 4, 1, pi->scalprops);
}
if (material->builtins & GPU_PARTICLE_LOCATION) {
GPU_shader_uniform_vector(shader, material->partcoloc, 3, 1, pi->location);
GPU_shader_uniform_vector(shader, material->partcoloc, 4, 1, pi->location);
}
if (material->builtins & GPU_PARTICLE_VELOCITY) {
GPU_shader_uniform_vector(shader, material->partvel, 3, 1, pi->velocity);

View File

@ -189,16 +189,18 @@ void geom(
}
void particle_info(
vec4 sprops, vec3 loc, vec3 vel, vec3 avel,
out float random, out float age, out float life_time, out vec3 location,
vec4 sprops, vec4 loc, vec3 vel, vec3 avel,
out float index, out float random, out float age,
out float life_time, out vec3 location,
out float size, out vec3 velocity, out vec3 angular_velocity)
{
random = sprops.x;
index = sprops.x;
random = loc.w;
age = sprops.y;
life_time = sprops.z;
size = sprops.w;
location = loc;
location = loc.xyz;
velocity = vel;
angular_velocity = avel;
}

View File

@ -29,6 +29,7 @@
#include "RE_shader_ext.h"
static bNodeSocketTemplate outputs[] = {
{ SOCK_FLOAT, 0, "Index" },
{ SOCK_FLOAT, 0, "Random" },
{ SOCK_FLOAT, 0, "Age" },
{ SOCK_FLOAT, 0, "Lifetime" },
@ -45,7 +46,7 @@ static void node_shader_exec_particle_info(void *data, int UNUSED(thread), bNode
{
ShadeInput *shi = ((ShaderCallData *)data)->shi;
RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec);
RE_instance_get_particle_info(shi->obi, out[0]->vec, out[1]->vec, out[2]->vec, out[3]->vec, out[4]->vec, out[5]->vec, out[6]->vec, out[7]->vec);
}
static int gpu_shader_particle_info(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)

View File

@ -217,7 +217,7 @@ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3],
const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex,
struct ImagePool *pool);
float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]);
void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]);
void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]);
float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta);

View File

@ -1482,9 +1482,10 @@ ObjectInstanceRen *RE_addRenderInstance(
return obi;
}
void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3])
void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3])
{
*index = obi->part_index;
*random = BLI_hash_int_01(obi->part_index);
*age = obi->part_age;
*lifetime = obi->part_lifetime;
copy_v3_v3(co, obi->part_co);