Creator3D 水纹及水波Shader

水纹shader

CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      properties: &props
        color:        { value: [1, 1, 1, 1], inspector: { type: color } }
        tilingOffset: { value: [1, 1, 0, 0] }
        mainTexture:  { value: grey         }
        iOffset:      { value: [0.2, 0.2], inspector: { displayName : "偏移值" } }
  - name: transparent
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendSrcAlpha: src_alpha
          blendDstAlpha: one_minus_src_alpha
      properties: *props
}%

CCProgram unlit-vs %{
  precision mediump float;
  #include <cc-global>
  #include <cc-local-batch>
  #include <input>

  #if USE_VERTEX_COLOR
    in vec4 a_color;
    out vec4 v_color;
  #endif

  #if USE_TEXTURE
    in vec2 a_texCoord;
    out vec2 v_uv;
    uniform TexCoords {
      vec4 tilingOffset;
    };
  #endif

  highp vec4 vert () {
    vec4 position;
    CCVertInput(position);

    highp mat4 matWorld;
    CCGetWorldMatrix(matWorld);

    highp vec4 pos = cc_matProj * (cc_matView * matWorld) * position;

    #if USE_TEXTURE
      v_uv = a_texCoord;
      #if FLIP_UV
        v_uv.y = 1.0 - v_uv.y;
      #endif
      v_uv = v_uv * tilingOffset.xy + tilingOffset.zw;

    #endif

    #if USE_VERTEX_COLOR
      v_color = a_color;
    #endif

    return pos;
  }
}%

CCProgram unlit-fs %{
  precision mediump float;
  #include <output>

  #if USE_TEXTURE
    in vec2 v_uv;
    uniform sampler2D mainTexture;
    uniform Tex {
      vec2 iOffset;
    };
  #endif

  #if USE_COLOR
    uniform Constant {
      vec4 color;
    };
  #endif

  #if USE_VERTEX_COLOR
    in vec4 v_color;
  #endif

  vec4 frag () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      vec2 uv = v_uv;
      float time = mod(cc_time.x, 360.) * 3.;
      uv.x += (sin(uv.y * 30.0 + time) / 30.0 * iOffset[0]);
      uv.y += (sin(uv.x * 30.0 + time) / 30.0 * iOffset[1]);
      o *= texture(mainTexture, uv);
    #endif

    #if USE_COLOR
      o *= color;
    #endif

    #if USE_VERTEX_COLOR
      o *= v_color;
    #endif

    return CCFragOutput(o);
  }
}%

水波shader

CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      properties: &props
        color:        { value: [1, 1, 1, 1], inspector: { type: color } }
        tilingOffset: { value: [1, 1, 0, 0] }
        mainTexture:  { value: grey         }
        center: { value: [0.5, 0.5], inspector: { displayName: "水波中心" } }
        _WaveStrength: { value: 0.01, inspector: { displayName: "增强" } }
        _WaveFactor: { value: 50, inspector: { displayName: "水波因子" } }
        _TimeScale: { value: 10, inspector: { displayName: "速度" } }
  - name: transparent
    passes:
    - vert: unlit-vs:vert
      frag: unlit-fs:frag
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendSrcAlpha: src_alpha
          blendDstAlpha: one_minus_src_alpha
      properties: *props
}%

CCProgram unlit-vs %{
  precision mediump float;
  #include <cc-global>
  #include <cc-local-batch>
  #include <input>

  #if USE_VERTEX_COLOR
    in vec4 a_color;
    out vec4 v_color;
  #endif

  #if USE_TEXTURE
    in vec2 a_texCoord;
    out vec2 v_uv;
    uniform TexCoords {
      vec4 tilingOffset;
    };
  #endif

  highp vec4 vert () {
    vec4 position;
    CCVertInput(position);

    highp mat4 matWorld;
    CCGetWorldMatrix(matWorld);

    highp vec4 pos = cc_matProj * (cc_matView * matWorld) * position;

    #if USE_TEXTURE
      v_uv = a_texCoord;
      #if FLIP_UV
        v_uv.y = 1.0 - v_uv.y;
      #endif
      v_uv = v_uv * tilingOffset.xy + tilingOffset.zw;
    #endif

    #if USE_VERTEX_COLOR
      v_color = a_color;
    #endif

    return pos;
  }
}%

CCProgram unlit-fs %{
  precision mediump float;
  #include <output>

  #if USE_TEXTURE
    in vec2 v_uv;
    uniform sampler2D mainTexture;
    uniform Tex {
      vec2 center;
      float _WaveStrength;
      float _WaveFactor;
      float _TimeScale;
    };
  #endif

  #if USE_COLOR
    uniform Constant {
      vec4 color;
    };
  #endif

  #if USE_VERTEX_COLOR
    in vec4 v_color;
  #endif

  vec4 frag () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      vec2 uvDir = normalize(v_uv - center);
      float dis = distance(v_uv, center);
      vec2 uv = v_uv + _WaveStrength * uvDir * sin(cc_time.x * _TimeScale + dis * _WaveFactor);
      o *= texture(mainTexture, uv);
    #endif

    #if USE_COLOR
      o *= color;
    #endif

    #if USE_VERTEX_COLOR
      o *= v_color;
    #endif

    return CCFragOutput(o);
  }
}%


使用办法:

  1. 在项目资源里创建一个Effect文件,然后把上面的的shader代码全放进去
  2. 再创建一个Material文件,然后选中Material文件,在右边属性栏处,Effect选择第1步创建的Effect
  3. 再把贴图拉进MainTexture里面。其它参数可以自行修改试试,会出现不同的效果。
  4. 最后再把这个材质拉到你的对象材质上。
12赞

很nice

well

marrk

mark

刚才准备一个切入战斗的shader。感谢lz的无私奉献

mark

大佬强!:+1:

我根据你的水纹效果,我写了一个玩水效果。

试玩链接
完整代码
参考文章

请教大佬一个问题,如何在 cocos3D 中实现 uniform 数组变量的定义和传输呢?:raising_hand:

2赞

数组定义及传输的实现。。
参与tiling的变量

      properties: &props
        color:        { value: [1, 1, 1, 1], inspector: { type: color } }
        tilingOffset: { value: [1, 1, 0, 0] }
        tiling: { value: [1, 1, 1, 1] }
        mainTexture:  { value: grey         }

用vec4的数组,用vec3,vec2定义时,接收都会出错。

    uniform TexCoords {
      vec4 tilingOffset;
      vec4 tiling[4];
    };

接收时,用vec4当类型,数组维数由自己根据需要定义。

      v_uv *= tiling[1].xy;

使用时,直接取数组下标即可。

mat.setProperty("tilings", [ cc.v2(3,4,5), cc.v2(4,5,6) ]);

传值时就直接整个数组传入。


creator 目测还识别不了这种数组定义,用数组时,打开材质的编辑界面会报错。但并不影响使用。

1赞

:joy_cat: 对,我就是看着它报错,以为自己写错了。

mark

mark

引擎是支持 uniform 数组的,编辑器目前有 bug,后面会跟进修复

1赞

玩shader的都是大佬

在1.2里报错

[Asset DB] …/effect.effect - unlit-fs:frag: Error EFX2406: compilation failed: ↓↓↓↓↓ EXPAND THIS MESSAGE FOR MORE INFO ↓↓↓↓↓
ERROR: 0:307: ‘a_texCoord’ : redefinition
1 #version 100
2 #define USE_INSTANCING 1
3 #define USE_BATCHING 1
4 #define USE_LIGHTMAP 1
5 #define CC_USE_MORPH 1
6 #define CC_MORPH_TARGET_COUNT 2
7 #define CC_SUPPORT_FLOAT_TEXTURE 1
8 #define CC_MORPH_PRECOMPUTED 1

##下载一个gifCam 可以录制gif展示效果 不错

解决了吗?我也碰到了,一直没找到解决方法。

好像是1.2里默认导入了a_texCoord,把里面的in vec2 a_texCoord;注释掉就行了.

mark.

太感谢了 :100: