CocosCreator Effect (Shader) - 斜条纹如何画
左图是原图,没有使用九宫格sliced。也没有在图集中。这篇文章作为基础,只考虑如何画斜条纹。另外两篇文章讨论了如何处理在九宫格和在图集中使用的问题。
注意,所有的改动都在这里:
void main () {vec4 o = vec4(1, 1, 1, 1);#if USE_TEXTURECCTexture(texture, v_uv0, o);#endifo *= v_color;// 在这里进行斜条纹的绘制ALPHA_TEST(o);#if USE_BGRAgl_FragColor = o.bgra;#elsegl_FragColor = o.rgba;#endif}
}%
亮度提升
其实把r,g,b都加个数就可以了,但是为了更加自然,我把亮度调节到当前值与vec3(1,1,1)的中间位置。这样无论是亮的部分或是暗的部分,都会呈现出一些变化,而不会把亮部“曝光过渡”。
vec3 one = vec3(1, 1, 1);float fin = .5;o.rgb = mix(o.rgb, one, fin * .5);
方式1,平移x,求奇偶
这种方式开销较大,切角度控制不均匀不方便,不推荐使用。学习shader的可以理解一下。
一条分界线
有了亮度的区别,那么我们就可以以不同的亮度显示出一条线来。实际上是两种不同的亮度拼凑出一条线。
vec3 one = vec3(1, 1, 1);float fin = step(v_uv0.x, v_uv0.y);o.rgb = mix(o.rgb, one, fin * .5);
从图像就能看出来,uv坐标轴是这样的:
x轴从左上角到右上角为[0,1]
y轴从左上角到左下角为[0,1],
注意跟我们习惯的右下角原点坐标系是y轴相反,且原点在左上角。
另外step的意义,例如 float fin = step(a,b):当a小于b时返回0,否则返回1。好像是一个开关。0乘在下面的mix函数中,就代表不做变换,完全用原值。而1则代表做变换。
平移分界线求每个使能结果的和的奇偶性
平移x,得到不同的边缘斜线部分的覆盖。数一数有多少个。它们一定是呈现1,2,3,4,5,6…这样的自然数的。那么我们在对2求模,根据得到的结果是0还是1,来作为开关。1就是变亮,0就是不变亮。
vec3 one = vec3(1, 1, 1);float rate = step(v_uv0.x, v_uv0.y);rate += step(v_uv0.x + .1, v_uv0.y);rate += step(v_uv0.x + .2, v_uv0.y);rate += step(v_uv0.x + .3, v_uv0.y);rate += step(v_uv0.x + .4, v_uv0.y);rate += step(v_uv0.x + .5, v_uv0.y);rate += step(v_uv0.x + .6, v_uv0.y);rate += step(v_uv0.x + .7, v_uv0.y);rate += step(v_uv0.x + .8, v_uv0.y);rate += step(v_uv0.x + .9, v_uv0.y);rate += step(v_uv0.x - .1, v_uv0.y);rate += step(v_uv0.x - .2, v_uv0.y);rate += step(v_uv0.x - .3, v_uv0.y);rate += step(v_uv0.x - .4, v_uv0.y);rate += step(v_uv0.x - .5, v_uv0.y);rate += step(v_uv0.x - .6, v_uv0.y);rate += step(v_uv0.x - .7, v_uv0.y);rate += step(v_uv0.x - .8, v_uv0.y);rate += step(v_uv0.x - .9, v_uv0.y);float fin = mod(rate, 2.0);o.rgb = mix(o.rgb, one, fin * .5);
想一想如果修改其中2.0,和 .5这两个呈现什么效果?
比如对应改为:4.0和.2
不过这不是最终想要的哈。
方式2,只按x轴求模做step,再旋转
这个方式就比较好了,不需要求多个step,只需要一个step即可。可以360度均匀无死角旋转,对时间动画比较友好。
x求模
float fin = mod(v_uv0.x, .1) * 10.0;o.rgb = mix(o.rgb, one, fin * .5);
其中由于模.1,取值[0,0.1]幅度比较小,不容易观察,所以我在后面放大了10倍。
在中间亮度处做一下step
float fin = mod(v_uv0.x, .1);fin = step(.05, fin);o.rgb = mix(o.rgb, one, fin * .5);
注意之前乘的10倍已经去掉了,因为我们从0.05处求step就可以变为0或1。
旋转
条纹已经出来了,我们把输入的uv先旋转一下。用旋转后的uv做条纹处理看看。
t就是旋转的弧度,比如下面的四分之π就是45度。具体它往哪边转,大家自己体会一下。不是高中数学的坐标轴方向我也很蒙,多调试,结果当成经验就好。
float t = 3.1416 / 4.0;mat2 rot = mat2(cos(t), -sin(t), sin(t), cos(t));vec2 uv2 = v_uv0 * rot;float fin = mod(uv2.x, .1);fin = step(.05, fin);o.rgb = mix(o.rgb, one, fin * .5);
处理锯齿
上图其实已经基本完成了,但是明显的狗牙齿我们不能忍。先把step改smoothstep试试:
float fin = mod(uv2.x, .1);// fin = step(.05, fin);fin = smoothstep(.05-.01, .05+.01, fin);o.rgb = mix(o.rgb, one, fin * .5);
这样一来我们干掉了一半的狗牙。想想另一半,突变在求模的函数上,不连续,直接用模值还真没办法。因为smoothstep函数似乎不能直接用在一个不连续的值上。(如果有小伙伴能直接用的话可以教教我)
那么我尝试着把不连续的模值构造成连续的。其实在.05附近连续的即可:反转一下每偶数个模周期的值就行了。
下面我把基础值提出,求了模周期奇偶even,并且按照奇偶性的区间翻转了smoothstep的结果:
float t = 3.1416 / 4.0;mat2 rot = mat2(cos(t), -sin(t), sin(t), cos(t));vec2 uv2 = v_uv0 * rot;float x = uv2.x;float d = .05;float hd = d / 2.0;float d10 = d / 10.0;float even = mod(floor(x/d), 2.0);float fin = smoothstep(hd-d10, hd+d10, mod(x, d));fin = (1.0 - even) * fin + even * (1.0 - fin);o.rgb = mix(o.rgb, one, fin * .5);
所谓“翻转”就是指用1减一下。就是0~1之间的函数图形上下反过来了。
另外里面的d变成了hd,d的1半。在实际操作中发现的。当对奇偶性进行了翻转,结果原来的两个断面接在了一起,造成了条纹宽度变大了一倍,那么在一开始就先缩小一倍。大家可以自行体验。
到此,线条造型部分就已经完成了。
处理透明部分
由于按钮图片有个阴影,那么阴影按常理是不要加条纹的。就根据其透明度来判断即可。注意里面的enable变量如何得来和使用。
一般来说我喜欢用smoothstep代替step,它可以使交接部分变得平滑,此处透明度的处理上也是一样的原理。毕竟从一个临界值硬生生的分开总是不好的。
float t = 3.1416 / 4.0;mat2 rot = mat2(cos(t), -sin(t), sin(t), cos(t));vec2 uv2 = v_uv0 * rot;float x = uv2.x;float d = .05;float hd = d / 2.0;float d10 = d / 10.0;float even = mod(floor(x/d), 2.0);float fin = smoothstep(hd-d10, hd+d10, mod(x, d));fin = (1.0 - even) * fin + even * (1.0 - fin);float min_gray = .5;float enable = smoothstep(min_gray-.2, min_gray, o.a);o.rgb = mix(o.rgb, one, fin * enable * .5);
此时就是开头的图片结果了。
总结
以上的方式和流程也是我做这个效果时的处理方式。我觉得记录的已经足够详细了。可能后面要补充一下旋转,因为这里的旋转轴是角上的点。如果围绕中心点选择呢?还需要做一些平移反平移的变换。
另外,下面有个文章在这个基础上做了针对九宫格的兼容性变换。就比如这个图,我是需要用在各种尺寸的长方形按钮上的。那么就要sliced(九宫格)模式了。如果直接用这篇文章的结论,画出来的线会出现明显的折射感。
还有,如果所用到的图,在图集里面该怎么办?另一篇文章讲解了如何对图集的图做一个兼容性变换。
各种变换都是提前做出变换,要让这篇文章用到的输入还能照常使用,不需要改变代码。
CocosCreator Effect (Shader) - 反九宫格补偿
CocosCreator Effect (Shader) - 反图集打包(Packable)补偿
CocosCreator Effect (Shader) - 斜条纹如何画相关推荐
- Opengl入门基础-shader着色器画方形并且填颜色
文章目录 一.目的 二.结果 三.详细过程 下载 一.目的 opengl shader画方形并且填颜色 二.结果 成功画方形并用shader填充彩色 三.详细过程 https://blog.csdn. ...
- 【转】Silverlight 3 Beta 新特性解析(7)- Child Window和Shader Effect篇
前提条件: 阅读本文之前请确认你已经安装了如下软件 Visual Studio 2008 (Express) SP1 Silverlight 3 Tools For Visual Studio Mic ...
- 【Shader与ShaderToy 】画一个五角星
写在前面 看了几篇关于用shadertoy画线与画点的文章之后,突然想自己做一个五角星的效果来练练手.但是想归想,动起手来还是充满了"坎坷".折腾了一个周末只是思路清晰,但代码却一 ...
- CocosCreator2.3.3 Effect中换算图集中UV
CocosCreator2.3.3 Effect中换算图集中UV 需求 环境 准备知识(要点) 线性变换 spriteFrame在自动图集中的位置 一个Demo 编写Effect (Shader) T ...
- Unity Shader着色器优化
对游戏开发者而言,着色器长久以来就是游戏开发中的重要部分,在Unity中编写并实现着色器的过程直观且高效,优秀的着色器还可以创造非常精美的游戏画面,同时保证极高的性能.今天将由Unity的技术工程师张 ...
- Unity学习之Shader
Shader 是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序.其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Pixel Shader(像素着色器)主要负责片元颜色 ...
- unity Shader 入门精要 EX
unity Shader 入门精要: 1.shader概念 2.shader分类(顶点Shader.像素Shader) 3.Shader编程语言 4.Unity Shader 4.1概述 4.2分类( ...
- UnityShader2:Shader与材质
前置:Unity3D基础3:贴图与材质球 一.Shader 与材质 贴图 + 着色器(Shader) = 材质球 同一张贴图使用不同的着色器,可以展现出不同的效果: 在下面这个位置设置 Shader, ...
- 1.Unity之Shader新手入门
Unity Shader着色器的基本概念 如何使用Unity Shader着色器 示例:如何使用Unity Shader着色器创建复杂的效果 总结 什么是Unity中的Shader着色器? Shade ...
最新文章
- 也说说Silverlight动态加载DLL
- Kali Linux打开多个终端窗口
- 每日一皮:产品经理的黑化,你听过几个?
- Winform判断一个窗口是否以模态化方式打开
- w7旗舰版计算机替换,win7系统电脑替换全部系统图标的操作方法
- python json解析方法_Python 中的 JSON 方式讲解
- web项目通过ajax提交数据太大报错
- 一些建议:给当年刚做程序员的我
- 目标检测发展路程(一)——Two stage
- CPU多核并发缓存架构介绍
- python标签控件是_Python 图形用户界面编程
- 图解java多线程设计模式 pdf_图解Java设计模式之状态模式
- linux的so命令,每天一个 Linux 命令(67): ldd 命令
- mooc中习题--简单运算器
- 【阅读理解】机器阅读理解综述(一)
- php自动tag,帝国cms自动增加TAG关键字教程
- 精读CSS权威指南第四版(3)
- linux硬盘异响,完美解决Ubuntu Linux关机异响[SATA硬盘]
- [生存志] 第57节 孔子微言春秋大义
- 北斗微信与服务器怎么联接,北斗卫星的导航服务全球性升级,手机怎样“连接”使用北斗导航?...