V7投稿|保姆级 sharder水波效果(3D版)

引言

笔者之前在商城上架的水波水流sharder效果(2D版本)【PS:就卖1块钱,内心os:快夸我很良心】,部分同学问我能不能给改个3D版本的,今天就手把手教同学们改个3D版本的。

首先,我们先看下效果:
20240329112735_rec_
进入正题

1.在引擎资源库里面直接搜索 builtin-unlit
2e9b4103bbe8ee401ae4f2dfe3315ab
2.复制这个文件,到自己的文件夹下,修改命名,笔者这里修改为 waterTest
dc7ed641e91c6d81d4a3099f8889447
3.打开这个文件(源码这里就不放了)

4.找到pass 添加‘扩散速度’,方便后面调整效果
image
value:1.0 是指默认值,target:speed 标记为下面代码要用到的变量,editor:range 为取值区域,editor:slide 表示该值可以用滑动条控制

5.找到片段着色器

引入上面我们定义的‘扩散速度’!

image

我们以纹理中心作为水波起点

image

水波一圈一圈向外扩散看起来像什么,没错像不像sin

水波肯定不是只有一圈,那么我们就直接在sin内部给个大的倍数

但是sin的取值区域是-1 到 1,我们希望便宜不那么大,所以给个缩小系数

顺手,我们再加上让水波根据时间进行扩散,那么就变成了动态的了(ps:想自己控制扩散的同学,也可以舍弃时间变量,自己使用代码控制)

image
接下来就很简单了,计算一下偏移,然后让texColor使用新的uv取值,就结束了
image

代码部分就已经完成了,接下来实装到材质上

1.在自己的文件夹,右键->创建->材质,修改命名,笔者这里修改为 waterTest
6e471c8c56adb5715b1d440741a94f0
2.选中该材质,在属性检查器中选择effect为刚刚我们修改的effect文件
f02b966ed0c7036531904121f0c8c68
3.但是这时候,我们看到的还是一个纯色的方块,那么我们需要,勾选USE TEXTURES宏,
c1b3302b6eb957d1dda31b7a106fcd4
4.在Main Texture 拖入一个纹理文件(记得保存)
a41e5984d42c9872ca72316f24ae555
材质部分已经完成,接下来实装到界面上

1.在scene中,右键->创建->3D对象->Plane平面
6f23e33f8333510efa574f316e7ad28
418d0eb278913295088d586ada2d96b
2.在plane节点的属性检查器中,替换材质
ea47ea74a02ea2f21ac4dbc37a4b69b
3.接下来在场景编辑器中,按住鼠标右键,就可以看见效果了(ps:运行项目也可以查看)

PS:最开始,我们引入的‘扩散速度’,在材质的属性检查器中,就可以直接修改(修改完,记得保存)
3454aa76e31312f5fe5482d8f8f8ed5
完整effect代码
// Copyright © 2017-2020 Xiamen Yaji Software Co., Ltd.

CCEffect %{

  techniques:

  - name: opaque

    passes:

    - vert: unlit-vs:vert

      frag: unlit-fs:frag

      properties: &props

        mainTexture:    { value: grey }

        tilingOffset:   { value: [1, 1, 0, 0] }

        mainColor:      { value: [1, 1, 1, 1], linear: true, editor: { type: color } }

        colorScale:     { value: [1, 1, 1], target: colorScaleAndCutoff.xyz }

        alphaThreshold: { value: 0.5, target: colorScaleAndCutoff.w, editor: { parent: USE_ALPHA_TEST } }

        color:          { target: mainColor, linear: true, editor: { visible: false } } # backward compability

        扩散速度: { value: 1.0, target: speed, editor: { range:[1, 10, 0.1], slide: true} }

      migrations: &migs

        properties:

          mainColor:    { formerlySerializedAs: color }

  - name: transparent

    passes:

    - vert: unlit-vs:vert

      frag: unlit-fs:frag

      depthStencilState: &d1

        depthTest: true

        depthWrite: false

      blendState:

        targets:

        - blend: true

          blendSrc: src_alpha

          blendDst: one_minus_src_alpha

          blendDstAlpha: one_minus_src_alpha

      properties: *props

      migrations: *migs

  - name: add

    passes:

    - vert: unlit-vs:vert

      frag: unlit-fs:frag

      rasterizerState: &r1 { cullMode: none }

      depthStencilState: *d1

      blendState:

        targets:

        - blend: true

          blendSrc: src_alpha

          blendDst: one

          blendSrcAlpha: src_alpha

          blendDstAlpha: one

      properties: *props

      migrations: *migs

  - name: alpha-blend

    passes:

    - vert: unlit-vs:vert

      frag: unlit-fs:frag

      rasterizerState: *r1

      depthStencilState: *d1

      blendState:

        targets:

        - blend: true

          blendSrc: src_alpha

          blendDst: one_minus_src_alpha

          blendSrcAlpha: src_alpha

          blendDstAlpha: one_minus_src_alpha

      properties: *props

      migrations: *migs

}%

CCProgram unlit-vs %{

  precision highp float;

  #include <legacy/input>

  #include <builtin/uniforms/cc-global>

  #include <legacy/decode-base>

  #include <legacy/local-batch>

  #include <legacy/input>

  #include <legacy/fog-vs>

  #if USE_VERTEX_COLOR

    in lowp vec4 a_color;

    out lowp vec4 v_color;

  #endif

  #if USE_TEXTURE

    out vec2 v_uv;

    uniform TexCoords {

      vec4 tilingOffset;

    };

  #endif

  vec4 vert () {

    vec4 position;

    CCVertInput(position);

    mat4 matWorld;

    CCGetWorldMatrix(matWorld);

    #if USE_TEXTURE

      v_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;

      #if SAMPLE_FROM_RT

        CC_HANDLE_RT_SAMPLE_FLIP(v_uv);

      #endif

    #endif

    #if USE_VERTEX_COLOR

      v_color = a_color;

    #endif

    CC_TRANSFER_FOG(matWorld * position);

    return cc_matProj * (cc_matView * matWorld) * position;

  }

}%

CCProgram unlit-fs %{

  precision highp float;

  #include <legacy/output-standard>

  #include <legacy/fog-fs>

  #include <builtin/uniforms/cc-global>

  #if USE_ALPHA_TEST

    #pragma define-meta ALPHA_TEST_CHANNEL options([a, r, g, b])

  #endif

  #if USE_TEXTURE

    in vec2 v_uv;

    uniform sampler2D mainTexture;

  #endif

  uniform Constant {

    vec4 mainColor;

    vec4 colorScaleAndCutoff;

  };

  #if USE_VERTEX_COLOR

    in lowp vec4 v_color;

  #endif

 

  uniform Factor {

    float speed;

  };

  vec4 frag () {

    vec4 o = mainColor;

    o.rgb *= colorScaleAndCutoff.xyz;

   

    #if USE_VERTEX_COLOR

      o.rgb *= SRGBToLinear(v_color.rgb);

      o.a *= v_color.a;

    #endif

    #if USE_TEXTURE

      vec2 distance_vec = v_uv - vec2(0.5, 0.5);

      float distance = length(distance_vec);

      float sin_factor = sin(cc_time.x * speed - distance * 100.0 ) * 0.05;

   

      // 计算总的uv的偏移值

      vec2 offset = normalize(distance_vec) * sin_factor;

      vec2 nuv = offset + v_uv;

      vec4 texColor = texture(mainTexture, nuv);

      texColor.rgb = SRGBToLinear(texColor.rgb);

      o *= texColor;

    #endif

    #if USE_ALPHA_TEST

      if (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;

    #endif

    CC_APPLY_FOG(o);

    return CCFragOutput(o);

  }

}%

以上就是水波sharder效果(3D版本)的全部内容,快去试试吧。

4赞