尝试搭建webgl游戏引擎-渲染管线

上一篇为:尝试搭建webgl游戏引擎-场景管理

本篇记录一下渲染管线的学习

webgl的渲染管线,学起来还是很痛苦的。
要了解的知识点比较多。
目前也没有彻底明白,不过不耽误此篇进行简单的记录。

我所理解的渲染管线

我理解渲染管线就是CPU将数据准备好,然后通知一声GPU:
“老弟,可以开工了”
然后GPU拿着这些数据,
经过一系列处理,最终显示到屏幕上。

关键点就是这一系列处理

首先是空间的变换

要将一个虚拟的点,最终映射到屏幕上的一个像素。
需要经历几个空间的转换:

1. 局部模型空间到世界空间

一个点,一般是附属于一个模型的。
比如正方体的8个顶点。
右上角的顶点坐标为(1,1,1)
这个坐标是相对于这个模型的正中心的。

但是在整个webgl里,是把所有顶点都当成了自己的儿子。
如果这个即使正方体移动到了天边,webgl还是认为这个点在(1,1,1)的位置。

所以我们需要经过一个变换transform,来将这些孙子点,都升级成儿子点。
如果只是位移的话,就非常简单了,自己坐标加上自己爸爸的坐标就是最终的坐标了。
(当然,如果爷爷健在,那么还得加上爷爷的,以此类推)
不过,实际上有很多变换综合,比如旋转,缩放,错切,变形等。
那么就需要用到矩阵来综合运算了。因为矩阵相乘最终还是矩阵。
可以将很多变换最后合成一个矩阵给到GPU老弟。
GPU老弟在自己的顶点函数里,进行一次运算就可以将所有复杂的顶点关系都离散到世界空间中了。

2. 世界空间到摄像机空间(视图空间)

好了,现在所有儿子都已经排排站站好了。
搞了这么复杂的伦理变换。不得纪念一下?
所以我们请来了一个摄像师。
这个摄像师就是引擎中的摄像机了。

这个摄像师为了找到一个好背景,不断的搬自己的工具到想要的位置。
视图变换,就是将顶点从世界空间移动到视图空间。
目的是找到每个顶点,相对于摄像机的位置。
这也是一个相对问题。
比如摄像师拿着家伙事儿往右移动了一些,那么镜头中的风景就往左挪动了一些。
为了方便计算,摄像机移动到世界坐标原点是最nice的了。
所以,将所有顶点,按照摄像机的逆变换就可以找到正确的位置。

比如摄像机的世界坐标是(1,2,-3)
某个顶点的世界坐标是(12,-10,1)
那么摄像机的逆变换就是(-1,-2,3)
(就是让摄像机回到原点)
那么顶点最后的视图空间的坐标就是(11,-12,4)
这只是位移,没有算旋转和缩放等变换。最后都需要用到矩阵的

3. 视图空间到投影空间(裁剪空间)

ok。摄像师终于找好了一个绝佳的位置。
不过很可惜,摄像机就那么大的屏幕
不可能装得下整个世界。
所以,有些儿子就很遗憾的没有出现在屏幕上了。
被裁了。emo了。

从视图空间到裁剪空间,需要通过一个投影变换。
投影变换又有正交投影和透视投影。
反正不管那种投影方式,都有一个包围盒。
只有在包围盒内的内容才可以显示
包围盒有一个近裁剪面,一般作为最后的显示成像面。
投影变换用来将所有顶点转换到这个近裁剪面
也可以说是框到了一个CVV的规则裁剪空间中

正交投影的矩阵比较简单,保留x,y,对z进行换算(主要用来做深度检测)
透视投影涉及到一些比例换算,齐次坐标等知识。不过自己推导一遍,也没那么复杂了。
这里就不做详细记录了。毕竟篇幅已经很长了。

4. 裁剪空间到NDC

这一步是比较难理解的。NDC是标准设备坐标。
我之前一直没理解,咋冒出来个这么个东西。
后来知道了透视投影后,是一个齐次坐标。
x,y,z的值都是乘以了一个w后的值。
为了复核webgl的空间坐标系。
进行一次齐次除法,将坐标转换一下。

5. NDC到屏幕空间

然后就到了最后的显示了。
NDC说起来也就是-1到1的坐标系。
而屏幕是按照像素来算的。
所以最后还要基于屏幕的分辨率进行缩放变换。
将坐标换算到到(0,0)到(w,h)范围内。

小结

所以空间变换的顺序就是:
模型空间–世界空间–视图空间–裁剪空间–NDC–屏幕空间

其它管线节点

渲染管线不仅仅是这些空间变换就能完全代表的。
在这之中还有一些其它的处理也是需要了解的。

顶点着色

就是处理模型到裁剪的变换。可以添加颜色,法线等顶点属性变换。

图元装配

这个非常重要,需要CPU告诉GPU用什么样的方式组织这些零散的顶点。
比如拿出3个顶点,构成一个三角面。
这样之后,就可以在3个顶点间进行属性插值。
这一步是在顶点处理完事后,即已经到了完成了NDC的变换。

裁剪

在进行图元装配和,才进行裁剪。将外面的图元裁剪掉。
如果只是裁剪外面的点,那么图形就不完整了。
所以需要先进行图元装配再进行裁剪。

光栅化

进行了图元裁剪后,所有可以显示的图元数据就有了。
也对应到了规则的空间。
那么就可以将规则的图元映射到屏幕像素里。
这一步就叫做光栅化。
感觉像是将逻辑的数据离散到物理的单位上。
光栅化有很多算法,但是不是我目前关心的重点了。

片元着色

等到光栅化完毕后,就形成了非常多的片元(像素)
每个片元都携带了一些信息,比如坐标,深度等等。
然后就可以自定义处理一些内容,然后转向后面。

模板测试

等到片元着色完事后,就可以进行模板测试了。
模板测试使用模板缓冲,将不通过的片元丢弃。
模板测试主要用来做一些自定义的效果。我目前没有用到。

深度测试

等到模板测试后,就可以深度测试了。
深度测试主要用来完成片元的遮挡关系。
将z值大的同一位置的片元丢弃。
这里我理解的是,同一个像素位置可能会有多个片元。
所以需要将后面的片元丢弃,不用重复绘制。

小结

想要将一个图形最终变到屏幕上,真是要费很大的周章。
不过这也是为了适应各种可能性。

顶点着色器和片元着色器

可编程渲染管线的重点就是可以自定义书写顶点着色器和片元着色器。
在webgl中,用glsl的语法进行编写。
在写引擎或者游戏的时候,也几乎就处理这两者。
然后通过attribute,uniform,in,out进行数据通信和流转。

结语

要学的东西有很多。
只能不断学习,才不会变成咸鱼。

文章写的很不好,不过会越来越好的。

希望自己有找一日找到自己的财富密码。

下一篇写简单的点击事件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值