Cocos Creator Shader实践 :手写一个搓扑克牌的效果(一)

翻书动画、搓牌特效,总觉得帧动画浪费,骨骼动画效果不好。唯有Shader可拯救吾等强迫症患者。

本文只介绍做法,OpenGl ES 着色器的基础知识建议大家买本厚点的书看看^_^

Shader简介:

要显示一张图像,由CPU读取纹理到内存,再交给GPU(显卡核心)。而显卡决定了这张图以什么方式呈现,如纹理的位置、色调、饱和度、对比度。渲染流水线中有两个阶段是可以编程的:

  1. 顶点变换(Vertex Transformation)
  2. 片断纹理化和色彩化(Fragment Texturing and Coloring)

这两个阶段的编程,就是着色器编程(shader programming)

shader代码由显卡执行,可以节省很多CPU时间。

简单例子:

先通过图像置灰的例子,看下Shader在Cocos Creator中的使用方式。

新建两个Script,用于存储Shader代码。

顶点代码:

注:Cocos Creator中OpenGl ES使用的Shader语言为GLSL。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//shader.gray.vert.js
module.exports =
`
//内部变量,运行时为绘制顶点的位置,直接访问gl_Vertex与此相同
attribute vec4 a_position;
//内部变量,运行时为渲染纹理的位置(纹理位置类似于anchor那种小数,后面详解)
attribute vec2 a_texCoord;
//该顶点颜色
attribute vec4 a_color;
//varying变量,可在后面的片元shader中访问
varying vec4 v_fragmentColor;
//varying变量,纹理坐标用于传递a_texCoord
varying vec2 v_texCoord;
void main()
{
//gl_Position为顶点的最终位置,与矩阵CC_PMatrix相乘,变换为cocos坐标系,CC_PMatrix Cocos内置矩阵。
gl_Position = CC_PMatrix * a_position;
//变量赋值
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
`
片元代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//shader.gray.frag.js
module.exports =
`
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

void main(){
//texture2D Cocos内置函数,获取指定纹理位置颜色值
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
//0.2126,0.7152,0.0722这三个数值是根据人眼对颜色的识别能力计算出来的,RGB颜色值相乘,即为灰
gl_FragColor.xyz = vec3(0.2126*c.r + 0.7152*c.g + 0.0722*c.b);
//第四个值为Alpha
gl_FragColor.w = c.w;
}
`
使用Shader:
1
2
3
4
5
6
7
var glProgram = new cc.GLProgram();
var vert = require("shader.gray.vert");
var frag = require("shader.gray.frag");
glProgram.initWithString(vert, frag);
glProgram.link();
glProgram.updateUniforms();
[sprite]._sgNode.setShaderProgram(glProgram);

完成。
下一节从一张简单图片开始,继续研究Shader。