Beispiel #1
0
 Spectrum PhotonMap::estimate_radiance(const Point& p, const Normal& nn,
     const Vector& wo, const Bsdf& bsdf, float radius) const
 {
   (void)nn;
   Spectrum power(0.f);
   this->photon_tree.lookup(p, square(radius),
     [&](const Photon& photon, float dist_square, float radius_square) {
       (void)dist_square;
       if(dot(photon.nn, nn) >= 0.7f) {
         power += photon.power * bsdf.f(wo, photon.wi, BSDF_ALL);
       }
       return radius_square;
     });
   return power / (float(this->emitted_count) * PI * square(radius));
 }
Beispiel #2
0
// private method of li
Spectrum InstantRadiosity::_li( const Ray& r , bool ignoreLe , float* first_intersect_dist ) const
{
	// return if it is larger than the maximum depth
    if( r.m_Depth > max_recursive_depth )
		return 0.0f;

	// get intersection from camera ray
	Intersection ip;
	if( false == scene.GetIntersect( r , &ip ) )
		return ignoreLe?0.0f:scene.Le( r );

	// eavluate light path less than two vertices
	Spectrum radiance = ignoreLe?0.0f:ip.Le( -r.m_Dir );
	unsigned light_num = scene.LightNum();
	for( unsigned i = 0 ; i < light_num ; ++i )
	{
		const Light* light = scene.GetLight(i);
		radiance += EvaluateDirect( r , scene , light , ip , LightSample(true) , BsdfSample(true) , BXDF_TYPE( BXDF_ALL ) );
	}
	
	if( first_intersect_dist )
		*first_intersect_dist = ip.t;

	// pick a virtual light source randomly
	const unsigned lps_id = min( m_nLightPathSet - 1 , (int)(sort_canonical() * m_nLightPathSet) );
	list<VirtualLightSource> vps = m_pVirtualLightSources[lps_id];

	Bsdf*	bsdf = ip.primitive->GetMaterial()->GetBsdf(&ip);

	// evaluate indirect illumination
	Spectrum indirectIllum;
	list<VirtualLightSource>::const_iterator it = vps.begin();
	while( it != vps.end() )
	{
		if( r.m_Depth + it->depth > max_recursive_depth )
		{
			++it;
			continue;
		}

		Vector	delta = ip.intersect - it->intersect.intersect;
		float	sqrLen = delta.SquaredLength();
		float	len = sqrt( sqrLen );
		Vector	n_delta = delta / len;

		Bsdf* bsdf1 = it->intersect.primitive->GetMaterial()->GetBsdf(&(it->intersect));

		float		gterm = AbsDot( n_delta , ip.normal ) * AbsDot( n_delta , it->intersect.normal ) / max( m_fMinSqrDist , sqrLen );
		Spectrum	f0 = bsdf->f( -r.m_Dir , -n_delta );
		Spectrum	f1 = bsdf1->f( n_delta , it->wi );

		Spectrum	contr = gterm * f0 * f1 * it->power;
		if( !contr.IsBlack() )
		{
			Visibility vis(scene);
			vis.ray = Ray( it->intersect.intersect , n_delta , 0 , 0.001f , len - 0.001f );

			if( vis.IsVisible() )
				indirectIllum += contr;
		}

		++it;
	}
	radiance += indirectIllum / (float)m_nLightPaths;

	if( m_fMinDist > 0.0f )
	{
		Vector	wi;
		float	bsdf_pdf;
		Spectrum f = bsdf->sample_f( -r.m_Dir , wi , BsdfSample( true ) , &bsdf_pdf );

		if( !f.IsBlack() && bsdf_pdf != 0.0f )
		{
			PixelSample ps;
			float gather_dist;
			Ray gather_ray( ip.intersect , wi , r.m_Depth + 1 , 0.001f , m_fMinDist - 0.001f );
			Spectrum li = _li( gather_ray , true , &gather_dist );

			if( !li.IsBlack() )
			{
				float dgterm = AbsDot( wi , ip.normal ) * max( 0.0f , 1.0f - gather_dist * gather_dist / m_fMinSqrDist );
				radiance += f * li * dgterm / bsdf_pdf;
			}
		}
	}

	return radiance;
}