能解释一下基础知识吗?我还是什么都不懂。
照顾好新人,麻烦从头开始!
于是我做了一个大胆的决定:删除不需要的东西,从最简单的效果开始,简单到没有任何一行代码就跑不了。
我将其命名为 cocos-shader-helloworld.effect游戏图片素材,它将呈现下面的效果。
现在非常简单,但随着教程的继续,它会变得越来越奇特。
为了帮助大家更好的理解每个细节,麒麟子在Shader中添加了注释,请看下图:
2. 可编程流水线简析
麒麟子一直在思考“3D可编程流水线”应该如何以及到什么程度教给大家。
当我看到上面的截图时,我有了一个想法。
下面我们从Cocos Shader的角度从上到下讲解一下涉及到的3D管线知识。
2.1.定义部分
在cocos Shader Effect中,可以定义多种Technology,每种Technology的主要属性就是name和pass。
在上面的cocos-shaer-helloworld.effect中,我们定义了一种称为opaque的技术,并且该技术只有一次pass。
如果你不喜欢它,你可以更改技术的名称,这不会对效果产生任何影响。
2.2. vert 函数(顶点着色器)
在这种情况下,顶点着色器的入口点函数是vert()。
顺便说一句,由 vert:unlit-vs:vert 引用。
unlit-vs 是 CCProgram 的名称。在一个效果文件中,我们可以定义多个CCProgram。每个CCProgram可以有多个函数,然后根据配置确定入口函数。
在本文所示的vert函数中,我们只输出最基本的位置信息:顶点坐标信息经过世界变换、相机变换和投影变换后作为vert函数的返回值。
2.3.顶点坐标从本地到屏幕的传递
很多朋友误认为投影变换后的坐标就是屏幕坐标,这是错误的。
vert 函数输出的坐标不是屏幕坐标。在一些书中,这些被称为裁剪坐标。不管叫什么,只要记住它是投影后的坐标即可。
为了适应不同的显示设备,投影坐标将被处理为标准化设备坐标系(NDC)。
NDC处理后,将进行视口映射。
视口映射完成后,显示在窗口上。
麒麟子用自己蹩脚的绘画功底,给大家画了下面这个变形图。可以清楚的看到顶点坐标需要经历的变换步骤。
注意:投影变换后,坐标信息不受Shader控制。
2.4.光栅化
经过顶点着色器之后,不会直接传递到像素着色器。相反,顶点着色器的输出将首先进行插值和像素化。
这个过程有一个术语:光栅化
如下图所示,三角形经过光栅化后转化为像素。
除了顶点位置信息之外,顶点法线、颜色、纹理坐标等首先被光栅化,然后传递给像素着色器。
由于所有vert输出值都会被光栅化,所以在使用顶点着色器传递给像素着色器的法线向量时,记得先对其进行归一化,否则会出现意想不到的效果。
关于光栅化的内容,建议大家上网搜索资料,有更深入的了解。
2.5. frag 函数(像素着色器)
光栅化的顶点信息被传递到像素着色器。
在后面的教程中,为了实现一些高级效果,我们实际上大多数情况下都增强了frag功能。在本文的例子中,为了尽可能降低大家的理解成本cocos shader,麒麟子甚至没有从外部传递颜色,而是直接在代码中定义了颜色。
可以修改frag()函数中的颜色值来查看像素的变化
顺便说一下,像素着色器和片段着色器是同一个东西。前者来自Direct3D圈,后者来自OpenGL圈。
2.6。像素寿命
经过像素着色器处理后cocos shader,像素将经历一系列的测试和操作。只有通过测试的像素才会写入目标缓冲区。如下图:
2.6.1.模板测试
模板测试根据预设的模板测试参数进行工作,并决定是否丢弃像素。
在本文中,齐林子不打算进一步讨论模板测试的细节。
如果模板测试在后面的章节中有用,将会详细解释。
如果你现在想了解模板测试游戏素材,请自行搜索。
2.6.2.深度测试
“深度测试”需要深度缓冲区的配合。请先查看本文第6.4节中的“深度缓冲区”概念。
深度测试提供 > >= == <