// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' Shader "MesshingAround/Liquid_Effect (Built-in)" { Properties { [Header(Surface Inputs)] [Header(Main Color)] [NoScaleOffset]_LUTTex ("GradientTexture", 2D) = "white" {} [HDR]_TopColor ("Top Color", Color) = (0, 0.6946828, 0.764151, 1) [HDR]_Tint ("Tint", Color) = (1,1,1,1) [NoScaleOffset]_MainTex ("Main Texture", 2D) = "white" {} _GradientIndex ("GradientIndex", Float) = 73.9 _GradientCount ("GradientCount", Float) = 110 [Header(Foam Edge)] _LineSmooth ("Foam Smoothness", Range(0,0.3)) = 0.026 [HDR]_FoamColor ("Foam/EdgeColor", Color) = (1,1,1,1) _Line ("FoamWidth", Range(0,0.3)) = 0 [Header(Sine)] _Freq ("Frequency", Range(0,25)) = 0 _Amplitude ("Amplitude", Range(0,0.2)) = 0 [Header(Rim)] _RimPower ("Rim Power", Range(0,5)) = 2.44 [HDR]_RimColor ("Rim Color", Color) = (0.693879, 1, 0.3254717, 1) // Hidden properties set by script - DO NOT REMOVE [HideInInspector]_WobbleX ("Wobble X", Float) = 0 [HideInInspector]_WobbleZ ("Wobble Z", Float) = 0 [HideInInspector]_FillAmount ("Fill Amount", Vector) = (0,0,0,0) [HideInInspector][NoScaleOffset]_GrayscaleTex ("GrayScaleTexture", 2D) = "white" {} } SubShader { Tags {"Queue"="Geometry" "RenderType"="Opaque" "DisableBatching" = "True" } Pass { Zwrite On Cull Off AlphaToMask On CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fog #pragma multi_compile_instancing #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; float3 viewDir : COLOR; float3 normal : COLOR2; float3 fillPosition : TEXCOORD2; float3 worldNormal : TEXCOORD3; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _LUTTex; sampler2D _GrayscaleTex; // Non-instanced properties (fallback when instancing is disabled) #if !defined(UNITY_INSTANCING_BUFFER_START) float _GradientIndex; float _GradientCount; float3 _FillAmount; float _WobbleX; float _WobbleZ; float4 _TopColor; float4 _RimColor; float4 _FoamColor; float4 _Tint; float _Line; float _RimPower; float _LineSmooth; float _Freq; float _Amplitude; #endif // GPU Instancing: Properties that can vary per instance UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(float, _GradientIndex) UNITY_DEFINE_INSTANCED_PROP(float, _GradientCount) UNITY_DEFINE_INSTANCED_PROP(float3, _FillAmount) UNITY_DEFINE_INSTANCED_PROP(float, _WobbleX) UNITY_DEFINE_INSTANCED_PROP(float, _WobbleZ) UNITY_DEFINE_INSTANCED_PROP(float4, _TopColor) UNITY_DEFINE_INSTANCED_PROP(float4, _RimColor) UNITY_DEFINE_INSTANCED_PROP(float4, _FoamColor) UNITY_DEFINE_INSTANCED_PROP(float4, _Tint) UNITY_DEFINE_INSTANCED_PROP(float, _Line) UNITY_DEFINE_INSTANCED_PROP(float, _RimPower) UNITY_DEFINE_INSTANCED_PROP(float, _LineSmooth) UNITY_DEFINE_INSTANCED_PROP(float, _Freq) UNITY_DEFINE_INSTANCED_PROP(float, _Amplitude) UNITY_INSTANCING_BUFFER_END(Props) float3 Unity_RotateAboutAxis_Degrees(float3 In, float3 Axis, float Rotation) { Rotation = radians(Rotation); float s = sin(Rotation); float c = cos(Rotation); float one_minus_c = 1.0 - c; Axis = normalize(Axis); float3x3 rot_mat = { one_minus_c * Axis.x * Axis.x + c, one_minus_c * Axis.x * Axis.y - Axis.z * s, one_minus_c * Axis.z * Axis.x + Axis.y * s, one_minus_c * Axis.x * Axis.y + Axis.z * s, one_minus_c * Axis.y * Axis.y + c, one_minus_c * Axis.y * Axis.z - Axis.x * s, one_minus_c * Axis.z * Axis.x - Axis.y * s, one_minus_c * Axis.y * Axis.z + Axis.x * s, one_minus_c * Axis.z * Axis.z + c }; float3 Out = mul(rot_mat, In); return Out; } float4 SampleLUTFromGrayscale(float2 uv, float gradientIndex, float gradientCount) { float grayscaleValue = tex2D(_GrayscaleTex, uv).r; float v = (round(gradientIndex) + 0.5) / gradientCount; float2 lutUV = float2(grayscaleValue, v); return tex2D(_LUTTex, lutUV); } v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); // Access instanced properties float wobbleX = UNITY_ACCESS_INSTANCED_PROP(Props, _WobbleX); float wobbleZ = UNITY_ACCESS_INSTANCED_PROP(Props, _WobbleZ); float3 fillAmount = UNITY_ACCESS_INSTANCED_PROP(Props, _FillAmount); // Calculate world position of vertex float3 worldPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)).xyz; // Get object pivot position in world space (same as SHADERGRAPH_OBJECT_POSITION in URP) float3 objectPosition = unity_ObjectToWorld._m03_m13_m23; // Calculate position relative to object pivot float3 worldPosRelative = worldPos - objectPosition; // Apply fill amount offset float3 worldPosOffset = worldPosRelative - fillAmount; // Apply wobble rotations to the offset float3 worldPosX = Unity_RotateAboutAxis_Degrees(worldPosOffset, float3(0,0,1), 90); float3 worldPosZ = Unity_RotateAboutAxis_Degrees(worldPosOffset, float3(1,0,0), 90); // Combine wobble effects float3 wobbleOffset = (worldPosX * wobbleX) + (worldPosZ * wobbleZ); // Final fill position: offset + wobble o.fillPosition = worldPosOffset + wobbleOffset; o.viewDir = normalize(WorldSpaceViewDir(v.vertex)); o.normal = v.normal; o.worldNormal = normalize(mul((float3x3)unity_ObjectToWorld, v.normal)); return o; } fixed4 frag (v2f i, fixed facing : VFACE) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); bool isFrontFace = facing > 0; // Access instanced properties float wobbleX = UNITY_ACCESS_INSTANCED_PROP(Props, _WobbleX); float wobbleZ = UNITY_ACCESS_INSTANCED_PROP(Props, _WobbleZ); float amplitude = UNITY_ACCESS_INSTANCED_PROP(Props, _Amplitude); float freq = UNITY_ACCESS_INSTANCED_PROP(Props, _Freq); float gradientIndex = UNITY_ACCESS_INSTANCED_PROP(Props, _GradientIndex); float gradientCount = UNITY_ACCESS_INSTANCED_PROP(Props, _GradientCount); float4 topColor = UNITY_ACCESS_INSTANCED_PROP(Props, _TopColor); float4 tint = UNITY_ACCESS_INSTANCED_PROP(Props, _Tint); float4 foamColor = UNITY_ACCESS_INSTANCED_PROP(Props, _FoamColor); float4 rimColor = UNITY_ACCESS_INSTANCED_PROP(Props, _RimColor); float lineWidth = UNITY_ACCESS_INSTANCED_PROP(Props, _Line); float lineSmooth = UNITY_ACCESS_INSTANCED_PROP(Props, _LineSmooth); float rimPower = UNITY_ACCESS_INSTANCED_PROP(Props, _RimPower); // Wobble intensity calculation float wobbleIntensity = abs(wobbleX) + abs(wobbleZ); // Sine wave wobble effect float wobble = sin((i.fillPosition.x * freq) + (i.fillPosition.z * freq) + (_Time.y)) * (amplitude * wobbleIntensity); // Moving fill position with wobble float movingfillPosition = i.fillPosition.y + wobble; // Sample textures and apply LUT with URP triple multiplication fixed4 mainTex = tex2D(_MainTex, movingfillPosition.xx); fixed4 lutColor = SampleLUTFromGrayscale(i.uv, gradientIndex, gradientCount); // URP color system: MainTex * LUT * Tint fixed4 col = mainTex * lutColor * tint; UNITY_APPLY_FOG(i.fogCoord, col); // Cutoff logic - step(movingfillPosition, 0.5) float cutoffTop = step(movingfillPosition, 0.5); // Foam calculation float foamEdge1 = 0.5 - lineWidth - lineSmooth; float foamEdge2 = 0.5 - lineWidth; float foamSmooth = smoothstep(foamEdge1, foamEdge2, movingfillPosition); float mainFoam = foamSmooth * cutoffTop; // FRONT FACES if (isFrontFace) { // Apply foam to front faces float4 foamColored = mainFoam * foamColor; float liquidMask = (1.0 - mainFoam); float4 liquidColored = col * liquidMask; // Rim light calculation (URP system) float4 RimResult = float4(0,0,0,0); if (rimPower > 0.001) { // URP: inverts power (5 - rimPower) for fresnel, then multiplies by original rimPower float invertedPower = 5.0 - rimPower; float fresnel = pow(1 - saturate(dot(i.worldNormal, i.viewDir)), invertedPower); RimResult = fresnel * rimColor * rimPower; } float4 finalResult = liquidColored + foamColored; finalResult.rgb += RimResult.rgb; // Clip pixels above the fill line clip(cutoffTop - 0.01); return finalResult; } // BACK FACES - No foam on backfaces else { clip(cutoffTop - 0.01); // Solid top color on backfaces return topColor; } } ENDCG } } }