re->stats_draw(&re->i);
}
-static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
+void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
{
VlakRen *vlr= (VlakRen*)is->face;
ObjectInstanceRen *obi= RAY_OBJECT_GET(&R, is->ob);
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
}
- else
- shade_material_loop(shi, shr);
-
+ else {
+ if (shi->mat->material_type == MA_SOLID) shade_material_loop(shi, shr);
+ else if (shi->mat->material_type == MA_VOLUME) shade_volume_loop(shi, shr);
+ }
/* raytrace likes to separate the spec color */
VECSUB(shr->diff, shr->combined, shr->spec);
}
ray_ao_spheresamp(shi, shadfac);
}
+ static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco)
+ {
+ /* magic numbers for reordering sample positions to give better
+ * results with adaptive sample, when it usually only takes 4 samples */
+ int order8[8] = {0, 1, 5, 6, 2, 3, 4, 7};
+ int order11[11] = {1, 3, 8, 10, 0, 2, 4, 5, 6, 7, 9};
+ int order16[16] = {1, 3, 9, 12, 0, 6, 7, 8, 13, 2, 4, 5, 10, 11, 14, 15};
+ int count = count_mask(shi->mask);
+
+ /* for better antialising shadow samples are distributed over the subpixel
+ * sample coordinates, this only works for raytracing depth 0 though */
+ if(!shi->strand && shi->depth == 0 && count > 1 && count <= max) {
+ float xs, ys, zs, view[3];
+ int samp, ordsamp, tot= 0;
+
+ for(samp=0; samp<R.osa; samp++) {
+ if(R.osa == 8) ordsamp = order8[samp];
+ else if(R.osa == 11) ordsamp = order11[samp];
+ else if(R.osa == 16) ordsamp = order16[samp];
+ else ordsamp = samp;
+
+ if(shi->mask & (1<<ordsamp)) {
+ /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
+ xs= (float)shi->scanco[0] + R.jit[ordsamp][0] + 0.5f;
+ ys= (float)shi->scanco[1] + R.jit[ordsamp][1] + 0.5f;
+ zs= shi->scanco[2];
+
+ shade_input_calc_viewco(shi, xs, ys, zs, view, NULL, jitco[tot], NULL, NULL);
+ tot++;
+ }
+ }
+
+ *totjitco= tot;
+ }
+ else {
+ VECCOPY(jitco[0], shi->co);
+ *totjitco= 1;
+ }
+ }
static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
{
QMCSampler *qsa=NULL;
- QMCSampler *qsa_jit=NULL;
int samples=0;
- float samp3d[3], jit[3], jitbias= 0.0f;
+ float samp3d[3];
float fac=0.0f, vec[3];
float colsq[4];
float adapt_thresh = lar->adapt_thresh;
- int max_samples = lar->ray_totsamp;
- float pos[3];
+ int min_adapt_samples=4, max_samples = lar->ray_totsamp;
+ float *co;
int do_soft=1, full_osa=0;
+ float jitco[RE_MAX_OSA][3];
+ int totjitco;
+
colsq[0] = colsq[1] = colsq[2] = 0.0;
if(isec->mode==RE_RAY_SHADOW_TRA) {
shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
if (do_soft) max_samples = lar->ray_totsamp;
else max_samples = (R.osa > 4)?R.osa:5;
}
-
- if(shi->vlr && ((shi->vlr->flag & R_FULL_OSA) == 0))
- jitbias= 0.5f*(VecLength(shi->dxco) + VecLength(shi->dyco));
+
+ ray_shadow_jittered_coords(shi, max_samples, jitco, &totjitco);
/* sampling init */
- if (lar->ray_samp_method==LA_SAMP_HALTON) {
+ if (lar->ray_samp_method==LA_SAMP_HALTON)
qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples);
- qsa_jit = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples);
- } else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY) {
+ else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY)
qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
- qsa_jit = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
- }
QMC_initPixel(qsa, shi->thread);
- QMC_initPixel(qsa_jit, shi->thread);
VECCOPY(vec, lampco);
while (samples < max_samples) {
isec->faceorig= (RayFace*)shi->vlr;
isec->oborig= RAY_OBJECT_SET(&R, shi->obi);
-
+
/* manually jitter the start shading co-ord per sample
* based on the pre-generated OSA texture sampling offsets,
* for anti-aliasing sharp shadow edges. */
- VECCOPY(pos, shi->co);
- if (shi->vlr && !full_osa) {
- QMC_sampleRect(jit, qsa_jit, shi->thread, samples, 1.0, 1.0);
-
- pos[0] += shi->dxco[0]*jit[0] + shi->dyco[0]*jit[1];
- pos[1] += shi->dxco[1]*jit[0] + shi->dyco[1]*jit[1];
- pos[2] += shi->dxco[2]*jit[0] + shi->dyco[2]*jit[1];
- }
+ co = jitco[samples % totjitco];
if (do_soft) {
/* sphere shadow source */
float ru[3], rv[3], v[3], s[3];
/* calc tangent plane vectors */
- v[0] = pos[0] - lampco[0];
- v[1] = pos[1] - lampco[1];
- v[2] = pos[2] - lampco[2];
+ v[0] = co[0] - lampco[0];
+ v[1] = co[1] - lampco[1];
+ v[2] = co[2] - lampco[2];
Normalize(v);
VecOrthoBasisf(v, ru, rv);
s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2];
VECCOPY(samp3d, s);
-
- if(jitbias != 0.0f) {
- /* bias away somewhat to avoid self intersection */
- pos[0] -= jitbias*v[0];
- pos[1] -= jitbias*v[1];
- pos[2] -= jitbias*v[2];
- }
}
else {
/* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */
VECCOPY(isec->end, vec);
}
- if(jitbias != 0.0f && !(do_soft && lar->type==LA_LOCAL)) {
+ if(shi->strand) {
/* bias away somewhat to avoid self intersection */
+ float jitbias= 0.5f*(VecLength(shi->dxco) + VecLength(shi->dyco));
float v[3];
- VECSUB(v, pos, isec->end);
+ VECSUB(v, co, isec->end);
Normalize(v);
- pos[0] -= jitbias*v[0];
- pos[1] -= jitbias*v[1];
- pos[2] -= jitbias*v[2];
+ co[0] -= jitbias*v[0];
+ co[1] -= jitbias*v[1];
+ co[2] -= jitbias*v[2];
}
- VECCOPY(isec->start, pos);
-
+ VECCOPY(isec->start, co);
/* trace the ray */
if(isec->mode==RE_RAY_SHADOW_TRA) {
if ((lar->ray_samp_method == LA_SAMP_HALTON)) {
/* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */
- if ((max_samples > 4) && (adapt_thresh > 0.0) && (samples > max_samples / 3)) {
+ if ((max_samples > min_adapt_samples) && (adapt_thresh > 0.0) && (samples > max_samples / 3)) {
if (isec->mode==RE_RAY_SHADOW_TRA) {
if ((shadfac[3] / samples > (1.0-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh))
break;
} else
shadfac[3]= 1.0f-fac/samples;
- if (qsa_jit)
- release_thread_qmcsampler(&R, shi->thread, qsa_jit);
if (qsa)
release_thread_qmcsampler(&R, shi->thread, qsa);
}
}
}
+/* delivers a fully filled in ShadeResult, for all passes */
+void shade_volume_loop(ShadeInput *shi, ShadeResult *shr)
+{
+ if(R.r.mode & R_RAYTRACE) volume_trace(shi, shr);
+}
+
/* do a shade, finish up some passes, apply mist */
void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
shi->har= shi->mat->har;
- shade_material_loop(shi, shr);
+ if (shi->mat->material_type == MA_SOLID) shade_material_loop(shi, shr);
+ else if (shi->mat->material_type == MA_VOLUME) shade_volume_loop(shi, shr);
}
/* copy additional passes */
}
}
- /* scanline pixel coordinates */
- /* requires set_triangle */
- void shade_input_set_viewco(ShadeInput *shi, float x, float y, float z)
+ /* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
+ void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float *view, float *dxyview, float *co, float *dxco, float *dyco)
{
- float fac;
+ /* returns not normalized, so is in viewplane coords */
+ calc_view_vector(view, x, y);
- /* currently in use for dithering (soft shadow), node preview, irregular shad */
- shi->xs= (int)(x);
- shi->ys= (int)(y);
-
- calc_view_vector(shi->view, x, y); /* returns not normalized, so is in viewplane coords */
-
- /* wire cannot use normal for calculating shi->co */
if(shi->mat->mode & MA_WIRE) {
-
+ /* wire cannot use normal for calculating shi->co, so
+ * we reconstruct the coordinate less accurate */
if(R.r.mode & R_ORTHO)
- calc_renderco_ortho(shi->co, x, y, z);
+ calc_renderco_ortho(co, x, y, z);
else
- calc_renderco_zbuf(shi->co, shi->view, z);
+ calc_renderco_zbuf(co, view, z);
}
else {
- float dface, v1[3];
+ /* for non-wire, intersect with the triangle to get the exact coord */
+ float fac, dface, v1[3];
VECCOPY(v1, shi->v1->co);
-
if(shi->obi->flag & R_TRANSFORMED)
Mat4MulVecfl(shi->obi->mat, v1);
float fx= 2.0f/(R.winx*R.winmat[0][0]);
float fy= 2.0f/(R.winy*R.winmat[1][1]);
- shi->co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
- shi->co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
+ co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
+ co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
/* using a*x + b*y + c*z = d equation, (a b c) is normal */
if(shi->facenor[2]!=0.0f)
- shi->co[2]= (dface - shi->facenor[0]*shi->co[0] - shi->facenor[1]*shi->co[1])/shi->facenor[2];
+ co[2]= (dface - shi->facenor[0]*co[0] - shi->facenor[1]*co[1])/shi->facenor[2];
else
- shi->co[2]= 0.0f;
+ co[2]= 0.0f;
- if(shi->osatex || (R.r.mode & R_SHADOW) ) {
- shi->dxco[0]= fx;
- shi->dxco[1]= 0.0f;
+ if(dxco && dyco) {
+ dxco[0]= fx;
+ dxco[1]= 0.0f;
if(shi->facenor[2]!=0.0f)
- shi->dxco[2]= (shi->facenor[0]*fx)/shi->facenor[2];
+ dxco[2]= (shi->facenor[0]*fx)/shi->facenor[2];
else
- shi->dxco[2]= 0.0f;
+ dxco[2]= 0.0f;
- shi->dyco[0]= 0.0f;
- shi->dyco[1]= fy;
+ dyco[0]= 0.0f;
+ dyco[1]= fy;
if(shi->facenor[2]!=0.0f)
- shi->dyco[2]= (shi->facenor[1]*fy)/shi->facenor[2];
+ dyco[2]= (shi->facenor[1]*fy)/shi->facenor[2];
else
- shi->dyco[2]= 0.0f;
+ dyco[2]= 0.0f;
- if( (shi->mat->texco & TEXCO_REFL) ) {
- if(shi->co[2]!=0.0f) fac= 1.0f/shi->co[2]; else fac= 0.0f;
- shi->dxview= -R.viewdx*fac;
- shi->dyview= -R.viewdy*fac;
+ if(dxyview) {
+ if(co[2]!=0.0f) fac= 1.0f/co[2]; else fac= 0.0f;
+ dxyview[0]= -R.viewdx*fac;
+ dxyview[1]= -R.viewdy*fac;
}
}
}
else {
float div;
- div= shi->facenor[0]*shi->view[0] + shi->facenor[1]*shi->view[1] + shi->facenor[2]*shi->view[2];
+ div= shi->facenor[0]*view[0] + shi->facenor[1]*view[1] + shi->facenor[2]*view[2];
if (div!=0.0f) fac= dface/div;
else fac= 0.0f;
- shi->co[0]= fac*shi->view[0];
- shi->co[1]= fac*shi->view[1];
- shi->co[2]= fac*shi->view[2];
+ co[0]= fac*view[0];
+ co[1]= fac*view[1];
+ co[2]= fac*view[2];
/* pixel dx/dy for render coord */
- if(shi->osatex || (R.r.mode & R_SHADOW) ) {
+ if(dxco && dyco) {
float u= dface/(div - R.viewdx*shi->facenor[0]);
float v= dface/(div - R.viewdy*shi->facenor[1]);
- shi->dxco[0]= shi->co[0]- (shi->view[0]-R.viewdx)*u;
- shi->dxco[1]= shi->co[1]- (shi->view[1])*u;
- shi->dxco[2]= shi->co[2]- (shi->view[2])*u;
+ dxco[0]= co[0]- (view[0]-R.viewdx)*u;
+ dxco[1]= co[1]- (view[1])*u;
+ dxco[2]= co[2]- (view[2])*u;
- shi->dyco[0]= shi->co[0]- (shi->view[0])*v;
- shi->dyco[1]= shi->co[1]- (shi->view[1]-R.viewdy)*v;
- shi->dyco[2]= shi->co[2]- (shi->view[2])*v;
+ dyco[0]= co[0]- (view[0])*v;
+ dyco[1]= co[1]- (view[1]-R.viewdy)*v;
+ dyco[2]= co[2]- (view[2])*v;
- if( (shi->mat->texco & TEXCO_REFL) ) {
+ if(dxyview) {
if(fac!=0.0f) fac= 1.0f/fac;
- shi->dxview= -R.viewdx*fac;
- shi->dyview= -R.viewdy*fac;
+ dxyview[0]= -R.viewdx*fac;
+ dxyview[1]= -R.viewdy*fac;
}
}
}
}
+ /* 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);
+ Normalize(view);
+ }
+
+ /* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
+ void shade_input_set_viewco(ShadeInput *shi, float x, float y, float xs, float ys, float z)
+ {
+ float *dxyview= NULL, *dxco= NULL, *dyco= NULL;
+
+ /* currently in use for dithering (soft shadow), node preview, irregular shad */
+ shi->xs= (int)xs;
+ shi->ys= (int)ys;
+
+ /* original scanline coordinate without jitter */
+ shi->scanco[0]= x;
+ shi->scanco[1]= y;
+ shi->scanco[2]= z;
+
+ /* check if we need derivatives */
+ if(shi->osatex || (R.r.mode & R_SHADOW)) {
+ dxco= shi->dxco;
+ dyco= shi->dyco;
+
+ if((shi->mat->texco & TEXCO_REFL))
+ dxyview= &shi->dxview;
+ }
+
+ shade_input_calc_viewco(shi, xs, ys, z, shi->view, dxyview, shi->co, dxco, dyco);
}
/* calculate U and V, for scanline (silly render face u and v are in range -1 to 0) */
for(samp=0; samp<R.osa; samp++) {
if(curmask & (1<<samp)) {
- xs= (float)x + R.jit[samp][0] + 0.5f; /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
+ /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
+ xs= (float)x + R.jit[samp][0] + 0.5f;
ys= (float)y + R.jit[samp][1] + 0.5f;
if(shi_cp)
shi->mask= (1<<samp);
// shi->rl= ssamp->rlpp[samp];
shi->samplenr= R.shadowsamplenr[shi->thread]++; /* this counter is not being reset per pixel */
- shade_input_set_viewco(shi, xs, ys, (float)ps->z);
+ shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
xs= (float)x + 0.5f;
ys= (float)y + 0.5f;
}
+
shi->mask= curmask;
shi->samplenr= R.shadowsamplenr[shi->thread]++;
- shade_input_set_viewco(shi, xs, ys, (float)ps->z);
+ shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
shi++;
uiDefButF(block, NUMSLI, B_TEXPRV, "W4: ", 10, 10, 150, 19, &tex->vn_w4, -2.0, 2.0, 10, 0, "Sets feature weight 4");
}
+static void texture_panel_pointdensity(Tex *tex)
+{
+ uiBlock *block;
+ PointDensity *pd;
+ short yco=PANEL_YMAX;
+
+ block= uiNewBlock(&curarea->uiblocks, "texture_panel_pointdensity", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Point Density", "Texture", PANELX, PANELY, PANELW, PANELH)==0) return;
+ uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
+
+ if(tex->pd==NULL) {
+ tex->pd= BKE_add_pointdensity();
+ tex->pd->object= OBACT;
+ }
+ if(tex->pd) {
+ pd= tex->pd;
+
+ uiDefBut(block, LABEL, B_NOP, "Density estimation:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, "");
+
+ uiDefButF(block, NUM, B_REDR, "Radius: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->radius), 0.001, 100.0, 10, 2, "Radius to look for nearby particles within");
+
+ yco -= YSPACE;
+
+ uiDefBut(block, LABEL, B_NOP, "Falloff:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_REDR, "Standard %x0|Smooth %x1|Sharp %x2|Constant %x3|Root %x4",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &pd->falloff_type, 0.0, 0.0, 0, 0, "Falloff type");
+
+ yco -= YSPACE;
+
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, TEX_PD_TURBULENCE, B_REDR, "Turbulence",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->flag), 0, 0, 0, 0, "Add directed turbulence to the density estimation");
+
+ if (pd->flag & TEX_PD_TURBULENCE) {
+
+ uiDefButF(block, NUM, B_REDR, "Size: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_size), 0.001, 100.0, 10, 2, "Turbulence size");
+ uiDefButS(block, NUM, B_REDR, "Depth: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_depth), 0.0, 100.0, 10, 2, "Turbulence depth");
+ uiDefButF(block, NUM, B_REDR, "Strength: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_fac), 0.001, 100.0, 10, 2, "");
+
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+
+ if (pd->source == TEX_PD_PSYS) {
+ uiDefButS(block, MENU, B_REDR, "Noise Influence %t|Static %x0|Velocity %x1|Angular Velocity %x2",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_influence), 0.0, 0.0, 0, 0, "Noise Influence");
+ }
+ }
+ uiBlockEndAlign(block);
+
+ yco = PANEL_YMAX;
+
+ uiDefBut(block, LABEL, B_NOP, "Point data source:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, "");
+
+ uiDefButS(block, MENU, B_TEXREDR_PRV, "Particle System %x0|Object Vertices %x1",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->source, 0.0, 0.0, 0, 0, "Source");
+
+ yco -= YSPACE;
+
+ if (pd->source == TEX_PD_PSYS) {
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->object), "Object that has the particle system");
+
+ if (pd->object && pd->object->particlesystem.first) {
+ uiDefButS(block, NUM, B_REDR, "PSys:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->psysindex), 1, 10, 10, 3, "Particle system number in the object");
+ }
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+
+ uiDefBut(block, LABEL, B_NOP, "Cache particles in:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_TEXREDR_PRV, "Emit Object Location %x0|Emit Object Space %x1|Global Space %x2",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->psys_cache_space, 0.0, 0.0, 0, 0, "Co-ordinate system to cache particles in");
+
+ }
+ else if (pd->source == TEX_PD_OBJECT) {
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->object), "Object to render as points");
+
+ yco -= YSPACE;
+
+ uiDefBut(block, LABEL, B_NOP, "Cache vertices in:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_TEXREDR_PRV, "Object Location %x0|Object Space %x1|Global Space %x2",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->ob_cache_space, 0.0, 0.0, 0, 0, "Co-ordinate system to cache vertices in");
+ }
+ }
+
+}
+
static char *layer_menu(RenderResult *rr, short *curlay)
{
if(ima_pp && *ima_pp) {
Image *ima= *ima_pp;
- ima->id.us--;
+ /* (for time being, texturefaces are no users, conflict in design...) */
+ if(ima->id.us>1)
+ ima->id.us--;
*ima_pp= NULL;
}
}
/* newnoise: all texture types as menu, not enough room for more buttons.
* Can widen panel, but looks ugly when other panels overlap it */
- sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap %%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic %%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi %%x%d|DistortedNoise %%x%d", 0, TEX_IMAGE, TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, TEX_DISTNOISE);
+ sprintf(textypes, "Texture Type %%t|None %%x%d|Image %%x%d|EnvMap %%x%d|Clouds %%x%d|Marble %%x%d|Stucci %%x%d|Wood %%x%d|Magic %%x%d|Blend %%x%d|Noise %%x%d|Plugin %%x%d|Musgrave %%x%d|Voronoi %%x%d|DistortedNoise %%x%d|Point Density %%x%d", 0, TEX_IMAGE, TEX_ENVMAP, TEX_CLOUDS, TEX_MARBLE, TEX_STUCCI, TEX_WOOD, TEX_MAGIC, TEX_BLEND, TEX_NOISE, TEX_PLUGIN, TEX_MUSGRAVE, TEX_VORONOI, TEX_DISTNOISE, TEX_POINTDENSITY);
uiDefBut(block, LABEL, 0, "Texture Type", 160, 150, 140, 20, 0, 0.0, 0.0, 0, 0, "");
uiDefButS(block, MENU, B_TEXTYPE, textypes, 160, 125, 140, 25, &tex->type, 0,0,0,0, "Select texture type");
case B_SHADBUF:
la= G.buts->lockpoin;
la->mode &= ~LA_SHAD_RAY;
+ BIF_preview_changed(ID_LA);
allqueue(REDRAWBUTSSHADING, 0);
allqueue(REDRAWVIEW3D, 0);
break;
/* yafray: 'softlight' uses it's own shadbuf. flag.
Must be cleared here too when switching from ray shadow */
la->mode &= ~LA_YF_SOFT;
+ BIF_preview_changed(ID_LA);
allqueue(REDRAWBUTSSHADING, 0);
allqueue(REDRAWVIEW3D, 0);
break;
uiDefButBitS(block, TOG, 1, B_MATPRV, "PAttr", 250,160,60,19, &pattr, 0, 0, 0, 0, "Display settings for particle attributes");
uiBlockSetCol(block, TH_AUTO);
}
+ else if (ma->material_type == MA_VOLUME) {
+ uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Density", 10,180,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
+ uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit", 70,180,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
+ uiDefButBitS(block, TOG, MAP_COL, B_MATPRV, "Emit Col", 120,180,80,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic color of the material");
+ uiDefButBitS(block, TOG, MAP_COLMIR, B_MATPRV, "Absorb Col", 200,180,80,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic color of the material");
+ }
else {
uiDefButBitS(block, TOG, MAP_COL, B_MATPRV, "Col", 10,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic color of the material");
uiDefButBitS(block, TOG3, MAP_NORM, B_MATPRV, "Nor", 50,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the rendered normal");
/* TEXCO */
uiBlockBeginAlign(block);
- 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");
- if(mtex->texco == TEXCO_UV && !(mtex->texflag & MTEX_DUPLI_MAPTO)) {
- if(!verify_valid_uv_name(mtex->uvname))
- uiBlockSetCol(block, TH_REDALERT);
- but=uiDefBut(block, TEX, B_MATPRV, "UV:", 750,180,158,18, mtex->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer");
- uiButSetCompleteFunc(but, autocomplete_uv, NULL);
- uiBlockSetCol(block, TH_AUTO);
- }
- else
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "Ob:",750,180,158,18, &(mtex->object), "");
- uiDefButS(block, ROW, B_MATPRV, "UV", 630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates");
- uiDefButS(block, ROW, B_MATPRV, "Orco", 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object");
- if( ob->particlesystem.first )
- uiDefButS(block, ROW, B_MATPRV, "Strand", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)");
- else
- uiDefButS(block, ROW, B_MATPRV, "Stick", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates");
- uiDefButS(block, ROW, B_MATPRV, "Win", 775,160,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates");
- uiDefButS(block, ROW, B_MATPRV, "Nor", 820,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates");
- uiDefButS(block, ROW, B_MATPRV, "Refl", 864,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates");
+ if (ma->material_type == MA_VOLUME) {
+ 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");
+ 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");
- uiDefButS(block, ROW, B_MATPRV, "Stress", 630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh");
- uiDefButS(block, ROW, B_MATPRV, "Tangent", 700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses the optional tangent vector as texture coordinates");
- uiBlockEndAlign(block);
- if(ELEM(mtex->texco, TEXCO_UV, TEXCO_ORCO))
- uiDefButBitS(block, TOG, MTEX_DUPLI_MAPTO, B_MATPRV, "From Dupli", 820,140,88,18, &(mtex->texflag), 0, 0, 0, 0, "Dupli's instanced from verts, faces or particles, inherit texture coordinate from their parent");
- else if(mtex->texco == TEXCO_OBJECT)
- uiDefButBitS(block, TOG, MTEX_OB_DUPLI_ORIG, B_MATPRV, "From Original", 820,140,88,18, &(mtex->texflag), 0, 0, 0, 0, "Dupli's derive their object coordinates from the original objects transformation");
+ } 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");
+ if(mtex->texco == TEXCO_UV && !(mtex->texflag & MTEX_DUPLI_MAPTO)) {
+ if(!verify_valid_uv_name(mtex->uvname))
+ uiBlockSetCol(block, TH_REDALERT);
+ but=uiDefBut(block, TEX, B_MATPRV, "UV:", 750,180,158,18, mtex->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer");
+ uiButSetCompleteFunc(but, autocomplete_uv, NULL);
+ uiBlockSetCol(block, TH_AUTO);
+ }
+ else
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "Ob:",750,180,158,18, &(mtex->object), "");
+
+ uiDefButS(block, ROW, B_MATPRV, "UV", 630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates");
+ uiDefButS(block, ROW, B_MATPRV, "Orco", 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object");
+ if( ob->particlesystem.first )
+ uiDefButS(block, ROW, B_MATPRV, "Strand", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)");
+ else
+ uiDefButS(block, ROW, B_MATPRV, "Stick", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates");
+ uiDefButS(block, ROW, B_MATPRV, "Win", 775,160,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates");
+ uiDefButS(block, ROW, B_MATPRV, "Nor", 820,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates");
+ uiDefButS(block, ROW, B_MATPRV, "Refl", 864,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates");
+
+ uiDefButS(block, ROW, B_MATPRV, "Stress", 630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh");
+ uiDefButS(block, ROW, B_MATPRV, "Tangent", 700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses the optional tangent vector as texture coordinates");
+ uiBlockEndAlign(block);
+ if(ELEM(mtex->texco, TEXCO_UV, TEXCO_ORCO))
+ uiDefButBitS(block, TOG, MTEX_DUPLI_MAPTO, B_MATPRV, "From Dupli", 820,140,88,18, &(mtex->texflag), 0, 0, 0, 0, "Dupli's instanced from verts, faces or particles, inherit texture coordinate from their parent");
+ else if(mtex->texco == TEXCO_OBJECT)
+ uiDefButBitS(block, TOG, MTEX_OB_DUPLI_ORIG, B_MATPRV, "From Original", 820,140,88,18, &(mtex->texflag), 0, 0, 0, 0, "Dupli's derive their object coordinates from the original objects transformation");
+ }
/* COORDS */
uiBlockBeginAlign(block);
}
-static void material_panel_material(Material *ma)
+static void material_panel_material_solid(Material *ma)
{
uiBlock *block;
float *colpoin = NULL;
}
+static void material_panel_material_volume(Material *ma)
+{
+ uiBlock *block;
+ short yco=PANEL_YMAX;
+
+ block= uiNewBlock(&curarea->uiblocks, "material_panel_material_volume", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Volume", "Material", PANELX, PANELY, PANELW, PANELH)==0) return;
+
+ uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_MATPRV, "Step Size: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_stepsize), 0.001, 100.0, 10, 2, "Ray marching step size");
+ uiBlockEndAlign(block);
+
+ 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 -= YSPACE;
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, MENU, B_TEXREDR_PRV, "Scattering Direction %t|Isotropic %x0|Mie Hazy %x1|Mie Murky %x2|Rayleigh %x3|Henyey-Greenstein %x4|Schlick %x5",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &ma->vol_phasefunc_type, 0.0, 0.0, 0, 0, "Scattering Direction (Phase Function)");
+ if (ELEM(ma->vol_phasefunc_type, MA_VOL_PH_HG, MA_VOL_PH_SCHLICK)) {
+ uiDefButF(block, NUM, B_MATPRV, "Asymmetry: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_phasefunc_g), -1.0, 1.0, 0, 0, "> 0 is forward scattering, < 0 is back scattering");
+ }
+ uiBlockEndAlign(block);
+
+
+ yco = PANEL_YMAX;
+
+ uiDefButF(block, NUMSLI, B_MATPRV, "Density: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->alpha), 0.0, 1.0, 0, 0, "Base opacity value");
+
+ yco -= YSPACE;
+
+ 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);
+
+ 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)
{
bNode *node;
block= uiNewBlock(&curarea->uiblocks, "material_panel_links", UI_EMBOSS, UI_HELV, curarea->win);
/* 310 makes sorting code to put it right after preview panel */
- if(uiNewPanel(curarea, block, "Links and Pipeline", "Material", 310, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Links and Pipeline", "Material", 310, 0, 338, 204)==0) return;
/* Links from object to material/nodes */
uiDefBut(block, ROUNDBOX, 0, "", 5, 90, 310, 110, NULL, 7.0, 0.0, 15 , 20, "");
uiDefButBitI(block, TOG, MA_ONLYCAST, B_MATPRV,"OnlyCast", 85,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes faces cast shadows only, not rendered");
uiDefButBitI(block, TOG, MA_TRACEBLE, B_NOP,"Traceable", 160,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes material detectable by ray tracing");
uiDefButBitI(block, TOG, MA_SHADBUF, B_MATPRV, "Shadbuf", 235,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes material cast shadows from shadow buffer lamps");
-
+ uiBlockEndAlign(block);
+
+ uiDefButS(block, MENU, B_MATPRV, "Material Type %t|Solid %x0|Halo %x1|Volume %x2",
+ 10, -15, 300, 20, &(ma->material_type), 0.0, 0.0, 0, 0, "");
}
ma= editnode_get_active_material(ma);
if(ma) {
- material_panel_material(ma);
- material_panel_ramps(ma);
- material_panel_shading(ma);
-
- if (G.scene->r.renderer==R_INTERN)
- material_panel_tramir(ma);
- else {
- if(ma->YF_ar==0.f) {
- ma->YF_ar = ma->YF_ag = ma->YF_ab = 1;
- ma->YF_dscale = 1;
+ if (ma->material_type == MA_SOLID) {
+ material_panel_material_solid(ma);
+ material_panel_ramps(ma);
+ material_panel_shading(ma);
+
+ if (G.scene->r.renderer==R_INTERN)
+ material_panel_tramir(ma);
+ else {
+ if(ma->YF_ar==0.f) {
+ ma->YF_ar = ma->YF_ag = ma->YF_ab = 1;
+ ma->YF_dscale = 1;
+ }
+ material_panel_tramir_yafray(ma);
}
- material_panel_tramir_yafray(ma);
- }
- material_panel_sss(ma);
+ material_panel_sss(ma);
+
+ } else if (ma->material_type == MA_VOLUME) {
+ material_panel_material_volume(ma);
+ }
material_panel_texture(ob, ma);
mtex= ma->mtex[ ma->texact ];
case TEX_VORONOI:
texture_panel_voronoi(tex);
break;
+ case TEX_POINTDENSITY:
+ texture_panel_pointdensity(tex);
+ break;
}
}
}