如何通过Unity Shader编写实现逼真水波纹效果的长尾Shader代码?

2026-03-31 12:201阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计925个文字,预计阅读时间需要4分钟。

如何通过Unity Shader编写实现逼真水波纹效果的长尾Shader代码?

原文示例:本文字例为大家分享了Unity Shader实现水波纹效果的完整代码,供大家参考,具体内容如下+效果:Shader代码:Shader Custom/shuibowen{ Properties{ _MainTex (Base (RGB), 2D)=white{} _distanceFactor (Distancefa, Range(0, 1))=0.5{} } SubShader{ Tags{ RenderType=Opaque } LOD 100 Pass{ CGPROGRAM PassName Vertex Target 3.0{ #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; }; sampler2D _MainTex; float _distanceFactor; v2f vert(appdata v){ v2f o; o.vertex=UnityObjectToClipPos(v.vertex); o.uv=v.uv; return o; } fixed4 frag(v2f i) : SV_Target{ float4 col=tex2D(_MainTex, i.uv); float dist=length(i.vertex.xy - float2(0.5, 0.5)) * _distanceFactor; float4 wave=tex2D(_MainTex, i.uv + float2(dist, 0)); return lerp(col, wave, dist); } ENDCG } } } }

改写后:Unity Shader实现水波纹效果代码示例,提供参考。具体内容如下:Shader代码:Shader Custom/shuibowen{ Properties{ _MainTex (Base (RGB), 2D)=white{} _distanceFactor (Distancefa, Range(0, 1))=0.5{} } SubShader{ Tags{ RenderType=Opaque } LOD 100 Pass{ CGPROGRAM PassName Vertex Target 3.0{ #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; }; sampler2D _MainTex; float _distanceFactor; v2f vert(appdata v){ v2f o; o.vertex=UnityObjectToClipPos(v.vertex); o.uv=v.uv; return o; } fixed4 frag(v2f i) : SV_Target{ float4 col=tex2D(_MainTex, i.uv); float dist=length(i.vertex.xy - float2(0.5, 0.5)) * _distanceFactor; float4 wave=tex2D(_MainTex, i.uv + float2(dist, 0)); return lerp(col, wave, dist); } ENDCG } } } }

本文实例为大家分享了Unity Shader实现水波纹的具体代码,供大家参考,具体内容如下

效果:

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 }

C#代码:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class WaterWaveEffect : 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; } } }

新建一个材质球,选择此shader,并赋值给这个脚本,点击屏幕即可看到效果

如何通过Unity Shader编写实现逼真水波纹效果的长尾Shader代码?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。

本文共计925个文字,预计阅读时间需要4分钟。

如何通过Unity Shader编写实现逼真水波纹效果的长尾Shader代码?

原文示例:本文字例为大家分享了Unity Shader实现水波纹效果的完整代码,供大家参考,具体内容如下+效果:Shader代码:Shader Custom/shuibowen{ Properties{ _MainTex (Base (RGB), 2D)=white{} _distanceFactor (Distancefa, Range(0, 1))=0.5{} } SubShader{ Tags{ RenderType=Opaque } LOD 100 Pass{ CGPROGRAM PassName Vertex Target 3.0{ #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; }; sampler2D _MainTex; float _distanceFactor; v2f vert(appdata v){ v2f o; o.vertex=UnityObjectToClipPos(v.vertex); o.uv=v.uv; return o; } fixed4 frag(v2f i) : SV_Target{ float4 col=tex2D(_MainTex, i.uv); float dist=length(i.vertex.xy - float2(0.5, 0.5)) * _distanceFactor; float4 wave=tex2D(_MainTex, i.uv + float2(dist, 0)); return lerp(col, wave, dist); } ENDCG } } } }

改写后:Unity Shader实现水波纹效果代码示例,提供参考。具体内容如下:Shader代码:Shader Custom/shuibowen{ Properties{ _MainTex (Base (RGB), 2D)=white{} _distanceFactor (Distancefa, Range(0, 1))=0.5{} } SubShader{ Tags{ RenderType=Opaque } LOD 100 Pass{ CGPROGRAM PassName Vertex Target 3.0{ #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; }; sampler2D _MainTex; float _distanceFactor; v2f vert(appdata v){ v2f o; o.vertex=UnityObjectToClipPos(v.vertex); o.uv=v.uv; return o; } fixed4 frag(v2f i) : SV_Target{ float4 col=tex2D(_MainTex, i.uv); float dist=length(i.vertex.xy - float2(0.5, 0.5)) * _distanceFactor; float4 wave=tex2D(_MainTex, i.uv + float2(dist, 0)); return lerp(col, wave, dist); } ENDCG } } } }

本文实例为大家分享了Unity Shader实现水波纹的具体代码,供大家参考,具体内容如下

效果:

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 }

C#代码:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class WaterWaveEffect : 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; } } }

新建一个材质球,选择此shader,并赋值给这个脚本,点击屏幕即可看到效果

如何通过Unity Shader编写实现逼真水波纹效果的长尾Shader代码?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。