Implement text skew, grayscale image, and marquee fade.

Marquee fade currently does not work with text shadow as the repeatedly drawn font accumulates its alpha.
This commit is contained in:
Skyth
2024-12-09 20:31:44 +03:00
parent 70268e41b5
commit 8ca852583b
8 changed files with 110 additions and 23 deletions
+13 -2
View File
@@ -4,6 +4,9 @@
#define IMGUI_SHADER_MODIFIER_SCANLINE 1
#define IMGUI_SHADER_MODIFIER_CHECKERBOARD 2
#define IMGUI_SHADER_MODIFIER_SCANLINE_BUTTON 3
#define IMGUI_SHADER_MODIFIER_TEXT_SKEW 4
#define IMGUI_SHADER_MODIFIER_MARQUEE_FADE 5
#define IMGUI_SHADER_MODIFIER_GRAYSCALE 6
#ifdef __cplusplus
@@ -13,14 +16,16 @@ enum class ImGuiCallback : int32_t
SetShaderModifier = -2,
SetOrigin = -3,
SetScale = -4,
SetMarqueeFade = -5,
// -8 is ImDrawCallback_ResetRenderState, don't use!
};
union ImGuiCallbackData
{
struct
{
float gradientMin[2];
float gradientMax[2];
float boundsMin[2];
float boundsMax[2];
uint32_t gradientTop;
uint32_t gradientBottom;
} setGradient;
@@ -39,6 +44,12 @@ union ImGuiCallbackData
{
float scale[2];
} setScale;
struct
{
float boundsMin[2];
float boundsMax[2];
} setMarqueeFade;
};
extern ImGuiCallbackData* AddImGuiCallback(ImGuiCallback callback);
@@ -1,9 +1,11 @@
#pragma once
#include "../imgui_common.h"
struct PushConstants
{
float2 GradientMin;
float2 GradientMax;
float2 BoundsMin;
float2 BoundsMax;
uint GradientTop;
uint GradientBottom;
uint ShaderModifier;
+14 -4
View File
@@ -1,5 +1,4 @@
#include "imgui_common.hlsli"
#include "../imgui_common.h"
float4 DecodeColor(uint color)
{
@@ -82,11 +81,22 @@ float4 main(in Interpolators interpolators) : SV_Target
if (g_PushConstants.Texture2DDescriptorIndex != 0)
color *= g_Texture2DDescriptorHeap[g_PushConstants.Texture2DDescriptorIndex].Sample(g_SamplerDescriptorHeap[0], interpolators.UV);
if (any(g_PushConstants.GradientMin != g_PushConstants.GradientMax))
if (g_PushConstants.ShaderModifier == IMGUI_SHADER_MODIFIER_MARQUEE_FADE)
{
float2 factor = saturate((interpolators.Position.xy - g_PushConstants.GradientMin) / (g_PushConstants.GradientMax - g_PushConstants.GradientMin));
color *= lerp(DecodeColor(g_PushConstants.GradientTop), DecodeColor(g_PushConstants.GradientBottom), factor.y);
float minAlpha = saturate((interpolators.Position.x - g_PushConstants.BoundsMin.x) / g_PushConstants.Scale.x);
float maxAlpha = saturate((g_PushConstants.BoundsMax.x - interpolators.Position.x) / g_PushConstants.Scale.x);
color.a *= minAlpha;
color.a *= maxAlpha;
}
else if (any(g_PushConstants.BoundsMin != g_PushConstants.BoundsMax))
{
float2 factor = saturate((interpolators.Position.xy - g_PushConstants.BoundsMin) / (g_PushConstants.BoundsMax - g_PushConstants.BoundsMin));
color *= lerp(DecodeColor(g_PushConstants.GradientTop), DecodeColor(g_PushConstants.GradientBottom), smoothstep(0.0, 1.0, factor.y));
}
if (g_PushConstants.ShaderModifier == IMGUI_SHADER_MODIFIER_GRAYSCALE)
color.rgb = dot(color.rgb, float3(0.2126, 0.7152, 0.0722));
return color;
}
+12 -3
View File
@@ -1,9 +1,18 @@
#include "imgui_common.hlsli"
void main(in float2 position : POSITION, in float2 uv : TEXCOORD, in float4 color : COLOR, out Interpolators interpolators)
{
float2 correctedPosition = g_PushConstants.Origin + (position - g_PushConstants.Origin) * g_PushConstants.Scale;
interpolators.Position = float4(correctedPosition * g_PushConstants.InverseDisplaySize * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
{
if (g_PushConstants.ShaderModifier == IMGUI_SHADER_MODIFIER_TEXT_SKEW)
{
if (position.y < g_PushConstants.Origin.y)
position.x += g_PushConstants.Scale.x;
}
else if (g_PushConstants.ShaderModifier != IMGUI_SHADER_MODIFIER_MARQUEE_FADE)
{
position.xy = g_PushConstants.Origin + (position.xy - g_PushConstants.Origin) * g_PushConstants.Scale;
}
interpolators.Position = float4(position.xy * g_PushConstants.InverseDisplaySize * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
interpolators.UV = uv;
interpolators.Color = color;
}
+6 -3
View File
@@ -1101,8 +1101,8 @@ static constexpr uint32_t PLACEMENT_ALIGNMENT = 0x200;
struct ImGuiPushConstants
{
ImVec2 gradientMin{};
ImVec2 gradientMax{};
ImVec2 boundsMin{};
ImVec2 boundsMax{};
ImU32 gradientTop{};
ImU32 gradientBottom{};
uint32_t shaderModifier{};
@@ -1921,7 +1921,7 @@ static void ProcDrawImGui(const RenderCommand& cmd)
switch (static_cast<ImGuiCallback>(reinterpret_cast<size_t>(drawCmd.UserCallback)))
{
case ImGuiCallback::SetGradient:
commandList->setGraphicsPushConstants(0, &callbackData->setGradient, offsetof(ImGuiPushConstants, gradientMin), sizeof(callbackData->setGradient));
commandList->setGraphicsPushConstants(0, &callbackData->setGradient, offsetof(ImGuiPushConstants, boundsMin), sizeof(callbackData->setGradient));
break;
case ImGuiCallback::SetShaderModifier:
commandList->setGraphicsPushConstants(0, &callbackData->setShaderModifier, offsetof(ImGuiPushConstants, shaderModifier), sizeof(callbackData->setShaderModifier));
@@ -1931,6 +1931,9 @@ static void ProcDrawImGui(const RenderCommand& cmd)
break;
case ImGuiCallback::SetScale:
commandList->setGraphicsPushConstants(0, &callbackData->setScale, offsetof(ImGuiPushConstants, scale), sizeof(callbackData->setScale));
break;
case ImGuiCallback::SetMarqueeFade:
commandList->setGraphicsPushConstants(0, &callbackData->setScale, offsetof(ImGuiPushConstants, boundsMin), sizeof(callbackData->setMarqueeFade));
break;
}
}