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

下面我们新建两个文件,先了解下顶点和片元中两个非常重要的变量。

shader.card.vert.js顶点Shader

shader.card.frag.js片元Shader

顶点gl_Vertex:

为了查看顶点数目,我们先打开状态信息,并在场景中仅放置一张图片:

1
cc.director.setDisplayStats(true);

"顶点数目信息"

OpenGl在渲染的时候,并不是一张图片四个顶点,而是由两个三角形组成。所以每当我们添加一张图片时,gl verts就会增加6。默认三角形如下图:
"三角形分布图"

下面我们来尝试修改顶点数据看看会发生什么变化.

shader.card.vert.js 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports =
`
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main(){
//纹理位置,后面讲解
v_texCoord = a_texCoord;
// gl_Vertex是一个GLSL提供的属性变量,在顶点shader中它是只读的
vec4 v = vec4(gl_Vertex);
// CC_PMatrix是Cocos插入的一个矩阵变量 uniform mat4 CC_PMatrix
v = CC_PMatrix * v;
// 右上角点A与A'
if(v.x > 0&&v.y > 0){
//向左移动
v.x-=150;
}
gl_Position = v;
}
`;

shader.card.frag.js代码

1
2
3
4
5
6
7
8
module.exports = 
`
varying vec2 v_texCoord;
void main()
{
gl_FragColor = texture2D(CC_Texture0, v_texCoord);
}
`;

Cocos Creator使用Shader的方式在第一篇中已经讲过。

为了效果明显,我们把图片换为带边框的正方形网格图,效果如下:

原图300x300
"原图"
"修改顶点数据后"

有明显的三角形边界

片元texCoord

我们的纹理图,按照顶点的位置,也被分成了两个三角形。纹理的位置数据在顶点Shader中可以访问到:attribute vec2 a_texCoord;

它与gl_Vertex略有不同,用0.0f-1.0f的浮点数表示,计算方式为

gl_Vertex.x / width

gl_Vertex.y / height

如下图,原点为左上角B点:
"texCoord展示"

我们下面通过修正texCoord,消除纹理的拉伸。

shader.card.vert.js 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports =
`
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main(){
//传递给片元Shader
v_texCoord = a_texCoord;
// gl_Vertex是一个GLSL提供的属性变量,在顶点shader中它是只读的
vec4 v = vec4(gl_Vertex);
// CC_PMatrix是Coco插入的一个矩阵变量 uniform mat4 CC_PMatrix
v = CC_PMatrix * v;
// 右上角点A与A'
if(v.x > 0&&v.y > 0){
//向左移动,150为300的一半
v.x-=150;
//[新增代码]:纹理位置修改,将A,A'设置到顶部中间位置
v_texCoord.x=0.5f;
v_texCoord.y=0.0f;
}
gl_Position = v;
}
`;

"texCoord修正效果图"


总结

我们先移动了一个顶点的位置,通过图片发生的变化,能清晰的看出顶点组成的两个三角形,纹理也因此发生了变形。之后我们再通过修正texCoord的位置,恢复了纹理。

顶点Shader的代码,每有一个vert执行一次。其设置的v_texCoord将被片元Shader使用。

片元Shader每有一个片元便执行一次(相当于图片像素数目)其访问的变量varying vec2 v_texCoord;由顶点Shader中设置的v_texCoord计算得出。


verts,texCoord都是可以手动控制的,了解了这两个Shader的作用后,我们下一节开始操作扑克牌。