【shader】鼠标点击屏幕产生水波效果

本文详细介绍了如何使用Unity的Shader系统实现水波纹视觉效果。通过调整距离系数、时间系数等参数,可以控制波纹的大小、振幅及扩散速度。文中提供了完整的Shader代码和C#脚本,用于动态更新波纹效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不废话,先上效果图:

 

下面是shader代码:

Shader "Custom/shuibowen"{
	Properties{
		_MainTex("Base (RGB)",2D)="white"{}
		_distanceFactor("Distancefactor",float)=1
		_timeFactor("time factor",float)=2
		_totalFactor("total factor",float)=3
		_waveWidth("wave width",float)=4
		_curWaveDis("curwave dis",float)=5
		_startPos("star pos",Vector) = (1,1,1,1)
		_MainTex_TexelSize("Maintex_texelSize",vector)=(1,1,1,1)
	}
	CGINCLUDE
	#include "UnityCG.cginc"
	uniform sampler2D _MainTex;  
	float4 _MainTex_TexelSize;
    uniform float _distanceFactor;  
    uniform float _timeFactor;  
    uniform float _totalFactor;  
    uniform float _waveWidth;  
    uniform float _curWaveDis;  
	uniform float4 _startPos;
	fixed4 frag(v2f_img i) : SV_Target  
    {  
        //DX下纹理坐标反向问题  
        #if UNITY_UV_STARTS_AT_TOP  
        if (_MainTex_TexelSize.y < 0)  
            _startPos.y = 1 - _startPos.y;  
        #endif  
        //计算uv到中间点的向量(向外扩,反过来就是向里缩)  
        float2 dv = _startPos.xy - i.uv;				//--决定方向
        //按照屏幕长宽比进行缩放  
        dv = dv * float2(_ScreenParams.x / _ScreenParams.y, 1); 
        //计算像素点距中点的距离  
        float dis = sqrt(dv.x * dv.x + dv.y * dv.y);  
        //用sin函数计算出波形的偏移值factor  
        //dis在这里都是小于1的,所以我们需要乘以一个比较大的数,比如60,这样就有多个波峰波谷  
        //sin函数是(-1,1)的值域,我们希望偏移值很小,所以这里我们缩小100倍,据说乘法比较快,so...  
        float sinFactor = sin(dis * _distanceFactor + _Time.y * _timeFactor) * _totalFactor * 0.01;  
        //距离当前波纹运动点的距离,如果小于waveWidth才予以保留,否则已经出了波纹范围,factor通过clamp设置为0  
        float discardFactor = clamp(_waveWidth - abs(_curWaveDis - dis), 0, 1) / _waveWidth;  
        //归一化  
        float2 dv1 = normalize(dv);  
        //计算每个像素uv的偏移值  
        float2 offset = dv1  * sinFactor * discardFactor;  
        //像素采样时偏移offset  
        float2 uv = offset + i.uv;  
        return tex2D(_MainTex, uv);   
    }  
	ENDCG  
	SubShader   
    {  
        Pass  
        {  
            ZTest Always  
            Cull Off  
            ZWrite Off  
            Fog { Mode off }  
  
            CGPROGRAM  
            #pragma vertex vert_img  
            #pragma fragment frag  
            #pragma fragmentoption ARB_precision_hint_fastest   
            ENDCG  
        }  
    }  
    Fallback off  
}

下面是摄像机上挂的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class test111 : PostEffectsBase
{
    //距离系数  
    public float distanceFactor = 60.0f;
    //时间系数  
    public float timeFactor = -30.0f;
    //sin函数结果系数  
    public float totalFactor = 1.0f;

    //波纹宽度  
    public float waveWidth = 0.3f;
    //波纹扩散的速度  
    public float waveSpeed = 0.3f;

    private float waveStartTime;
    private Vector4 startPos = new Vector4(0.5f, 0.5f, 0, 0);
    public Material _Material;

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        //计算波纹移动的距离,根据enable到目前的时间*速度求解  
        float curWaveDistance = (Time.time - waveStartTime) * waveSpeed;
        //设置一系列参数  
        _Material.SetFloat("_distanceFactor", distanceFactor);
        _Material.SetFloat("_timeFactor", timeFactor);
        _Material.SetFloat("_totalFactor", totalFactor);
        _Material.SetFloat("_waveWidth", waveWidth);
        _Material.SetFloat("_curWaveDis", curWaveDistance);
        _Material.SetVector("_startPos", startPos);
        Graphics.Blit(source, destination, _Material);
    }

    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Vector2 mousePos = Input.mousePosition;
            //将mousePos转化为(0,1)区间  
            startPos = new Vector4(mousePos.x / Screen.width, mousePos.y / Screen.height, 0, 0);
            waveStartTime = Time.time;
        }

    }
}

 

C#中属性解释:

    //距离系数  
    public float distanceFactor = 60.0f;  //---这个理解为每个波的大小
    //时间系数  
    public float timeFactor = -30.0f;   //---振幅
    //sin函数结果系数  
    public float totalFactor = 1.0f;     //----波峰

    //波纹宽度  
    public float waveWidth = 0.3f;
    //波纹扩散的速度  
    public float waveSpeed = 0.3f;

    private float waveStartTime;
    private Vector4 startPos;波中心位置

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值