前言:
内容前瞻,本次笔记主要先完善成像部分(也就是遮挡),然后开始涉及shading(着色)部分。非常抱歉这么久才更新,最近这段时间本小白一直在忙着进行毕业答辩,后面每每学习了新的东西我都会更新的,感谢大家喜欢。
1、遮挡
前面回顾一下,我们经过了视图变化以后可以得到真正的二维图像,我们已经到了光栅化以后得到了一个个的三角形,不过大家有没有想过,遮挡剔除这部分的内容呢?
通过上面的渲染流水管线可知,在调用GPU渲染管线之前,会有剔除操作。这里我们主要详细讲解一下,如果不同物体的深度值(z轴),那么物体和物体之间的遮挡是怎么是实现的呢?
1.1、遮挡方法1(先画后方物体,再画前方物体)
这是什么意思呢?
像前面那幅画一样,先画后面的物体,再画前面的树等物体进行覆盖操作,这就实现了根据深度来判断是不是遮挡。
但是这种方法实际上是有前提的,那就是被渲染的物体一定有明显的深度变化,可是,如果用这种方法,怎么实现以下效果呢?
如果按照大块图形的深度来划分,实际上这根本就不可能实现。那么我们换一种思路,既然大块的图像不行,我们能不能直接根据像素值来呢?这就是真正的渲染管线使用的遮挡方法,深度缓冲。
1.2、遮挡方法2(深度缓冲)
那么什么是深度缓冲呢?
奉上百度百科的原理概念:
当三维图形卡渲染物体的时候,每一个所生成的像素的深度(即z坐标)就保存在一个缓冲区中。这个缓冲区叫作z缓冲区或者深度缓冲区,这个缓冲区通常组织成一个保存每个屏幕像素深度的x-y二维数组。如果场景中的另外一个物体也在同一个像素生成渲染结果,那么图形处理卡就会比较二者的深度,并且保留距离观察者较近的物体。然后这个所保留的物体点深度保存到深度缓冲区中。最后,图形卡就可以根据深度缓冲区正确地生成通常的深度感知效果:较近的物体遮挡较远的物体。这个过程叫作z消隐。
是不是非常枯燥且难懂?这里将说明一下本小白的看法。
正如百度百科中所说的,深度缓冲是基于像素来的,那么这段数据是在哪里呢?
引用大佬博客图片:Unity渲染流程(渲染管线)(渲染流水线)-CSDN博客
可以看到,实际上深度缓存的操作是从主存到显存,而主存的数据是在CPU阶段就已经确定了的,那么也就是说,深度缓存的数据是确定在应用阶段。
那么深度缓存算法是怎么实现的呢?
左边的图片是需要渲染的图片,右边是做了深度缓存以后的图片,可以看出来,在一个屏幕上,同一个像素点只渲染深度或者说从视角出发在前面的像素点。根据这个理论实际上很好的就可以写出对应的代码:
可以看出,深度缓存的时间复杂度实际上只有O(n)。也就是遍历选出最小值而已。将代码图像化如下所示:
自此,从应用阶段到光栅化阶段的所有流程已经讲完了。此时成像的是一个已经是很好的一个光栅化后得到的像素点也就是屏幕坐标了的。
2、着色(shading)
2.1、着色器与材质球
那么,大家有没有想过,如果只是单纯的经过渲染管线以后得到的效果会是什么样呢?
是不是总感觉这个是一个正确的图像,但是少了一部分的东西?那么这一部分实际上就是着色操作,先给大家放一个上述图片着色后得到的图像。
以下是关于shading的定义:引入明暗和颜色的不同。
ok,引入了我们每一个unity开发程序员都很熟悉的东西了,材质球。不知道大家和我会不会有同样的问题,如果按照上述的描述来说,材质球也就是shader根本没有进入到GPU的渲染管线内部,那么shader的工作原理又是在哪儿呢?
首先定义好什么是shader:着色器(Shader)是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。
那么我们就应该明白,shader应该是作用在全程的,也就是GPU全程阶段的,那么有没有证据呢?!当然有,那就是shader中最简单的shader,unityShader,它是由顶点着色器和片元着色器构成,是不是很熟悉?就是本小白的Games101-4的内容。
因此换句话说,unity的渲染管线开放了GPU渲染阶段,让开发者可以使用unityshader来制作出开发需要的效果。这么一来是不是就显得非常合理了?
2.2、漫反射
其实说到shader ,我们可以是使用shader来制作出一系列的例如波浪等效果(就是通过vertexshader来使用正弦函数来重复播放即可),那么除了这种简单的特效以外,要想渲染更加符合实际,那么光反射是必不可少的,这里就先讲解一下,什么是漫反射。
Diffuse reflection就是漫反射,它的公式是
也就是:DiffuseColor = _LightColor0 * tex2D(uv, _MainTex) * saturate(dot(normal, lightDir))
怎么进行理解呢?
一步一步来,我们首先得知道,为什么需要知道
这一部分怎么来的,也就是法向量点乘光照方向的max,大家还记得点乘所代表的意义是什么吗?就是得到夹角,如果知道了这个,那么是不是就可以理解下图了
我们把反射的明暗比作能量,那么接受的能量是不是有限的且可以算出来的(通过夹角cos)。
前面的怎么理解呢?
将光能看作一种波形,根据能量守恒,越远光照能量强度越弱,因此就可以的出来与距离是有关的,就可以得到以上的式子了。
_LightColor0 * tex2D(uv, _MainTex)至于这一部分我理解为被该颜色吸收的光能。
这里补充一下,实际上漫反射公式可以看出,反射出来的颜色只跟光照方向和法线方向有关,与视角是无关的,因此我们可以得出一个结论,漫反射得到的光线无论从哪个视角出发都是,看到的都是一样的。saturate作用是规范颜色到(0-1);
总结:
自此实际上已经开始接触shader 的原理前瞻和写法了。如果有错误的地方欢迎各位大佬和我一起讨论,我们一起探讨,共同进步。
历来笔记链接:后续本小白会陆续把历史链接都添上来
小白计算机图形学入门之路一(Games101-5)-CSDN博客
小白计算机图形学入门之路一(Games101-4)-CSDN博客
小白计算机图形学入门之路一(Games101-3)-CSDN博客