// 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); }
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); } }