void RandomKnot::assignColors(void) { // Initialize the color indices; -1 indicates an as-yet-unknown color. int color = mPrefs.technicolor() ? -1 : 0; for (int y = 0; y < mVSections; ++y) { for (int x = 0; x < mHSections; ++x) { mpSectionColors[BOT][y * mHSections + x] = color; mpSectionColors[TOP][y * mHSections + x] = color; } } ++color; // Assign colors to the sections by tracing all the 'strands' in the knot. for (int y = 0; y < mVSections; ++y) { for (int x = 0; x < mHSections; ++x) { if (mpSectionColors[TOP][y * mHSections + x] < 0) { // Assign a color to the top strand. if (traceColor(color, TOP, x, y, 0, 0)) { ++color; } } if (mpSectionColors[BOT][y * mHSections + x] < 0) { // Assign a color to the bottom strand. switch (mpSectionTypes[y * mHSections + x]) { case D: case H: if (traceColor(color, BOT, x, y, 0, 1)) { ++color; } break; case V: if (traceColor(color, BOT, x, y, 1, 0)) { ++color; } break; case N: break; } } } } // Generate the random colors. mpColors = new RandomColor[color]; int hue = randomInteger(360); const int gamut = 90 + randomInteger(270); const int shift = gamut / color; for (int i = 0; i < color; ++i) { mpColors[i] = RandomColor(0.4, 0.9, 0.6, 1.0, 1.0, 1.0, hue); hue = (hue + shift) % 360; } }
//trace the ray and find out the color at its intersection point with the scene Vector4 Renderer::traceColor(Ray ray, Scene* scene, unsigned int recDepth) { Vector4 color(0,0,0); ray.min_t = ray.min_t + ray.epsilon_t; IntersectionData* iData = scene->intersect(ray); if (iData && (recDepth < m_recursionDepth)) { // sucessful intersection test //=== EXERCISE 2.2.3 === Vector3 N = (iData->normal).normalize(); Vector3 R = ((N.operator*(2)).operator*(N.dot(-ray.direction))+ray.direction).normalize(); // calculate R Ray newRay(iData->position, R); newRay.min_t = newRay.min_t + ray.epsilon_t; color = traceColor(newRay, scene, recDepth+1).operator*(iData->reflectionPercentage) + ( m_shader->shade(iData, scene).operator*(1 - iData->reflectionPercentage)) ; // recursion } else { color = m_shader->shade(iData, scene); //color = scene->getBackground(); // background color } // clean if (iData!=NULL){ delete(iData); } return color.clamp01(); }
//main renderloop that raytraces the given scene void Renderer::render(Scene* scene){ if (scene) { // Initialize Sampler Point p = scene->getCamera()->getResolution(); m_sampler->init(p.x, p.y); // Initialize fields Ray ray; std::vector<Ray> shadowRays; IntersectionData* iData = 0; Sample* sample = new Sample(0,0); //reset film in camera sample->setSize( (p.x > p.y? p.x : p.y) ); scene->setSample(*sample); scene->getCamera()->initFilm(); // Renderloop while (m_sampler->getNextSample(sample)) { // generate camera ray and intersect it with the scene ray = scene->getCamera()->generateRay(*sample); sample->setColor(traceColor(ray, scene,0)); // write back the sample color scene->setSample(*sample); // observer update if (m_sampler->cycleComplete()) notifyObservers(); } //cleanup delete sample; } }