首页 > 其他分享 >Cocos Creator 3.8 开发2D水面波纹Shader

Cocos Creator 3.8 开发2D水面波纹Shader

时间:2024-01-11 16:22:54浏览次数:27  
标签:Cocos baseLine Creator uv0 pos value Shader cc

 使用cocos Creator 3.8做了一个游戏开中常用的2D的波浪水面,把技术点给记录一下,并提供完整的Shader代码。先上效果:

 

 

 

2D 波浪的基本技术原理

 2D 水面波纹的主要原理就是给定一个正选波的边界,在范围内的片元uv就显示,在范围外的片元uv就不显示。同时利用正弦波表达式:

y = A * sin(w * t+offset)

将片元的uv坐标uv.x 带入上面的公式offset,算出y0值。Cocos 的uv 左上角为(0, 0),我们要在图片的上方做水波纹,那么片元的uv.y < y0的片元就丢弃, uv.y >= y0的就正常显示。 

 

 

为了让水波能动起来,我们就要不断的改变同一个位置offset, 对应的y0的值,那么我们加一个 w * t, 角速度*时间。这样随着时间的推移同一个uv(x, y),会得到不同的y0的值。有了不同的边界,这样就会决定不同的片元的显示和丢弃。

具体编写Shader

第001步: 新建一个标准2D Shader 模板,能正常显示图片

Cocos Creator的版本不一样,可能导致以前编写的Shader无法正常运行,这种其实很好解决,我们在开发Shader的时候,基于现在Cocos Creator的版本先创建一个现有的模板出来,然后再将关键代码移植过去。我们做一个2D的Shader,所以复制一个buildin-sprite的Shader模板。然后创建一个材质选好我们新创建的Shader文件,将材质设置到Sprite组件上,能正常显示图片。

 

 

第002步: 定义好uniform给用户的控制参数:

baseLine: 基准线,该参数用于控制波浪在图片的位置(波形的基准线);

A: 振幅,该参数用于控制波浪线的高度;

wSpeed:角速度,该参数用来控制一个波形的长度;

 

 

 

第003步: 修改Frag片元着色的Shader代码

完成基准线功能,编写代码基准线以上的片元直接丢弃,基准线一下的片元保留,代码如下:

float value = 0;

if(uv0.y < baseLine + value) {

      discard;

}

这样基准线baseLine以上的,就不显示,baseLine以下的显示。

第004步:基于A*sin(offset)来将基准线做正弦波处理

基准线确定好后,还需给基准线加上正弦波,offset为uv.x, value = A*sin(offset),  baseLine + value, 这样就把baseLine做成了正弦波的分界线。

float value = A * sin(uv0.x * 30.0);

if(uv0.y < baseLine + value) {

   discard;

}

第005步:让正弦波动起来

为了让正弦波动起来,我们在sin加上w*t, 在cocos ccreator里面cc_time是一个vec4的向量, cc_time.x是从启动后到现在的时间,随着时间不断地变化,value = A * sin(uv0.x * 30.0 + wSpeed * cc_time.x); value地值也成周期变化,这样波形就动起来了。

float value = A * sin(uv0.x * 30.0 + wSpeed * cc_time.x);

if(uv0.y < baseLine + value) {

     discard;

}

完整Shader代码

  最后上代码(Cocos Creator 3.8.0):

   // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.

CCEffect %{

  techniques:

  - passes:

    - vert: sprite-vs:vert

      frag: sprite-fs:frag

      depthStencilState:

        depthTest: false

        depthWrite: false

      blendState:

        targets:

        - blend: true

          blendSrc: src_alpha

          blendDst: one_minus_src_alpha

          blendDstAlpha: one_minus_src_alpha

      rasterizerState:

        cullMode: none

      properties:

        alphaThreshold: { value: 0.5 }

        baseLine: { value: 0.5}

        wSpeed: { value: 10.0 }

        A: { value: 0.01}

 

 

}%

 

CCProgram sprite-vs %{

  precision highp float;

  #include <builtin/uniforms/cc-global>

  #if USE_LOCAL

    #include <builtin/uniforms/cc-local>

  #endif

  #if SAMPLE_FROM_RT

    #include <common/common-define>

  #endif

  in vec3 a_position;

  in vec2 a_texCoord;

  in vec4 a_color;

 

  out vec4 color;

  out vec2 uv0;

 

  vec4 vert () {

    vec4 pos = vec4(a_position, 1);

 

    #if USE_LOCAL

      pos = cc_matWorld * pos;

    #endif

 

    #if USE_PIXEL_ALIGNMENT

      pos = cc_matView * pos;

      pos.xyz = floor(pos.xyz);

      pos = cc_matProj * pos;

    #else

      pos = cc_matViewProj * pos;

    #endif

 

    uv0 = a_texCoord;

    #if SAMPLE_FROM_RT

      CC_HANDLE_RT_SAMPLE_FLIP(uv0);

    #endif

    color = a_color;

 

    return pos;

  }

}%

 

CCProgram sprite-fs %{

  precision highp float;

  #include <builtin/uniforms/cc-global>

  #include <builtin/internal/embedded-alpha>

  #include <builtin/internal/alpha-test>

 

  in vec4 color;

  

 

  #if USE_TEXTURE

    in vec2 uv0;

    #pragma builtin(local)

    layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;

    

  #endif

 

  uniform MyUniform {

    float baseLine;

    float wSpeed;

    float A;

  };

 

  vec4 frag () {

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

 

    #if USE_TEXTURE

      o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);

    #endif

 

    float value = A * sin(uv0.x * 30.0 + wSpeed * cc_time.x);

    if(uv0.y < baseLine + value) {

      discard;

    }

    

 

 

    o *= color;

    

    return o;

  }

}%

 关注我,可以获取这个项目工程地源码。

 

标签:Cocos,baseLine,Creator,uv0,pos,value,Shader,cc
From: https://www.cnblogs.com/rainy1unity/p/17958821

相关文章

  • Shader随笔02
    GlobalBake这里是简化Lighting.cginc的UnityGI_Base函数以及AutoLight.cginc的LightingLambert来实现bake贴图采样(没开灯光)其中,Mixed是重点DirectionalMode是重点Light组件的Mode需要调成Mixed完成以上内容可以在使用unity标准Shader的情况下看的bake情况自定义cginc......
  • Cocos Creator 3.x之点击选择3D物体
    一,场景设计二,SelectView.tsimport{_decorator,Component,Node,Camera,MeshRenderer,Mesh,EventTouch,input,Input,Vec2,v2,geometry,PhysicsSystem,PhysicsRayResult,Material,isValid}fro......
  • Cocos Creator 3.x之旋转基础
    一,场景设计二,整体场景效果三,QuatView.ts代码import{_decorator,Component,EventTouch,Input,input,Node,Quat,v3,Vec3,Vec2}from"cc";const{ccclass,property}=_decorator;@ccclass("QuatView")exportclassQuatViewextendsComponent{......
  • ProjectorMultiply.Shader 非固定管线版本
    //UpgradeNOTE:replaced'_Projector'with'unity_Projector'//UpgradeNOTE:replaced'_ProjectorClip'with'unity_ProjectorClip'Shader"Projector/Multiply"{Properties{_ShadowTex("......
  • Unity3d Vertex/Fragment Shader添加Shadow
    Shader"ZX/BaseVertFragmentShadow"{Properties{_DiffuseTexture("DiffuseTexture",2D)="white"{}_DiffuseTint("DiffuseTint",Color)=(1,1,1,1)}SubShader{......
  • cocos 自定义property
    exportenumAviaBC2CountryEnum{GBR=1,USA=2,}//定义一个图片类型的类@ccclass("SpriteTypes")//这个名字一定要写,而且还注意不能取下面的类名不然cocosCreator会一直报警告classSpriteType{//语言@property({type:cc.Enum(AviaBC2Cou......
  • mac m1 编译cocos2d-x 在模拟器上运行 一些问题汇总
     如果涉及到侵权请联系本人删除 1  》〉/Users/yzfhkms-m/Library/Developer/Xcode/DerivedData/formi-dlcfwgxcmidqefdkxnvnfwfprpfs/Build/Products/Debug-iphonesimulator/formi-mobile.appisnotavalidpathtoanexecutablefile.Pleaserebuildtheprojectto......
  • Unity3D Shader在GPU上是如何执行的详解
    Unity3D是一款广泛应用于游戏开发的跨平台开发引擎,它提供了丰富的功能和工具来帮助开发者创建高质量的游戏。其中一个重要的功能就是Shader,它可以用来控制对象的渲染效果。在Unity3D中,Shader是在GPU上执行的,那么它是如何工作的呢?本文将详细解释Unity3DShader在GPU上的执行过程,并......
  • Unity3D Shader Compute Shader基于GPU的并发计算详解
    在游戏开发中,计算密集型的任务通常需要耗费大量的CPU资源,这可能导致游戏性能下降,影响玩家的游戏体验。为了解决这个问题,Unity3D引入了ShaderComputeShader技术,它使用GPU进行并发计算,将一些计算密集型任务从CPU转移到GPU上执行,以提高游戏的性能和效率。本文将详细介绍Unity3DSha......
  • 关于URP项目shader相关的一些问题
    1,Unity-3DURP项目自定义Shader显示不正常,渲染队列2000,物体却是透明的?-知乎(zhihu.com)《Unity的URP项目中使用自定义shader导致材质消失的解决办法》-CSDN博客我是把DepthPrimingMode改成Disabled就正常了 ......