Cocos Creator Shader Effect 系列 - 2 - Effect 文件解读

一、题外话

实际上,官方已经存在一份 Effect 文件的解读,不过是位于 Cocos 3D 的材质目录下 Effect Syntax 。建议提前阅读(没阅读过也没关系,我会教你阅读)。

那么,我还写些什么呢?

  1. 前面章节,我们提及到 Cocos 的官方文档可能有些隐晦。因此我会尽量结合自己的理解,再详细做一次解读。
  2. 同时,上述官方文档是针对 Cocos 3D 的 Effect,而这和 Cocos Creator 的 Effect 有些区别,我会 着重针对 Cocos Creator 的 Effect 去进行解读。

当然,如果你已经很Effect 文件的语法,那么可以跳过本章节。

二、安装 Effect 语法高亮插件

首先,Visual Studio Code 用户先安装 Cocos Effect 高亮插件,这是 Cocos 官方写的插件,极大地方便我们使用 Visual Studio Code 去查看和编辑任何 *.effect 文件

Cocos Effect Plugin

三、Effect 文件

OK,安装好插件后,现在我们可以选择一个 Cocos Creator 内置的一个 Effect 文件去进行解读了。那么,解读哪个材质对应的 Effect 文件呢?

在我们创建一个 Sprite 组件的时候,可以看到,所采用的的材质是 builtin-2d-sprite ,事实上, Label 组件也是默认用的 builtin-2d-sprite 材质。作为最常用的两个组件,这份 builtin-2d-sprite 材质已然很值得我们解读,下面我们见开始针对 builtin-2d-sprite 进行解读

builtin-2d-sprite

buildin-2d-sprite 的 Effect 文件在编辑器的「资源管理器」中,位于 internal/resources/effects/builtin-2d-sprite,用 VsCode 打开后就可以看到完整内容

Effect Summary

ps:可以看到 builtin-2d-sprite.effect 文件的实际路径,以及文件的结构组成。

折叠一下,可以看到 Effect 文件主要由 1个 CCEffect 结构 以及 多个 CCProgram 结构 组成的,同时,整个 Effect 文件采用 YMAL 1.2 标准规范 (建议阅读此链接)

四、CCEffect 结构说明

展开 CCEffect 后,我们可以看到如下定义:

CCEffect

以下是CCEffect结构的注解(整个注解文件在 仓库的 builtin-2d-sprite-explain

CCEffect explain

以上截图解释为 Cocos Creator 2.2.1 版本的 Effect ,在 Cocos Creator 2.3.0 版本,支持 Effect 变种,会有区别,但是关键属性应该不会变动。

特别地,

在上面截图解释 vertfrag 参数的含义时,我提及到的 「文档」 一词,具体的文档是指 官方 Effect Syntax 的 《Pass 中可配置的参数》 章节

Pass Parameter

事实上,在打开 Pass 可配置 GL 参数及默认值的完整列表 后,你还能发现 blendState.targets[i].blend以及 rasterizerState.cullMode 等参数的身影:

image.png

现在贴上这么一张图之后,我相信你已经很清楚 Pass 可以配置什么属性,默认值是什么,意思是什么了。

实际上,在我一开始看这些文档的时候,是一脸懵逼的,因为不知道什么对应什么。但其实官方文档都有写,感觉就是有些 隐晦 ,直到我对着实际代码时,在对着文档看,才能体会到这中间的说明。

五、CCProgram 结构说明

在 passes 数组中,我们通过 vert 参数指定了顶点着色器,通过 frag 参数指定了片元着色器,而在 Cocos Creator 的 Effect 文件中,是通过 CCProgram 去包裹这两个着色器的实现代码

5.1 顶点 Shader 说明

展开 CCProgram vs 后,我们可以看到如下代码:

CCProgram vs

以下为解释说明(整个注解文件在 仓库的 builtin-2d-sprite-explain):

在你看解析图之前,请先看这几点:

  1. 考虑了很久,我还是决定用截图的形式去进行解读,不是偷懒,只是我认为这种方式会比较直观地介绍一些关系
  2. 如果图片中有错误,欢迎指正,我会在补充说明
  3. 图片阅读顺序
    3.1 请先忽略箭头相关,先看一遍左侧的编辑器的说明
    3.2 看完之后,在看箭头,从上往下看,箭头主要是解析说明一些函数,所在头文件,以及头文件位置
CCProgram vs explain

相信你到这里之后,应该对默认的顶点着色器代码有个大概关系理解,不会再出现这函数从哪来的疑问了,当然,你可能还存在疑问,比如:

  • cc_matProj 函数是什么意思?
  • cc_matWorld 函数是什么意思?
  • 还有什么函数,还有什么头文件?

现在你终于触发了一个新的篇章,实际上,这些疑问的答案在 官方的内置 shader 变量 文档中有说明。

builtin-shader-variables

但是在你理解个中关系之前,直接查阅这个篇章可能会一头雾水,现在这一切是否开始变得清晰了。Shader 是否在开始变得有趣起来呢,别急,我们再看看片元 Shader。

5.2 片元 Shader 说明

展开 CCProgram fs 后,我们可以看到如下代码:

CCProgram fs

以下为解释说明(整个注解文件在 仓库的 builtin-2d-sprite-explain):

CCProgram fs explain

有了 CCEffect 和 CCProgram vs 的解释做基础铺垫后,相信现在你在看上面这个解释会比较容易理解,如果有不理解的,可以提出互相交流。

六、属性编辑器 Inspector 与 uniform 参数关系

在《Cocos Creator Shader Effect 系列 - 1 - 材质,Effect,Inspector,纹理之间的关系》中,我们曾经提及过

Cocos Creator 的编辑器就会帮我们预编译并解析我们的绑定的 Effect 文件中的 可改变属性

当时没有细解这句话,现在可以了,因为我们已经了解 CCEffect 结构了!

实际上,可改变属性,其实是指 uniform 参数。所有 uniform 参数都必须在 CCEffect 参数的 properties 中声明,而 properties 中的参数列表,则会显示在我们的 Inspector 上

Inspector

而在 CCProgram fs 结构中,我可以找到 texture 参数的定义

texture

可以看到,这个 texture 参数是在宏定义 USE_TEXTURE 中定义的,而宏定义,在Inspector中,则会有个虚线框框!

Inspector

现在是不是很透彻了!

那么我们再找找 alphaThreshold 参数,此时你会发现,在 buildin-2d-sprite.effect 中是没有 alphaThreshold 参数的定义的,那么这个参数又会是从哪里来的呢?

实际上,这个参数是在 alpha-test 头文件中定义的

alpha-test

OK,现在是不是很透彻了!

七、总结

本文,我们先总体概览 Effect 文件结构,然后又拆开了里面每一份结构去进行解释,那么现在,我们再来一次总体回顾,将拆开来的在合一起看看,以及补充一些可能漏说明的

比如:

  • 搜索 v_uv0 的时候,你可以发现它是从 CCProgram vs 中进行计算并输出,然后在 CCProgram fs 中得到 v_uv0 的输入值,然后参与计算
  • ...

但由于篇幅问题,这些我们暂时不再深入说下去,后面会在用到的地方继续说明,现在请先抽点时间在理清和复习一下本次介绍的内容,最好自己实践一遍~

同时,在本文的说明过程中,已经基本引用过现在Cocos 材质的说明相关文档了,或许你在之前阅读存在 困难,或许你还没有阅读过,但是现在的你已经可以真正阅读了,并且一切都会变得明朗起来了

image.png

好了,就这么多先。我们下篇文章见~

下一篇:

上一篇:

推荐阅读更多精彩内容

  • 俗世凌寒,凋零一冬。 唯雪梅清质,悬崖傲枝,岁月盛放。 寻远古晨钟,执红伞,漾孤舟,千古遗情。 曾记否,月下携手,...
    绿竹君子阅读 197评论 0 3
  • 一个人上班 一个人吃饭 一个人睡觉 似乎一切都习惯了 感谢你的出现让我有了久违的心动 陪你写诗 陪你静止 陪你做不...
    Mr_Zoul阅读 131评论 0 0