首页 > 其他分享 >Unity shader实现水波的技术原理

Unity shader实现水波的技术原理

时间:2024-02-01 09:46:12浏览次数:28  
标签:水波 vertex shader Unity 水面 Speed

Unity shader 是 Unity 引擎中非常重要的一个部分,它可以用来实现各种各样的特效效果,其中包括水波效果。本文将详细讲解 Unity shader 实现水波的技术原理,并给出相关的 Shader 代码实现。

对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。

首先,我们需要了解一下水波的物理原理。水波是由于水面上的液体分子在受到外力作用时发生的振动而产生的,这种振动可以传递到水面上的其他区域,形成波纹。因此,要实现水波效果,我们需要模拟这种振动。

在 Unity 中,我们可以通过 shader 来模拟水波的振动。具体实现方式为:首先,我们需要在 shader 中定义一个纹理,用来表示水面的高度。然后,我们可以通过修改这个纹理中的像素值,来模拟水面上的振动。在每一帧中,我们可以根据当前的时间和水面上每个像素的位置,来计算出这个像素的高度值。这个高度值可以通过某种算法来计算得到,例如使用 sin 函数来模拟正弦波的形状。

接下来,我们需要将这个高度值应用到水面的顶点上。在 shader 中,我们可以使用顶点着色器来对每个顶点进行处理。具体实现方式为:在顶点着色器中,我们可以将每个顶点的位置根据对应的纹理像素的高度值进行偏移。这样,我们就可以通过 shader 来实现水面的振动效果了。

下面是一个简单的 shader 代码示例,用于实现水波效果:

Shader "Custom/Water" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        _Speed ("Speed", Range(0, 10)) = 1
        _Height ("Height", Range(0, 1)) = 0.1
    }
 
    SubShader {
        Tags {"Queue"="Transparent" "RenderType"="Opaque"}
        LOD 100
 
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
 
            struct appdata {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
 
            struct v2f {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 worldPos : TEXCOORD1;
            };
 
            sampler2D _MainTex;
            float _Speed;
            float _Height;
 
            v2f vert (appdata v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                float2 offset = float2(sin(_Time.y * _Speed + o.worldPos.x * 0.01),
                                       sin(_Time.y * _Speed + o.worldPos.y * 0.01));
                o.vertex.xy += offset * _Height;
                return o;
            }
 
            fixed4 frag (v2f i) : SV_Target {
                return tex2D(_MainTex, i.uv);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

 

在这个 shader 中,我们定义了三个属性:_MainTex 表示水面的纹理,_Speed 表示水波的速度,_Height 表示水波的高度。在顶点着色器中,我们通过计算 sin 函数来模拟水波的振动,并将计算出的偏移量应用到顶点的位置上。在片段着色器中,我们直接对纹理进行采样,以便将水面的纹理显示出来。

综上所述,通过 Unity shader 来实现水波效果的原理是模拟水面上的振动,并将计算出的偏移量应用到水面的顶点上。通过这种方式,我们可以实现非常逼真的水波效果。

标签:水波,vertex,shader,Unity,水面,Speed
From: https://www.cnblogs.com/bycw/p/18000566

相关文章

  • Unity引擎2D游戏开发,滑铲功能实现总结
    滑铲到悬崖边下落时无法取消动画由于是使用的协程方式实现,所以当滑铲到悬崖边的时候,不能使用yieldbreak,因为该指令会直接退出当前的协程方法,无法执行到isSlide=false指令privateIEnumeratorTriggerSlide(Vector3target){do{yieldreturnnull;......
  • Unity引擎2D游戏开发,滑墙及蹬墙跳的实现总结
    一、滑墙动画的实现执行动画的逻辑//在墙壁上onWall=(touchLeftWall||touchRightWall)&&!isGround;基本逻辑:紧贴墙壁并且不在地面上的时候执行滑墙动画但是实际上,紧贴墙壁原地跳起也会执行滑墙动画所以,需要额外添加一个条件。跳起离开地面,并施加与面朝X轴方向的力......
  • Shader实现模糊效果
    模糊效果一直是游戏当中用的比较多的,比如一些景深啊,FPS游戏震屏时的模糊,还有些剧情跳转都用到了模糊效果。我们在unity中可以使用Shader来处理模糊效果。一般我们有两种模糊方式,一种是比较简单直接的均值模糊,一种是比较高级当然也有些难度的高斯模糊。简单方式有它的缺陷,难的方式......
  • Unity架构师进阶:红点系统的架构与设计
     面试的时候经常被问道如何来设计一个红点系统,本文将详细地介绍如何设计一个红点系统,有哪些接口,并完整地给出实现。红点系统的需求分析首先我们来分析一下红点系统的设计需求: 红点系统严格意义上来说不属于框架,而是游戏逻辑,所以代码不要放到通用的框架里面,并不属于基础服务......
  • Unity3D DrawCall和openGL、光栅化等有何内在联系详解
    前言Unity3D是一款跨平台的游戏引擎,广泛应用于游戏开发领域。在Unity3D中,DrawCall是一个重要的概念,它与OpenGL、光栅化等技术有着密切的内在联系。本文将详细解释DrawCall的概念,并给出相关技术的详细解释和代码实现。对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交......
  • Unity5.x shader打包AssetBundle总结
    unity5.x  shader打包AssetBundle总结最近比较忙,好久没有更新博客了,新项目切换到unity5.x后使用了新的打包机制,在打包shader的时候遇到了一些问题,这里来记录一下吧。 在上一个项目中,我们使用unity4.7,对于shader并没有进行依赖打包,而是由unity打包到了每个用到的AssetBundle......
  • Unity3D DrawCall和openGL、光栅化等有何内在联系详解
    Unity3D是一款跨平台的游戏引擎,广泛应用于游戏开发领域。在Unity3D中,DrawCall是一个重要的概念,它与OpenGL、光栅化等技术有着密切的内在联系。本文将详细解释DrawCall的概念,并给出相关技术的详细解释和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础......
  • Unity_物体对象跟随鼠标移动360°旋转
    ///<summary>///对象旋转跟随鼠标移动///</summary>publicvoidObjectRotateFollowMouseMove(){if(Input.GetMouseButtonDown(0)){lastMousePoint=Input.mousePosition;}elseif(Input.Get......
  • Unity-GC优化相关笔记
    Unity官网GC定义如下创建对象、字符串或数组时,用于存储它的内存是从称为堆的中央池分配的。当此项不再使用时,其先前占用的内存可被回收并用于其他目的。在过去,通常由程序员通过适当的函数调用显式地分配和释放这些堆内存块。如今,Unity的Mono引擎等运行时系统会自动为您管理内......
  • 最新Unity DOTS Instancing合批:如何针对单个渲染实体修改材质参数
    最近在做DOTS的教程,由于DOTS(版本1.0.16)目前不支持角色的骨骼动画,我们是将角色的所有动画数据Baker到一个纹理里面,通过修改材质中的参数AnimBegin,AnimEnd来决定动画播放的起点和终点,材质参数AnimTime记录当前过去的动画时间。但是在做大规模战斗控制的时候,有10000+的小兵在战斗......