Beispiel #1
0
// sample the bsdf
Colour BSDF::sample(RenderContext *rc,
					const HitContext *hc, 
	 				const Vec3 &woW, 
					Vec3 &wiW, 
					float &pdf, 
					const float r1, 
					const float r2, 
					const float r3, 
					BxDFtype flags,
					BxDFtype *sampled) const
{
	// Grab the number of appropriate BxDF
	int matchingComps = numComponents(flags);

	if (matchingComps == 0) 
	{
		pdf = 0.f;
		return Colours::black;
	}

	// Pick the bxdf
	int which = (int)(r3 * matchingComps);//rc->rnd.randInt(matchingComps - 1);
	which = which == matchingComps ? matchingComps - 1 : which;
	
	BxDF *bxdf = NULL;
	int count = which;
	int bxdfNum = 0;

	for (int i = 0; i < numBxDFs; ++i)
	{
		if (bxdfs[i]->hasFlags(flags))
		{
			if (count-- == 0) 
			{
				bxdf = bxdfs[i];
				bxdfNum = i;
				break;
			}
		}
	}

	// Sample the appropriate BxDF
	pdf = 0.0f;
	Vec3 wi;
	const Vec3 wo = hc->onb.untransform(woW);
	const Colour C = getCol(rc, hc, bxdfNum);	

	Colour f = bxdf->sample(rc, wo, wi, pdf, r1, r2, C);
	f = adjust(hc, f, bxdfNum, wo, wi); // custom adjustment for each BSDF
	
	if (pdf == 0.0f) return 0.0f;
	if (sampled != NULL) *sampled = bxdf->type;
	wiW = hc->onb.transform(wi);

	// Compute overall PDF with all matching BxDFs
	if (matchingComps > 1)
	{
		if (!(bxdf->type & BSDF_SPECULAR)) 
		{
			for (int i = 0; i < numBxDFs; ++i) 
			{
				if (bxdfs[i] != bxdf && bxdfs[i]->hasFlags(flags))
					pdf += bxdfs[i]->pdf(wo, wi);
			}
		}
		
		pdf /= matchingComps;
	}

	// Compute value of BSDF for sampled direction
	if (!(bxdf->type & BSDF_SPECULAR)) 
	{
		f = 0.0;
		
		if (Dot(wiW, hc->gNormal) * Dot(woW, hc->gNormal) > 0)
			flags = BxDFtype(flags & ~BSDF_TRANSMISSION); // ignore BTDFs
		else
			flags = BxDFtype(flags & ~BSDF_REFLECTION); // ignore BRDFs
		
		for (int i = 0; i < numBxDFs; ++i)
		{
			if (bxdfs[i]->hasFlags(flags))
			{
				// Tweak eval output to suit each BSDF
				f += adjust(hc, bxdfs[i]->eval(wo, wi, getCol(rc, hc, bxdfNum)), i, wo, wi);
			}
		}
	}

	return f;
}