* Some more tweaks to particle density rendering. I'm not 100%
authorMatt Ebb <matt@mke3.net>
Fri, 26 Sep 2008 07:12:36 +0000 (07:12 +0000)
committerMatt Ebb <matt@mke3.net>
Fri, 26 Sep 2008 07:12:36 +0000 (07:12 +0000)
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.

source/blender/blenkernel/intern/material.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_material_types.h
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/volumetric.c
source/blender/src/buttons_shading.c

index 8f4e65576d83e0d1fc7d74cf84a50727716328fa..04a68d1b1e1f95c64bb3284bf930492c4623b3cd 100644 (file)
@@ -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;
index 658c14f58767a1c373f7616b1952752ec85f75e9..49ad309695766e404f1d08f5f596d56ae8093d77 100644 (file)
@@ -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;
                        }
                }
        }
index 814e9b9ab66f043a36b41d118421236e248cb790..dc23e7fcc6a2452e48118c6260b408adf86b6346 100644 (file)
@@ -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;
index 7fc8dc05ec35dc76f27e3074365ca2f415aa0dea..14288167c4a50a6eaae3215a958897da05b76aaa 100644 (file)
@@ -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);
        
        
 }
index 83250ebfd362b48b5e5a3e2505e37411d1e2a866..543c89f6b962eab8220448705c571bcd28a078c3 100644 (file)
@@ -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);
index 50e5e69ea166ac82104c3588b317c40207b2f374..4e6560a035a29752acd92c2ce535e956a75e7bd4 100644 (file)
@@ -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);
 }