* Worked a bit on cleaning up the code involving layering volumes on
solids, in front of other volumes, etc. Now there's a 'layer depth' value that works similarly to refraction depth - a limit for how many times the view ray will penetrate different volumetric surfaces. I have it close to being able to return alpha, but it's still not 100% correct and needs a bit more work. Going to sit on this for a while.
This commit is contained in:
@@ -172,6 +172,7 @@ void init_material(Material *ma)
|
||||
ma->vol_absorption = 1.0f;
|
||||
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->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_RAYBIAS|MA_TANGENT_STR;
|
||||
|
||||
|
||||
@@ -7871,6 +7871,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
ma->vol_absorption = 1.0f;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ typedef struct Material {
|
||||
float vol_absorption, vol_scattering;
|
||||
float vol_absorption_col[3];
|
||||
float vpad2;
|
||||
short vol_raydepth;
|
||||
short vol_shadeflag;
|
||||
short vpad;
|
||||
|
||||
float fresnel_mir, fresnel_mir_i;
|
||||
float fresnel_tra, fresnel_tra_i;
|
||||
|
||||
@@ -113,7 +113,7 @@ typedef struct ShadeInput
|
||||
|
||||
/* internal face coordinates */
|
||||
float u, v, dx_u, dx_v, dy_u, dy_v;
|
||||
float co[3], view[3];
|
||||
float co[3], view[3], camera_co[3];
|
||||
|
||||
/* copy from material, keep synced so we can do memcopy */
|
||||
/* current size: 23*4 */
|
||||
|
||||
@@ -671,6 +671,10 @@ void shade_input_set_viewco(ShadeInput *shi, float x, float y, float z)
|
||||
}
|
||||
}
|
||||
|
||||
/* set camera coords - for scanline, it's always 0.0,0.0,0.0 (render is in camera space)
|
||||
* however for raytrace it can be different - the position of the last intersection */
|
||||
shi->camera_co[0] = shi->camera_co[1] = shi->camera_co[2] = 0.0f;
|
||||
|
||||
/* cannot normalize earlier, code above needs it at viewplane level */
|
||||
Normalize(shi->view);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
extern struct Render R;
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
#if 0
|
||||
|
||||
static int vol_backface_intersect_check(Isect *is, int ob, RayFace *face)
|
||||
{
|
||||
VlakRen *vlr = (VlakRen *)face;
|
||||
@@ -64,21 +64,33 @@ static int vol_backface_intersect_check(Isect *is, int ob, RayFace *face)
|
||||
* of foward facing geometry don't cause the ray to stop */
|
||||
return (INPR(is->vec, vlr->n) < 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define VOL_IS_SAMEOBJECT 1
|
||||
static int vol_frontface_intersect_check(Isect *is, int ob, RayFace *face)
|
||||
{
|
||||
VlakRen *vlr = (VlakRen *)face;
|
||||
|
||||
/* only consider faces away, so overlapping layers
|
||||
* of foward facing geometry don't cause the ray to stop */
|
||||
return (INPR(is->vec, vlr->n) > 0.0f);
|
||||
}
|
||||
|
||||
static int vol_always_intersect_check(Isect *is, int ob, RayFace *face)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define VOL_IS_BACKFACE 1
|
||||
#define VOL_IS_SAMEMATERIAL 2
|
||||
|
||||
|
||||
#define VOL_BOUNDS_DEPTH 0
|
||||
#define VOL_BOUNDS_SS 1
|
||||
|
||||
static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type)
|
||||
/* TODO: Box or sphere intersection types could speed things up */
|
||||
static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type, int checkfunc)
|
||||
{
|
||||
/* TODO: Box or sphere intersection types could speed things up */
|
||||
|
||||
/* raytrace method */
|
||||
float maxsize = RE_ray_tree_max_size(R.raytree);
|
||||
int intersected=0;
|
||||
|
||||
/* TODO: use object's bounding box to calculate max size */
|
||||
VECCOPY(isect->start, co);
|
||||
@@ -86,16 +98,21 @@ static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco,
|
||||
isect->end[1] = co[1] + vec[1] * maxsize;
|
||||
isect->end[2] = co[2] + vec[2] * maxsize;
|
||||
|
||||
if (intersect_type == VOL_BOUNDS_DEPTH) isect->faceorig= (RayFace*)shi->vlr;
|
||||
else if (intersect_type == VOL_BOUNDS_SS) isect->faceorig= NULL;
|
||||
|
||||
isect->mode= RE_RAY_MIRROR;
|
||||
isect->oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
isect->face_last= NULL;
|
||||
isect->ob_last= 0;
|
||||
isect->lay= -1;
|
||||
|
||||
if(RE_ray_tree_intersect(R.raytree, isect))
|
||||
if (intersect_type == VOL_BOUNDS_DEPTH) isect->faceorig= (RayFace*)shi->vlr;
|
||||
else if (intersect_type == VOL_BOUNDS_SS) isect->faceorig= NULL;
|
||||
|
||||
if (checkfunc==VOL_IS_BACKFACE)
|
||||
intersected = RE_ray_tree_intersect_check(R.raytree, isect, vol_backface_intersect_check);
|
||||
else
|
||||
intersected = RE_ray_tree_intersect(R.raytree, isect);
|
||||
|
||||
if(intersected)
|
||||
{
|
||||
float isvec[3];
|
||||
|
||||
@@ -245,7 +262,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
|
||||
VecMulf(lv, -1.0f);
|
||||
|
||||
/* find minimum of volume bounds, or lamp coord */
|
||||
if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) {
|
||||
if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS, 0)) {
|
||||
float dist = VecLenf(co, hitco);
|
||||
|
||||
if (ELEM(lar->type, LA_SUN, LA_HEMI))
|
||||
@@ -312,87 +329,7 @@ void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float stepsi
|
||||
VECCOPY(scatter, col);
|
||||
}
|
||||
|
||||
static void shade_intersection(ShadeInput *shi, float *col, Isect *is)
|
||||
{
|
||||
ShadeInput shi_new;
|
||||
ShadeResult shr_new;
|
||||
|
||||
memset(&shi_new, 0, sizeof(ShadeInput));
|
||||
|
||||
shi_new.mask= shi->mask;
|
||||
shi_new.osatex= shi->osatex;
|
||||
shi_new.depth= 1; /* only used to indicate tracing */
|
||||
shi_new.thread= shi->thread;
|
||||
shi_new.xs= shi->xs;
|
||||
shi_new.ys= shi->ys;
|
||||
shi_new.lay= shi->lay;
|
||||
shi_new.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
|
||||
shi_new.combinedflag= 0xFFFFFF; /* ray trace does all options */
|
||||
shi_new.light_override= shi->light_override;
|
||||
shi_new.mat_override= shi->mat_override;
|
||||
|
||||
memset(&shr_new, 0, sizeof(ShadeResult));
|
||||
|
||||
shade_ray(is, &shi_new, &shr_new);
|
||||
|
||||
col[0]= shr_new.diff[0] + shr_new.spec[0];
|
||||
col[1]= shr_new.diff[1] + shr_new.spec[1];
|
||||
col[2]= shr_new.diff[2] + shr_new.spec[2];
|
||||
}
|
||||
|
||||
|
||||
static void vol_trace_behind(ShadeInput *shi, float *co, Isect *isect_first, float *col)
|
||||
{
|
||||
RayFace *rforig=NULL;
|
||||
Isect isect;
|
||||
float maxsize = RE_ray_tree_max_size(R.raytree);
|
||||
|
||||
if (isect_first != NULL) {
|
||||
/* there was already a ray intersection -
|
||||
* either the back of volume object or another object */
|
||||
ObjectInstanceRen *obi= RAY_OBJECT_GET(&R, isect_first->ob);
|
||||
|
||||
if (obi != shi->obi) {
|
||||
/* already intersected with another object, so shade it */
|
||||
shade_intersection(shi, col, isect_first);
|
||||
return;
|
||||
} else {
|
||||
rforig = isect_first->face;
|
||||
}
|
||||
}
|
||||
|
||||
/* get ready to trace a new ray behind the volume */
|
||||
VECCOPY(isect.start, co)
|
||||
|
||||
if (rforig == NULL) {
|
||||
/* if there's no original ray intersection then the original
|
||||
* shaded surface is the inside of the volume at the far bounds.
|
||||
* We can use this face for the raytrace orig face */
|
||||
isect.faceorig= (RayFace *)shi->vlr;
|
||||
} else {
|
||||
isect.faceorig= rforig;
|
||||
}
|
||||
|
||||
isect.end[0] = isect.start[0] + shi->view[0] * maxsize;
|
||||
isect.end[1] = isect.start[1] + shi->view[1] * maxsize;
|
||||
isect.end[2] = isect.start[2] + shi->view[2] * maxsize;
|
||||
|
||||
isect.mode= RE_RAY_MIRROR;
|
||||
isect.oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
isect.face_last= NULL;
|
||||
isect.ob_last= 0;
|
||||
isect.lay= -1;
|
||||
|
||||
/* check to see if there's anything behind the volume, otherwise shade the sky */
|
||||
if(RE_ray_tree_intersect(R.raytree, &isect)) {
|
||||
shade_intersection(shi, col, &isect);
|
||||
} else {
|
||||
shadeSkyView(col, co, shi->view, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco, Isect *isect)
|
||||
static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco)
|
||||
{
|
||||
float tr[3] = {1.0f, 1.0f, 1.0f}; /* total transmittance */
|
||||
float radiance[3] = {0.f, 0.f, 0.f}, d_radiance[3] = {0.f, 0.f, 0.f};
|
||||
@@ -403,18 +340,17 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float
|
||||
int s;
|
||||
float step_sta[3], step_end[3], step_mid[3];
|
||||
float col_behind[3];
|
||||
float total_density = 0.f;
|
||||
|
||||
float alpha;
|
||||
float density = vol_get_density(shi, co);
|
||||
|
||||
/* multiply col_behind with beam transmittance over entire distance */
|
||||
vol_trace_behind(shi, endco, isect, col_behind);
|
||||
vol_get_attenuation(shi, tau, co, endco, density, stepsize);
|
||||
tr[0] *= exp(-tau[0]);
|
||||
tr[1] *= exp(-tau[1]);
|
||||
tr[2] *= exp(-tau[2]);
|
||||
VecMulVecf(radiance, tr, col_behind);
|
||||
VecMulVecf(radiance, tr, col);
|
||||
tr[0] = tr[1] = tr[2] = 1.0f;
|
||||
|
||||
|
||||
/* ray marching */
|
||||
nsteps = (int)ceil(VecLenf(co, endco) / stepsize);
|
||||
@@ -444,7 +380,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float
|
||||
tr[2] *= exp(-tau[2]);
|
||||
|
||||
/* Terminate raymarching if transmittance is small */
|
||||
//if (rgb_to_luminance(tr[0], tr[1], tr[2]) < 1e-3) break;
|
||||
//if ((tr[0] + tr[1] + tr[2] * 0.333f) < 0.01f) continue;
|
||||
|
||||
/* incoming light via emission or scattering (additive) */
|
||||
vol_get_emission(shi, step_emit, step_mid, density);
|
||||
@@ -461,18 +397,14 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float
|
||||
|
||||
VECCOPY(step_sta, step_end);
|
||||
VecAddf(step_end, step_end, stepvec);
|
||||
|
||||
total_density += density;
|
||||
}
|
||||
|
||||
|
||||
|
||||
col[0] = radiance[0];
|
||||
col[1] = radiance[1];
|
||||
col[2] = radiance[2];
|
||||
|
||||
col[3] = 1.0f;
|
||||
//col[3] = total_density * stepsize;
|
||||
alpha = 1.0f -(tr[0] + tr[1] + tr[2]) * 0.333f;
|
||||
col[3] = alpha;
|
||||
|
||||
/*
|
||||
Incoming radiance =
|
||||
@@ -492,56 +424,124 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float
|
||||
-- To find radiance from segments along the way:
|
||||
find radiance for one step:
|
||||
- loop over lights and weight by phase function
|
||||
|
||||
- single scattering
|
||||
: integrate over sphere
|
||||
|
||||
then multiply each step for final exit radiance
|
||||
*/
|
||||
}
|
||||
|
||||
static void shade_intersection(ShadeInput *shi, float *col, Isect *is)
|
||||
{
|
||||
ShadeInput shi_new;
|
||||
ShadeResult shr_new;
|
||||
|
||||
memset(&shi_new, 0, sizeof(ShadeInput));
|
||||
|
||||
shi_new.mask= shi->mask;
|
||||
shi_new.osatex= shi->osatex;
|
||||
shi_new.depth= shi->depth + 1;
|
||||
shi_new.thread= shi->thread;
|
||||
shi_new.xs= shi->xs;
|
||||
shi_new.ys= shi->ys;
|
||||
shi_new.lay= shi->lay;
|
||||
shi_new.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
|
||||
shi_new.combinedflag= 0xFFFFFF; /* ray trace does all options */
|
||||
shi_new.light_override= shi->light_override;
|
||||
shi_new.mat_override= shi->mat_override;
|
||||
|
||||
VECCOPY(shi_new.camera_co, is->start);
|
||||
|
||||
memset(&shr_new, 0, sizeof(ShadeResult));
|
||||
|
||||
if (shi->depth < shi->mat->vol_raydepth)
|
||||
shade_ray(is, &shi_new, &shr_new);
|
||||
|
||||
col[0] = shr_new.combined[0];
|
||||
col[1] = shr_new.combined[1];
|
||||
col[2] = shr_new.combined[2];
|
||||
col[3] = shr_new.alpha;
|
||||
}
|
||||
|
||||
static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *col)
|
||||
{
|
||||
Isect isect;
|
||||
float maxsize = RE_ray_tree_max_size(R.raytree);
|
||||
|
||||
VECCOPY(isect.start, co);
|
||||
isect.end[0] = isect.start[0] + shi->view[0] * maxsize;
|
||||
isect.end[1] = isect.start[1] + shi->view[1] * maxsize;
|
||||
isect.end[2] = isect.start[2] + shi->view[2] * maxsize;
|
||||
|
||||
isect.faceorig= (RayFace *)vlr;
|
||||
|
||||
isect.mode= RE_RAY_MIRROR;
|
||||
isect.oborig= RAY_OBJECT_SET(&R, shi->obi);
|
||||
isect.face_last= NULL;
|
||||
isect.ob_last= 0;
|
||||
isect.lay= -1;
|
||||
|
||||
/* check to see if there's anything behind the volume, otherwise shade the sky */
|
||||
if(RE_ray_tree_intersect(R.raytree, &isect)) {
|
||||
shade_intersection(shi, col, &isect);
|
||||
} else {
|
||||
shadeSkyView(col, co, shi->view, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr)
|
||||
{
|
||||
float hitco[3], col[4];
|
||||
float hitco[3], col[4] = {0.f,0.f,0.f,0.f};
|
||||
Isect is;
|
||||
|
||||
memset(shr, 0, sizeof(ShadeResult));
|
||||
|
||||
/* if original normal is facing away from the camera,
|
||||
* then we're inside the volume already.
|
||||
* so integrate from the camera to the shading coord */
|
||||
//if (INPR(shi->orignor, shi->view) < 0.0f) {
|
||||
/* if 1st hit normal is facing away from the camera,
|
||||
* then we're inside the volume already. */
|
||||
if (shi->flippednor) {
|
||||
/* trace behind the 1st hit point */
|
||||
vol_trace_behind(shi, shi->vlr, shi->co, col);
|
||||
|
||||
const float co_cam[3] = {0.0, 0.0, 0.0};
|
||||
volumeintegrate(shi, col, co_cam, shi->co, NULL);
|
||||
/* shade volume from 'camera' to 1st hit point */
|
||||
volumeintegrate(shi, col, shi->camera_co, shi->co);
|
||||
|
||||
shr->combined[0] = col[0];
|
||||
shr->combined[1] = col[1];
|
||||
shr->combined[2] = col[2];
|
||||
shr->combined[3] = 1.0f;
|
||||
|
||||
if (col[3] > 1.0f) col[3] = 1.0f;
|
||||
shr->combined[3] = col[3];
|
||||
shr->alpha = col[3];
|
||||
|
||||
VECCOPY(shr->diff, shr->combined);
|
||||
|
||||
}
|
||||
else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) {
|
||||
volumeintegrate(shi, col, shi->co, hitco, &is);
|
||||
/* trace to find a backface, the other side bounds of the volume */
|
||||
/* (ray intersect ignores front faces here) */
|
||||
else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH, 0)) {
|
||||
VlakRen *vlr = (VlakRen *)is.face;
|
||||
|
||||
/* if it's another face in the same material */
|
||||
if (vlr->mat == shi->mat) {
|
||||
/* trace behind the 2nd (raytrace) hit point */
|
||||
vol_trace_behind(shi, (VlakRen *)is.face, hitco, col);
|
||||
} else {
|
||||
shade_intersection(shi, col, &is);
|
||||
}
|
||||
|
||||
/* shade volume from 1st hit point to 2nd hit point */
|
||||
volumeintegrate(shi, col, shi->co, hitco);
|
||||
|
||||
|
||||
shr->combined[0] = col[0];
|
||||
shr->combined[1] = col[1];
|
||||
shr->combined[2] = col[2];
|
||||
shr->combined[3] = 1.0f;
|
||||
|
||||
//if (col[3] > 1.0f)
|
||||
col[3] = 1.0f;
|
||||
shr->combined[3] = col[3];
|
||||
shr->alpha = col[3];
|
||||
|
||||
VECCOPY(shr->diff, shr->combined);
|
||||
}
|
||||
else {
|
||||
/* no hit */
|
||||
shr->combined[0] = 0.0f;
|
||||
shr->combined[1] = 0.0f;
|
||||
shr->combined[2] = 1.0f;
|
||||
shr->combined[2] = 0.0f;
|
||||
shr->combined[3] = shr->alpha = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3528,6 +3528,8 @@ static void material_panel_map_input(Object *ob, Material *ma)
|
||||
uiDefButS(block, ROW, B_MATPRV, "Object", 675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
|
||||
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "Ob:",750,180,158,18, &(mtex->object), "");
|
||||
uiDefButS(block, ROW, B_MATPRV, "Local", 630,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object");
|
||||
|
||||
|
||||
} else {
|
||||
uiDefButS(block, ROW, B_MATPRV, "Glob", 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
|
||||
uiDefButS(block, ROW, B_MATPRV, "Object", 675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
|
||||
@@ -4244,43 +4246,41 @@ static void material_panel_material_volume(Material *ma)
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_stepsize), 0.001, 100.0, 10, 2, "Ray marching step size");
|
||||
uiDefButF(block, NUMSLI, B_MATPRV, "Density: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->alpha), 0.0, 1.0, 0, 0, "Base opacity value");
|
||||
uiDefButS(block, NUM, B_MATPRV, "Layer Depth: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_raydepth), 0.0, 512.0, 10, 2, "Number of layered volume ray intersections allowed per pixel");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_MATPRV, "Absorption: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption), 0.0, 10.0, 10, 0, "Multiplier for absorption");
|
||||
uiDefButF(block, COL, B_MATPRV, "",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption_col), 0, 0, 0, B_MATCOL, "");
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUMSLI, B_MATPRV, "Emit: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->emit), 0.0, 2.0, 0, 0, "Emission component");
|
||||
uiDefButF(block, COL, B_MATPRV, "",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->r), 0, 0, 0, B_MATCOL, "");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
uiDefButF(block, NUM, B_MATPRV, "Scattering: ",
|
||||
X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_scattering), 0.0, 10.0, 10, 0, "Multiplier for scattering");
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, MA_VOL_ATTENUATED, B_MATPRV, "Shading",
|
||||
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");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
yco = PANEL_YMAX;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUM, B_MATPRV, "Absorption: ",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption), 0.0, 10.0, 10, 0, "Multiplier for absorption");
|
||||
uiDefButF(block, COL, B_MATPRV, "",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->vol_absorption_col), 0, 0, 0, B_MATCOL, "");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefBut(block, LABEL, B_DIFF, "",
|
||||
X2CLM2, yco, BUTW2, BUTH, 0, 0, 0, 0, 0, "");
|
||||
yco -= YSPACE;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButF(block, NUMSLI, B_MATPRV, "Emit: ",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->emit), 0.0, 2.0, 0, 0, "Emission component");
|
||||
uiDefButF(block, COL, B_MATPRV, "",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->r), 0, 0, 0, B_MATCOL, "");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
yco -= YSPACE;
|
||||
|
||||
uiDefButF(block, NUM, B_MATPRV, "Scattering: ",
|
||||
X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->vol_scattering), 0.0, 10.0, 10, 0, "Multiplier for scattering");
|
||||
}
|
||||
|
||||
static void material_panel_nodes(Material *ma)
|
||||
|
||||
Reference in New Issue
Block a user