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

继续使用上一节的js文件。
shader.card.vert.js顶点Shader

shader.card.frag.js片元Shader

调整图像位置

首先,修改>shader.card.vert.js代码,将图片verts值调整,移动至画面中央:

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(){

v_texCoord = a_texCoord;
// 坐标
vec4 v = vec4(gl_Vertex);
// 顶点测试,未与矩阵CC_PMatrix相乘前,顶点数据为(0,0)至(600,400)的数据,与我们Buffer中的数据一致
if(v.x >= 596 && v.y >= 398){
v.x+=100;
v.y+=100;
}
// 图片置中,以图片中心为锚点计算得出偏移量
v.x+=180;
v.y+=70;

v = CC_PMatrix * v;
gl_Position = v;
}
`;

效果如下图:

移动至画面中央

折叠卡牌

下面我们先折叠卡牌,试下效果:

注:由于10x10网格效果不佳,我把上一节中的网格数调整为100x100

1
2
3
//100x100的网格,计算顶点位置
var widthDiv = 100;
var heightDiv = 100;

修改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
23
module.exports =
`
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main(){
v_texCoord = a_texCoord;
// 坐标
vec4 v = vec4(gl_Vertex);

// 折叠右侧
if(v.x >= 500){
//对称点公式
v.x -= 2*(v.x-500);
}

// 图片置中,以图片中心为锚点计算得出偏移量
v.x+=180;
v.y+=70;

v = CC_PMatrix * v;
gl_Position = v;
}
`;

再次运行效果图:

运行效果图

我们对z坐标进行一些调整,形成一定的折角效果.

1
2
3
4
5
6
// 折叠右侧
if(v.x >= 500){
//对称点公式
v.z = (v.x - 500)/2;
v.x -= 2*(v.x-500);
}

运行图:

运行效果图

对折说明:当三角形的三个顶点都移动到某直线的对称点时,顶点顺序会发生颠倒——逆时针变顺时针,顺时针变逆时针。所以卡背被折叠隐藏,卡面显示了出来。

摄像机说明:Cocos因为是2d引擎,摄像机始终与xy平面垂直,z坐标越大,越靠近摄像机,会显示的大一些。

接下来,我们利用线对称点的公式实现下左下角的对折效果:

(x,y)关于直线Ax+By+C=0对称→(X,Y),已推导公式见图:

公式

推导:对称点连线垂直已知直线,斜率相乘=1


修改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
23
24
25
26
27
28
29
30
31
32
33
module.exports =
`
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main(){
v_texCoord = a_texCoord;
// 坐标
vec4 v = vec4(gl_Vertex);

// 折叠右侧
if(v.x >= 500){
//对称点公式
v.z = (v.x - 500)/2;
v.x -= 2*(v.x-500);
}

// 折叠左下角,关于直线v.x + v.y = 200对称
vec4 tmp_pos = vec4(0.0, 0.0, 0.0, 0.0);
if(v.x + v.y <= 200){
v.z = (200 - (v.x + v.y))/2;
tmp_pos.x = 200-v.y;
tmp_pos.y = 200-v.x;
v.x = tmp_pos.x;
v.y = tmp_pos.y;
}

// 图片置中,以图片中心为锚点计算得出偏移量
v.x+=180;
v.y+=70;

v = CC_PMatrix * v;
gl_Position = v;
}`;

运行效果图:

运行效果图

可以看到,左下角的翘起效果很不明显,下一节我们将添加对折处的弧边效果。

完整代码下载:
点击下载