non-working WIP commit to continue coding at home.
authorMatt Ebb <matt@mke3.net>
Fri, 17 Oct 2008 05:54:42 +0000 (05:54 +0000)
committerMatt Ebb <matt@mke3.net>
Fri, 17 Oct 2008 05:54:42 +0000 (05:54 +0000)
nothing to see here, move along!

source/blender/makesdna/DNA_material_types.h
source/blender/render/intern/include/render_types.h
source/blender/render/intern/include/volumetric.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/volumetric.c
source/blender/src/buttons_shading.c

index 7b6e945dfbf634a34ac32abe61b183a812cf5016..3ceb267ce67c1749a9b712563c3be41755b02415 100644 (file)
@@ -357,6 +357,7 @@ typedef struct Material {
 #define MA_VOL_SHADED          1
 #define MA_VOL_ATTENUATED      2
 #define MA_VOL_RECVSHADOW      4
+#define MA_VOL_PRECACHESHADING 8
 
 /* vol_phasefunc_type */
 #define MA_VOL_PH_ISOTROPIC            0
index b0003cadb55ba38670daa020354c412c0db4c905..6f4537d84fbb9ac43f74341554056bd2e4dc5a83 100644 (file)
@@ -201,6 +201,8 @@ struct Render
        ListBase customdata_names;
 
        struct Object *excludeob;
+       
+       ListBase vol_precache_obs;
 
        /* arena for allocating data for use during render, for
                * example dynamic TFaces to go in the VlakRen structure.
@@ -285,6 +287,8 @@ typedef struct ObjectInstanceRen {
 
        float dupliorco[3], dupliuv[2];
        float (*duplitexmat)[4];
+       
+       float *volume_precache;
 
        float *vectors;
        int totvector;
@@ -396,6 +400,16 @@ typedef struct StrandRen {
        float orco[3];
 } StrandRen;
 
+/* ------------------------------------------------------------------------- */
+
+typedef struct VolPrecache
+{
+       struct VolPrecache *next, *prev;
+       struct Material *ma;
+       struct ObjectRen *obr;
+} VolPrecache;
+
+/* ------------------------------------------------------------------------- */
 
 struct LampRen;
 struct MTex;
index 290be427f013462980649a46cb9cba27280e1abc..fb87035145fbbdbb3ac01233d3a5efb9d6353dde 100644 (file)
@@ -27,4 +27,6 @@
  */
 
 void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
-void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
\ No newline at end of file
+void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
+void volume_precache(Render *re);
+void free_volume_precache(Render *re);
\ No newline at end of file
index 0660d9e0b2439b6fbe430de21a320c1b9bc458b2..4c9914aa4d3cfe9942c4cb06f5bcb7fd25eda1e1 100644 (file)
@@ -3026,6 +3026,18 @@ static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge,
        }
 }
 
+static void add_vol_precache(Render *re, ObjectRen *obr, Material *ma)
+{
+       struct VolPrecache *vp;
+       
+       vp = MEM_mallocN(sizeof(VolPrecache), "volume precache object");
+       
+       vp->ma = ma;
+       vp->obr = obr;
+       
+       BLI_addtail(&re->vol_precache_obs, vp);
+}
+
 static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
 {
        Object *ob= obr->ob;
@@ -3080,6 +3092,10 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
                        if(re->r.mode & R_RADIO)
                                if(ma->mode & MA_RADIO) 
                                        do_autosmooth= 1;
+                       
+                       if (ma->vol_shadeflag & MA_VOL_PRECACHESHADING) {
+                               add_vol_precache(re, obr, ma);
+                       }
                }
        }
 
@@ -4436,6 +4452,7 @@ void RE_Database_Free(Render *re)
        end_render_materials();
        
        free_pointdensities(re);
+       free_volume_precache(re);
        
        if(re->wrld.aosphere) {
                MEM_freeN(re->wrld.aosphere);
@@ -4891,6 +4908,9 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
                        /* point density texture */
                        if(!re->test_break())
                                make_pointdensities(re);
+                               
+                       if(!re->test_break())
+                               volume_precache(re);
                }
                
                if(!re->test_break())
index d44b49cc7065a812d603db7928141e2f247235b9..1bc1c1a712a96eca01d6a3053107db6de4a6abd2 100644 (file)
@@ -1323,6 +1323,7 @@ ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob,
        obi->index= index;
        obi->psysindex= psysindex;
        obi->lay= lay;
+       obi->volume_precache = NULL;
 
        if(mat) {
                Mat4CpyMat4(obi->mat, mat);
index 6e2e817fc85ee3a37b20a7c521828ff4ee9b839e..3128c67ee88db50ffb472c938a347faf76ff70ce 100644 (file)
@@ -31,6 +31,8 @@
 #include <stdlib.h>
 #include <float.h>
 
+#include "MEM_guardedalloc.h"
+
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_rand.h"
@@ -44,6 +46,7 @@
 #include "DNA_lamp_types.h"
 
 #include "BKE_global.h"
+#include "BKE_main.h"
 
 #include "render_types.h"
 #include "pixelshading.h"
@@ -166,7 +169,6 @@ float vol_get_density(struct ShadeInput *shi, float *co)
        return density * density_scale;
 }
 
-
 /* compute emission component, amount of radiance to add per segment
  * can be textured with 'emit' */
 void vol_get_emission(ShadeInput *shi, float *em, float *co, float density)
@@ -182,14 +184,16 @@ void vol_get_emission(ShadeInput *shi, float *em, float *co, float density)
        VecMulVecf(em, em, col);
 }
 
+/* scattering multiplier, values above 1.0 are non-physical, 
+ * but can be useful to tweak lighting */
 void vol_get_scattering_fac(ShadeInput *shi, float *scatter_fac, float *co, float density)
 {
-       //float col[3] = {0.0, 0.0, 0.0};
-       //do_volume_tex(shi, co, MAP_EMIT+MAP_COL, col, &emission);
-       
        *scatter_fac = shi->mat->vol_scattering;
 }
 
+/* phase function - determines in which directions the light 
+ * is scattered in the volume relative to incoming direction 
+ * and view direction */
 float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w, float *wp)
 {
        const float costheta = Inpf(w, wp);
@@ -235,7 +239,7 @@ void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co)
 
 /* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau.
  * Used in the relationship Transmittance = e^(-attenuation)
- * can be textured with 'alpha' */
+ */
 void vol_get_attenuation(ShadeInput *shi, float *tau, float *co, float *endco, float density, float stepsize)
 {
        /* input density = density at co */
@@ -249,6 +253,7 @@ void vol_get_attenuation(ShadeInput *shi, float *tau, float *co, float *endco, f
        dist = VecLenf(co, endco);
        nsteps = (int)ceil(dist / stepsize);
        
+       /* trigger for recalculating density */
        if (density < -0.001f) density = vol_get_density(shi, co);
        
        if (nsteps == 1) {
@@ -327,6 +332,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
                        float dist = VecLenf(co, hitco);
                        VlakRen *vlr = (VlakRen *)is.face;
                        
+                       /* simple internal shadowing */
                        if (vlr->mat->material_type == MA_SOLID) {
                                lacol[0] = lacol[1] = lacol[2] = 0.0f;
                                return;
@@ -347,9 +353,9 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
                        VecMulVecf(lacol, lacol, tr);
                }
                else {
-                       /* point is on the outside edge of the volume,
-                        * therefore no attenuation, full transmission
-                        * radiance from lamp remains unchanged */
+                       /* Point is on the outside edge of the volume,
+                        * therefore no attenuation, full transmission.
+                        * Radiance from lamp remains unchanged */
                }
        }
        
@@ -358,13 +364,6 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
        
 }
 
-/* shadows -> trace a ray to find blocker geometry
-   - if blocker is outside the volume, use standard shadow functions
-   - if blocker is inside the volume, use raytracing
-    -- (deep shadow maps could potentially slot in here too I suppose)
-   - attenuate from current point, to blocked point or volume bounds
-*/
-
 /* single scattering only for now */
 void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float stepsize, float density)
 {
@@ -382,7 +381,7 @@ void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float stepsi
                if (lar==NULL) continue;
                
                vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density);
-                       
+               
                VecMulf(lacol, density);
                
                VecAddf(col, col, lacol);
@@ -425,7 +424,28 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float
        
        /* get radiance from all points along the ray due to participating media */
        for (s = 0; s < nsteps; s++) {
-               if (s > 0) density = vol_get_density(shi, step_sta);
+
+               if (shi->mat->vol_shadeflag & MA_VOL_PRECACHESHADING) {
+                       int res = 10;
+                       int x,y,z;
+                       
+                       step_mid[0] = step_sta[0] + (stepvec[0] * 0.5);
+                       step_mid[1] = step_sta[1] + (stepvec[1] * 0.5);
+                       step_mid[2] = step_sta[2] + (stepvec[2] * 0.5);
+                       
+                       //CLAMP(step_mid[0], 0.0f, 1.0f);
+                       //CLAMP(step_mid[1], 0.0f, 1.0f);
+                       //CLAMP(step_mid[2], 0.0f, 1.0f);
+                       
+                       MTC_Mat4MulVecfl(R.viewinv, step_mid);
+                       
+                       x = (int)step_mid[0] * res;
+                       y = (int)step_mid[1] * res;
+                       z = (int)step_mid[2] * res;
+                       
+                       density = shi->obi->volume_precache[x*res + y*res + z*res];
+               }
+               else if (s > 0) density = vol_get_density(shi, step_sta);
                
                /* there's only any use in shading here
                 * if there's actually some density to shade! */
@@ -661,3 +681,75 @@ void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct
 
 }
 
+void vol_precache_objectinstance(Render *re, ObjectInstanceRen *obi, Material *ma)
+{
+       int x, y, z;
+       int res = 10;
+       float co[3];
+       ShadeInput shi;
+       int foundma=0;
+       float density;
+       float resf;
+       int i;
+       
+       memset(&shi, 0, sizeof(ShadeInput)); 
+       shi.depth= 1;
+       shi.mask= 1;
+       shi.mat = ma;
+       shi.vlr = NULL;
+       memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));  // note, keep this synced with render_types.h
+       shi.har= shi.mat->har;
+
+       shi.obi= obi;
+       shi.obr= obi->obr;
+
+       resf = (float) res;
+       
+       obi->volume_precache = MEM_mallocN(sizeof(float)*res*res*res, "volume light cache");
+       
+       for (x=0; x < res; x++) {
+               co[0] = (float)x / resf;
+               
+               for (y=0; y < res; y++) {
+                       co[1] = (float)y / resf;
+                       
+                       for (z=0; z < res; z++) {
+                               co[2] = (float)z / resf;
+                               
+                               density = vol_get_density(&shi, co);
+                       
+                               obi->volume_precache[x*res + y*res + z*res] = density;
+                               
+                               printf("vol_light_cache[%d][%d][%d] = %f \n", x, y, z, obi->volume_precache[x*res + y*res + z*res]); 
+                       }
+               }
+       }
+}
+
+void volume_precache(Render *re)
+{
+       ObjectInstanceRen *obi;
+       VolPrecache *vp;
+       
+       printf("Precaching %d volumes... \n", BLI_countlist(&re->vol_precache_obs));
+       
+       for(vp= re->vol_precache_obs.first; vp; vp= vp->next) {
+               for(obi= re->instancetable.first; obi; obi= obi->next) {
+                       if (obi->obr == vp->obr)
+                               printf("precaching object: %s with material: %s \n", vp->obr->ob->id.name+2, vp->ma->id.name+2);
+                               vol_precache_objectinstance(re, obi, vp->ma);
+               }
+       }
+}
+
+void free_volume_precache(Render *re)
+{
+       ObjectInstanceRen *obi;
+       
+       for(obi= re->instancetable.first; obi; obi= obi->next) {
+               if (obi->volume_precache)
+                       MEM_freeN(obi->volume_precache);
+       }
+       
+       BLI_freelistN(&re->vol_precache_obs);
+}
\ No newline at end of file
index 430b50717dfb4f45a4b880ede3a0d55ab2af51b2..63fa127824a072bbfa414d59cf046589ac71a26d 100644 (file)
@@ -4375,6 +4375,8 @@ static void material_panel_material_volume(Material *ma)
                X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shadeflag), 0, 0, 0, 0, "Uses absorption for light attenuation");
        uiDefButF(block, NUM, B_MATPRV, "Step Size: ",
                X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shade_stepsize), 0.001, 100.0, 10, 2, "Step");
+       uiDefButBitS(block, TOG, MA_VOL_PRECACHESHADING, B_MATPRV, "Precache",
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shadeflag), 0, 0, 0, 0, "precache");
        uiBlockEndAlign(block);
        
        yco -= YSPACE;