步骤
对于不透明的区域直接渲染出来
通过周期性调整像素的alpha值即可实现呼吸效果
shader 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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #ifdef GL_ES precision mediump float ; #endif varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform vec2 resolution; uniform vec3 glow_color; uniform float glow_expand; uniform float glow_range; const float sampleNum = 5 ;const float AsNotAlpha = 0.3 ; void debug (float x) { { gl_FragColor = vec4(x/255.0 , x/255.0 , x/255.0 , 1.1 ); } } int getStrokeCount () { vec2 unit = 1.0 / resolution.xy; float r = glow_range; float step = r / sampleNum; int count = 0 ; for (float x = -r; x < r; x += step) { for (float y = -r; y < r; y += step) { vec4 col = texture2D(CC_Texture0, v_texCoord + vec2(x * unit.x, y * unit.y)); if (col.a > AsNotAlpha) { count = count + 1 ; } } } return count; } void main () { vec4 myC = texture2D(CC_Texture0, v_texCoord); if (myC.a > AsNotAlpha) { gl_FragColor = v_fragmentColor * myC; return ; } int strokeCount = getStrokeCount(); float totalSample = (sampleNum * sampleNum * 2 ); float limit = totalSample * 0.8 ; if (strokeCount > limit) { myC.rgb = glow_color * glow_expand; myC.a = (strokeCount ) * glow_expand / totalSample; } else { myC.rgb = glow_color * strokeCount * glow_expand / limit; myC.a = (strokeCount ) * glow_expand / totalSample; } gl_FragColor = v_fragmentColor * myC; }
实现呼吸效果 原理是通过scheduleUpdate
的方式,然后设置alpha的值做周期性变化,即:sin 或 cos,如下图:
但是alpha值不可能是负数,所以对sin(time)去一个绝对值即可。
1 2 3 4 5 logo:scheduleUpdate(function (delta) time = time + delta local sin_value = math .abs (math .sin (time )) glProgramState:setUniformFloat("glow_expand" , sin_value) end )
最终效果:
完整lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 local logo = self .holder:getChildByName("Sprite_start_logo" )local size = logo:getTexture():getContentSizeInPixels()glProgramState:setUniformVec2("resolution" , {x = size.width, y = size.height}) glProgramState:setUniformVec3("glow_color" , cc.vec3(0 , 1 , 0 )) glProgramState:setUniformFloat("glow_range" , 10 ) glProgramState:setUniformFloat("glow_expand" , 1 ) local time = 0 logo:scheduleUpdate(function (delta) time = time + delta local sin_value = math .sin (time ) glProgramState:setUniformFloat("glow_expand" , math .abs (sin_value)) end )logo:setGLProgramState(glProgramState)