unity shader ---水箱水位线效果

应功能需求,要做一个透明水箱效果,并包含一个水位线,表示水位高度,找了一些资源整改了一下,接下来,上代码

效果:

unity shader ---水箱水位线效果_第1张图片

 

shader:

Shader "Unlit/SpecialFX/Liquid"
{
	Properties//属性
	{
		_Tint("Tint", Color) = (1,1,1,1)
		_FillAmount("Fill Amount", Range(0,1)) = 0.0
		_WobbleX("WobbleX", Range(-1,1)) = 0.0
		_WobbleZ("WobbleZ", Range(-1,1)) = 0.0
		_TopColor("Top Color", Color) = (1,1,1,1)
		_FoamColor("Foam Line Color", Color) = (1,1,1,1)
		_Rim("Foam Line Width", Range(0,0.1)) = 0.0
		_RimColor("Rim Color", Color) = (1,1,1,1)
		_RimPower("Rim Power", Range(0,10)) = 0.0
		_CubeColor("CubeColor", color) = (1,1,1,1)
		_Width("Width", range(0,0.5)) = 0.1
		_Length("Length", range(0.5,1)) = 0.1
		_ScaleColor("ScaleColor", color) = (1,1,1,1)
		_ScaleWidth("ScaleLine Width", Range(0,0.1)) = 0.0
		_ScaleHight("ScaleLine Hight", range(0,1)) = 0.1
	}

	SubShader//着色器
	{
		Tags {"Queue" = "Transparent"  "DisableBatching" = "True" }
		Pass {
			Zwrite On//将像素的深度写入深度缓存中  
			Cull Off // 关闭阴影剔除
			AlphaToMask On // transparency
			blend srcalpha oneminussrcalpha
		//渲染代码在CGPROGRAM和ENDCG之间
		CGPROGRAM

		#pragma vertex vert
		#pragma fragment frag			
		#pragma multi_compile_fog// make fog work
		#include "UnityCG.cginc"//引入Unity内置定义
		fixed4 _Tint;
		fixed4 _CubeColor;
		fixed4 _LineColor;
		fixed _Width;
		fixed _Length;
		float _FillAmount, _WobbleX, _WobbleZ;
		float4 _TopColor, _RimColor, _FoamColor, _ScaleColor;
		float _Rim, _RimPower, _ScaleWidth, _ScaleHight;


		struct v2f {
			float4 pos : SV_POSITION;
			float2 uv : TEXCOORD0;
			UNITY_FOG_COORDS(1)
			float3 viewDir : COLOR;
			float3 normal : COLOR2;
			float fillEdge : TEXCOORD2;
			float warningLine : TEXCOORD1;
		};

		struct appdata {
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
			float3 normal : NORMAL;
		};

		float4 RotateAroundYInDegrees(float4 vertex, float degrees) {
			float alpha = degrees * UNITY_PI / 180;
			float sina, cosa;
			sincos(alpha, sina, cosa);
			float2x2 m = float2x2(cosa, sina, -sina, cosa);
			return float4(vertex.yz , mul(m, vertex.xz)).xzyw;
		}


		v2f vert(appdata v)
		{
		   v2f o;
		   o.pos = UnityObjectToClipPos(v.vertex);
		   o.uv = v.uv;
		   UNITY_TRANSFER_FOG(o,o.pos);
		   //获取世界坐标
		   float3 worldPos = mul(unity_ObjectToWorld, v.vertex.xyz);
		   // XY轴晃动
		   float3 worldPosX = RotateAroundYInDegrees(float4(worldPos,0),360);
		   // XZ轴晃动 
		   float3 worldPosZ = float3 (worldPosX.y, worldPosX.z, worldPosX.x);
		   // 结合旋转与worldPos,基于正弦波,脚本控制
		   float3 worldPosAdjusted = worldPos + (worldPosX  * _WobbleX) + (worldPosZ* _WobbleZ);
		   // 控制液体高度
		   o.fillEdge = worldPosAdjusted.y + _FillAmount;
		   o.warningLine = worldPos.y + _ScaleHight;
		   o.viewDir = normalize(ObjSpaceViewDir(v.vertex));
		   o.normal = v.normal;
		   return o;
		}

		fixed4 frag(v2f i, fixed facing : VFACE) : SV_Target
		{
			fixed4 col = _Tint;
			
			//边框线  有待优化 理应不应使用if块
			if (((i.uv.x < _Width || i.uv.x > 1 - _Width) && (i.uv.y < 1 - _Length || i.uv.y > _Length)) || ((i.uv.y < _Width || i.uv.y > 1 - _Width) && (i.uv.x < 1 - _Length || i.uv.x > _Length)))
			{
				col += _CubeColor;
			}
			//液位线
			float4 lineHight = step(i.warningLine,0.5) - step(i.warningLine, (0.5 -_ScaleWidth));
			float4 lineColored = lineHight * (_ScaleColor*0.9 );

			//烟雾效果
			UNITY_APPLY_FOG(i.fogCoord, col);

			//边缘高光
			float dotProduct = 1 - pow(dot(i.normal, i.viewDir), _RimPower);
			float4 RimResult = smoothstep(0.5, 1.0, dotProduct);
			RimResult *= _RimColor;
			
			// 液体表面
			float4 foam = step(i.fillEdge, 0.5) - step(i.fillEdge, (0.5 - _Rim));
			float4 foamColored = foam * (_FoamColor * 0.9);
			// 液体内部
			float4 result = step(i.fillEdge, 0.5) - foam;
			float4 resultColored = result * col;
			// 液体融合
			float4 finalResult =  foamColored + col+ lineColored;
			finalResult.rgb += RimResult;
			
			// color of backfaces/ top
			float4 topColor = _TopColor * (foam + result);
			//VFACE returns positive for front facing, negative for backfacing
			return facing > 0 ? finalResult : topColor;
			}
			 ENDCG
		}
	}
}

c#:

using UnityEngine;

namespace DataVisualization
{
    public class Wobble : MonoBehaviour
    {
        Renderer rend;
        Vector3 lastPos;
        Vector3 velocity;
        Vector3 lastRot;
        Vector3 angularVelocity;
        public float MaxWobble = 0.03f;
        public float WobbleSpeed = 1f;
        public float Recovery = 1f;
        float wobbleAmountY;
        float wobbleAmountZ;
        float wobbleAmountToAddY;
        float wobbleAmountToAddZ;
        float pulse;
        float time = 0.5f;

        // Use this for initialization
        void Start()
        {
            rend = GetComponent();
        }
        private void Update()
        {
            time += Time.deltaTime;
          
           
            // decrease wobble over time
            wobbleAmountToAddY = Mathf.Lerp(wobbleAmountToAddY, 0, Time.deltaTime * (Recovery));
            wobbleAmountToAddZ = Mathf.Lerp(wobbleAmountToAddZ, 0, Time.deltaTime * (Recovery));

            // make a sine wave of the decreasing wobble
            pulse = 2 * Mathf.PI * WobbleSpeed;
            wobbleAmountY = wobbleAmountToAddY * Mathf.Sin(pulse * time);
            wobbleAmountZ = wobbleAmountToAddZ * Mathf.Sin(pulse * time) * 0.1f;
            // send it to the shader
            rend.material.SetFloat("_WobbleX", wobbleAmountY);
            rend.material.SetFloat("_WobbleZ", wobbleAmountZ);

            // velocity
            angularVelocity = transform.rotation.eulerAngles - lastRot;
            if (Input.GetMouseButton(1))
            {
                // add clamped velocity to wobble
                wobbleAmountToAddY += Mathf.Clamp((Input.GetAxis("Mouse X") + (angularVelocity.z * 0.2f)) * MaxWobble, -MaxWobble, MaxWobble);
                wobbleAmountToAddZ += Mathf.Clamp((Input.GetAxis("Mouse Y") + (angularVelocity.x * 0.2f)) * MaxWobble, -MaxWobble, MaxWobble);
            }
            // keep last position
            lastRot = transform.rotation.eulerAngles;
        }



    }
}

你可能感兴趣的:(个人,unity,游戏引擎,shader)