Shader顶点偏移通道实现旗帜飘动效果

您所在的位置:网站首页 unity中布料飘动效果 Shader顶点偏移通道实现旗帜飘动效果

Shader顶点偏移通道实现旗帜飘动效果

2023-12-22 18:09| 来源: 网络整理| 查看: 265

简介:

    在游戏中,如果遇到了类似旗子飘动的动画,可以使用Shader来简单实现,搞了个Shader,把原理和算法简单写了下注释,大家如果需要加上贴图,调整下参数就可以直接用。

/************************************************************************ * File : FlagsFluttering * Author : Mango * Time : 2018-5-28 * UnityVer.: 2017.1.0f3 * Description: 实现旗子飘动效果(向前及阴影渲染) ************************************************************************ */ Shader "Shader/FlagsFluttering" { Properties{ //旗子纹理 _Texture("Texture", 2D) = "white" {} //旗子飘动振幅(y轴) _Magnitude("Magnitude", Range(0, 10)) = 1 //旗子飘动速度 _Speed("Speed", Range(0, 10)) = 3 } SubShader{ Tags{ "RenderType" = "Opaque" } Pass{ Name "FORWARD" Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #define UNITY_PASS_FORWARDBASE #include "UnityCG.cginc" #pragma multi_compile_fwdbase_fullshadows #pragma multi_compile_fog #pragma only_renderers d3d9 d3d11 glcore gles #pragma target 3.0 uniform sampler2D _Texture; uniform float4 _Texture_ST; uniform float _Magnitude; uniform float _Speed; struct VertexInput { float4 vertex : POSITION; float2 texcoord0 : TEXCOORD0; }; struct VertexOutput { float4 pos : SV_POSITION; float2 uv0 : TEXCOORD0; float4 posWorld : TEXCOORD1; UNITY_FOG_COORDS(2) }; //旗子飘动,算法是根据当前旗子贴图上所有顶点,根据时间的正弦值做周期运动 VertexOutput vert(VertexInput v) { VertexOutput o = (VertexOutput)0; o.uv0 = v.texcoord0; //获取当前物体的世界坐标,用于在移动旗子的时候,旗子的顶点移动会相对此时的物体,避免移动过程中出现不再飘动 float4 objPos = mul(unity_ObjectToWorld, float4(0,0,0,1)); float4 time = _Time; //顶点的坐标计算,根据当前物体位置,计算出当前所有顶点的位置,然后根据时间关系计算正弦值 v.vertex.xyz += (sin((((mul(unity_ObjectToWorld, v.vertex).r - objPos.r) + (mul(unity_ObjectToWorld, v.vertex).b - objPos.b)) + (time.g*_Speed)))*float3(0,1,0)*_Magnitude*o.uv0.r); o.posWorld = mul(unity_ObjectToWorld, v.vertex); o.pos = UnityObjectToClipPos(v.vertex); UNITY_TRANSFER_FOG(o,o.pos); return o; } //最终贴图显示 float4 frag(VertexOutput i) : COLOR{ float4 objPos = mul(unity_ObjectToWorld, float4(0,0,0,1)); float4 _Texture_var = tex2D(_Texture,TRANSFORM_TEX(i.uv0, _Texture)); float3 finalColor = _Texture_var.rgb; fixed4 finalRGBA = fixed4(finalColor,1); UNITY_APPLY_FOG(i.fogCoord, finalRGBA); return finalRGBA; } ENDCG } Pass{ Name "ShadowCaster" Tags{ "LightMode" = "ShadowCaster" } Offset 1, 1 Cull Back CGPROGRAM #pragma vertex vert #pragma fragment frag #define UNITY_PASS_SHADOWCASTER #include "UnityCG.cginc" #include "Lighting.cginc" #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile_shadowcaster #pragma multi_compile_fog #pragma only_renderers d3d9 d3d11 glcore gles #pragma target 3.0 uniform float _Magnitude; uniform float _Speed; struct VertexInput { float4 vertex : POSITION; float2 texcoord0 : TEXCOORD0; }; struct VertexOutput { V2F_SHADOW_CASTER; float2 uv0 : TEXCOORD1; float4 posWorld : TEXCOORD2; }; VertexOutput vert(VertexInput v) { VertexOutput o = (VertexOutput)0; o.uv0 = v.texcoord0; float4 objPos = mul(unity_ObjectToWorld, float4(0,0,0,1)); float4 time = _Time; v.vertex.xyz += (sin((((mul(unity_ObjectToWorld, v.vertex).r - objPos.r) + (mul(unity_ObjectToWorld, v.vertex).b - objPos.b)) + (time.g*_Speed)))*float3(0,1,0)*_Magnitude*o.uv0.r); o.posWorld = mul(unity_ObjectToWorld, v.vertex); o.pos = UnityObjectToClipPos(v.vertex); TRANSFER_SHADOW_CASTER(o) return o; } float4 frag(VertexOutput i) : COLOR{ float4 objPos = mul(unity_ObjectToWorld, float4(0,0,0,1)); SHADOW_CASTER_FRAGMENT(i) } ENDCG } } //注意回滚Shader FallBack "Diffuse" }

再给大家推荐一个Shader的可视化编辑插件——Shader Forge,类似PlayerMaker,使用多个节点,根据相应的算法进行计算组合就可以实现简单的Shader。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3