Beispiel #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);
}	
Beispiel #2
0
void fill_dp_matrix(const std::vector<double> & x,
                    std::vector< std::vector< double > > & S,
                    std::vector< std::vector< size_t > > & J)
  /*
   x: One dimension vector to be clustered, must be sorted (in any order).
   S: K x N matrix. S[k][i] is the sum of squares of the distance from
   each x[i] to its cluster mean when there are exactly x[i] is the
   last point in cluster k
   J: K x N backtrack matrix

   NOTE: All vector indices in this program start at position 0
   */
{
  const int K = S.size();
  const int N = S[0].size();

  std::vector<double> sum_x(N), sum_x_sq(N);

  double shift = x[N/2]; // median. used to shift the values of x to
  //  improve numerical stability

  for(int i = 0; i < N; ++i) {
    if(i == 0) {
      sum_x[0] = x[0] - shift;
      sum_x_sq[0] = (x[0] - shift) * (x[0] - shift);
    } else {
      sum_x[i] = sum_x[i-1] + x[i] - shift;
      sum_x_sq[i] = sum_x_sq[i-1] + (x[i] - shift) * (x[i] - shift);
    }

    // Initialize for k = 0
    S[0][i] = ssq(0, i, sum_x, sum_x_sq);
    J[0][i] = 0;
  }

  for(int k = 1; k < K; ++k) {
    int imin;
    if(k < K - 1) {
      imin = std::max((size_t)1, (size_t)k);
    } else {
      // No need to compute S[K-1][0] ... S[K-1][N-2]
      imin = N-1;
    }

#ifdef DEBUG
    std::cout << std::endl << "k=" << k << ":";
#endif
    fill_row_k(imin, N-1, k, S, J, sum_x, sum_x_sq);
  }
}