RayTracing, как бороться с искажениями? - PullRequest
0 голосов
/ 29 февраля 2020

Мои сферы выглядят овальными из-за искажения перспективы, и я попытался изменить вертикальное поле обзора, но искажение не исправлено. Я также пытался варьировать расстояние от камеры до плоскости изображения. Что-то не так с кодом? Я использовал трассировку лучей в камере выходного дня, но они не получают такое же искажение. Не обращайте внимания на черную часть, я все еще работаю над тенью. Любая помощь, чтобы справиться с этим? enter image description here

камера. cpp

#include "camera.h"

Camera::Camera(vec lookat, vec lookfrom, vec vup, float vfov, float aspect_ratio)
{
    vec u, v, w;
    vfov = (vfov/180)*M_PI;
    float half_height = tan(vfov/2)* 10;
    float half_width = half_height * aspect_ratio;
    origin = lookfrom;
    w = unit_vector(lookfrom - lookat);
    u = unit_vector(cross(w, vup));
    v = cross(w, u);
    lower_left_corner = origin - half_width*u - half_height*v - w;
    horizontal = 2*half_width*u;
    vertical = 2*half_height*v;
}

ray Camera::CreateRay(float u, float v)
{
    vec dir = unit_vector(lower_left_corner + v*vertical + u*horizontal - origin);
    return ray(origin, dir);
}

основной. cpp часть, которая генерирует лучи

int main()
{
    const int w = 200, h = 100;
    FILE *fp;
    fp = fopen("img.ppm", "wb");
    fprintf(fp, "P6\n%d %d\n255\n", w, h);
    Camera cam(vec(0,0,-3), vec(-2,2,1), vec(0,1,0), 45, float(w)/float(h));
    for(int j = h - 1; j >= 0; j--)
    {
        for(int i = 0; i < w; i++)
        {
            vec col(0, 0, 0);
            static unsigned char pixel[3];
            for(int s = 0; s < 200; s++){
                float u = 1.0 - 2.0*float(i + 0.5)/float(w);
                float v = 2.0*float(j + 0.5)/float(h) - 1.0;
                ray r = cam.CreateRay(u, v);
                col += color(r);
            }
            col /= float(200);
            pixel[0] = int(clamp(col.r() * 255));
            pixel[1] = int(clamp(col.g() * 255));
            pixel[2] = int(clamp(col.b() * 255));
            fwrite(pixel, 3, 1, fp);
        }


    }
    fclose(fp);
    return 0;
}

1 Ответ

0 голосов
/ 08 апреля 2020

Я провел достаточно времени, борясь с той же проблемой. Класс камеры идет ниже. Пожалуйста, обратитесь к хранилищу для других классов. Реализация трассировки лучей

struct Camera {
    Vec3fa position, direction;
    float fovDist, aspectRatio;
    double imgWidth, imgHeight;
    SGRTMat4 camMatrix;

    Camera(Vec3fa pos, Vec3fa cRot, Vec3fa cDir, float cfov, int width, int height) {
        position = pos;
        aspectRatio = width / (float)height;
        imgWidth = width;
        imgHeight = height;

        Vec3fa angle = Vec3fa(cRot.x, cRot.y, -cRot.z);
        camMatrix.setRotationRadians(angle * M_PI / 180.0f);

        direction = Vec3fa(0.0f, 0.0f, -1.0f);
        camMatrix.rotateVect(direction);

        fovDist = 2.0f * tan(M_PI * 0.5f * cfov / 180.0);
    }

    Vec3fa getRayDirection(float x, float y) {
        Vec3fa delta = Vec3fa((x-0.5f) * fovDist * aspectRatio, (y-0.5f) * fovDist, 0.0f);
        camMatrix.rotateVect(delta);
        return (direction + delta);
    }
};
...