non-working WIP commit to continue coding at home.
nothing to see here, move along!
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user