Files
Test/Assets/ColbyO/VNTG/Editor/Shaders/PalettePreviewGenerator.shader
2026-11-01 23:39:55 +02:00

151 lines
5.2 KiB
GLSL

Shader "Hidden/ColbyO/VNTG/Editor/PalettePreviewGenerator"
{
Properties
{
_WheelRadius ("Wheel Radius", Float) = 35.8
_OutlineSize ("Outline Size", Float) = 2.5
_CardFoldSize ("Card Fold Size", Float) = 28.16
_CardCornerRadius ("Card Corner Radius", Float) = 7.68
_OutlineColor ("Outline Color", Color) = (0.1, 0.1, 0.1, 1.0)
_FileColor ("File Color", Color) = (0.2, 0.2, 0.2, 1.0)
_BackgroundColor ("Background Color", Color) = (0.0, 0.0, 0.0, 0.0)
}
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType"="Opaque" }
LOD 100
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
};
float _Width;
float _Height;
float _WheelRadius;
float _OutlineSize;
float2 _CardHalfSize;
float _CardCornerRadius;
float _CardFoldSize;
float4 _OutlineColor;
float4 _FileColor;
float4 _BackgroundColor;
int _PaletteCount;
float4 _PaletteColors[256];
Varyings vert (Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.uv;
return output;
}
float ChamferedRectSDF(float2 p, float2 size, float radius, float cutSize)
{
float2 d = max(abs(p) - size + radius, 0.0);
float boxSDF = length(d) - radius;
float cutPlane = (p.x - (size.x - cutSize)) + (p.y - (size.y - cutSize)) - cutSize;
return max(boxSDF, cutPlane);
}
float GetAngleAt(float2 delta)
{
float angle = atan2(delta.y, delta.x) * 57.2957795;
if (angle < 0.0) angle += 360.0;
return angle;
}
float4 GetSliceColor(float2 delta, float distFromCenter)
{
if (_PaletteCount <= 0) return _FileColor;
if (_PaletteCount == 1) return _PaletteColors[0];
float angle = GetAngleAt(delta);
float sliceSize = 360.0 / (float)_PaletteCount;
float angularPixelWidth = (1.0 / (distFromCenter + 0.001)) * 57.2957795;
float remainder = fmod(angle, sliceSize);
float distToEdge = min(remainder, sliceSize - remainder);
int currentIndex = min((int)floor(angle / sliceSize), _PaletteCount - 1);
if (distToEdge < angularPixelWidth * 0.5)
{
float t = clamp((distToEdge + (angularPixelWidth * 0.5)) / angularPixelWidth, 0.0, 1.0);
int neighborIndex = (remainder < sliceSize * 0.5)
? (currentIndex - 1 + _PaletteCount) % _PaletteCount
: (currentIndex + 1) % _PaletteCount;
return lerp(_PaletteColors[neighborIndex], _PaletteColors[currentIndex], t);
}
return _PaletteColors[currentIndex];
}
float4 SamplePreviewColorWheel(float2 delta, float distFromCenter)
{
float aaWidth = 1.0;
float innerEdge = _WheelRadius;
float outerEdge = _WheelRadius + _OutlineSize;
if (distFromCenter >= outerEdge + aaWidth) return _FileColor;
float4 wheelColor = GetSliceColor(delta, distFromCenter);
float toOutline = clamp((distFromCenter - (innerEdge - aaWidth * 0.5)) / aaWidth, 0.0, 1.0);
float toBackground = clamp((distFromCenter - (outerEdge - aaWidth * 0.5)) / aaWidth, 0.0, 1.0);
float4 mixedColor = lerp(wheelColor, _OutlineColor, toOutline);
return lerp(mixedColor, _FileColor, toBackground);
}
float4 frag (Varyings input) : SV_Target
{
float2 pixelPos = input.uv * float2(_Width, _Height);
float2 center = float2(_Width, _Height) * 0.5;
float2 delta = pixelPos - center;
float distFromCenter = length(delta);
float sdf = ChamferedRectSDF(delta, _CardHalfSize, _CardCornerRadius, _CardFoldSize);
if (sdf <= 0.0)
{
if (sdf > -_OutlineSize)
{
return _OutlineColor;
}
else
{
return SamplePreviewColorWheel(delta, distFromCenter);
}
}
return _BackgroundColor;
}
ENDHLSL
}
}
}