Пример #1
0
// generate sample in two dimension
void RegularSampler::Generate2D( float* sample , unsigned num , bool accept_uniform ) const
{
	Sort_Assert( sample != 0 );

	unsigned n = (unsigned)sqrt((float)num);
	Sort_Assert( n * n == num );
	unsigned dn = 2 * n;

	for( unsigned i = 0 ; i < n ; ++i )
	{
		unsigned offset = dn * i;
		for( unsigned j = 0 ; j < dn ; j+=2 )
		{
			// fall back to random sampling if uniform sampling is not accepted.
			// For certain cases, like sampling brdf and light, uniform sampling is not acceptable
			if( !accept_uniform )
			{
				sample[offset+j] = sort_canonical();
				sample[offset+j+1] = sort_canonical();
				continue;
			}

			sample[offset+j] = ( (float)j/2 + 0.5f ) / (float)n ;
			sample[offset+j+1] = ( (float)i + 0.5f ) / (float)n ;
		}
	}
}
Пример #2
0
// generate sample in one dimension
void RandomSampler::Generate1D( float* sample , unsigned num , bool accept_uniform ) const
{
	Sort_Assert( sample != 0 );

	for( unsigned i = 0 ; i < num ; ++i )
		sample[i] = sort_canonical();
}
Пример #3
0
// generate sample in one dimension
void StratifiedSampler::Generate1D( float* sample , unsigned num , bool accept_uniform ) const
{
    Sort_Assert( sample != 0 );

    for( unsigned i = 0 ; i < num ; ++i )
        sample[i] = ( (float)i + sort_canonical() ) / (float)num ;
}
Пример #4
0
// sample a ray from light
Spectrum SpotLight::sample_l( const LightSample& ls , Ray& r , float* pdfW , float* pdfA , float* cosAtLight ) const
{
    // udpate ray
	r.m_fMin = 0.0f;
	r.m_fMax = FLT_MAX;
	r.m_Ori = light_pos;
    
    // sample a light direction
	const Vector local_dir = UniformSampleCone( ls.u , ls.v , cos_total_range );
	r.m_Dir = light2world.matrix( local_dir );

    // product of pdf of sampling a point w.r.t surface area and a direction w.r.t direction
	if( pdfW )
    {
		*pdfW = UniformConePdf( cos_total_range );
		Sort_Assert( *pdfW != 0.0f );
	}
    // pdf w.r.t surface area
	if( pdfA )
        *pdfA = 1.0f;
    if( cosAtLight )
        *cosAtLight = 1.0f;
	
	const float falloff = SatDot( r.m_Dir , light_dir );
	if( falloff <= cos_total_range )
		return 0.0f;
	if( falloff >= cos_falloff_start )
		return intensity;
	const float d = ( falloff - cos_total_range ) / ( cos_falloff_start - cos_total_range );
	if( d == 0.0f )
		return 0.0f;

	return intensity * d * d;
}
Пример #5
0
// generate sample in two dimension
void StratifiedSampler::Generate2D( float* sample , unsigned num , bool accept_uniform ) const
{
    Sort_Assert( sample != 0 );

    unsigned n = (unsigned)sqrt((float)num);
    Sort_Assert( n * n == num );
    unsigned dn = 2 * n;

    for( unsigned i = 0 ; i < n ; ++i )
    {
        unsigned offset = dn * i;
        for( unsigned j = 0 ; j < dn ; j+=2 )
        {
            sample[offset+j] = ( (float)j/2 + sort_canonical() ) / (float)n ;
            sample[offset+j+1] = ( (float)i + sort_canonical() ) / (float)n ;
        }
    }
}
Пример #6
0
// generate sample in two dimension
void RandomSampler::Generate2D( float* sample , unsigned num , bool accept_uniform ) const
{
	Sort_Assert( sample != 0 );

	int count = 2 * num;
	for( int i = 0 ; i < count ; i += 2 )
	{
		sample[i] = sort_canonical();
		sample[i+1] = sort_canonical();
	}
}
Пример #7
0
// generate sample in one dimension
void RegularSampler::Generate1D( float* sample , unsigned num , bool accept_uniform ) const
{
	Sort_Assert( sample != 0 );

	for( unsigned i = 0 ; i < num ; ++i )
	{
		// fall back to random sampling if uniform sampling is not accepted.
		// For certain cases, like sampling brdf and light, uniform sampling is not acceptable
		if( !accept_uniform )
			sample[i] = sort_canonical();
		else
			sample[i] = ( (float)i + 0.5f ) / (float)num ;
	}
}
Пример #8
0
// return the radiance of a specific direction
// note : there are one factor makes the method biased.
//		there is a limitation on the number of vertexes in the path
Spectrum PathTracing::Li( const Ray& ray , const PixelSample& ps ) const
{
	Spectrum	L = 0.0f;
	Spectrum	throughput = 1.0f;

	int			bounces = 0;
	Ray	r = ray;
	while(true)
	{
		Intersection inter;

		// get the intersection between the ray and the scene
		// if it's a light , accumulate the radiance and break
		if( false == scene.GetIntersect( r , &inter ) )
		{
			if( bounces == 0 )
				return scene.Le( r );
			break;
		}

		if( bounces == 0 ) L+=inter.Le(-r.m_Dir);

		// make sure there is intersected primitive
		Sort_Assert( inter.primitive != 0 );

		// evaluate the light
		Bsdf*			bsdf = inter.primitive->GetMaterial()->GetBsdf(&inter);
		float			light_pdf = 0.0f;
		LightSample		light_sample = (bounces==0)?ps.light_sample[0]:LightSample(true);
		BsdfSample		bsdf_sample = (bounces==0)?ps.bsdf_sample[0]:BsdfSample(true);
		const Light*	light = scene.SampleLight( light_sample.t , &light_pdf );
		if( light_pdf > 0.0f )
			L += throughput * EvaluateDirect(	r  , scene , light , inter , light_sample , 
												bsdf_sample , BXDF_TYPE(BXDF_ALL) ) / light_pdf;

		// sample the next direction using bsdf
		float		path_pdf;
		Vector		wi;
		BXDF_TYPE	bxdf_type;
		Spectrum f;
		BsdfSample	_bsdf_sample = (bounces==0)?ps.bsdf_sample[1]:BsdfSample(true);
		f = bsdf->sample_f( -r.m_Dir , wi , _bsdf_sample , &path_pdf , BXDF_ALL , &bxdf_type );
		if( f.IsBlack() || path_pdf == 0.0f )
			break;

		// update path weight
		throughput *= f * AbsDot( wi , inter.normal ) / path_pdf;

		if( throughput.GetIntensity() == 0.0f )
			break;
		if( bounces > 4 )
		{
			float continueProperbility = min( 0.5f , throughput.GetIntensity() );
			if( sort_canonical() > continueProperbility )
				break;
			throughput /= continueProperbility;
		}

		r.m_Ori = inter.intersect;
		r.m_Dir = wi;
		r.m_fMin = 0.001f;

		++bounces;

		// note :	the following code makes the method biased
		//			'path_per_pixel' could be set very large to reduce the side-effect.
		if( bounces >= max_recursive_depth )
			break;
	}

	return L;
}
Пример #9
0
void OrthoCamera::SetCameraHeight( float h )
{
	Sort_Assert( h > 0.0f );
	m_camHeight = h;
}
Пример #10
0
// set the camera range
void OrthoCamera::SetCameraWidth( float w )
{
	Sort_Assert( w > 0.0f );
	m_camWidth = w;
}