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

        }
}
相关推荐
郝学胜-神的一滴1 天前
[简化版 GAMES 101] 计算机图形学 16:纹理走样、Mipmap、三线性插值、各向异性过滤原理全解
unity·游戏引擎·godot·图形渲染·three.js·opengl·unreal
吴梓穆2 天前
untiy TextMeshPro (TMP) text 操作 中文字符集 字体材质操作(添加纹理 添加描边 添加阴影)
unity
想你依然心痛2 天前
嵌入式单元测试:Unity/CMock框架与硬件在环测试——测试驱动、桩函数
unity·单元测试·游戏引擎
xcLeigh2 天前
Unity基础:Game视图详解——游戏预览、分辨率模拟与性能显示
游戏·unity·游戏引擎·音频·视频·game·play模式
xcLeigh2 天前
Unity基础:Scene视图操作完全指南——视角控制、物体选择与场景导航
unity·游戏引擎·scene·试图·场景导航
mxwin2 天前
Unity Shader exp 函数的算法与渲染应用
算法·unity·游戏引擎·shader
mxwin3 天前
Unity URP Exposure曝光原理与实战应用
unity·游戏引擎
WarPigs3 天前
AB包自定义打包工具
unity
叶帆20 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
久数君20 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型