标签:
本文教大家如何使用shader让描边动起来。实质就是间隔一定时间改变描边的颜色。难点:如何通过程序把颜色传给shader。想在quick2.25里面尝试的朋友,参考quick2.25精灵变灰 配置一下环境。
一、shader代码。都是cocos官方自带的
//outLiner.vsh #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif attribute vec4 a_position; attribute vec2 a_texCoord; attribute vec4 a_color; void main() { gl_Position = CC_MVPMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } //outLiner.fsh #ifdef GL_ES precision mediump float; #endif varying vec2 v_texCoord; varying vec4 v_fragmentColor; uniform vec3 u_outlineColor; uniform float u_threshold; uniform float u_radius; uniform sampler2D CC_Texture0; void main() { float radius = u_radius; vec4 accum = vec4(0.0); vec4 normal = vec4(0.0); normal = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y)); //获取上下左右四个像素的纹理 accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y - radius)); accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y - radius)); accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y + radius)); accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y + radius)); accum *= u_threshold; accum.rgb = u_outlineColor * accum.a; accum.a = 0.0; normal = ( accum * (1.0 - normal.a)) + (normal * normal.a); gl_FragColor = v_fragmentColor * normal; }
二、shader调用
local color = {{255,0,0},{0,255,0},{0,0,255}}
local index =1
self.sp = display.newSprite("img_248.png"):addTo(self)
self:outLiner(self.sp)
local scheduler = require("framework.scheduler")
scheduler.scheduleGlobal(handler(self,self.changeColor),0.1) --每间隔0.1秒改变一下颜色
function MainScene:changeColor()
if index>3 then
index = 1
end
local color = color[index]
local p = self.sp:getShaderProgram()
local outlineColor = p:getUniformLocationForName("u_outlineColor"); --对应ps里面的u_outlineColor变量
p:use() --注意必须加这个 否则不管用
p:setUniformLocationWith3fv(outlineColor,color,1) -- 给u_outlineColor赋值
index = index +1
end
--实质上getUniformLocationForName里面调用opengl的glGetUniformLocation(m_uProgram, name);
--setUniformLocationWith3fv调用opengl 的glUniform3iv();
--作用就是给shader里面的uniform变量赋值
function MainScene:outLiner(node)
local pProgram = CCGLProgram:createWithFilenames("res/shader/outLiner.vsh","res/shader/outLiner.fsh")
pProgram:addAttribute("a_position", 0)
pProgram:addAttribute("a_color", 1)
pProgram:addAttribute("a_texCoord", 2)
pProgram:link()
pProgram:updateUniforms()
local threshold = pProgram:getUniformLocationForName("u_threshold");
pProgram:setUniformLocationWith1f(threshold,1.75)
local radius = pProgram:getUniformLocationForName("u_radius");
pProgram:setUniformLocationWith1f(radius,0.001)
node:setShaderProgram(pProgram)
end
特别注意:导出的setUniformLocationWith3fv函数,传的第二个参数有问题,需要做如下修改:(大家以后从lua中传数组给C++ 也可以参考此方法)

附上最终效果图:

标签:
原文地址:http://www.cnblogs.com/U-tansuo/p/quick2-25_outliner.html