【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
             }

        }
}
相关推荐
一步一个foot-print3 小时前
【Unity】Light Probe 替代点光源给环境动态物体加光照
unity·游戏引擎
@LYZY5 小时前
Unity 中隐藏文件规则
unity·游戏引擎·游戏程序·vr
霜绛7 小时前
C#知识补充(二)——命名空间、泛型、委托和事件
开发语言·学习·unity·c#
Sator19 小时前
使用Unity ASE插件设置数值不会生效的问题
unity·游戏引擎
程序猿追11 小时前
轻量级云原生体验:在OpenEuler 25.09上快速部署单节点K3s
人工智能·科技·机器学习·unity·游戏引擎
B0URNE11 小时前
【Unity基础详解】(7)Unity核心:动画系统
unity·游戏引擎
我的golang之路果然有问题12 小时前
mac M系列芯片 unity 安装会遇到的错误以及解决
经验分享·学习·macos·unity·游戏引擎
Hody912 天前
【XR开发系列】2025 年 XR 开发入门,我该选择 Unity 还是 Unreal Engine?
unity·xr·虚幻
DvLee10242 天前
UnityGLTF 材质创建与赋值流程
unity·材质
HahaGiver6662 天前
从0到1做一个“字母拼词”Unity小游戏(含源码/GIF)- 字母拼词正确错误判断
unity·游戏引擎·游戏程序