Files
Emberwild/Assets/GAME/Shaders/UI/UIGlass.shader
2026-07-07 16:43:51 +02:00

199 lines
6.8 KiB
Plaintext

Shader "GAME/UIGlass"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[Header(Glass Body)][Space]
_GlassColor ("Glass Color", Color) = (0.8, 0.9, 1.0, 1)
_Opacity ("Opacity", Range(0,1)) = 0.25
[Header(Shape rounded glass panel)][Space]
_Corner ("Corner Radius", Range(0,1)) = 0.35
_Aspect ("Aspect (set to Width divided by Height)", Float) = 1
[Header(Bevel fake 3D raised edge)][Space]
_EdgeThickness ("Edge Thickness", Range(0.001,0.6)) = 0.15
_EdgeLight ("Edge Light (lit side)", Range(0,2)) = 0.7
_EdgeShade ("Edge Shade (dark side)", Range(0,2)) = 0.35
_LightAngle ("Light Angle (degrees)", Range(0,360)) = 135
[Header(Top Sheen)][Space]
_Sheen ("Sheen Strength", Range(0,2)) = 0.3
_SheenSize ("Sheen Size", Range(0,1)) = 0.5
[Header(Gloss Streak diagonal reflection)][Space]
_StreakStrength ("Streak Strength", Range(0,2)) = 0.35
_StreakPos ("Streak Position", Range(0,2)) = 0.7
_StreakWidth ("Streak Width", Range(0.01,1)) = 0.15
// --- Standard UI machinery (masking, stencil, alpha clip). ---
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "UIGlass"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPos : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
float4 _ClipRect;
fixed4 _GlassColor;
half _Opacity;
half _Corner;
half _Aspect;
half _EdgeThickness;
half _EdgeLight;
half _EdgeShade;
half _LightAngle;
half _Sheen;
half _SheenSize;
half _StreakStrength;
half _StreakPos;
half _StreakWidth;
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPos = v.vertex;
OUT.vertex = UnityObjectToClipPos(v.vertex);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
// Bright band centred on a diagonal, used for the gloss streak.
half DiagonalBand(float2 uv, half pos, half width)
{
half d = abs((uv.x + uv.y) - pos);
return 1.0 - smoothstep(0.0, width, d);
}
fixed4 frag(v2f IN) : SV_Target
{
float2 uv = IN.texcoord;
// Work in centred, aspect-corrected space so corners stay round on any
// rectangle. Height spans -1..1; width spans -_Aspect.._Aspect.
float2 p = (uv - 0.5) * 2.0;
p.x *= _Aspect;
float2 halfSize = float2(_Aspect, 1.0);
// Signed distance to a rounded rectangle: negative inside, zero at the edge.
float2 q = abs(p) - (halfSize - _Corner);
float dist = length(max(q, 0.0)) - _Corner;
// Antialiased panel silhouette from that distance field.
half aa = fwidth(dist);
half shape = 1.0 - smoothstep(-aa, aa, dist);
// How deep this pixel sits inside the border, 0 at the edge.
half inside = -dist;
half edge = 1.0 - smoothstep(0.0, _EdgeThickness, inside);
// Outward edge direction, so the bevel can be lit from one side to fake
// a raised 3D pane: corners use the diagonal, straight edges use the axis.
float2 outward;
float2 qc = max(q, 0.0);
if (qc.x + qc.y > 1e-4)
outward = normalize(qc * sign(p));
else
outward = (q.x > q.y) ? float2(sign(p.x), 0) : float2(0, sign(p.y));
float a = radians(_LightAngle);
float2 lightDir = float2(cos(a), sin(a));
half facing = dot(outward, lightDir);
half bevelLight = edge * saturate(facing) * _EdgeLight;
half bevelShade = edge * saturate(-facing) * _EdgeShade;
// Top sheen and a single diagonal gloss streak across the pane.
half sheen = smoothstep(1.0 - _SheenSize, 1.0, uv.y) * _Sheen;
half streak = DiagonalBand(uv, _StreakPos, _StreakWidth) * _StreakStrength;
half highlight = sheen + streak + bevelLight;
fixed3 rgb = saturate(_GlassColor.rgb + highlight - bevelShade);
half alpha = saturate(_Opacity * _GlassColor.a + highlight);
fixed4 col = fixed4(rgb, alpha * shape) * IN.color;
#ifdef UNITY_UI_CLIP_RECT
col.a *= UnityGet2DClipping(IN.worldPos.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip(col.a - 0.001);
#endif
return col;
}
ENDCG
}
}
}