Beispiel #1
0
static Vector hemisphereSample(const Vector& normal)
{
	Random& rnd = getRandomGen();

	double u = rnd.randdouble();
	double v = rnd.randdouble();

	double theta = 2 * PI * u;
	double phi   = acos(2 * v - 1);

	Vector vec(
		cos(theta) * sin(phi),
		cos(phi),
		sin(theta) * sin(phi)
	);

	if (dot(vec, normal) < 0)
		vec = -vec;

	return vec;
}
Beispiel #2
0
Color Refl::shade(const Ray& ray, const IntersectionInfo& info)
{
	Vector n = faceforward(ray.dir, info.normal);

	if (glossiness == 1) {
		Ray newRay = ray;
		newRay.start = info.ip + n * 0.000001;
		newRay.dir = reflect(ray.dir, n);
		newRay.depth++;

		return raytrace(newRay) * multiplier;
	} else {
		Random& rnd = getRandomGen();
		Color result(0, 0, 0);
		int count = numSamples;
		if (ray.depth > 0)
			count = 2;
		for (int i = 0; i < count; i++) {
			Vector a, b;
			orthonormalSystem(n, a, b);
			double x, y, scaling;

			rnd.unitDiscSample(x, y);
			//
			scaling = tan((1 - glossiness) * PI/2);
			x *= scaling;
			y *= scaling;

			Vector modifiedNormal = n + a * x + b * y;

			Ray newRay = ray;
			newRay.start = info.ip + n * 0.000001;
			newRay.dir = reflect(ray.dir, modifiedNormal);
			newRay.depth++;

			result += raytrace(newRay) * multiplier;
		}
		return result / count;
	}
}
void RectLight::getNthSample(int sampleIdx, const Vector& hitPos, Vector& samplePos, Color& color)
{
	Random& rnd = getRandomGen();
	// stratified sampling: subdivide the unit square into xSubd * ySubd subrectangles
	// and take a random points from each one of them. I.e., getNthSample() gets a random sample
	// from one of those subrectangles. The subrectangle in question is determined by sampleIdx.
	float x = (sampleIdx % xSubd + rnd.randfloat()) / (float) xSubd;
	float y = (sampleIdx / xSubd + rnd.randfloat()) / (float) ySubd;
	
	// create the sample in local space - in the (-0.5, 0, -0.5) -- (0.5, 0, 0.5) square
	Vector sample(x - 0.5, 0, y - 0.5);
	samplePos = T.transformPoint(sample); // transform the sample into world space
	
	// transform the point that is to be shaded into local space first
	Vector hitPos_LS = IT.transformPoint(hitPos);
	if (hitPos_LS.y > 0) {
		color.makeZero(); // point is behind the light - unilluminated.
	} else {
		// otherwise, return light color, attenuated by the angle of incidence
		// (the cosine between the light's direction and the normed ray toward the hitpos)
		color = this->col * float((area * dot(Vector(0, -1, 0), hitPos_LS) / hitPos_LS.length()));
	}
}
Random& getRandomGen()
{
	return getRandomGen(SDL_ThreadID());
}