簡述情況:
·游戲運行平台: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是我自己的拓展庫縮寫(Maria’s 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)是RGB轉YUV的參數值,轉換用的。
計算完灰度后,根據原來的紋理alpha值輸出處理后的顏色到gl_FragColor,於是簡單的灰度圖就搞定了。
以下是代碼分享。http://files.cnblogs.com/j1223jesus/MMGrayScaleSprite.rar
