#include "ReShade.fxh" texture FontTexture < source = "font.png"; > { Width = 512; Height = 512; Format = RGBA8; }; sampler FontSampler { Texture = FontTexture; }; uniform bool TD_Show = false; uniform bool TD_Enabled = false; uniform float TD_World = 1.0; uniform float TD_AI = 1.0; // Define caracters for "Time Dilation ON" (size 32) static const int ON_LENGTH = 17; static float ON_CHARS[32] = { 84 - 32, 105 - 32, 109 - 32, 101 - 32, // T, i, m, e 32 - 32, 100 - 32, 105 - 32, 108 - 32, // , d, i, l 97 - 32, 116 - 32, 105 - 32, 111 - 32, // a, t, i, o 110 - 32, 32 - 32, 79 - 32, 78 - 32, // n, , O, N 32 - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // ' ' + filling }; // Define caracters for "Time Dilation OFF" (size 32) static const int OFF_LENGTH = 17; static float OFF_CHARS[32] = { 84 - 32, 105 - 32, 109 - 32, 101 - 32, // T, i, m, e 32 - 32, 100 - 32, 105 - 32, 108 - 32, // , d, i, l 97 - 32, 116 - 32, 105 - 32, 111 - 32, // a, t, i, o 110 - 32, 32 - 32, 79 - 32, 70 - 32, // n, , O, F 70 - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F + filling }; static const int WORLD_LEN = 7; static float WORLD_CHARS[32] = { 87 - 32,111 - 32,114 - 32, 108 - 32, // W, o, r, l 100 - 32, 58 - 32, 32 - 32, 0, // d, :, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const int AI_LEN = 5; static float AI_CHARS[32] = { 32 - 32, 65 - 32, 73 - 32, 58 - 32, // ' ', A, I, : 32 - 32, 0, 0, 0, // ' ' + filling 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Fonction SDF pour le rectangle (inchangée) float sdRoundRect(float2 p, float2 b, float r) { float2 q = abs(p) - b + r; return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r; } // Draw a character float4 DrawChar(float2 uv, float2 pos, float2 charSize, float charIndex) { float2 texSize = float2(14.0, 7.0); float2 fontUV = float2(charIndex % texSize.x, floor(charIndex / texSize.x)) / texSize; float2 fontUVSize = 1.0 / texSize; float2 localUV = (uv - pos) / charSize; float2 finalFontUV = fontUV + fontUVSize * localUV; return tex2D(FontSampler, finalFontUV); } // Draw a characters array float4 DrawText(float2 uv, float2 startPos, float2 charSize, float chars[32], int length) { float4 col = float4(0, 0, 0, 0); [unroll] for (int i = 0; i < 32; i++) { if (i >= length) break; float2 charPos = startPos + float2(i * charSize.x, 0.0); // test si le pixel est dans le quad du caractère if (uv.x >= charPos.x && uv.x < charPos.x + charSize.x && uv.y >= charPos.y && uv.y < charPos.y + charSize.y) { float4 glyph = DrawChar(uv, charPos, charSize, chars[i]); // proper alpha-over col.rgb = lerp(col.rgb, glyph.rgb, glyph.a); col.a = max(col.a, glyph.a); } } return col; } float4 DrawFloat(float2 uv, float2 startPos, float2 charSize, float value) { float4 col = float4(0,0,0,0); float v = abs(value); int iv = (int)(v * 100.0 + 0.5); int i0 = iv / 100; int i1 = (iv / 10) % 10; int i2 = iv % 10; float chars[4]; chars[0] = i0 + 16; // '0' chars[1] = 14; // '.' chars[2] = i1 + 16; chars[3] = i2 + 16; [unroll] for (int i = 0; i < 4; i++) { float2 pos = startPos + float2(i * charSize.x, 0); if (uv.x >= pos.x && uv.x < pos.x + charSize.x && uv.y >= pos.y && uv.y < pos.y + charSize.y) { float4 g = DrawChar(uv, pos, charSize, chars[i]); col.rgb = lerp(col.rgb, g.rgb, g.a); col.a = max(col.a, g.a); } } return col; } void AlphaBlend(inout float4 dst, float4 src) { dst.rgb = lerp(dst.rgb, src.rgb, src.a); dst.a = max(dst.a, src.a); } float4 PS_OSD(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target { float4 col = tex2D(ReShade::BackBuffer, uv); if (TD_Show) { // ---- Size & position of the frame ---- float margin_top = 20.0; // ---- aspect ratio correction for SDF ---- float2 screen_size = float2(BUFFER_WIDTH, BUFFER_HEIGHT); float aspect = screen_size.x / screen_size.y; // Pure UV Center (for text) float2 center_uv = float2(0.5, margin_top / screen_size.y + 0.01); float2 p = uv - center_uv; p.x *= aspect; // Compute total text length to center it horizontally float totalLen = (TD_Enabled ? ON_LENGTH + WORLD_LEN + 4 + AI_LEN + 4 : OFF_LENGTH) ; // 4 = 3 chiffres + '.' float2 charSize = float2(0.003, 0.02); // width, height float charAdvance = charSize.x; // SDF center (for the frame) float textWidthUV = totalLen * charAdvance; float padding = charAdvance * 1.0; float2 size_uv = float2((textWidthUV * 0.5 + padding) * aspect, 20.0 / screen_size.y); // ---- Thickness and radius in pixels ---- float thickness_px = 1.0; float thickness = thickness_px * ReShade::PixelSize.y; float radius_px = 2.0; float radius = radius_px * ReShade::PixelSize.y; float d = sdRoundRect(p, size_uv, radius); // ---- Border drawing ---- if (abs(d) < thickness) { float3 border = TD_Enabled ? float3(0.3, 1.0, 0.3) : float3(1.0, 0.3, 0.3); // green ON , red OFF col.rgb = lerp(col.rgb, border, 0.85); } // ---- Draw the text (ON/OFF + World + AI) ---- float2 pen = center_uv; pen.x -= totalLen * charAdvance * 0.5; // horizontal centering pen.y -= charSize.y * 0.5; // vertical centering float4 t0, t1, wv, t2, av; float4 textCol = float4(0,0,0,0); if (TD_Enabled) { // "Time Dilation ON" t0 = DrawText(uv, pen, charSize, ON_CHARS, ON_LENGTH); pen.x += charAdvance * ON_LENGTH; // "World: " t1 = DrawText(uv, pen, charSize, WORLD_CHARS, WORLD_LEN); pen.x += charAdvance * WORLD_LEN; // World value wv = DrawFloat(uv, pen, charSize, TD_World); pen.x += charAdvance * 4; // "AI: " t2 = DrawText(uv, pen, charSize, AI_CHARS, AI_LEN); pen.x += charAdvance * AI_LEN; // AI value av = DrawFloat(uv, pen, charSize, TD_AI); } else // "Time Dilation OFF" t0 = DrawText(uv, pen, charSize, OFF_CHARS, OFF_LENGTH); // ---- Combine all glyphs ---- float4 combined = t0; AlphaBlend(combined, t1); AlphaBlend(combined, wv); AlphaBlend(combined, t2); AlphaBlend(combined, av); float3 textColor = TD_Enabled ? float3(0.3,1.0,0.3) : float3(1.0,0.3,0.3); combined.rgb *= textColor; // ---- final blend ---- col.rgb = lerp(col.rgb, combined.rgb, combined.a); } return col; } technique TimeDilationOSD { pass { VertexShader = PostProcessVS; PixelShader = PS_OSD; } }