/* tracing */
static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3])
{
	float visibility = 1.f;
	
	if (lar->shb) {
		float dxco[3] = {0.f, 0.f, 0.f}, dyco[3] = {0.f, 0.f, 0.f};
		
		visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0);
	}
	else if (lar->mode & LA_SHAD_RAY) {
		/* trace shadow manually, no good lamp api atm */
		Isect is;
		
		copy_v3_v3(is.start, co);
		if (lar->type == LA_SUN || lar->type == LA_HEMI) {
			is.dir[0] = -lar->vec[0];
			is.dir[1] = -lar->vec[1];
			is.dir[2] = -lar->vec[2];
			is.dist = R.maxdist;
		}
		else {
			sub_v3_v3v3(is.dir, lar->co, is.start);
			is.dist = normalize_v3(is.dir);
		}

		is.mode = RE_RAY_MIRROR;
		is.check = RE_CHECK_VLR_NON_SOLID_MATERIAL;
		is.skip = 0;
		
		if (lar->mode & (LA_LAYER | LA_LAYER_SHADOW))
			is.lay = lar->lay;
		else
			is.lay = -1;
			
		is.orig.ob = NULL;
		is.orig.face = NULL;
		is.last_hit = lar->last_hit[shi->thread];
		
		RE_instance_rotate_ray(shi->obi, &is);

		if (RE_rayobject_raycast(R.raytree, &is)) {
			RE_instance_rotate_ray_restore(shi->obi, &is);

			visibility = 0.f;
		}
		
		lar->last_hit[shi->thread] = is.last_hit;
	}
	return visibility;
}
Example #2
0
/* tracing */
static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co)
{
	float visibility = 1.f;
	
	if(lar->shb) {
		float dxco[3]={0.f, 0.f, 0.f}, dyco[3]={0.f, 0.f, 0.f};
		
		visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0);		
	} else if (lar->mode & LA_SHAD_RAY) {
		/* trace shadow manually, no good lamp api atm */
		Isect is;
		
		VecCopyf(is.start, co);
		if(lar->type==LA_SUN || lar->type==LA_HEMI) {
			is.vec[0] = -lar->vec[0];
			is.vec[1] = -lar->vec[1];
			is.vec[2] = -lar->vec[2];
			is.labda = R.maxdist;
		} else {
			VECSUB( is.vec, lar->co, is.start );
			is.labda = VecLength( is.vec );
		}

		is.mode = RE_RAY_MIRROR;
		is.skip = RE_SKIP_VLR_RENDER_CHECK | RE_SKIP_VLR_NON_SOLID_MATERIAL;
		
		if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW))
			is.lay= lar->lay;	
		else
			is.lay= -1;
			
		is.orig.ob = NULL;
		is.orig.face = NULL;
		is.last_hit = lar->last_hit[shi->thread];
		
		if(RE_rayobject_raycast(R.raytree,&is)) {
			visibility = 0.f;
		}
		
		lar->last_hit[shi->thread]= is.last_hit;
	}
	return visibility;
}
Example #3
0
static void render_lighting_halo(HaloRen *har, float col_r[3])
{
	GroupObject *go;
	LampRen *lar;
	float i, inp, inpr, rco[3], dco[3], lv[3], lampdist, ld, t, *vn;
	float ir, ig, ib, shadfac, soft, lacol[3];
	
	ir= ig= ib= 0.0;
	
	copy_v3_v3(rco, har->co);
	dco[0]=dco[1]=dco[2]= 1.0f/har->rad;
	
	vn= har->no;
	
	for (go=R.lights.first; go; go= go->next) {
		lar= go->lampren;
		
		/* test for lamplayer */
		if (lar->mode & LA_LAYER) if ((lar->lay & har->lay)==0) continue;
		
		/* lampdist cacluation */
		if (lar->type==LA_SUN || lar->type==LA_HEMI) {
			copy_v3_v3(lv, lar->vec);
			lampdist= 1.0;
		}
		else {
			lv[0]= rco[0]-lar->co[0];
			lv[1]= rco[1]-lar->co[1];
			lv[2]= rco[2]-lar->co[2];
			ld = len_v3(lv);
			lv[0]/= ld;
			lv[1]/= ld;
			lv[2]/= ld;
			
			/* ld is re-used further on (texco's) */
			
			if (lar->mode & LA_QUAD) {
				t= 1.0;
				if (lar->ld1>0.0f)
					t= lar->dist/(lar->dist+lar->ld1*ld);
				if (lar->ld2>0.0f)
					t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
				
				lampdist= t;
			}
			else {
				lampdist= (lar->dist/(lar->dist+ld));
			}
			
			if (lar->mode & LA_SPHERE) {
				t= lar->dist - ld;
				if (t<0.0f) continue;
				
				t/= lar->dist;
				lampdist*= (t);
			}
			
		}
		
		lacol[0]= lar->r;
		lacol[1]= lar->g;
		lacol[2]= lar->b;
		
		if (lar->mode & LA_TEXTURE) {
			ShadeInput shi;
			
			/* Warning, This is not that nice, and possibly a bit slow,
			 * however some variables were not initialized properly in, unless using shade_input_initialize(...),
			 * we need to do a memset */
			memset(&shi, 0, sizeof(ShadeInput)); 
			/* end warning! - Campbell */
			
			copy_v3_v3(shi.co, rco);
			shi.osatex= 0;
			do_lamp_tex(lar, lv, &shi, lacol, LA_TEXTURE);
		}
		
		if (lar->type==LA_SPOT) {
			
			if (lar->mode & LA_SQUARE) {
				if (lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) {
					float x, lvrot[3];
					
					/* rotate view to lampspace */
					copy_v3_v3(lvrot, lv);
					mul_m3_v3(lar->imat, lvrot);
					
					x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2]));
					/* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
					
					inpr = 1.0f / (sqrtf(1.0f + x * x));
				}
				else inpr= 0.0;
			}
			else {
				inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
			}
			
			t= lar->spotsi;
			if (inpr<t) continue;
			else {
				t= inpr-t;
				soft= 1.0;
				if (t<lar->spotbl && lar->spotbl!=0.0f) {
					/* soft area */
					i= t/lar->spotbl;
					t= i*i;
					soft= (3.0f*t-2.0f*t*i);
					inpr*= soft;
				}
				if (lar->mode & LA_ONLYSHADOW) {
					/* if (ma->mode & MA_SHADOW) { */
					/* dot product positive: front side face! */
					inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
					if (inp>0.0f) {
						/* testshadowbuf==0.0 : 100% shadow */
						shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
						if ( shadfac>0.0f ) {
							shadfac*= inp*soft*lar->energy;
							ir -= shadfac;
							ig -= shadfac;
							ib -= shadfac;
							
							continue;
						}
					}
					/* } */
				}
				lampdist*=inpr;
			}
			if (lar->mode & LA_ONLYSHADOW) continue;
			
		}
		
		/* dot product and  reflectivity*/
		
		inp = 1.0f - fabsf(dot_v3v3(vn, lv));
		
		/* inp= cos(0.5*M_PI-acos(inp)); */
		
		i= inp;
		
		if (lar->type==LA_HEMI) {
			i= 0.5f*i+0.5f;
		}
		if (i>0.0f) {
			i*= lampdist;
		}
		
		/* shadow  */
		if (i> -0.41f) { /* heuristic valua! */
			if (lar->shb) {
				shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
				if (shadfac==0.0f) continue;
				i*= shadfac;
			}
		}
		
		if (i>0.0f) {
			ir+= i*lacol[0];
			ig+= i*lacol[1];
			ib+= i*lacol[2];
		}
	}
	
	if (ir<0.0f) ir= 0.0f;
	if (ig<0.0f) ig= 0.0f;
	if (ib<0.0f) ib= 0.0f;

	col_r[0]*= ir;
	col_r[1]*= ig;
	col_r[2]*= ib;
	
}