Vec3d DiffuseBSDF::SampleAndEvaluate( BSDFRecord& record, BSDFSample& sample, double& pdf, Intersection& isect )
{
	if ((record.type & BSDFType::DiffuseReflection) == 0 || CosTheta(record.wi) <= 0)
	{
		return Vec3d();
	}

	// Sample direction (cosine weighted)
	record.wo = RenderUtils::CosineSampleHemisphere(sample.u);
	record.sampledType = BSDFType::DiffuseReflection;

	// Pdf
	pdf = Pdf(record);
	if (pdf == 0.0)
	{
		return Vec3d();
	}

	// Correction factor for shading normal
	double sf = ShadingNormalCorrectionFactor(record, isect);
	if (sf == 0.0)
	{
		return Vec3d();
	}

	// f(wi, wo) * cos(theta) / p(wo)
	// = R * invPi * cos(theta) / (cos(theta) * invPi) = R
	return R->Evaluate(isect.uv) * sf;
}
// commented, dpl 10 august 2005
Spectrum Lafortune::Sample_f(const Vector &wo, Vector *wi,
		float u1, float u2, float *pdf) const {
	u_int comp = RandomUInt() % (nLobes+1);
	if (comp == nLobes) {
		// Cosine-sample the hemisphere, flipping the direction if necessary
		*wi = CosineSampleHemisphere(u1, u2);
		if (wo.z < 0.) wi->z *= -1.f;
	}
	else {
		// Sample lobe _comp_ for Lafortune BRDF
		float xlum = x[comp].y();
		float ylum = y[comp].y();
		float zlum = z[comp].y();
		float costheta = powf(u1, 1.f / (.8f * exponent[comp].y() + 1));
		float sintheta = sqrtf(max(0.f, 1.f - costheta*costheta));
		float phi = u2 * 2.f * M_PI;
		Vector lobeCenter = Normalize(Vector(xlum * wo.x, ylum * wo.y, zlum * wo.z));
		Vector lobeX, lobeY;
		CoordinateSystem(lobeCenter, &lobeX, &lobeY);
		*wi = SphericalDirection(sintheta, costheta, phi, lobeX, lobeY,
			lobeCenter);
	}
	if (!SameHemisphere(wo, *wi)) return Spectrum(0.f);
	*pdf = Pdf(wo, *wi);
	return f(wo, *wi);
}
Exemple #3
0
Spectrum LambertianTransmission::Sample_f(const Vector3f &wo, Vector3f *wi,
                                          const Point2f &u, Float *pdf,
                                          BxDFType *sampledType) const {
    *wi = CosineSampleHemisphere(u);
    if (wo.z > 0) wi->z *= -1;
    *pdf = Pdf(wo, *wi);
    return f(wo, *wi);
}
Exemple #4
0
Spectrum BxDF::Sample_f(const Vector3f &wo, Vector3f *wi, const Point2f &u,
                        Float *pdf, BxDFType *sampledType) const {
    // Cosine-sample the hemisphere, flipping the direction if necessary
    *wi = CosineSampleHemisphere(u);
    if (wo.z < 0) wi->z *= -1;
    *pdf = Pdf(wo, *wi);
    return f(wo, *wi);
}
Spectrum BxDF::Sample_f(const Vector &wo, Vector *wi,
		float u1, float u2, float *pdf) const {
	// Cosine-sample the hemisphere, flipping the direction if necessary
	*wi = CosineSampleHemisphere(u1, u2);
	if (wo.z < 0.) wi->z *= -1.f;
	*pdf = Pdf(wo, *wi);
	return f(wo, *wi);
}
Exemple #6
0
Spectrum MicrofacetTransmission::Sample_f(const Vector3f &wo, Vector3f *wi,
                                          const Point2f &u, Float *pdf,
                                          BxDFType *sampledType) const {
    Vector3f wh = distribution->Sample_wh(wo, u);
    Float eta = CosTheta(wo) > 0 ? (etaA / etaB) : (etaB / etaA);
    if (!Refract(wo, (Normal3f)wh, eta, wi)) return 0;
    *pdf = Pdf(wo, *wi);
    return f(wo, *wi);
}
Exemple #7
0
// --------------------------------------------------
status_t 
DrawShape::IterateClose(void)
{
	REPORT(kDebug, 0, "IterateClose %s", IsDrawing() ? (fStroke ? "stroke" : "fill") : "clip");
	if (fDrawn) REPORT(kDebug, 0, ">>> IterateClose called multiple times!");
	if (TransformPath())
		fSubPath.Close();
	else
		PDF_closepath(Pdf());
	Draw();
	return B_OK;
}
Exemple #8
0
// BxDF Method Definitions
bool BxDF::SampleF(const SpectrumWavelengths &sw, const Vector &wo, Vector *wi,
	float u1, float u2, SWCSpectrum *const f, float *pdf, float *pdfBack,
	bool reverse) const
{
	// Cosine-sample the hemisphere, flipping the direction if necessary
	*wi = CosineSampleHemisphere(u1, u2);
	if (wo.z < 0.f)
		wi->z = -(wi->z);
	// wi may be in the tangent plane, which will 
	// fail the SameHemisphere test in Pdf()
	if (!SameHemisphere(wo, *wi)) 
		return false;
	*pdf = Pdf(sw, wo, *wi);
	if (pdfBack)
		*pdfBack = Pdf(sw, *wi, wo);
	*f = SWCSpectrum(0.f);
	if (reverse)
		F(sw, *wi, wo, f);
	else
		F(sw, wo, *wi, f);
	*f /= *pdf;
	return true;
}
Exemple #9
0
// --------------------------------------------------
status_t 
DrawShape::IterateMoveTo(BPoint *point)
{
	REPORT(kDebug, 0, "IterateMoveTo ");
	if (!TransformPath()) {
		PDF_moveto(Pdf(), tx(point->x), ty(point->y)); 
	} else {
		EndSubPath();
		fSubPath.MakeEmpty();
		fSubPath.AddPoint(*point);
	}
	REPORT(kDebug, 0, "(%f, %f)", point->x, point->y);
	fCurrentPoint = *point;
	return B_OK;
}
Exemple #10
0
Spectrum
Heitz::Sample_f(const Vector &wo, Vector *wi,
                              float u1, float u2, float *pdf) const 
{
    // TODO: for test
    if (mUseUniformSampling) {
        return BxDF::Sample_f(wo, wi, u1, u2, pdf);

    } else {
        // TODO: what percentage between diffuse and specular? Currently use 50%
        if (u1 < 0.5f) {
            // Stretch u1 back to [0, 1)
            u1 *= 2;

            if (wo.z < 0.f) {
                // Reverse side
                mDistribution.Sample_f(-wo, wi, u1, u2, pdf);
                *wi = -(*wi);
            } else {
                mDistribution.Sample_f(wo, wi, u1, u2, pdf);
            }

            // Note: wo and wi are not guaranteed to be on the +Z side, nor are
            //      they to be on the same side

            if (*pdf == 0.f) {
                // The sample is invalid - note it still needs to be considered
                // in Monte Carlo because invalid sample takes part of the PDF
                return Spectrum(0.f);
            }

        } else {
            // Stretch u1 back to [0, 1)
            u1 = 2 * (u1 - 0.5f);

            // Sampling wi at the same side as wo
            *wi = CosineSampleHemisphere(u1, u2);
            if (wo.z < 0.f) {
                *wi = -(*wi);
            }
        }

        // Compute PDF by calling Pdf(). This implementation is simpler and
        // less prone to error, but it's also less efficient
        *pdf = Pdf(wo, *wi);
        return f(wo, *wi);
    }
}
// commented, dpl 10 august 2005
Spectrum FresnelBlend::Sample_f(const Vector &wo,
		Vector *wi, float u1, float u2, float *pdf) const {
	if (u1 < .5) {
		u1 = 2.f * u1;
		// Cosine-sample the hemisphere, flipping the direction if necessary
		*wi = CosineSampleHemisphere(u1, u2);
		if (wo.z < 0.) wi->z *= -1.f;
	}
	else {
		u1 = 2.f * (u1 - .5f);
		distribution->Sample_f(wo, wi, u1, u2, pdf);
		if (!SameHemisphere(wo, *wi)) return Spectrum(0.f);
	}
	*pdf = Pdf(wo, *wi);
	return f(wo, *wi);
}
Exemple #12
0
// --------------------------------------------------
status_t 
DrawShape::IterateLineTo(int32 lineCount, BPoint *linePoints)
{
	REPORT(kDebug, 0, "IterateLineTo %d", (int)lineCount);
	BPoint *p = linePoints;
	for (int32 i = 0; i < lineCount; i++) {
		REPORT(kDebug, 0, "(%f, %f) ", p->x, p->y);

		if (TransformPath()) {
			fSubPath.AddPoint(*p);
		} else {
			PDF_lineto(Pdf(), tx(p->x), ty(p->y));
		}
		fCurrentPoint = *p;
		p++;
	}
	return B_OK;
}
Exemple #13
0
// --------------------------------------------------
void
DrawShape::Draw()
{
	if (!fDrawn) {
		fDrawn = true;
		if (IsDrawing()) {
			if (fStroke) 
				fWriter->StrokeOrClip(); // strokes always
			else {
				fWriter->FillOrClip(); // fills always
			}
		} else if (TransformPath()) {
			EndSubPath();
		} else {
			PDF_closepath(Pdf());
		}
	}
}
Exemple #14
0
// --------------------------------------------------
status_t 
DrawShape::IterateBezierTo(int32 bezierCount, BPoint *control)
{
	REPORT(kDebug, 0, "BezierTo");
	for (int32 i = 0; i < bezierCount; i++, control += 3) {
		REPORT(kDebug, 0,"    (%f %f) (%f %f) (%f %f)", tx(control[0].x), ty(control[0].y), tx(control[1].x), ty(control[1].y), tx(control[2].x), ty(control[2].y));
		if (TransformPath()) {
			BPoint p[4] = { fCurrentPoint, control[0], control[1], control[2] };
			CreateBezierPath(p);
		} else {
			PDF_curveto(Pdf(), 
				tx(control[0].x), ty(control[0].y),
				tx(control[1].x), ty(control[1].y),
	    		tx(control[2].x), ty(control[2].y));
	    }
		fCurrentPoint = control[2];
	}
	return B_OK;
}
Exemple #15
0
Spectrum FresnelBlend::Sample_f(const Vector3f &wo, Vector3f *wi,
                                const Point2f &uOrig, Float *pdf,
                                BxDFType *sampledType) const {
    Point2f u = uOrig;
    if (u[0] < .5) {
        u[0] = 2 * u[0];
        // Cosine-sample the hemisphere, flipping the direction if necessary
        *wi = CosineSampleHemisphere(u);
        if (wo.z < 0) wi->z *= -1;
    } else {
        u[0] = 2 * (u[0] - .5f);
        // Sample microfacet orientation $\wh$ and reflected direction $\wi$
        Vector3f wh = distribution->Sample_wh(wo, u);
        *wi = Reflect(wo, wh);
        if (!SameHemisphere(wo, *wi)) return Spectrum(0.f);
    }
    *pdf = Pdf(wo, *wi);
    return f(wo, *wi);
}
Exemple #16
0
// sample a direction randomly
Spectrum Bxdf::sample_f( const Vector& wo , Vector& wi , const BsdfSample& bs , float* pdf ) const
{
	wi = CosSampleHemisphere( bs.u , bs.v );
	if( pdf ) *pdf = Pdf( wo , wi );
	return f( wo , wi );
}