<十四>入门CocosShader之CocosCreator3.x案例应用
前言
如何在CocosCreator3.x中绘制一个如同上篇中的矩形呢?
CocosShader对Shader的功能做了多层封装,开发者根据需要组装即可。
根据之前的矩形绘制流程可以分为以下几步:
-
数据准备
提供顶点数据,在之前的示例中提供的是一组固定的数据。
在CocosCreator中有很多地方可以提供顶点数据,例如:2D 的渲染组件(Sprite、Graphics 等),3D 的模型组件(MeshRenderer、SkinnedMeshRendere 等)等。用户也可以自定义顶点数据。 -
画布清除阶段
这部分跟相机有关。因为游戏场景往往是由很多对象构造而成,但是实际呈现的画面只有其中一小部分,呈现的部分就是相机照射的部分。由于屏幕画布只有一块,因此,由相机决定是否要擦除之前的内容重新绘制,或者在原有内容的基础上继续绘制。 -
着色指令部分
类似于顶点/片元文本的编写。在 Cocos Creator 3.x 里通过 Cocos Effect 来实现。
这里会从最基础绘图组件 Graphics 进行绘制
创建项目 && 新建场景
- 在场景中创建一个Graphics节点
- 创建一个绘制脚本Draw并挂载在Graphics节点上
- 编辑Draw脚本
import { _decorator, Component, Graphics, Node } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('Draw')
export class Draw extends Component {
start() {
//获取基础绘制组件Graphics
const g = this.getComponent(Graphics);
//绘制并填充矩形
g.fillRect(0, 0, 400, 300);
}
}
- 保存脚本,运行预览
![image]()
- 解析
是不是超简单,实际上整个绘制流程经历了以下几个部分
![image]()
如图,首先CocosEffect会提供所需要的Shader文本,因为Graphics是内置组件,可以打开引擎目录查看一下源码
![image]()
这里可以看到builtinResMgr(内置资源管理模块)
进入模块,搜索'ui-graphics-material'
![image]()
可以一个叫“builtin-graphics”的effect使用在Graphics中new出来的defaultGraphicsMtl上。
可以在内置资源管理中的Effect目录下找到这个builtin-graphics查看一下
以上就有Effect和材质。
在 Creator 中,顶点坐标起源于模型空间,最终需要转换到屏幕空间,这过程需要经历以下几个步骤:
![image]()
Local Space 局部坐标,也可以称之为模型坐标。可以理解为就是相对于父节点的坐标。
World Space 世界坐标。世界坐标是一个很大的空间范围,相对于世界原点。通过模型坐标结合模型矩阵得出。
View Space 观察坐标。可以理解为将世界坐标转换到相机空间的坐标,转换后的值是相对于相机原点。通过世界坐标结合观察矩阵得出。
Clip Space 裁剪坐标。也就是将观察坐标处理到 -1.0 ~ 1.0 的范围,也就是我们在 WebGL 里提供的标准设备化坐标,最终剔除超出 -1 ~ 1 的坐标。通过观察坐标结合投影矩阵得出。
Screen Space 屏幕坐标。这个过程其实就是将 -1.0 ~ 1.0 范围的坐标转换到 gl.viewport 所定义的坐标范围内。最后变换出来的坐标会送到光栅器,转换成片段。
Graphics 提供的是模型坐标可以在引擎底层 graphics.ts 里的 activeMode、_uploadData 和 graphics-assemler 部分,这里就处理了顶点数据缓存创建、绘制数据收集,绑定等步骤。 - 标准设备化坐标和屏幕坐标
标准化设备坐标是 x 轴向右,y 轴向上,x 和 y 的取值都是从 -1~1,在这个范围内的顶点可见,否则都不可见。屏幕坐标是 x 轴向右,y 轴向下,x 和 y 的取值范围都是从 0 对应到屏幕宽高,在矩阵变换的最后一步,就是将标准化设备坐标转换到屏幕坐标后上屏显示。
Cocos Effect
shader对应的文本在CocosCreator中对应Cocos Effect。
Cocos Effect 是一种基于 YAML 和 GLSL 的单源码嵌入式领域特定语言,YAML 部分声明流程控制清单,GLSL 部分声明实际的着色片段,这两部分内容上相互补充,共同构成了一个完整的渲染流程描述。引擎会根据这份描述执行相对应的渲染程序。Cocos Effect 无法单独使用,需要搭配材质使用。
提示:如果使用 VSCode 编辑自定义 Effect。推荐在 VSCode 上搜索安装 Cocos Effect 插件,以便获得代码高亮提示。
YAML101
YAML 是一种序列化语言,也可以理解为是一种专注于写配置文件的语言。Cocos Creator 3.x 完全支持 YAML 1.2 标准的解析器。YAML 完全兼容 Json 语法,所以 Json 也可以看做是 YAML 的子集。
相机
创建 Canvas 节点的时候,可以看到默认会创建出一个 Camera 节点,Camera 节点上的 Camera 组件持有 ClearFlags,ClearColor 以及 Rect 这三个属性,在 WebGL 就分别控制了 gl.viewport、gl.clear 和 gl.clearColor 部分。其中:
ClearFlags 的 SOLID_COLOR 模式,要求每帧清除屏幕内容
ClearColor 要求清除屏幕内容后默认填充什么颜色
Rect 定义屏幕空间视口,xy 值限制在 -1~1,wh 值限制在 0~1
所有场景里的对象都必须在相机的可视区域内,才能被最终渲染出来。相机的可视条件分为两部分:
条件一:相机的 Visibility 包含节点的 Layer 值。比如:2D 相机的 Visibility 包含 UI_3D 和 UI_2D,节点的 layer 为 DEFAULT,那么此节点就无法被 2D 相机渲染。
条件二:在条件一满足的情况下,物体需要在相机照射的视距框内,物体才可被渲染。
最终,所有的内容经过渲染管线的处理成为一个“拍扁”后的 2D 像素。此时不代表最终呈现的就是这样的 2D 像素,最后一个阶段是 viewport。假设,此时将相机 Rect 的 w 分量改为 0.5,可以看看前后渲染内容的对比:

可以清楚的看到由于视口的调整,只有左半边屏幕能够呈现内容,因此,只有以相机原点为中心所照射的一半内容被呈现了出来。





浙公网安备 33010602011771号