cocos2dx 3.17.2 lua shader使用心得
记录一下,防止下次踩坑
直接插入一个示例函数,方便理解

-- 图片外描边发光 -- @params sp(sprite,scale9sprite) 精灵 -- @params flag(bool) 是否添加描边 -- @params color(c3b) 描边颜色 -- @params line_size(float) 线大小 function setSpriteOutLine_2(sp, flag, color, line_size) -- vert local vertShaderByteArray = "\n" .. "attribute vec4 a_position; \n" .. "attribute vec2 a_texCoord; \n" .. "attribute vec4 a_color; \n" .. "#ifdef GL_ES \n" .. "varying lowp vec4 v_fragmentColor;\n" .. "varying mediump vec2 v_texCoord;\n" .. "#else \n" .. "varying vec4 v_fragmentColor; \n" .. "varying vec2 v_texCoord; \n" .. "#endif \n" .. "void main() \n" .. "{\n" .. "gl_Position = CC_PMatrix * a_position; \n" .. "v_fragmentColor = a_color;\n" .. "v_texCoord = a_texCoord;\n" .. "}" -- frag local flagShaderByteArray = [[ #ifdef GL_ES precision mediump float; #endif varying vec2 v_texCoord; varying vec4 v_fragmentColor; uniform vec3 u_color ; // 描边颜色 uniform float u_line_size ; //描边偏移大小 // 获得背面区域 float getBackArea() { vec4 color_up; vec4 color_down; vec4 color_left; vec4 color_right; vec4 color_up_left; vec4 color_up_right; vec4 color_down_left; vec4 color_down_right; float total = 0 ; color_up = texture(CC_Texture0, v_texCoord + vec2(0, u_line_size)); color_down = texture(CC_Texture0, v_texCoord - vec2(0, u_line_size)); color_left = texture(CC_Texture0, v_texCoord - vec2(u_line_size, 0)); color_right = texture(CC_Texture0, v_texCoord + vec2(u_line_size, 0)); color_up_left = texture(CC_Texture0, v_texCoord + vec2(u_line_size, -u_line_size)); color_up_right = texture(CC_Texture0, v_texCoord + vec2(u_line_size, u_line_size)); color_down_left = texture(CC_Texture0, v_texCoord + vec2(-u_line_size, -u_line_size)); color_down_right = texture(CC_Texture0, v_texCoord + vec2(-u_line_size, u_line_size)); total = color_right.a + color_left.a + color_down.a + color_up.a + color_up_left.a + color_up_right.a + color_down_left.a + color_down_right.a; return clamp(total, 0.0, 1.0); } void main() { // 获取正常的颜色值 vec4 fragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); float isBack = getBackArea(); // 正常的rgb + 正常的透明区域 * 背面颜色 * 描边颜色 gl_FragColor = vec4(fragColor.rgb + (1.0 - fragColor.a)* u_color * isBack, fragColor.a); } ]] -- -- 移除frag local pszRemoveGrayShader = "#ifdef GL_ES \n" .. "precision mediump float; \n" .. "#endif \n" .. "varying vec4 v_fragmentColor; \n" .. "varying vec2 v_texCoord; \n" .. "void main(void) \n" .. "{ \n" .. "gl_FragColor = texture2D(CC_Texture0, v_texCoord); \n" .. "}" if flag then local glProgram = cc.GLProgram:createWithByteArrays(vertShaderByteArray, flagShaderByteArray) glProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION) glProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR) glProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) glProgram:link() glProgram:updateUniforms() --之前一直报错,是因为没有调用getUniformLocation直接调用setUniformVec3赋值了,特此注意 local glProgramState = cc.GLProgramState:getOrCreateWithGLProgram(glProgram) local uniform_color = gl.getUniformLocation(glProgram:getProgram(), "u_color") local uniform_line_size = gl.getUniformLocation(glProgram:getProgram(), "u_line_size") glProgramState:setUniformVec3(uniform_color, cc.vec3(color.r / 255, color.g / 255, color.b / 255)) --cc.vec3(1.0, 0.0, 0.0) glProgramState:setUniformFloat(uniform_line_size, line_size) --0.01 sp:setGLProgramState(glProgramState) sp:setGLProgram(glProgram) else local glProgram = cc.GLProgram:createWithByteArrays(vertShaderByteArray, pszRemoveGrayShader) glProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION) glProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR) glProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) glProgram:link() glProgram:updateUniforms() sp:setGLProgram(glProgram) end end
文中的shader片段是借鉴其他文章的,自己对shader使用不是特别熟练,原文地址忘记了,就不往上贴了
没有传参的没啥特殊的,有传参数的需要注意下
一开始出现这个错误cc.GLProgramState:setUniformFloat argument #2 is 'string'; 'number' expected.是因为lua这边不能直接
glProgramState:setUniformFloat("u_line_size", 0.01)这样,必须
local uniform_line_size = gl.getUniformLocation(glProgram:getProgram(), "u_line_size")
glProgramState:setUniformFloat(uniform_line_size, 0.01)