Example #1
0
// TODO: implement adaptive supersampling
RGBColour World::colourForPixelAt(int i, int j) {
	double d = viewport.getViewingDistance();

	if (ss_level == 1) {
		// no super-sampling
		double uValue = viewport.uAmount(i, 1, 0, false);
		double vValue = viewport.vAmount(j, 1, 0, false);
		vec3 direction = wAxis.scaled(-d) + uAxis.scaled(uValue) + vAxis.scaled(vValue);
		Ray theRay(cameraPosition, direction);

		return RGBColour(traceRay(theRay, 0.0, 0));
	}

	// 0.01 => x16, 1.2 => x64
	double thresholds[2] = {0.01, 1.2}; 


	double var = 0.0;
	int lvl_log = 2;

	RGBVec pixelColour;

	while (lvl_log <= ss_level) {
		pixelColour = RGBVec(0.0,0.0,0.0);

		int lvl = int_pow(2, lvl_log - 1); 

		double scale_factor = 1.0 / static_cast<double>(lvl*lvl);

		vec3 sum_x_sq(0.0,0.0,0.0);

		for (int a = 0; a < lvl; a++) {
			for (int b = 0; b < lvl; b++) {
				double uValue = viewport.uAmount(i, ss_level, a, lvl_log > 2);
				double vValue = viewport.vAmount(j, ss_level, b, lvl_log > 2);
				vec3 direction = wAxis.scaled(-d) + uAxis.scaled(uValue) + vAxis.scaled(vValue);	
				Ray theRay(cameraPosition, direction);
				RGBVec sample = traceRay(theRay, 0.0, 0).scaled(scale_factor);
				pixelColour += sample;
				if (ss_level > 2) sum_x_sq += sample.getVector().pointwise(sample.getVector());
			}
		}		

		if (lvl_log == 2 && ss_level > 2) {
			vec3 varvec = sum_x_sq.scaled(scale_factor) - pixelColour.getVector().pointwise(pixelColour.getVector());
			var = varvec.magnitude();
			if (i % 100 == 0 && j % 100 == 0) std::cout << "var: " << var << std::endl;
		}

		if (var < thresholds[lvl_log - 2] || lvl_log == ss_level) break;
		lvl_log++;
	}

	if (lvl_log == 2) renderStats.ss_x4++;
       	else if (lvl_log == 3) renderStats.ss_x16++;
	else if (lvl_log == 4) renderStats.ss_x64++;

	return RGBColour(pixelColour);
}	
Example #2
0
	Ray ray_for_pixel (int x_, int y_) const {
		float delta_x = float((x_ + 0.5f) - m_x_res * 0.5f) / (m_x_res * 0.5f);
		float delta_y = float((y_ + 0.5f) - m_y_res * 0.5f) / (m_y_res * 0.5f);

        // initialize ray diffferentials
        Vector3D d = m_z + (m_x * delta_x) + (m_y * delta_y);
        Vector3D dPdx, dPdy, dDdx, dDdy;
        dDdx = (( (m_x * d.dot(d)) - (d * d.dot(m_x)) )*(1.f/std::pow(d.dot(d), 1.5))) * (1.f/((float)m_x_res*0.5f));
        dDdy = (( (m_y * d.dot(d)) - (d * d.dot(m_y)) )*(1.f/std::pow(d.dot(d), 1.5))) * (1.f/((float)m_y_res*0.5f));
		
        Ray theRay(m_pos, d.normalize());
        theRay.setdDdx(dDdx);
        theRay.setdDdy(dDdy);
        theRay.setdPdx(dPdx);
        theRay.setdPdy(dPdy);

        return theRay;
	}