games101-1 光栅化与光线追踪中的空间变换

这篇具有很好参考价值的文章主要介绍了games101-1 光栅化与光线追踪中的空间变换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在学习了一些games101的课程之后,我还是有点困惑,尤其是对于课程讨论的空间的变换,幸而最*在做games101的第五次作业时,查询资料找到了scratchpixel这个网站,看了一些文章,终于把脑子里的一团乱麻组织起来了,也就有了这篇关于图形学的第一篇博客。
想要更好的理解这篇博客,强烈推荐先学习games101中关于transformation,rasterization和ray tracing的第一部分
以下内容参考:https://www.scratchapixel.com/lessons/3d-basic-rendering/computing-pixel-coordinates-of-3d-point/perspective-projection.html
https://www.scratchapixel.com/lessons/3d-basic-rendering/computing-pixel-coordinates-of-3d-point/mathematics-computing-2d-coordinates-of-3d-points.html
https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-generating-camera-rays/generating-camera-rays.html
如果内容有误,欢迎指出

  • 光栅化与光线追踪中的空间变换
    • 光栅化与光线追踪的理解
    • 不同空间的介绍
    • 光栅化中的空间变换
    • 光线追踪中的空间变换

光栅化与光线追踪的理解

在图形学中一个很重要的问题就是,我们如何把一个三维空间中的物体,去展示到一个二维*面上。
这件事其实我们可以分成两步去做,第一步是解决visibility的问题,第二步是解决shading的问题。
怎么理解这两种方法呢?我们先想象,现在在一个无穷大的场景里面,有很多物体,还有一个摄像机,摄像机面前一定距离有个*面,现在我们想知道通过摄像机在它面前这个二维*面上看到的所有三维物体的形象。
光栅化方法,就是把场景内的所有物体先都投影到这个*面上,然后进行着色shading,这里就是光栅化比较麻烦的地方,我们需要设计着色模型(games101中的bling-phone模型),考虑到物体的空间先后顺序我们需要z-buffer,考虑到阴影效果我们需要shadow map,以及纹理贴图来帮助我们。
而光线追踪,模拟了光线在场景中的传播,在光线追踪中,从观察点(或相机)出发的光线被跟踪以确定它们与场景中的物体相交点,然后计算反射、透射和光照等效果,是一种基于物理的渲染方法。
通过上述描述,我们可以发现光栅化可以短时间内处理大量物体,但在光照效果等方面不如光线追踪,而光线追踪速度较慢,因为需要考虑到光线的种种复杂的传播情况,这也就导致光栅化主要用于实时渲染,而光线追踪主要用于离线渲染
我们再来考虑针对这两种方法的空间变换,我们会发现这两种方法其实在干相反的事情,
光栅化做的就是从世界空间到栅格空间,实现每个物体的visibility,然后着色
而光线追踪做的是实现每个光线的可视化,然后着色,需要我们从栅格空间转换到世界空间。

不同空间的介绍

要理解光栅化与光线追踪的空间变换,我们首先要搞清楚几个空间的定义
世界空间:世界空间就是我们之前提到的无穷大的场景,所有的点的定义最初都是在这个三维空间中,与之对应的是世界坐标系
相机空间:相机空间就是以相机为坐标原点的坐标系建立的空间,我们可以使用games101中提到的camera transformation对应的矩阵,实现世界坐标系到相机坐标系之间的转换,一般来说,我们的相机的位置在(0,0,0)这个坐标原点,朝向世界坐标系的-z方向。
屏幕空间:屏幕空间是一个二维空间,相机空间中的点经过透视变换可以到image plane上,然后我们根据画布(canvas)的范围,可以在image plane这个无穷大的*面上划分出屏幕空间
games101-1 光栅化与光线追踪中的空间变换

NDC空间:把屏幕空间坐标系标准化到【0-1】的空间中

栅格空间:NDC空间中的2D点被转换为2D像素坐标,为此,我们将标准化点的 x 和 y 坐标乘以像素宽度和高度,从 NDC 到栅格空间还需要反转该点的 y 坐标。 由于像素坐标是整数,因此最终坐标需要四舍五入到最接*的以下整数。
下面的图很形象地展示了上面的三个空间的区别:
games101-1 光栅化与光线追踪中的空间变换

其实我们电脑的屏幕就相当于栅格空间,不同的分辨率代表着不同的水*像素数与竖直像素数,也就代表着不同的像素宽度与高度,代表着不同的栅格空间计算方法

注意我们这里的讨论实际上简化了屏幕坐标系与NDC坐标系,games101中的投影变换实际上就是直接从相机空间变换到了NDC空间或者说变换到了裁剪空间然后经过齐次除法到NDC空间,空间是三维的,因为我们不仅要完成投影,还需要记录点的z坐标信息来进行深度缓存等等,确定物体的先后关系:
games101-1 光栅化与光线追踪中的空间变换
可以看到二维空间与三维空间的区别就是二维空间舍弃了z坐标,它们在xy坐标方面做的都是投影,三维空间相当于多做了z坐标的投影

注意games101其实并没有过多的讨论裁剪空间,而是推导了一个矩阵直接转换到NDC空间,这也是未来博客中要探讨的内容,同时z-fighting的现象也未提及(*远*面距离过大导致的问题)

在我们这里的讨论屏幕坐标系与NDC坐标系是二维的,这样可以把光栅化与光线追踪的visibility处理统一起来,因为光线追踪中我们并不需要使用投影矩阵,就不存在光栅化中的视锥体与立方体,只需要二维的屏幕空间。

光栅化中的空间变换

世界空间到观察空间或者说是摄像机空间:
这一步很简单,和games100课程中的一样,实际上就是进行坐标系变换,进行旋转与*移,值得注意的是默认,相机正对的是z的负半轴,所以我们可见的物体的z坐标也是负的
那么在进行从观察空间到屏幕空间的过程中,我们要进行投影,将3维的点投影到2维的屏幕上:
games101-1 光栅化与光线追踪中的空间变换
这样我们根据相似关系,可以得到屏幕空间与观察空间的xy坐标映射,注意这里我们假设和**面的距离是1,可以得到:
\(\begin{array}{l} P'.x = \dfrac{P_{camera}.x}{P_{camera}.z}\\ P'.y = \dfrac{P_{camera}.y}{P_{camera}.z}. \end{array}\)

但是注意我们之前提到过物体的z坐标是负的,所以这样进行除法会导致xy发生颠倒,因此,我们要再加上负号:
\(\begin{array}{l} P'.x = \dfrac{P_{camera}.x}{-P_{camera}.z}\\ P'.y = \dfrac{P_{camera}.y}{-P_{camera}.z}. \end{array}\)

之前提到过屏幕空间是有范围的,由宽度与高度决定,所以我们要加上这个限制
\(\text {visible} = \begin{cases} yes & |P'.x| \le {W \over 2} \text{ or } |P'.y| \le {H \over 2}\\ no & \text{otherwise} \end{cases}\)

从屏幕空间到NDC空间,需要我们把原来在[-width/2]--[width/2]和[-height/2]到[height/2]之间的点转换到[0-1]的点(有的NDC空间采用的是[-1-1]):
\(\begin{array}{l} P'_{normalized}.x = \dfrac{P'.x + width / 2}{ width }\\ P'_{normalised}.y = \dfrac{P'.y + height / 2}{ height } \end{array}\)

从NDC空间到栅格空间,我们需要乘以像素宽度与高度,因为我们认为像素点是一个个小矩形来进行栅格化,并且取整,这一步也被称为viewport变换

\(\begin{array}{l} P'_{raster}.x = \lfloor{ P'_{normalized}.x * \text{ Pixel Width} }\rfloor\\ P'_{raster}.y = \lfloor{ P'_{normalized}.y * \text{Pixel Height} }\rfloor \end{array}\)

同时我们注意到栅格空间的y是向下的,所以改变方向取反:

\(\begin{array}{l} P'_{raster}.x = \lfloor{ P'_{normalized}.x * \text{ Pixel Width} }\rfloor\\ P'_{raster}.y = \lfloor{ (1 - P'_{normalized}.y) * \text{Pixel Height} }\rfloor \end{array}\)

以上我们就将三维空间中的点可视化到了二维空间中

光线追踪中的空间变换

针对光线追踪,我们需要的是可视化我们的光线,因为我们需要实际计算光线与物体相交,所以我们的光线需要世界坐标下的三维表示,简单来说一个光线可以如下定义:
games101-1 光栅化与光线追踪中的空间变换
我们已经知道了O的位置,它就是坐标原点(0,0,0)
现在需要知道P的位置

现在考虑下面这张图:
games101-1 光栅化与光线追踪中的空间变换

第一步转换到NDC空间:

\(\begin{array}{l} PixelNDC_x = \dfrac{(Pixel_x + 0.5)}{ImageWidth},\\ PixelNDC_y = \dfrac{(Pixel_y + 0.5)}{ImageHeight}. \end{array}\)
注意这里我们只考虑光线穿过像素点的中心,所以我们要加上0.5,然后再分别除以栅格空间的宽度与高度

第二步转换到屏幕空间:
注意屏幕空间的y轴发生了反转,同时由于我们是将原本的图像压缩到了-1-1的这个空间中,所以我们现在要将其还原回去,即宽度从[-1--1]转换成[-width/2---width/2],高度同理,我们使用宽高比以及fov角度来表示就可以得到:

\(ImageAspectRatio = Width / Height \\tan(\dfrac{\alpha}{2}) = Height / 2 /d(这里d = 1)\)
\(\begin{array}{l} PixelCamera_x = (2 * {PixelNDC_x } - 1) * ImageAspectRatio * tan(\dfrac{\alpha}{2}),\\ PixelCamera_y = (1 - 2 * {PixelNDC_y }) * tan(\dfrac{\alpha}{2}). \end{array}\)

其中tan(a/2)表示图像高度的一半,因为我们在这里假设**面坐标是-1

最后转换到世界空间中,只需要加入z坐标-1,然后从相机空间转换到世界空间即可(这里作业中省略了从相机空间到世界空间的变换矩阵)

上述过程也就是games101第五次作业求光线的实现文章来源地址https://www.toymoban.com/news/detail-739891.html

到了这里,关于games101-1 光栅化与光线追踪中的空间变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 光线追踪算法

    光线追踪算法是一种基于物理光线对场景进行渲染的算法,其原理是从像素出发,通过递归地追踪光线的方法计算得到像素最终的颜色。下面是光线追踪算法的简单步骤及相关公式: 对于每个像素,产生一条从摄像机出发的光线R,同时设置深度t为0。 对于场景中的每个物体

    2024年02月10日
    浏览(46)
  • 光追(光线追踪)和 DLSS是什么?

    最近,一款叫做《黑悟空》的游戏登上了热搜,游戏支持4K RTX ON光追+NVIDIA DLSS技术,那么什么是光追技术与DLSS呢,他们有什么区别呢?   1.光线追踪技术 光线追踪,是一种渲染技术,利用算法来模拟真实世界中的光线的物理特点,能够做到物理上精确的阴影、反射和折射以及

    2024年02月11日
    浏览(80)
  • 实时光线追踪(3)Ray Casting

    目录 硬件光追(Hardware Ray Tracing) 加速结构(Acceleration Structure,AS) AS 策略 Ray Tracing Pipeline Ray Generation Shader Intersection Shader Hit Shader Ray Query 软件光追(Software Ray Tracing) Screen Space Ray Tracing Linear Ray Marching + 二分法 Failure Case Height Field Ray Tracing Voxel Tracing Voxelization Voxel Ray Mar

    2024年02月09日
    浏览(50)
  • 在光线追踪中避免自相交的方法

    这是我阅读 Ray Tracing Gem 的一篇笔记,《避免自相交的快速可靠的方法》是 Ray Tracing Gem 的第六章。这篇博客文章主要是为了记录和解释原文末尾给出的魔法一般的代码。 数学上给出了很多不同的求解光线与几何体相交的方法,它们都是等价的,但对于计算机而言并不一定。

    2024年02月08日
    浏览(33)
  • GAMES101:作业3

    附其他所有作业超链接如下: Games101 作业0: 作业0 Games101 作业1: 作业1 Games101 作业2: 作业2 Games101 作业3: 作业3 Games101 作业4: 作业4 Games101 作业5: 作业5 Games101 作业6: 作业6 Games101 作业7: 作业7 完整代码获取途径: https://github.com/liupeining/Games_101_homework 照旧把这段代码

    2024年02月04日
    浏览(40)
  • 【GAMES101】03 Transformation

    1、Scale(缩放)  2、Reflection Matrix(反射矩阵)  3、Shear Matrix(剪切矩阵)  4、Rotation Matrix(旋转矩阵) 推导过程:     5、Translation Matrix(平移矩阵) 平移操作不属于线性变换的范畴。 引入 齐次坐标 ,通过增加维度,来将平移坐标写成同样的矩阵形式。 很显然,平移无

    2024年02月02日
    浏览(43)
  • games101 作业3

    1.项目才打开时无法运行。 解决方法: 切换成c++17 解决方法引用: Games101 作业3 环境问题 - 知乎  注:知乎里面的关于越界限制的控制不适用,虽然可以解决部分作业的问题,但是在bump里面依然会出现越界错误。应该用以下大佬的代码。  2.出现越界错误   解决方法: 在头

    2023年04月25日
    浏览(38)
  • GAMES101 作业1

    作业pa1对应的是GAMES101课程Lecture02到Lecture04这三节课的内容,主要是用于巩固空间中的物体投影到相机平面的整个过程。 说在前面,本文是在左手系下进行讨论的。 粗略地看一遍我们可以知晓main函数的流程: ①设定一些基本的初始参数并初始化源代码给出的 光栅化类raste

    2024年02月09日
    浏览(34)
  • GAMES101 作业0

    课上提供的环境是Linux, 还需要安装Vitrual Box和创建虚拟机,省事就直接在Windows系统下Visual Studio下操作了。 简单的环境配置: 下载Eigen 的库 在工程属性中添加目录: 2处地方 注意: 刚添加完后,我新建main.cpp后, 引入头文件 路径也没有设置错啊,但是就是找不到。 直到看

    2024年02月16日
    浏览(41)
  • GAMES101作业2

    在屏幕上画出一个实心三角形, 换言之,栅格化一个三角形。上一次作业中,在视口变化之后,我们调用了函数 rasterize_wireframe(const Triangle t)。但这一次,你需要自己填写并调用 函数 rasterize_triangle(const Triangle t)。 该函数的内部工作流程如下: 创建三角形的 2 维 bounding box。

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包