【Unity】管道流动模拟Shader

【Unity】管道流动模拟Shader

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

实现效果

Demo效果

Demo下载地址

管线光泽调整

管线颜色调整

流动方向调整

透明度调整

流动体粗细调整

管线横断

流动速度调整

shader源码

c# 复制代码
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
             }

        }
}
相关推荐
小李也疯狂9 小时前
Unity 中的立方体贴图(Cubemaps)
unity·游戏引擎·贴图·cubemap
牛掰是怎么形成的9 小时前
Unity材质贴图引用陷阱:包体暴涨真相
unity·材质·贴图
呆呆敲代码的小Y9 小时前
【Unity工具篇】| 超实用工具LuBan,快速上手使用
游戏·unity·游戏引擎·unity插件·luban·免费游戏·游戏配置表
EQ-雪梨蛋花汤9 小时前
【Unity优化】Unity多场景加载优化与资源释放完整指南:解决Additive加载卡顿、预热、卸载与内存释放问题
unity·游戏引擎
我的offer在哪里10 小时前
用 Unity 从 0 做一个「可以玩的」游戏,需要哪些步骤和流程
游戏·unity·游戏引擎
泡泡茶壶ᐇ10 小时前
Unity游戏开发入门指南:从零开始理解游戏引擎核心概念
unity·游戏引擎
YigAin11 小时前
Unity中的Lock,到底在锁什么,什么时候该用?
unity
Var_al12 小时前
抖小Unity WebGL分包命令行工具实践指南
unity·游戏引擎·webgl
天人合一peng14 小时前
unity 通过代码修改button及其名字字体的属性
unity·游戏引擎
GLDbalala18 小时前
Unity基于自定义管线实现经典经验光照模型
unity·游戏引擎