Files
PotionMaker/Assets/MesshingAround/StylizedPotionsPack/Shaders/BuiltIn/Liquid_Effect.shader
2026-03-27 16:34:08 +09:00

272 lines
12 KiB
GLSL

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