[cocos2d-x·分享]在cocos2d-x2.0上用shader实现灰度图

时间:2023-02-07 22:56:42

简述情况:

·游戏运行平台:Android

·Cocos2d-x引擎版本:cocos2d-2.0-x-2.0.2

·注意:目前cocos2d-x 2.0运行时如果按home键再返回游戏,shader显示会有问题,估计是因为Android将游戏切到后台时释放纹理所导致,这个问题如果我能解决就解决,解决不了的话只能待哲哥他们修复后再用shader吧。

 

之前在用cocos2d-x 1.0的时候,对shader并不了解,常见的效果像不规则图像、灰度图在1.0要消耗点纹理资源才能实现。自从cocos2d-x推出2.0之后,发现shader很好很强大,直接在片段着色器上对纹理进行颜色处理,不规则图像、灰度图都能高效实现。

 

今天分享一个黑白精灵类:MMGrayScaleSprite,像CCSprite那样读入图片,只不过输出的图片会是张黑白图。

我比较喜欢扯点题外话,MM是我自己的拓展库缩写(Marias Game Mania),我很感谢cocos2d-x引擎开发组,在cocos2d-x 1.0的时候,我想写个拓展库收集游戏开发中用到的通用代码,比如手机震动效果、灰度图、网络访问、ini读取配置等常见功能。不过自己编程水平实在不怎么样,搭过几个库用起来都不太好,公司也没写通用库的习惯,后来都没动力写下去了,挺无奈的。直到cocos2d-x2.0弄了个libExtensions,照样画葫芦搞了个libMaria,然后就顺顺利利开始编写自己的拓展,今天的MMGrayScaleSprite就是libMaria的第一个产物咯。

 

MMGrayScaleSprite只是继承了CCSprite,然后在initWithTexture里设置一个灰度Shader,没啥特别的,所以这里我打算说说shader,严格来说是片段着色器:

 

#ifdef GL_ES 

precision mediump float; 

#endif 

uniform sampler2D u_texture; 

varying vec2 v_texCoord; 

varying vec4 v_fragmentColor; 

void main(void) 

// Convert to greyscale using NTSC weightings 

float alpha = texture2D(u_texture, v_texCoord).a; 

float grey = dot(texture2D(u_texture, v_texCoord).rgb, vec3(0.299, 0.587, 0.114)); 

gl_FragColor = vec4(grey, grey, grey, alpha); 

}

 

这个是OpenGL Shader Language,我的理解是Shader在光栅化后的片段进行颜色处理,最后输出像素。因为不用额外产生纹理,所以实现某些特效会很高效,当然作复杂特效的话,手机上还是会卡的要死。还有一点是要注意,有些手机上的GLSL版本可能非常低,比如我家那台低端手机,GLSL版本1.0,有些shader函数比如fwidth,求余运算符都不支持,这样在手机上运行脚本会因为脚本编译不过而直接崩溃,对于shader开发还是个菜鸟,目前正在学习中。

 

上面这段shader脚本,主要是将RGB值转换为YUV值,然后取Y值来实现灰度图。YUV是据“一位我非常崇拜的程序大神”说是以前的一种灰度图格式,Y代表灰度,有兴趣可以百度一下。vec3(0.299, 0.587, 0.114)RGBYUV的参数值,转换用的。

 

计算完灰度后,根据原来的纹理alpha值输出处理后的颜色到gl_FragColor,于是简单的灰度图就搞定了。

以下是代码分享。http://files.cnblogs.com/j1223jesus/MMGrayScaleSprite.rar