歪みシェーダ
https://gyazo.com/90ad09dffe1633f98bdc735e422128a4
code:distortion_shader.cpp
namespace
{
void LoadAsset()
{
TextureAsset::Register(U"bay", U"example/bay.jpg");
}
void DrawBG()
{
const ColorF c{U"#009194"};
const ColorF color1 = c;
const ColorF color2 = c.lerp(ColorF{ 0 }, 0.08);
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:shader/distortion.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);
return (texColor * input.color) + g_colorAdd;
}