Add cheat time dilation shader OSD
This commit is contained in:
225
external/reshade/shaders/TimeDilationOSD.fx
vendored
Normal file
225
external/reshade/shaders/TimeDilationOSD.fx
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user