【问题标题】:Casting ray vs projecting vertices?投射光线与投影顶点?
【发布时间】:2016-08-09 08:42:12
【问题描述】:

我正在尝试为我的光线追踪图形引擎添加光栅化支持。但是,我希望无论采用何种方法都能获得相同的图像(当然不包括阴影)。

相反,我得到了两种不同尺寸的测试模型,所以我猜测它一定与我为光线追踪投射光线的方式,或者我为光栅化构建投影矩阵的方式有关。

这是我的“相机”构造函数(负责构建投影矩阵):

Camera::Camera(float fLength, float fov, float targetRatio, float zNear, float zFar)
{
    focalLength = fLength;
    fieldOfView = fov;
    aspectRatio = targetRatio;
    scale = tan(fieldOfView * 0.5 * DEG_TO_RAD);

    viewMatrix = Matrix4<float>();

    projectionMatrix = Matrix4<float>();

    float distance = zFar - zNear;

    projectionMatrix.xx = scale / aspectRatio;
    projectionMatrix.yy = scale;
    projectionMatrix.zz = -(zFar + zNear) / distance;
    projectionMatrix.zw = -1.0f;
    projectionMatrix.wz = -2.0f * zNear * zFar / distance;
    projectionMatrix.ww = 0.0;

    //aperture = tan(fieldOfView / 2 * DEG_TO_RAD) * focalLength * 2;
    //fieldOfView = atan((aperture / 2) / focalLength) * 2 * RAD_TO_DEG;
}

这就是我根据帧缓冲区尺寸和当前像素坐标投射光线的方式(我计算方向并从最后一个矩阵行获取相机位置):

Ray Camera::castRay(unsigned int width, unsigned int height, unsigned int x, unsigned int y)
{
    float dirX = (2 * (x + 0.5) / (float)width - 1) * aspectRatio * scale;
    float dirY = (1 - 2 * (y + 0.5) / (float)height) * scale;

    Vector3<float> dir = (Vector3<float>(dirX, dirY, -1.0) * viewMatrix).normalize();

    return Ray(Vector3<float>(viewMatrix.wx, viewMatrix.wy, viewMatrix.wz), dir);
}

另一方面,这就是我使用光栅化方法对顶点进行光栅化的方式:

    Vector4<float> vertexInRasterSpace;
    Vector4<float> vertexInCameraSpace;

    vertexInCameraSpace = currentVertex * camera.viewMatrix;
    vertexInRasterSpace = vertexInCameraSpace * camera.projectionMatrix;

    vertexInRasterSpace.x = std::min(width - 1, (int)((vertexInRasterSpace.x + 1) * 0.5 * width));
    vertexInRasterSpace.y = std::min(height - 1, (int)((1 - (vertexInRasterSpace.y + 1) * 0.5) * height));
    vertexInRasterSpace.z = -vertexInCameraSpace.z;

最后得到的结果:

-光线追踪->Ray tracing picture

-光栅化->Rasterization picture

针说,两个图像使用相同的模型视图矩阵。我最初的假设是我会得到相同(大小)的图像吗?

~天空

【问题讨论】:

    标签: c++ raytracing rasterizing


    【解决方案1】:

    取决于光栅化算法正在做什么(您是将顶点提供给 3D 图形 API 还是进行自己的光栅化?),但我的第一个怀疑是:

    在乘以透视矩阵之后,但在光栅化之前,您需要执行透视除法:即将向量的 X、Y 和 Z 分量除以 W 分量。这似乎不见了。

    如果您将输出顶点提供给 3D 图形 API,那么考虑窗口的宽度和高度可能不是您想要的(这是硬件的 视口变换 的一部分渲染管道)。

    【讨论】:

    • 感谢您的回答。我正在做软件光栅化。我的印象是,在将顶点乘以投影矩阵时,透视除法是隐含的,但是在阅读了您的答案后,我尝试在 Z 中进行翻译,但没有效果!我会做更多的挖掘,因为这可能是问题所在。
    • @SkyBladeCloud 是的。矩阵乘法运算实际上不能进行除法(它可以做的最好的事情是乘以 1/常数)。因此,将透视投影放入矩阵可以看作是一个聪明的技巧:排列所有内容,使除法分母中的值最终出现在 W 分量中,最后手动进行除法。 (实际上,您在 4D 同质空间中进行所有操作,最后的透视分割投影回 3D 欧几里得空间。)
    • 好吧,必须把它交给你,伙计,你什么都对。我终于设法在光线追踪和光栅化上获得了相同的转换。缺失的视角鸿沟确实是问题所在。光线追踪 -> i.imgur.com/tHLMbvg.png。光栅化 -> i.imgur.com/dMmPvzz.png。再次感谢:~天空
    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2018-07-08
    相关资源
    最近更新 更多