通过亮度加权计算纹理灰度,并用 GLProgramState 把自定义 Shader 应用到 Sprite。
图片灰度公式
1 2 3 4
| vec4 c = texture2D(CC_Texture0, v_texCoord);
float gray = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722));
|
效果图如下:

Lua 完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| local vert = [[ attribute vec4 a_position; // 默认坐标 attribute vec2 a_texCoord; // 默认纹理坐标 attribute vec4 a_color; // 默认颜色
#ifdef GL_ES varying lowp vec4 v_fragmentColor; // 顶点 varying mediump vec2 v_texCoord; // 坐标 #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif void main() { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } ]]
local frag = [[ #ifdef GL_ES precision mediump float; #endif
varying vec4 v_fragmentColor; varying vec2 v_texCoord;
void main(void) { // 当前片元的颜色 vec4 c = texture2D(CC_Texture0, v_texCoord); float gray = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)); gl_FragColor = vec4(vec3(gray), c.a) * v_fragmentColor; } ]]
local glProgram = cc.GLProgram:createWithByteArrays(vert, frag) local glProgramState = cc.GLProgramState:getOrCreateWithGLProgram(glProgram)
local logo = self.holder:getChildByName("Sprite_start_logo")
logo:setGLProgramState(glProgramState)
|
乘上 v_fragmentColor 可以继续保留节点自身的颜色和透明度设置。若多个节点需要不同 uniform 参数,还要注意不要共享同一个可变 GLProgramState。
相关阅读