Compare commits

...

8 commits

Author SHA1 Message Date
Mike Griese d5b59a09e2 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl-2021/more-shader-variables 2021-07-27 08:36:55 -05:00
Mike Griese 0c4173b238 This is a much better rainbow function 2021-07-27 08:29:01 -05:00
Mike Griese d5d8576d1b pass the glyph size to the shader too 2021-07-26 15:58:08 -05:00
Mike Griese 54db2c2c3b allow shaders to be reloaded with a pair of toggleShaderEffects actions 2021-07-26 15:38:45 -05:00
Mike Griese 3a8c8830e8 notes 2021-07-26 15:33:17 -05:00
Mike Griese eea3a9bebe Revert "This was a dead end"
This reverts commit 4695dd486c.
2021-07-26 15:17:15 -05:00
Mike Griese 4695dd486c This was a dead end 2021-07-26 15:16:09 -05:00
Mike Griese 1f906aba84 Add a few more members to the shaders. Only update the main shader settings once per frame 2021-07-26 14:31:48 -05:00
3 changed files with 83 additions and 5 deletions

View file

@ -14,8 +14,24 @@ cbuffer PixelShaderSettings {
float2 Resolution;
// Background color as rgba
float4 Background;
float2 GlyphSize;
float2 CursorPosition;
float2 BufferSize;
};
float3 HUEtoRGB(float H)
{
float R = abs(H * 6 - 3) - 1;
float G = 2 - abs(H * 6 - 2);
float B = 2 - abs(H * 6 - 4);
return saturate(float3(R,G,B));
};
#define TAU 6.28318530718
#define PI 3.1415926
// A pixel shader is a program that given a texture coordinate (tex) produces a color.
// tex is an x,y tuple that ranges from 0,0 (top left) to 1,1 (bottom right).
// Just ignore the pos parameter.
@ -26,7 +42,45 @@ float4 main(float4 pos : SV_POSITION, float2 tex : TEXCOORD) : SV_TARGET
float4 color = shaderTexture.Sample(samplerState, tex);
// Inverts the rgb values (xyz) but don't touch the alpha (w)
color.xyz = 1.0 - color.xyz;
// color.xyz = 1.0 - color.xyz;
float2 pxCursorTopLeft = CursorPosition * GlyphSize;
float2 pxCursorBottomRight = (CursorPosition + float2(1, 1)) * GlyphSize;
// Convert pixel position [{0}, {Resolution}) to texel space [{0}, {1})
float2 texelRelativeTopLeft = pxCursorTopLeft / Resolution;
float2 texelRelativeBottomRight = pxCursorBottomRight / Resolution;
// float2 relativeCursorPos = CursorPosition / BufferSize;
if ((tex.x >= texelRelativeTopLeft.x && tex.x <= texelRelativeBottomRight.x) &&
(tex.y >= texelRelativeTopLeft.y && tex.y <= texelRelativeBottomRight.y)) {
// float yWithinCursor = (tex.y-texelRelativeTopLeft.y) / texelRelativeBottomRight.y;
// float yWithinCursor = (tex.y) / texelRelativeBottomRight.y;
// float yWithinCursor = (texelRelativeTopLeft.y) / texelRelativeBottomRight.y;
// float2 withinCursor = (texelRelativeTopLeft) / texelRelativeBottomRight;
float2 withinCursor = (tex - texelRelativeTopLeft) * (GlyphSize);
float duration = 1.0;
// float hue = lerp(0, 1, 0.5 * cos(((TAU*Time - withinCursor.y)) / duration) + 0.5);
// float hue = lerp(0, 1, 0.5 * cos(((PI*Time - withinCursor.y)) / duration) + 0.5);
// float hue = lerp(0, 1, cos(((PI*Time - withinCursor.y)) / duration)+1);
// float hue = lerp(0.05, .95, .5*cos(((2*TAU*(Time - withinCursor.y))) / duration)+.5);
// float hue = lerp(0.00, .95, fmod(.5*cos(((TAU*(Time - withinCursor.y))) / duration)+.5, 1));
float hue = lerp(0.00, 1, fmod(1.5*(Time - withinCursor.y) / duration, 1));
// float hue = lerp(0, 1, 0.5 * cos((TAU) / duration * Time) + 0.5);
// float hue = withinCursor.y;
float3 hsv = float3(hue, 1, 1);
// float3 result = hsv2rgb(hsv);
float3 result = HUEtoRGB(hsv.x);
// color.xy = relativeCursorPos;
// color.z = 0.0;
// color.xyz = yWithinCursor;
// color.xy = withinCursor;
color.xyz = result;
color.a = 1.0;
}
// Return the final color
return color;

View file

@ -246,6 +246,12 @@ bool DxEngine::_HasTerminalEffects() const noexcept
void DxEngine::ToggleShaderEffects()
{
_terminalEffectsEnabled = !_terminalEffectsEnabled;
// If we're enabling the shader, try reloading it.
// It's not as good as hot reloading the hlsl file itself, but it's good enough.
if (_terminalEffectsEnabled)
{
_SetupTerminalEffects();
}
LOG_IF_FAILED(InvalidateAll());
}
@ -472,6 +478,12 @@ void DxEngine::_ComputePixelShaderSettings() noexcept
background.w = _backgroundColor.a;
_pixelShaderSettings.Background = background;
til::size glyphSize{ _fontRenderData->GlyphCell() };
_pixelShaderSettings.GlyphSize = XMFLOAT2{ ::base::saturated_cast<float>(glyphSize.width()), ::base::saturated_cast<float>(glyphSize.height()) };
_pixelShaderSettings.CursorPosition = XMFLOAT2{ ::base::saturated_cast<float>(_lastCursor.x()), ::base::saturated_cast<float>(_lastCursor.y()) };
_pixelShaderSettings.BufferSize = XMFLOAT2{ ::base::saturated_cast<float>(_lastBufferSize.width()), ::base::saturated_cast<float>(_lastBufferSize.height()) };
_d3dDeviceContext->UpdateSubresource(_pixelShaderSettingsBuffer.Get(), 0, nullptr, &_pixelShaderSettings, 0, 0);
}
CATCH_LOG();
@ -1086,6 +1098,7 @@ CATCH_RETURN()
// - S_OK
[[nodiscard]] HRESULT DxEngine::InvalidateCursor(const SMALL_RECT* const psrRegion) noexcept
{
_lastCursor = til::point{ psrRegion->Left, psrRegion->Top };
return Invalidate(psrRegion);
}
@ -1870,6 +1883,8 @@ try
::Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> shaderResource;
RETURN_IF_FAILED(_d3dDevice->CreateShaderResourceView(_framebufferCapture.Get(), &srvDesc, &shaderResource));
_ComputePixelShaderSettings();
// Render the screen quad with shader effects.
const UINT stride = sizeof(ShaderInput);
const UINT offset = 0;
@ -1967,7 +1982,7 @@ CATCH_RETURN()
}
// Update pixel shader settings as background color might have changed
_ComputePixelShaderSettings();
// _ComputePixelShaderSettings();
return S_OK;
}
@ -2038,7 +2053,7 @@ CATCH_RETURN();
RETURN_IF_FAILED(InvalidateAll());
// Update pixel shader settings as scale might have changed
_ComputePixelShaderSettings();
// _ComputePixelShaderSettings();
return S_OK;
}
@ -2062,8 +2077,9 @@ float DxEngine::GetScaling() const noexcept
// - srNewViewport - The bounds of the new viewport.
// Return Value:
// - HRESULT S_OK
[[nodiscard]] HRESULT DxEngine::UpdateViewport(const SMALL_RECT /*srNewViewport*/) noexcept
[[nodiscard]] HRESULT DxEngine::UpdateViewport(const SMALL_RECT srNewViewport) noexcept
{
_lastBufferSize = til::size{ srNewViewport.Right - srNewViewport.Left, srNewViewport.Bottom - srNewViewport.Top };
return S_OK;
}

View file

@ -225,6 +225,8 @@ namespace Microsoft::Console::Render
// Controls if configured terminal effects are enabled
bool _terminalEffectsEnabled;
til::point _lastCursor{ 0, 0 };
til::size _lastBufferSize{ 0, 0 };
// Experimental and deprecated retro terminal effect
// Preserved for backwards compatibility
@ -262,11 +264,17 @@ namespace Microsoft::Console::Render
{
// Note: This can be seen as API endpoint towards user provided pixel shaders.
// Changes here can break existing pixel shaders so be careful with changing datatypes
// and order of parameters
// and order of parameters.
float Time;
float Scale;
DirectX::XMFLOAT2 Resolution;
DirectX::XMFLOAT4 Background;
DirectX::XMFLOAT2 GlyphSize;
DirectX::XMFLOAT2 CursorPosition;
DirectX::XMFLOAT2 BufferSize;
// You can always add more values to the end, but they must always be in this order.
// Adding values is not a breaking change. Shaders that don't have those values declared will simply ignore them.
// However, if you want to use `CursorPostion`, then you'll need to declare all the members that preceed it.
#pragma warning(suppress : 4324) // structure was padded due to __declspec(align())
} _pixelShaderSettings;