【Unity】管道流动模拟Shader

【Unity】管道流动模拟Shader

抽象模拟管道介质流动的效果,使用顶点片元着色器。可以调整管线光泽,颜色,流动方向,透明度,流动体粗细,流动速度和横断面。

实现效果

Demo效果

Demo下载地址

管线光泽调整

管线颜色调整

流动方向调整

透明度调整

流动体粗细调整

管线横断

流动速度调整

shader源码

Shader "Unlit/PipeShaderTwoPass"
{
    Properties
    {
        _MoveTex("MoveTexture", 2D) = "white" {}
        _PipeTex("PipeTexture", 2D) = "white" {}
        _Color("Color",Color) = (1,1,1,0)
        [HDR]_MoveColor("MoveColor",Color) = (1,1,1,0)
        _CutVector("CutVector",Vector) = (0, 1, 0, 0)
        _CutCenter("CutCenter",Vector) = (0, 1, 0, 0)
        [Enum(Off,0,On,1)]_isCut("isCut",int) = 1
        [Enum(Off,0,On,1)]_isFront("isFront",int) = 1
        [Enum(Off,0,On,1)]_isMove("isMove",int) = 1
        _Alpha("Alpha",Range(0.85, 1.0)) = 1
        _Speed("Speed",Range(1, 3)) = 0.1
        _Metallic("Metallic", Range(0.0, 1.0)) = 0.5
        _Smoothness("Smoothness", Range(1.0, 2.0)) = 0.5
        _R("R",Range(0,1)) = 1
    }
        SubShader
        {
            Pass
            {
                Tags { "RenderType" = "Opaque"  }
                LOD 100
                ZWrite On
                Cull Off  //关闭剔除  
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                sampler2D _MoveTex;
                float4 _MoveTex_ST;
                float4 _CutCenter;
                float4 _CutVector;
                float4  _MoveColor;
                int _isCut;
                int _isFront;
                int _isMove;
                float _Speed;
                float _R;
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                    float3 normal : NORMAL;
                };
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float3  worldPos  : TEXCOORD1;
                };
                v2f vert(appdata v)
                {
                    v2f o;
                    o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                    o.vertex = UnityObjectToClipPos(v.vertex - (v.normal * _R));
                    o.uv = TRANSFORM_TEX(v.uv, _MoveTex);
                    return o;
                }
                fixed4 frag(v2f i) : SV_Target
                {
                      float2 uv = i.uv;
                      if (_isFront)
                      {
                          uv = float2(i.uv.x, -i.uv.y);
                      }
                      fixed4 col = tex2D(_MoveTex, uv - float2(0, _isMove * _Speed * _Time.y));
                  if (_isCut == 1)
                  {
                      float3 cutVector = normalize(_CutVector.xyz);//切割向量
                      float3 targetVer = i.worldPos - _CutCenter;//切割原点到模型点上的向量
                      float angel = -dot(cutVector, normalize(targetVer));//切割向量和targetVer点乘,正则同方向,父则反方向
                      clip(angel);//反方向剔除
                  }
                  clip(col.x - 0.1);
                  return col* _MoveColor;
                }
                ENDCG
             }
            
             Pass
            {
                Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "Queue" = "Geometry" }
                LOD 100
                ZWrite On
                Cull Off  //关闭剔除  
                Blend SrcAlpha OneMinusSrcAlpha
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                #include "UnityLightingCommon.cginc" // 对于 _LightColor0
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                    float3 normal : NORMAL;
                };

                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float3  worldPos  : TEXCOORD1;
                    half3 worldNormal : TEXCOORD2;
                    fixed4 diff : COLOR0; // 漫射光照颜色
                };

                sampler2D _PipeTex;
                float4 _PipeTex_ST;
                float4 _CutCenter;
                float4 _CutVector;
                int _isCut;
                fixed _Verical;
                float _Alpha;
                float4 _Color;
                float _Metallic;
                float _Smoothness;
                v2f vert(appdata v)
                {
                    v2f o;
                    o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = TRANSFORM_TEX(v.uv, _PipeTex);
                    o.worldNormal = UnityObjectToWorldNormal(v.normal);
                    half nl = max(0, dot(o.worldNormal, _WorldSpaceLightPos0.xyz) * 0.5 + 0.5);
                    o.diff = nl * _LightColor0;
                    o.diff.rgb += ShadeSH9(half4(o.worldNormal, 1));
                    return o;
                }

                fixed4 frag(v2f i) : SV_Target
                {
                      float2 uv = i.uv;
                      fixed4 col = tex2D(_PipeTex, uv);
                     if (_isCut == 1)
                     {
                      float3 cutVector = normalize(_CutVector.xyz);//切割向量
                      float3 targetVer = i.worldPos - _CutCenter;//切割原点到模型点上的向量
                      float angel = -dot(cutVector, normalize(targetVer));//切割向量和targetVer点乘,正则同方向,父则反方向
                      clip(angel);//反方向剔除
                      }
                      // 计算视图方向和反射矢量
                       // 此处为每像素计算
                      half3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                      half3 worldRefl = reflect(-worldViewDir, i.worldNormal);

                      // 与在先前的着色器中相同
                      half4 skyData = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, worldRefl);
                      half3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR);
                      fixed4 c = 0;
                      c.rgb = skyColor * _Metallic;
                      half4 endColor;
                      endColor = fixed4(((_Color + c) * i.diff * _Smoothness).rgb, _Color.a);
                      return fixed4(endColor.rgb, _Alpha);
                 }
                  ENDCG
             }

        }
}

猜你喜欢

转载自blog.csdn.net/dxs1990/article/details/136192758