Finishing touch for hair strand shadows;

- raytracing code now uses cylinder-line intersect for strands. It used
  to intersect with the screen-aligned strand quads, giving too many
  misses for tracing.
  Note; mirror for hair is still not well supported!

- added in Materials a choice for whether a material is Traceable for
  raytracing or whether it is part of Shadow buffers. This way you can
  exclude hair strands from raytracing, but still get shadowbuffers for it.
This commit is contained in:
Ton Roosendaal 2005-11-27 12:19:12 +00:00
parent f08200baa9
commit a494a76e9e
6 changed files with 66 additions and 7 deletions

@ -117,7 +117,7 @@ void init_material(Material *ma)
ma->rampfac_spec= 1.0;
ma->pr_lamp= 3; // two lamps, is bits
ma->mode= MA_TRACEBLE|MA_SHADOW|MA_RADIO|MA_TANGENT_STR;
ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_TANGENT_STR;
}
Material *add_material(char *name)

@ -5077,6 +5077,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ma->strand_sta= ma->strand_end= 1.0f;
ma->mode |= MA_TANGENT_STR;
}
/* remove this test before 2.40 too! pad is set to denote check was done */
if(ma->pad==0) {
if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF;
ma->pad= 1;
}
}
}

@ -155,6 +155,7 @@ typedef struct Material {
#define MA_RAYBIAS 0x400000
#define MA_FULL_OSA 0x800000
#define MA_TANGENT_STR 0x1000000
#define MA_SHADBUF 0x2000000
/* diff_shader */
#define MA_DIFF_LAMBERT 0

@ -632,7 +632,7 @@ void makeoctree(void)
/* ************ raytracer **************** */
/* only for self-intersecting test with current render face (where ray left) */
static short intersection2(VlakRen *vlr, float r0, float r1, float r2, float rx1, float ry1, float rz1)
static int intersection2(VlakRen *vlr, float r0, float r1, float r2, float rx1, float ry1, float rz1)
{
VertRen *v1,*v2,*v3,*v4=NULL;
float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22;
@ -705,13 +705,64 @@ static short intersection2(VlakRen *vlr, float r0, float r1, float r2, float rx1
return 0;
}
static short intersection(Isect *is)
/* ray - line intersection */
static int intersection_strand(Isect *is)
{
float *v1, *v2; /* length of strand */
float axis[3], rc[3], nor[3], radline, dist, len;
/* radius strand */
radline= 0.5f*VecLenf(is->vlr->v1->co, is->vlr->v2->co);
v1= is->vlr->v2->co;
v2= is->vlr->v3->co;
VECSUB(rc, v1, is->start); /* vector from base ray to base cylinder */
VECSUB(axis, v2, v1); /* cylinder axis */
CROSS(nor, is->vec, axis);
len= VecLength(nor);
if(len<FLT_EPSILON)
return 0;
dist= INPR(rc, nor)/len; /* distance between ray and axis cylinder */
if(dist<radline && dist>-radline) {
float dot1, dot2, dot3, rlen, alen, div;
float labda;
/* calculating the intersection point of shortest distance */
dot1 = INPR(rc, is->vec);
dot2 = INPR(is->vec, axis);
dot3 = INPR(rc, axis);
rlen = INPR(is->vec, is->vec);
alen = INPR(axis, axis);
div = alen * rlen - dot2 * dot2;
if (ABS(div) < FLT_EPSILON)
return 0;
labda = (dot1*dot2 - dot3*rlen)/div;
/* labda: where on axis do we have closest intersection? */
if(labda>=0.0f && labda<=1.0f)
return 1;
}
return 0;
}
/* ray - triangle or quad intersection */
static int intersection(Isect *is)
{
VertRen *v1,*v2,*v3,*v4=NULL;
float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
float m0, m1, m2, divdet, det1;
short ok=0;
if(is->vlr->flag & R_STRAND)
return intersection_strand(is);
v1= is->vlr->v1;
v2= is->vlr->v2;
if(is->vlr->v4) {
@ -986,7 +1037,7 @@ static Node *ocread(int x, int y, int z)
return NULL;
}
static short cliptest(float p, float q, float *u1, float *u2)
static int cliptest(float p, float q, float *u1, float *u2)
{
float r;
@ -1017,7 +1068,7 @@ static short cliptest(float p, float q, float *u1, float *u2)
/*
in top: static short coh_nodes[16*16*16][6];
in top: static int coh_nodes[16*16*16][6];
in makeoctree: memset(coh_nodes, 0, sizeof(coh_nodes));
static void add_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)

@ -2451,7 +2451,7 @@ void zbuffershad(LampRen *lar)
if(vlr->mat!= ma) {
ma= vlr->mat;
ok= 1;
if((ma->mode & MA_TRACEBLE)==0) ok= 0;
if((ma->mode & MA_SHADBUF)==0) ok= 0;
}
if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {

@ -3065,7 +3065,9 @@ static void material_panel_shading(Material *ma)
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitI(block, TOG, MA_TRACEBLE, 0, "Traceable", 245,150,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows or being detected by ray tracing");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, MA_TRACEBLE, 0,"Traceable", 245,160,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing");
uiDefButBitI(block, TOG, MA_SHADBUF, 0, "Shadbuf", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, MA_SHADOW, 0, "Shadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows");