水波纹shader在creator 和cocos2dx 中效果不同

creator1.6,水波纹效果,参考的这个链接http://www.cocoachina.com/bbs/read.php?tid-1693873-page-1.html,shader在creator和cocos2dx中效果不同,在cocos2dx中shader的表现正常可以循环,但是在creator中水波纹一直沿着Y轴方向移动,直到移出屏幕。为什么creator和cocos2dx中的表现不同呢?是因为CC_Time的原因么?shader代码如下:
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform sampler2D u_normalMap;

vec3 waveNormal(vec2 p) {
vec3 normal = texture2D(u_normalMap, p).xyz;
normal = -1.0 + normal * 2.0;
return normalize(normal);
}

void main() {
float timeFactor = 0.1;
float offsetFactor = 0.5;//0.5
float refractionFactor = 0.7;

// simple UV animation
vec3 normal = waveNormal(v_texCoord + vec2(CC_Time.y * timeFactor, CC_Time.x * timeFactor));

// simple calculate refraction UV offset
vec2 p = -1.0 + 2.0 * v_texCoord;//
vec3 eyePos = vec3(0, 0, 10); //眼睛位置 位于中心点正上方
vec3 inVec = normalize(vec3(p, 0) - eyePos);
vec3 refractVec = refract(inVec, normal, refractionFactor);  //根据入射向量,法线,折射系数计算折射向量
vec2 v_texCoordN = v_texCoord;
v_texCoordN += refractVec.xy * offsetFactor;
//v_texCoordN.x -= CC_Time.y*timeFactor *0.2; //移动水面贴图,可选 0.6

//gl_FragColor = texture2D(u_normalMap, v_texCoord);
gl_FragColor = texture2D(CC_Texture0, v_texCoordN);

}

1赞

CC_Time这个是什么意思啊,还可以取x/y的坐标,这方面的资料好少啊,我看cocos2d-x-lite的源码,只在CCGLProgram.cpp文件里有两处定义const char* GLProgram::UNIFORM_NAME_TIME = “CC_Time”;和"uniform vec4 CC_Time;\n",那么CC_Time.x和CC_Time.y是怎么获得的x和y坐标的?官方可以帮忙解释下这个概念么?为什么cocos2dx中shader效果正常,这个变量是怎么获得的呢?但是creator中不正常,这个变量需要在update中更新么?

CC_Time 是一个 Uniform,具体什么意义我也不清楚,一般 uniform 都需要设置的,这个可能要通过 gl program state 来设置,你可以问一下这个 shader 的作者

// 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();
setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_TIME], time/10.0f, time, time2, time4);
x/y不是坐标的意思。
.操作:数学{x, y, z, w}, 颜色{r, g, b, a}或 纹理坐标{s, t, r, q}
在cocos2dx中用这个CC_Tme变量可以有很好的效果。在creator中这个变量无效,需要换一个变量,在update中不断的更新这个变量,就可以达到预期的效果了,可以通过调整变量的取值函数控制水波纹的效果。

1赞

我在update里面更新 这个变量 后面水波纹 就不动了 应该是法线那个图 取值的时候 坐标不在图片里面 求知道

我更新的变量的取值函数为sin,法线图和贴图的尺寸相同,应该是变量的取值函数的问题。
可以参考这个,native可用,webgl不知道怎么传texture。
var _default_vert = require("…/shaders/ccShader_Default_Vert.js");
var _default_vert_no_mvp = require("…/shaders/ccShader_Default_Vert_noMVP.js");
var _watereffect = require("…/shaders/ccShader_WaterEffect.js");

let Shader_WaterEffect = cc.Class({
extends: cc.Component,

properties: {
    normalMapTextrue:{
        default:null,
        type:cc.SpriteFrame
    }
},

onLoad: function () {
    var self=this;
    var now = new Date();
    this.parameters={
        startTime:Date.now(),
        time:0.0,
    };

    self._use();
    
},
 update:function(dt){
    if(this._program){
        this._program.use();
        this.updateGLParameters();
        if(cc.sys.isNative){
            var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(this._program);
            glProgram_state.setUniformFloat( "iGlobalTime", this.parameters.time );   
        }else{
            this._program.setUniformLocationWith1f( this._time, this.parameters.time );
        }
    }
},
updateGLParameters:function(){
    this.parameters.time = Math.sin((Date.now() - this.parameters.startTime)/1000)/2;
    //console.log('updadateGLParameters:',this.parameters.time);
},

_use: function(){
    this._program = new cc.GLProgram();
    if (cc.sys.isNative) {
        cc.log("use native GLProgram");
        this._program.initWithString(_default_vert_no_mvp, _watereffect);

        this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
        this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
        this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);

        this._program.link();
        this._program.updateUniforms();  
    }else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
        cc.log("use webgl GLProgram");
        this._program.initWithVertexShaderByteArray(_default_vert_no_mvp, _watereffect);

        this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
        this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
        this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);

        this._program.link();
        this._program.updateUniforms();
    }
    if (cc.sys.isNative) {
        var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(this._program);
        glProgram_state.setUniformFloat( "iGlobalTime" , this.parameters.time );
    }else{
        this._time = this._program.getUniformLocationForName( "iGlobalTime" );
        this._program.setUniformLocationWith1f( this._time, this.parameters.time );
    }
    this.setProgram( this.node._sgNode, this._program );
},
setProgram:function (node, program) {
    if (cc.sys.isNative) {
        var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(program); 
        glProgram_state.setUniformTexture("u_normalMap", this.normalMapTextrue.getTexture());
        node.setGLProgramState(glProgram_state);
    } else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL){
        //this._uni_texture = program.getUniformLocationForName("u_normalMap");
        //program.setUniformLocationWith1f(this._uni_texture, this.normalMapTextrue.getTexture());
        //node.setShaderProgram(program);
    }
    let children = node.children;
    if (!children) {
        return;
    }

    for (let i = 0; i < children.length; i++)
    {
        this.setProgram(children[i], program);
    }
},

});

module.exports = Shader_WaterEffect;

3Q!

学习了!

这个shader 该怎么转为cocos creater 啊?
有大神可以说明看看吗