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
View Code

文中的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) 
posted @ 2022-09-09 15:25  微光0709  阅读(313)  评论(0)    收藏  举报