/* 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; }
/* 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; }
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; }