void Renderer::_computeSections() { QSize imageSize = _image.size(); Ray ray; ray.type = Ray::Primary; while (1) { _renderingTasksMutex.lock(); if (_renderingTasks.isEmpty()) { _renderingTasksMutex.unlock(); return ; } QRect task = _renderingTasks.takeFirst(); _renderingTasksMutex.unlock(); for (int x = 0; x < task.width(); ++x) { for (int y = 0; y < task.height(); ++y) { Color pixel = Color::BLACK; int resolution = config->antialiasingResolution(); float subSize = 1.0f / resolution; Config::AntialiasingType type = config->antialiasingType(); for (float x1 = 0.0f; x1 < 1.0f; x1 += subSize) { for (float y1 = 0.0f; y1 < 1.0f; y1 += subSize) { float vx = 0; float vy = 0; if (type == Config::Random) { vx = float(qrand()) / RAND_MAX; vy = float(qrand()) / RAND_MAX; } else if (type == Config::Uniform) { vx = x1 + subSize / 2.0f; vy = y1 + subSize / 2.0f; } else if (type == Config::Jittered) { vx = x1 + subSize * float(qrand()) / RAND_MAX; vy = y1 + subSize * float(qrand()) / RAND_MAX; } else if (type == Config::Shirley) { float vx1 = x1 + subSize * float(qrand()) / RAND_MAX; float vy1 = y1 + subSize * float(qrand()) / RAND_MAX; vx = (vx1 < 0.5) ? (-0.5f + qSqrt(2.0f * vx1)) : (1.5f - qSqrt(2.0f - 2.0f * vx1)); vy = (vy1 < 0.5) ? (-0.5f + qSqrt(2.0f * vy1)) : (1.5f - qSqrt(2.0f - 2.0f * vy1)); } vx = (vx + x + task.left()) / imageSize.width(); vy = (vy + y + task.top()) / imageSize.height(); Intersection hit; _camera->ray(vx, -vy, ray); ray.time = float(qrand()) / RAND_MAX; _integrator->compute(ray, hit); pixel.AddScaled(hit.shade, 1.0f / (resolution * resolution)); } } _setPixel(x + task.left(), y + task.top(), pixel); } } } }
void Renderer::_setPixel(int x, int y, const Color &color) { int idx = x + y * _image.width(); float f = 1.0f / (_sampleNumber + 1.0f); Color c = _imageColors[idx]; c.Scale(1.0f - f); c.AddScaled(color, f); _imageColors[idx] = c; _image.setPixel(x, y, c.ToInt()); }
void Camera::RenderPath(Scene &scn, int n) { RayTrace rayTrace(scn); for (int y = 0; y < _img.YRes; y++) { for (int x = 0; x < _img.XRes; x++) { // compute the primary ray Vector3 cy; cy.Cross(_worldMatrix.c, _worldMatrix.b); Vector3 cx = cy / pow(cy.Magnitude(), 2); cy.Cross(cx, _worldMatrix.c); float hfov = 2.f * atanf(_aspect * tanf(_verticalFOV / 2.f)); float cw = 2.f * tanf(hfov/2.f); float ch = cw / _aspect; Ray ray; ray.Origin = _worldMatrix.d; ray.Direction = _worldMatrix.c + ((float)(x + 0.5f) / (float)_img.XRes - 0.5f) * cw * cx + ((float)(y + 0.5f)/(float)_img.YRes - 0.5f) * ch * cy; ray.type = Ray::PRIMARY; // shoot the primary ray Intersection hit; if (x > 124 && x <= 140 && y == _img.YRes - 495 ) { // Color white = Color::WHITE; // std::cout << "debug pixel" << std::endl; // _img.SetPixel(x, y, white.ToInt()); // continue; } rayTrace.TraceRay(ray, hit); if (n != -1) { Color c; c.FromInt(_img.GetPixel(x, y)); Color avg = Color::BLACK; avg.AddScaled(c, n - 1); avg.Add(hit.Shade); avg.Scale(1.0f / n); _img.SetPixel(x, y, avg.ToInt()); } else _img.SetPixel(x, y, hit.Shade.ToInt()); } } }