cocos2d-lua 实现动态模糊 用于醉酒效果利用Rende
2017-11-13 本文已影响25人
人气小哥
先上一组图
正常.png 喝下一瓶酒.png 喝下三瓶酒.png
再上相关代码
--调用代码
local ShaderUtils = require("app.utils.ShaderUtils")
--run一个action,延时执行
function g_runDelayTime(node,callback,time)
local function call()
if callback then
callback()
end
end
local delayTime = cc.DelayTime:create(time or 0)
local func = cc.CallFunc:create(call)
local sequence = cc.Sequence:create(delayTime,func)
node:runAction(sequence)
end
--醉酒效果
function UIDicController:DrunkEffect()
local sprite = ShaderUtils.makeSpriteDynamicBlur(self._root, self, 100)
g_runDelayTime(sprite, function()
sprite:removeFromParent()
end, 2)
end
--封装源码
--[[
功能:动态模糊
参数:parent 父节点
panel 模糊模块
-- android效果极差
]]
local ShaderUtils = {}
local vertDefaultSource = "\n".."\n" ..
"attribute vec4 a_position;\n" ..
"attribute vec2 a_texCoord;\n" ..
"attribute vec4 a_color;\n\n" ..
"\n#ifdef GL_ES\n" ..
"varying lowp vec4 v_fragmentColor;\n" ..
"varying mediump vec2 v_texCoord;\n" ..
"\n#else\n" ..
"varying vec4 v_fragmentColor;" ..
"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" ..
"} \n"
-- local sprite_photo = nil
function ShaderUtils.makeSpriteDynamicBlur(parent, panel, zOrder)
local sprite_photo = nil
local win_size = size or (cc.Director:getInstance():getWinSize())
--截屏
-- local render_texture = cc.RenderTexture:create(win_size.width, win_size.height)
local render_texture = cc.RenderTexture:create(win_size.width, win_size.height, cc.TEXTURE2_D_PIXEL_FORMAT_RGB_A8888, gl.DEPTH24_STENCIL8_OES)
render_texture:begin()
panel:visit()
render_texture:endToLua()
-- 渲染
local photo_texture = render_texture:getSprite():getTexture()
if sprite_photo ~= nil then
sprite_photo:setTexture(photo_texture)
else
sprite_photo = cc.Sprite:createWithTexture(photo_texture)
sprite_photo:addTo(parent,zOrder)
sprite_photo:setAnchorPoint(cc.p(0.5, 0.5))
sprite_photo:pos(display.cx , display.cy)
ShaderUtils.makeSpriteBlur(sprite_photo)
-- if g_targetPlatform == cc.PLATFORM_OS_WINDOWS then
sprite_photo:setScaleY(-1)
-- end
end
return sprite_photo
end
--[[
功能:模糊效果
]]
-- function ShaderUtils.makeSpriteBlur(_sprite)
-- local size = _sprite:getTexture():getContentSizeInPixels()
-- local glState = cc.GLProgramState:getOrCreateWithGLProgramName("shaderStaticMohu")
-- _sprite:setGLProgramState(glState)
-- glState:setUniformVec2("resolution",cc.p(size.width, size.height))
-- glState:setUniformFloat("blurRadius",8)
-- glState:setUniformFloat("sampleNum",4)
-- end
--[[
功能:模糊效果
]]
function ShaderUtils.makeSpriteBlur(_sprite)
local vSource = vertDefaultSource
local fSource = cc.FileUtils:getInstance():getStringFromFile("res/shaders/sprite_yuanjiao.fsh")
local pProgram = cc.GLProgram:createWithByteArrays(vSource, fSource)
pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
pProgram:link()
pProgram:updateUniforms()
local size = _sprite:getTexture():getContentSizeInPixels()
_sprite:setGLProgram(pProgram)
_sprite:getGLProgramState():setUniformVec2("resolution",cc.p(size.width, size.height))
_sprite:getGLProgramState():setUniformFloat("blurRadius",8)
_sprite:getGLProgramState():setUniformFloat("sampleNum",4)
end
return ShaderUtils
shader文件
\res\shaders\sprite_yuanjiao.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform vec2 resolution;
uniform float blurRadius;
uniform float sampleNum;
vec4 blur(vec2);
void main(void)
{
vec4 col = blur(v_texCoord); //* v_fragmentColor.rgb;
gl_FragColor = vec4(col) * v_fragmentColor;
}
vec4 blur(vec2 p)
{
if (blurRadius > 0.0 && sampleNum > 1.0)
{
vec4 col = vec4(0);
vec2 unit = 1.0 / resolution.xy;
float r = blurRadius;
float sampleStep = r / sampleNum;
float count = 0.0;
for(float x = -r; x < r; x += sampleStep)
{
for(float y = -r; y < r; y += sampleStep)
{
float weight = (r - abs(x)) * (r - abs(y));
col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;
count += weight;
}
}
return col / count;
}
return texture2D(CC_Texture0, p);
}