예제 #1
0
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);
            }
        }
    }
}
예제 #2
0
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());
}
예제 #3
0
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());
        }
    }
    
}