分享cocos2d-x 和creator 可用的流光shader一个

研究了两天,移植了一个流光shader,分享给大家,效果图如下

这样就可以不用DrawNode来做了,性能上应该比DrawNode好, 暂时遇到一个小问题,就是这个shader在android真机上运行几分钟后发现流光的移动速度就不正常了,在cocos2d-x win32 和creator 中却正常,寻求官方支持也没人理睬,先分享给大家,希望各位大神能找到原因,帮忙解决造福大家。

#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord;

void main()
{
    vec2 iResolution = vec2(1136,640);//个人理解为游戏分辨率,不知是否正确
	vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv.x *= iResolution.x / iResolution.y;
    
    vec4 retCol = texture2D(CC_Texture0, v_texCoord);
    vec2 center = vec2(fract(CC_Time[1]*.3)*4.-1.6,.5);
    uv = uv - center;
    
    float a = 1.;
    float b = 1.;
    float c = 0.;
    float w = 0.07;
    
    
    float ap = abs(a*uv.x + b*uv.y + c);
    float ran = 1. - smoothstep(w-.004,w+.004,ap);
    retCol = retCol*(1.-ran) + retCol*vec4(3.)*ran*retCol.a;
    
    
    w = 0.02;
    uv += 0.1;
    ap = abs(a*uv.x + b*uv.y + c);
    ran = 1. - smoothstep(w-.004,w+.004,ap);
    retCol = retCol*(1.-ran) + retCol*vec4(2.)*ran*retCol.a;
    
	gl_FragColor = retCol;
}
4赞

顶一个不能沉,都是只看不说话,

dddd到底

不错 下次用到再研究 谢谢分享!

web上 可以用shader吗

只要预览器支持WEBGL就可以

iResolution应该是纹理的分辨率,也就是要加效果的那面墙的分辨率。至于Android速度不对的话能给个demo吗?

好的我做一个demo 传你,谢谢

这个是是一个demo, 屏幕中cocos iocn 上有高光扫过的特效使用shader实现, 刚开始在android 真机上测试很流畅,大约等待5分钟后,就发现高光移动就变得不流畅了,希望各位技术大牛帮我分析下原因;谢谢

cocos2d-x 3.12 测试机:小米2和荣耀7itest.zip (1.5 MB)

每两个小时过来看一眼,热切关注ing…

睡觉之前过来看一眼:blush::grin:

我还没太理解shader里的算法,不过CC_Time的值是会越来越大的,它的值是

if (_flags.usesTime) {
        log("use time");
        // This doesn't give the most accurate global time value.
        // Cocos2D doesn't store a high precision time value, so this will have to do.
        // Getting Mach time per frame per shader using time could be extremely expensive.
        float time = _director->getTotalFrames() * _director->getAnimationInterval();

        // 这里设置了CC_Time的值
        setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_TIME], time/10.0f, time, time*2, time*4);
        setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_SIN_TIME], time/8.0f, time/4.0f, time/2.0f, sinf(time));
        setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_COS_TIME], time/8.0f, time/4.0f, time/2.0f, cosf(time));
    }

也就是C_Time的问题?他的值不固定,执行一次的时间越来越长?那有什么好的解决方法吗?

是需要有个变化的值的,CC_Time可以用来做这个变化的值,但是感觉对它的使用不正确,不过具体要怎么改我不清楚,这需要在了解该算法的基础上才能做。

算法我是从国外的一个shader网站上移植过来的,我刚在win32上看了time的值确实在一直变大, 我看了下决定time的值的因素有两个,1是totalframes, 一个就是fps,在这我有一个疑问,在android上的fps要做变化的话,需要修改android部分的代码,问题是不是出现在这个部分?

CCTime[1]里包含了程序从开始到当前的时间。你有那个网站的地址吗?有算法的解释吗?

算法来自这里 https://www.shadertoy.com/view/4ddSDn

虽然我对具体的算法还不是很理解,但是应该改成

#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord;

void main()
{
    vec2 uv = v_texCoord;
    uv.y = 1. - uv.y;
    
    vec4 retCol = texture2D(CC_Texture0, v_texCoord);
    vec2 center = vec2(fract(CC_Time[1]*.3)*4.-1.6,0);
    uv = uv - center;
    
    float a = 1.;
    float b = 1.;
    float c = 0.;
    float w = 0.07;
    
    
    float ap = abs(a*uv.x + b*uv.y + c);
    float ran = 1. - smoothstep(w-.004,w+.004,ap);
    retCol = retCol*(1.-ran) + retCol*vec4(3.)*ran*retCol.a;
    
    
    w = 0.02;
    uv += 0.1;
    ap = abs(a*uv.x + b*uv.y + c);
    ran = 1. - smoothstep(w-.004,w+.004,ap);
    retCol = retCol*(1.-ran) + retCol*vec4(2.)*ran*retCol.a;
    
    gl_FragColor = retCol;
}

谢谢,这样就好了, 原来的算法fract函数计算的的值有问题,我在C++部分计算好值后传入也成功了,非常感谢,幸苦了。

哦,fract函数有问题啊,这个我到没想到。恭喜。