cocos2dx shader -- Vol.1(灰度、流光、百叶窗)
来源:互联网 发布:淘宝满减券漏洞 编辑:程序博客网 时间:2024/05/01 16:48
cocos2dx shader系列一——基本篇
这里介绍几种最基本也较常用的shader特效,当然序列帧动画也可以做这些特效,但远没有shader做的高效完美,而且省去不必要的内存消耗和cpu消耗,毕竟现在手机的gpu远远没有发挥它的作用,今天我们就让它发挥它该有的作为,让cpu歇一歇,不让你的手机烫坏你的手。。。。
以下shader均在cocos2dx引擎下测试过。
一、灰度图
这是最基本的shader,也是常用的效果,比如一个按钮会有三个状态,可点击、点击中、不可点击,第三种状态正是用灰度图表示的。灰度图也叫黑白图,即使用算法将每个像素RGB值转换为一种“灰色”颜色。
#ifdef GL_ES precision lowp float; #endif uniform sampler2D u_texture; // pass from vsvarying vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { vec4 texColor = texture2D(u_texture, v_texCoord); float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); gl_FragColor = v_fragmentColor * vec4(gray, gray, gray, texColor.a);}
二、流光
流光的特效也常用,当然闪光的特效也类似,主要是给像素的RGB乘个因子,比如闪光是所有像素变亮或变暗
vec4 texColor = texture2D(u_texture, v_texCoord); texColor[0] = texColor[0] * factor;texColor[1] = texColor[1] * factor;texColor[2] = texColor[2] * factor;gl_FragColor = v_fragmentColor * texColor;factor=1时就是正常的显示,大于1的话,会发亮,小与1会变暗。
做流光的话,就不能这么简单的处理了。因为是要用到2张texture的混合。这里我们用shader生成一个有颜色的线条,选择一个x+y-c=0这条斜线为高亮部分。c从0到
#ifdef GL_ES precision lowp float; #endif varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform sampler2D u_texture; uniform float factor;uniform float width;uniform float offset;uniform vec3 color; void main() { vec4 texColor = texture2D(u_texture, v_texCoord); // line (x+y-offset=0) offset:[0, 2] (2->0) // |y // | // ____|0__ 1__2____x // | | // |_______| float distance = abs(v_texCoord[0]+v_texCoord[1]/1.414; // linear gradient (base on distance) // (1/width)x + y = 1 distance = 1.0-(1.0/width)*distance; distance = max(distance, 0.0); vec4 sample = vec4(0.0,0.0,0.0,0.0); sample[0] = color[0] * distance; sample[1] = color[1] * distance; sample[2] = color[2] * distance; sample[3] = distance; gl_FragColor = v_fragmentColor * sample;}
生成的效果,width是线条的宽度,offset是线条的偏移(控制线条的移动),color是线条的颜色,
然后,我们用这条有颜色的线条来混合我们真实的贴图,起到高亮明显的效果。
void main() { vec4 texColor = texture2D(u_texture, v_texCoord); // line (x+y-offset=0) offset:[0, 2] (2->0) // |y // | // ____|0__ 1__2____x // | | // |_______|* float distance = abs(v_texCoord[0]+v_texCoord[1]-offset)/1.414; // linear gradient // (1/width)x + y = 1 distance = 1.0-(1.0/width)*distance; distance = max(distance, 0.0); vec4 sample = vec4(0.0,0.0,0.0,0.0); sample[0] = color[0] * distance; sample[1] = color[1] * distance; sample[2] = color[2] * distance; sample[3] = distance; // blend additive float alpha = sample[3]*texColor[3]; texColor[0] = texColor[0] + sample[0]*alpha*factor; texColor[1] = texColor[1] + sample[1]*alpha*factor; texColor[2] = texColor[2] + sample[2]*alpha*factor; gl_FragColor = v_fragmentColor * texColor;}
效果如下:
factor来控制凸显部分的亮度(如图为正常亮度,即factor=1)
ps:如果觉得麻烦,可以另外传一张贴图来代替第一步生成的线条,这样可以省去动态生成有颜色的线条。
三、百叶窗
这是关于texture切换的效果,需要传递2张texture,这里我们就可以控制那张texture显示,那张不显示。shader如下:
#ifdef GL_ES precision lowp float; #endif uniform sampler2D texture0;uniform sampler2D texture1;uniform float flag;uniform float lineWidth;uniform float offset;varying vec4 v_fragmentColor; varying vec2 v_texCoord; void main(){ float modPart = mod(v_texCoord[0], lineWidth); float solidPart = (1.0-offset) * lineWidth; // reduce tex-switch times // (0, 1) (2, 1) (2, 3) (0, 3) //modPart = modPart * flag; //solidPart = solidPart * flag; if (modPart > solidPart) { gl_FragColor = v_fragmentColor * texture2D(texture1, v_texCoord); } else { gl_FragColor = v_fragmentColor * texture2D(texture0, v_texCoord); }}我们通过linewidth变量来控制百叶窗分成几块,每一块区间[0,1],然后通过offset变量来控制[0, offset]部分显示tex0, [offset,1]部分显示tex1。效果如下:
ps:当有多张贴图时,就要改变texture0和texture1,之前担心切换texture的开销,所以加了个flag变量来较少切换的个数,不过在手机上试下,切换时不会卡顿。在不加flag变量的情况下需要切换2张texture,加了flag变量每次就只要切换一张texture。
例如 0, 1,2 三张texture,
不加flag: (0, 1) - > (1, 2) -> (2, 0) - > (0, 1)
加flag:(0, 1) -> (2, 1) - > (2, 0) - > (1, 0)
Repository:代码
- cocos2dx shader -- Vol.1(灰度、流光、百叶窗)
- cocos2dx shader -- Vol.2(blur, frost, bloom)
- Shader实例(流光实现)
- shader 流光效果
- 转载{shader流光效果}
- unity shader 流光效果
- U3D log Flash shader 效果(标题流光效果)
- Cocos Creator 实现按钮图标的流光特效(Shader)
- Cocos2d-x shader学习1: 灰度shader
- Cocos2d-x shader学习1: 灰度shader
- Unity3D 灰度shader(改编自NGUI)
- NGUI的流光shader解决方案(一)(支持UITexture和使用图集的UISprite)
- NGUI的流光shader解决方案(二)(支持UITexture和使用图集的UISprite)
- Unity Shader-非主流纹理采样研究(流光,溶解,隐身效果)
- Unity3D 通过 shader 实现流光效果
- Unity Shader之Logo流光特效
- cocos2dx shader
- cocos2dx shader实现灰度图android后台切换回来导致图像偏移的问题
- java-写一个死锁的案例
- Python3标准库(一) 内置函数
- C#重命名文件名
- 巧用dimens适配多个分辨率
- 我的多年编程经验总结(转)
- cocos2dx shader -- Vol.1(灰度、流光、百叶窗)
- Qt布局管理器的使用(一)
- java 零宽断言
- uva 10905(排序)
- Android 几个重要的英文单词
- C#格式化字符串
- 专访《迷你西游》江涛 用不断的创新点来留住玩家
- 关于《Proofs from THE BOOK》chapter22 单调序列问题
- 基于UIScrollView和UIPageControl控件做的用户引导界面