歪みシェーダ
https://gyazo.com/5032be73da63feea65bcf25796ac9939
https://gyazo.com/e15fdf6c7de28c3467747ef5d77fa8bf
https://scrapbox.io/files/6846eb9727737c32b23e8c68.mp4
code:cpp
namespace
{
void LoadAsset()
{
TextureAsset::Register(U"bay", U"example/bay.jpg");
}
void DrawBG()
{
const ColorF color1 = ColorF{ 0 }.lerp(Palette::Deeppink, 0.50);
const ColorF color2 = ColorF{ 0.08 }.lerp(Palette::Deeppink, 0.50);
Scene::Rect().draw(color1);
constexpr Size TileSize{ 50, 50 };
for (int iY = 0; iY < Scene::Height() / TileSize.y; ++iY)
{
for (int iX = 0; iX < Scene::Width() / TileSize.x; ++iX)
{
if ((iX + iY) % 2 == 0)
{
RectF{ iX * TileSize.x, iY * TileSize.y, TileSize }.draw(color2);
}
}
}
}
// カスタムシェーダ用の定数バッファ
struct DistortionCustomBuffer
{
float time;
};
}
void Main()
{
Scene::SetBackground(Palette::Black);
LoadAsset();
// ポストエフェクト用レンダーテクスチャ
const MSRenderTexture renderTexture{ Scene::Size() };
// カスタムシェーダ
const PixelShader ps2DTexture = HLSL{ U"distortion.hlsl", U"PS_Texture" };
if (not ps2DTexture)
{
return;
}
ConstantBuffer<DistortionCustomBuffer> cb;
// GUI用
bool enableShader = false;
while (System::Update())
{
renderTexture.clear(Palette::Black);
{
const ScopedRenderTarget2D target{ renderTexture };
DrawBG();
RectF{ Arg::center = Scene::CenterF() + Vec2{ 8, 8 }, 600, 400 }.draw(ColorF{ 0, 0.3 });
TextureAsset(U"bay").resized(600, 400).drawAt(Scene::CenterF());
}
Graphics2D::Flush();
renderTexture.resolve();
{
cb->time = Scene::Time();
Graphics2D::SetPSConstantBuffer(1, cb);
ScopedCustomShader2D shader{ enableShader ? ps2DTexture : PixelShader{} };
renderTexture.draw();
}
{
SimpleGUI::CheckBox(enableShader, U"enable", Vec2(20, 20));
}
}
}
code:hlsl
//
// Textures
//
Texture2D g_texture0 : register(t0);
SamplerState g_sampler0 : register(s0);
namespace s3d
{
//
// VS Output / PS Input
//
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
};
}
//
// Constant Buffer
//
cbuffer PSConstants2D : register(b0)
{
float4 g_colorAdd;
float4 g_sdfParam;
float4 g_sdfOutlineColor;
float4 g_sdfShadowColor;
float4 g_internal;
}
cbuffer DistortionCustomBuffer : register(b1)
{
float g_time;
}
float4 PS_Texture(s3d::PSInput input) : SV_TARGET
{
const float distFromCenter0_1 = distance(input.uv, float2(0.5, 0.5)) / sqrt(0.5 * 0.5 + 0.5 * 0.5);
// 歪み
float2 uv = input.uv;
const float ampT = sin(g_time * 6.0) * cos(g_time * 14.0);
const float ampX = 0.030 * distFromCenter0_1 * ampT;
const float waveT1 = 17.0;
const float waveT2 = 180.0 + 50 * sin(g_time * 20.0);
uv.x += ampX * sin(g_time * waveT1 + input.uv.y * waveT2);
float4 texColor = g_texture0.Sample(g_sampler0, uv);
// 歪みが大きいときに彩度を下げる
const float3 rgbGray = dot(texColor.rgb, float3(0.299, 0.587, 0.114));
const float3 rgb1 = lerp(texColor.rgb, rgbGray, 0.9 * abs(ampT));
// 歪みが大きいときに彩度を下げる
const float3 rgbDark = rgb1 * 0.7;
const float3 rgb2 = lerp(rgb1, rgbDark, 0.5 * abs(ampT));
texColor.rgb = rgb2;
return (texColor * input.color) + g_colorAdd;
}