一、题外话
实际上,官方已经存在一份 Effect 文件的解读,不过是位于 Cocos 3D 的材质目录下 Effect Syntax 。建议提前阅读(没阅读过也没关系,我会教你阅读)。
那么,我还写些什么呢?
- 前面章节,我们提及到 Cocos 的官方文档可能有些隐晦。因此我会尽量结合自己的理解,再详细做一次解读。
- 同时,上述官方文档是针对 Cocos 3D 的 Effect,而这和 Cocos Creator 的 Effect 有些区别,我会 着重针对 Cocos Creator 的 Effect 去进行解读。
当然,如果你已经很Effect 文件的语法,那么可以跳过本章节。
二、安装 Effect 语法高亮插件
首先,Visual Studio Code 用户先安装 Cocos Effect 高亮插件,这是 Cocos 官方写的插件,极大地方便我们使用 Visual Studio Code 去查看和编辑任何 *.effect
文件
三、Effect 文件
OK,安装好插件后,现在我们可以选择一个 Cocos Creator 内置的一个 Effect 文件去进行解读了。那么,解读哪个材质对应的 Effect 文件呢?
在我们创建一个 Sprite 组件的时候,可以看到,所采用的的材质是 builtin-2d-sprite
,事实上, Label 组件也是默认用的 builtin-2d-sprite
材质。作为最常用的两个组件,这份 builtin-2d-sprite
材质已然很值得我们解读,下面我们见开始针对 builtin-2d-sprite
进行解读
buildin-2d-sprite 的 Effect 文件在编辑器的「资源管理器」中,位于 internal/resources/effects/builtin-2d-sprite
,用 VsCode 打开后就可以看到完整内容
ps:可以看到 builtin-2d-sprite.effect
文件的实际路径,以及文件的结构组成。
折叠一下,可以看到 Effect 文件主要由 1个 CCEffect 结构 以及 多个 CCProgram 结构 组成的,同时,整个 Effect 文件采用 YMAL 1.2 标准规范 (建议阅读此链接)
四、CCEffect 结构说明
展开 CCEffect 后,我们可以看到如下定义:
以下是CCEffect结构的注解(整个注解文件在 仓库的 builtin-2d-sprite-explain)
以上截图解释为 Cocos Creator 2.2.1 版本的 Effect ,在 Cocos Creator 2.3.0 版本,支持 Effect 变种,会有区别,但是关键属性应该不会变动。
特别地,
在上面截图解释 vert
和 frag
参数的含义时,我提及到的 「文档」 一词,具体的文档是指 官方 Effect Syntax 的 《Pass 中可配置的参数》 章节
事实上,在打开 Pass 可配置 GL 参数及默认值的完整列表 后,你还能发现 blendState.targets[i].blend
以及 rasterizerState.cullMode
等参数的身影:
现在贴上这么一张图之后,我相信你已经很清楚 Pass 可以配置什么属性,默认值是什么,意思是什么了。
实际上,在我一开始看这些文档的时候,是一脸懵逼的,因为不知道什么对应什么。但其实官方文档都有写,感觉就是有些 隐晦 ,直到我对着实际代码时,在对着文档看,才能体会到这中间的说明。
五、CCProgram 结构说明
在 passes 数组中,我们通过 vert
参数指定了顶点着色器,通过 frag
参数指定了片元着色器,而在 Cocos Creator 的 Effect 文件中,是通过 CCProgram
去包裹这两个着色器的实现代码
5.1 顶点 Shader 说明
展开 CCProgram vs 后,我们可以看到如下代码:
以下为解释说明(整个注解文件在 仓库的 builtin-2d-sprite-explain):
在你看解析图之前,请先看这几点:
- 考虑了很久,我还是决定用截图的形式去进行解读,不是偷懒,只是我认为这种方式会比较直观地介绍一些关系
- 如果图片中有错误,欢迎指正,我会在补充说明
- 图片阅读顺序
3.1 请先忽略箭头相关,先看一遍左侧的编辑器的说明
3.2 看完之后,在看箭头,从上往下看,箭头主要是解析说明一些函数,所在头文件,以及头文件位置
相信你到这里之后,应该对默认的顶点着色器代码有个大概关系理解,不会再出现这函数从哪来的疑问了,当然,你可能还存在疑问,比如:
- cc_matProj 函数是什么意思?
- cc_matWorld 函数是什么意思?
- 还有什么函数,还有什么头文件?
现在你终于触发了一个新的篇章,实际上,这些疑问的答案在 官方的内置 shader 变量 文档中有说明。
但是在你理解个中关系之前,直接查阅这个篇章可能会一头雾水,现在这一切是否开始变得清晰了。Shader 是否在开始变得有趣起来呢,别急,我们再看看片元 Shader。
5.2 片元 Shader 说明
展开 CCProgram fs 后,我们可以看到如下代码:
以下为解释说明(整个注解文件在 仓库的 builtin-2d-sprite-explain):
有了 CCEffect 和 CCProgram vs 的解释做基础铺垫后,相信现在你在看上面这个解释会比较容易理解,如果有不理解的,可以提出互相交流。
六、属性编辑器 Inspector 与 uniform 参数关系
在《Cocos Creator Shader Effect 系列 - 1 - 材质,Effect,Inspector,纹理之间的关系》中,我们曾经提及过
Cocos Creator 的编辑器就会帮我们预编译并解析我们的绑定的 Effect 文件中的 可改变属性
当时没有细解这句话,现在可以了,因为我们已经了解 CCEffect 结构了!
实际上,可改变属性,其实是指 uniform 参数。所有 uniform
参数都必须在 CCEffect 参数的 properties
中声明,而 properties 中的参数列表,则会显示在我们的 Inspector 上
而在 CCProgram fs 结构中,我可以找到 texture 参数的定义
可以看到,这个 texture 参数是在宏定义 USE_TEXTURE 中定义的,而宏定义,在Inspector中,则会有个虚线框框!
现在是不是很透彻了!
那么我们再找找 alphaThreshold
参数,此时你会发现,在 buildin-2d-sprite.effect
中是没有 alphaThreshold 参数的定义的,那么这个参数又会是从哪里来的呢?
实际上,这个参数是在 alpha-test
头文件中定义的
OK,现在是不是很透彻了!
七、总结
本文,我们先总体概览 Effect 文件结构,然后又拆开了里面每一份结构去进行解释,那么现在,我们再来一次总体回顾,将拆开来的在合一起看看,以及补充一些可能漏说明的
比如:
- 搜索
v_uv0
的时候,你可以发现它是从CCProgram vs
中进行计算并输出,然后在CCProgram fs
中得到v_uv0
的输入值,然后参与计算 - ...
但由于篇幅问题,这些我们暂时不再深入说下去,后面会在用到的地方继续说明,现在请先抽点时间在理清和复习一下本次介绍的内容,最好自己实践一遍~
同时,在本文的说明过程中,已经基本引用过现在Cocos 材质的说明相关文档了,或许你在之前阅读存在 困难,或许你还没有阅读过,但是现在的你已经可以真正阅读了,并且一切都会变得明朗起来了
- 材质系统总览
- YAML 101
- Effect Syntax
- Pass Params
- Builtin Shader Variables
原创不易,如果我的文章对你起到帮助,不妨支持一下我吧
好了,就这么多先。我们下篇文章见~
下一篇:
- Cocos Creator Shader Effect 系列 - 3 - Effect 文件调试
上一篇:
- Cocos Creator Shader Effect 系列 - 1 - 材质,Effect,Inspector,纹理之间的关系