コード例 #1
0
ファイル: volumetric.c プロジェクト: danielmarg/blender-main
static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const float view[3], LampRen *lar, float lacol[3])
{
	float visifac, lv[3], lampdist;
	float tr[3] = {1.0, 1.0, 1.0};
	float hitco[3], *atten_co;
	float p, ref_col[3];
	
	if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay) == 0) return;
	if ((lar->lay & shi->lay) == 0) return;
	if (lar->energy == 0.0f) return;
	
	if ((visifac = lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return;
	
	copy_v3_v3(lacol, &lar->r);
	
	if (lar->mode & LA_TEXTURE) {
		shi->osatex = 0;
		do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE);
	}

	mul_v3_fl(lacol, visifac);

	if (ELEM(lar->type, LA_SUN, LA_HEMI))
		copy_v3_v3(lv, lar->vec);
	negate_v3(lv);
	
	if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) {
		mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
	}
	else if (ELEM3(shi->mat->vol.shade_type, MA_VOL_SHADE_SHADED, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)) {
		Isect is;
		
		if (shi->mat->vol.shadeflag & MA_VOL_RECV_EXT_SHADOW) {
			mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
			if (rgb_to_luma_y(lacol) < 0.001f) return;
		}
		
		/* find minimum of volume bounds, or lamp coord */
		if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) {
			float dist = len_v3v3(co, hitco);
			VlakRen *vlr = (VlakRen *)is.hit.face;
			
			/* simple internal shadowing */
			if (vlr->mat->material_type == MA_TYPE_SURFACE) {
				lacol[0] = lacol[1] = lacol[2] = 0.0f;
				return;
			}

			if (ELEM(lar->type, LA_SUN, LA_HEMI))
				/* infinite lights, can never be inside volume */
				atten_co = hitco;
			else if (lampdist < dist) {
				atten_co = lar->co;
			}
			else
				atten_co = hitco;
			
			vol_get_transmittance(shi, tr, co, atten_co);
			
			mul_v3_v3v3(lacol, lacol, tr);
		}
		else {
			/* Point is on the outside edge of the volume,
			 * therefore no attenuation, full transmission.
			 * Radiance from lamp remains unchanged */
		}
	}
	
	if (rgb_to_luma_y(lacol) < 0.001f) return;
	
	normalize_v3(lv);
	p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, view, lv);
	
	/* physically based scattering with non-physically based RGB gain */
	vol_get_reflection_color(shi, ref_col, co);
	
	lacol[0] *= p * ref_col[0];
	lacol[1] *= p * ref_col[1];
	lacol[2] *= p * ref_col[2];
}
コード例 #2
0
ファイル: pixelshading.c プロジェクト: mgschwan/blensor
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;
	
}