* Some more tweaks to particle density rendering. I'm not 100%
sure if this is 'correct' but so far in testing it's been working pretty well. This also exposes a new 'Nearest' value, to determine how many nearby particles are taken into account when determining density. A greater number is more accurate, but slower.
This commit is contained in:
@@ -173,7 +173,9 @@ void init_material(Material *ma)
|
||||
ma->vol_scattering = 1.0f;
|
||||
ma->vol_absorption_col[0] = ma->vol_absorption_col[1] = ma->vol_absorption_col[2] = 0.0f;
|
||||
ma->vol_raydepth = 15;
|
||||
|
||||
ma->vol_part_maxnearest = 5;
|
||||
ma->vol_part_searchradius = 0.2f;
|
||||
|
||||
ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_RAYBIAS|MA_TANGENT_STR;
|
||||
|
||||
ma->preview = NULL;
|
||||
|
||||
@@ -7872,6 +7872,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
ma->vol_scattering = 1.0f;
|
||||
ma->vol_absorption_col[0] = ma->vol_absorption_col[1] = ma->vol_absorption_col[2] = 0.0f;
|
||||
if (ma->vol_raydepth == 0) ma->vol_raydepth = 15;
|
||||
if (ma->vol_part_maxnearest == 0) ma->vol_part_maxnearest = 5;
|
||||
if (ma->vol_part_searchradius < 0.001f) ma->vol_part_searchradius = 0.20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,10 @@ typedef struct Material {
|
||||
float vol_absorption_col[3];
|
||||
float vol_part_searchradius;
|
||||
short vol_raydepth;
|
||||
short vol_part_maxnearest;
|
||||
short vol_shadeflag;
|
||||
short vol_pad[3];
|
||||
|
||||
|
||||
float fresnel_mir, fresnel_mir_i;
|
||||
float fresnel_tra, fresnel_tra_i;
|
||||
|
||||
@@ -1051,7 +1051,7 @@ ParticleRen *RE_cache_particle(Render *re, float *co, int index, float *vec)
|
||||
BLI_addtail(&re->vol_particles, pr);
|
||||
*/
|
||||
|
||||
BLI_kdtree_insert(re->particles_tree, index, co, vec);
|
||||
BLI_kdtree_insert(re->particles_tree, index, co, NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -129,8 +129,8 @@ static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco,
|
||||
}
|
||||
|
||||
/* need to figure out a good default here */
|
||||
#define MAX_PARTICLES_NEAREST 10
|
||||
float get_particle_density(float *co, float radius)
|
||||
#define MAX_PARTICLES_NEAREST 50
|
||||
float get_particle_density(float *co, float radius, int max_nearest)
|
||||
{
|
||||
KDTreeNearest nearest[MAX_PARTICLES_NEAREST];
|
||||
float density=0.0f;
|
||||
@@ -140,14 +140,20 @@ float get_particle_density(float *co, float radius)
|
||||
* can check for existence of particle kdtree better later on */
|
||||
if(R.r.scemode & R_PREVIEWBUTS) return;
|
||||
|
||||
neighbours = BLI_kdtree_find_n_nearest(R.particles_tree, MAX_PARTICLES_NEAREST, co, NULL, nearest);
|
||||
neighbours = BLI_kdtree_find_n_nearest(R.particles_tree, max_nearest, co, NULL, nearest);
|
||||
|
||||
for(n=1; n<neighbours; n++) {
|
||||
if ( nearest[n].dist < radius) {
|
||||
/* TODO: proper falloff/filter */
|
||||
density += 3.0f * (radius - nearest[n].dist);
|
||||
float dist = 1.0 - (nearest[n].dist / radius);
|
||||
|
||||
density += 3.0f*dist*dist - 2.0f*dist*dist*dist;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
density /= neighbours;
|
||||
density *= 1.0 / radius;
|
||||
|
||||
return density;
|
||||
}
|
||||
@@ -158,7 +164,7 @@ float vol_get_density(struct ShadeInput *shi, float *co)
|
||||
float col[3] = {0.0, 0.0, 0.0};
|
||||
|
||||
if (shi->mat->vol_shadeflag & MA_VOL_PARTICLES) {
|
||||
density += get_particle_density(co, shi->mat->vol_part_searchradius);
|
||||
density += get_particle_density(co, shi->mat->vol_part_searchradius, shi->mat->vol_part_maxnearest);
|
||||
}
|
||||
else if (shi->mat->flag & MA_IS_TEXTURED) {
|
||||
do_volume_tex(shi, co, MAP_ALPHA, col, &density);
|
||||
|
||||
@@ -4287,8 +4287,10 @@ static void material_panel_material_volume(Material *ma)
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, MA_VOL_PARTICLES, B_MATPRV, "Particles",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shadeflag), 0, 0, 0, 0, "Render global particle cache");
|
||||
uiDefButF(block, NUM, B_MATPRV, "Search Radius: ",
|
||||
uiDefButF(block, NUM, B_MATPRV, "Radius: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_part_searchradius), 0.001, 100.0, 10, 2, "Radius to look for nearby particles within");
|
||||
uiDefButS(block, NUM, B_MATPRV, "Nearby: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_part_maxnearest), 2.0, 30.0, 10, 2, "The number of nearby particles to check for density");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user