项目需要实现溶解效果,记录下基本实现:
实现原理:随着时间变化计算一个阙值(如sin(time)),当取样噪声图纹理的RGB中的某个值低于此阙值时,目标纹理的当前片段着色器调用discard函数,丢弃当前的片段并且终止着色器执行。
精灵显示的基本逻辑及片段着色器噪声图纹理的设置:
auto noiseSp = Sprite::create("noise.jpg");
noiseSp->setPosition(visibleSize*0.5);
this->addChild(noiseSp);
noiseSp->setVisible(false);
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(visibleSize*0.5);
this->addChild(sprite);
GLProgram *program = GLProgram::createWithFilenames("dissolve.vsh", "dissolve.fsh");
program->link();
sprite->setGLProgram(program);
sprite->getGLProgramState()->setUniformTexture("u_texture1", noiseSp->getTexture());
顶点着色器:
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
片段着色器:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord;
uniform sampler2D u_texture1;
void main(void)
{
gl_FragColor=texture2D(CC_Texture0,v_texCoord);
vec4 col=texture2D(u_texture1,v_texCoord);
float threshold = abs(sin(CC_Time[3] * 0.1));
if(col.g<threshold){
discard;
}
}
其中CC_Time为引擎内置的属性, u_texture1为传入的噪声图的纹理。
实现效果如下: