把 Lua 中的颜色传给片元着色器,使同一张图片渲染为不同颜色。
实现目标
传递颜色变量到 Shader,使图片渲染出不同的颜色:

如何定义变量与赋值
在 Shader 中使用 uniform 声明变量,再通过 GLProgramState 的 setUniformXXX(name, value) 接口赋值。
Cocos2d-x 3.17.2 常用接口
| GLSL 类型 |
C++ 接口 |
用途 |
int、bool |
setUniformInt |
布尔值通常以 0 或 1 传入 |
float |
setUniformFloat |
单个浮点值 |
float[] |
setUniformFloatv |
浮点数组,需要数量参数 |
vec2 / vec3 / vec4 |
setUniformVec2 / setUniformVec3 / setUniformVec4 |
单个向量 |
vec2[] / vec3[] / vec4[] |
setUniformVec2v / setUniformVec3v / setUniformVec4v |
向量数组,需要数量参数 |
mat4 |
setUniformMat4 |
4×4 矩阵 |
sampler2D |
setUniformTexture |
绑定纹理,不用于传布尔值 |
这张表对应 Cocos2d-x 3.17.2 的 GLProgramState C++ 接口。不同 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 46 47 48 49 50 51 52 53 54 55
| 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;
uniform vec3 color_v3;
void main(void) { vec4 c = texture2D(CC_Texture0, v_texCoord);
// 透明度大于0就改变颜色 if(c.a > 0.0) { gl_FragColor = vec4(color_v3, c.a) * v_fragmentColor; } else { gl_FragColor = c; } } ]]
local glProgram = cc.GLProgram:createWithByteArrays(vert, frag) local glProgramState = cc.GLProgramState:getOrCreateWithGLProgram(glProgram)
glProgramState:setUniformVec3("color_v3", cc.vec3(0.7, 0.61, 0.85))
local logo = self.holder:getChildByName("Sprite_start_logo")
logo:setGLProgramState(glProgramState)
|
状态共享注意事项
getOrCreateWithGLProgram 会复用与 GLProgram 对应的状态。多个节点共用该状态时,后设置的 uniform 可能影响其他节点。需要每个节点保持独立参数时,应创建或克隆独立的 GLProgramState。
相关阅读