cocosCreator Shader 扑克牌的透视效果

我这里用的是cocos creator 3.7.2版本,不同版本可能存在差异
看下效果
原图
效果图
可以看出效果还是比较明显的。
顶点着色器
开始实现这个功能,对定点着色器应该有了基本的了解,这里不过多说明。
这里我们先看下cocosCreator默认使用的着色器代码:builtin-sprite.effect
,可以直接在资源管理器中搜索
想要达到效果,其实修改就是扑克牌上边缘两个顶点的x轴坐标
但是想要修改,最起码得知道现在的值,做个小测试看一下。让顶点坐标的x值+=y值,观察x坐标的变化规律.
复制粘贴builtin-sprite.effect
文件(必须要复制粘贴,系统最开始的不能被修改),在复制出来的文件中搜索vec4 pos = vec4(a_position, 1)
并在该代码后面添加代码pos.x += pos.y;
,如下:1
2vec4 pos = vec4(a_position, 1);
pos.x += pos.y;
修改代码前:(方便看效果,牌做了放大处理)
修改代码后:
这里可以看到,蓝色框区域是牌原本显示的边框,底边的x轴没有变化,所以底边的+=pos.y这里的y值为0。
调整下牌的位置,让牌的左上角顶点和画布左上角顶点重合
从图上可以看出,当牌的左上角顶点和画布左上角顶点重合时,上边两个顶点的值往右偏了屏幕高度那么多的值。看下蓝框,很直观,一个正方形,偏移宽度=屏幕高度。
这说明顶点在画布上边缘位置时,顶点坐标y值是画布高。
这里测试x,y也是一样的(自己可以动手试下)其实片段着色器中我们拿到的a_position
就是一个屏幕左下角(0,0)
到 屏幕右上角(画布宽,画布高)
这样的vec2变量,有了定点的具体值,后面就好操作了。来看下顶点的屏幕坐标:
顶部偏移
我来定一个顶点point
,我要让所有的扑克都往这个点变形。设定point坐标vec2(屏幕宽/2,屏幕高0.85).
对每个点来说,点的x轴偏移值 = `(顶点x和pointx差值) (顶点y和point.y的比例)
把前面的pos.x += pos.y;
代码改为下面2行:1
2vec2 point = vec2(1920. * .5,1080. * 0.85);
pos.x += (point.x - pos.x) * (pos.y / point.y);
图片会往箭头所指的方向偏移。
修改起点y值
有个问题,就是这里的计算 都是用屏幕底边y值0计算的,我牌桌变如果不在屏幕底边咋办呢,我要指定一个起点的y值可以计算这个三角形。
比如我牌摆在离底边100px的位置,将参与计算的y坐标 减100就行了。1
pos.x += (point.x - pos.x) * ((pos.y - 100.) / point.y);
shader代码
放一下最终代码,让起点y值和终点坐标都用可变变量,从材质传值进来。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: sprite-vs:vert
frag: sprite-fs:frag
depthStencilState:
depthTest: false
depthWrite: false
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha
blendDstAlpha: one_minus_src_alpha
rasterizerState:
cullMode: none
properties:
alphaThreshold: { value: 0.5 }
u_point: { value: [1,1] }
u_starty: {value: 0 }
}%
1 | CCProgram sprite-vs %{ |
使用方法
在cocos creator 中找到精灵默认使用的材质ui-sprite-material.mtl
,将材质拷贝出来放在自己的资源文件夹下(必须拷贝出来,不然无法修改)。将上面代码保存为gradient.effect
,名字按照自己的想法来。最后修改下面4个地方即可
- 将精灵的”CustomMaterial”属性设置为你刚刚拷贝出来的材质
- 将材质的
Effect
属性设置为刚刚保存的gradient.effect
shader文件 - 这里
USE TEXTURE
一定要勾选上,不然没有纹理,只会显示一张空白图 - 调整这三个参数,获得自己想要的透视效果