// ===================================================== // UI Shader pour CosmicCore // Set 0 : Transform (UBO - par objet) // Set 1 : Material (UBO + Texture) // Set 2 : Projection (UBO - global) // ===================================================== // ─── Inputs ──────────────────────────────────────────── struct VSInput { [[vk::location(0)]] float2 inPosition; [[vk::location(1)]] float2 inUV; [[vk::location(2)]] float4 inColor; }; // ─── Outputs ─────────────────────────────────────────── struct VSOutput { float4 pos : SV_Position; float2 uv : TEXCOORD0; float4 color : COLOR; }; // ─── Set 0 : Transform (UBO par objet) ───────────────── struct TransformUBO { float4x4 model; float2 size; float zOrder; float padding; }; [[vk::binding(0, 0)]] ConstantBuffer transform; [[vk::binding(1, 1)]] Sampler2D uiTexture; // ─── Set 2 : Projection (UBO global) ────────────────── [[vk::binding(0, 2)]] ConstantBuffer projection; // ─── Vertex Shader ────────────────────────────────────── [shader("vertex")] VSOutput vertMain(VSInput input) { VSOutput output; // Transforme local vers monde float4 worldPos = mul(transform.model, float4(input.inPosition, 0.0, 1.0)); // Applique la projection output.pos = mul(projection, worldPos); output.uv = input.inUV; output.color = input.inColor; return output; } float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } [shader("fragment")] float4 fragMain(VSOutput vertIn) : SV_Target { float3 msd = uiTexture.Sample(vertIn.uv).rgb; float sigDist = median(msd.r, msd.g, msd.b) - 0.5; // largeur du dégradé en pixels écran (anti-aliasing correct) float2 unitRange = float2(1.0, 1.0) / float2(212.0, 212.0); float2 screenTexSize = 1.0 / fwidth(vertIn.uv); float screenPxRange = max(0.5 * dot(unitRange, screenTexSize), 1.0); float opacity = clamp(screenPxRange * sigDist + 0.5, 0.0, 1.0); return float4(vertIn.color.rgb, vertIn.color.a * opacity); }