うねうねシェーダ
スーパーファミコンやアーケードゲームなどでよく見られたラスタースクロールを模した、うねうねと波打つエフェクトです。
https://scrapbox.io/files/688f4047c6f7330b358d7d63.mp4
https://gyazo.com/4e674c5c5c8597a5b3bd0a52357e1983
https://gyazo.com/25834f54e868620892c5965d01504aaa
code:cpp
# include <Siv3D.hpp> // Siv3D v0.6.16
struct CB_UneuneConstants
{
float time;
};
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture texture{ U"example/windmill.png" };
const RenderTexture renderTexture(Scene::Width(), Scene::Height(), ColorF{ 0 });
PixelShader ps{ HLSL{ U"shader/uneune.hlsl", U"PS_Texture" } };
ConstantBuffer<CB_UneuneConstants> cb;
while (System::Update())
{
{
const ScopedRenderTarget2D target{ renderTexture };
Scene::Rect().draw(ColorF{ 0 });
texture.resized(Scene::Size()).draw();
}
cb->time = Scene::Time();
Graphics2D::SetPSConstantBuffer(1, cb);
{
const ScopedCustomShader2D shader{ ps };
renderTexture.draw();
}
}
}
code:uneune.hlsl
//
// Textures
//
Texture2D g_texture0 : register(t0);
SamplerState g_sampler0 : register(s0);
namespace s3d
{
//
// VS Input
//
struct VSInput
{
float2 position : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR0;
};
//
// VS Output / PS Input
//
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
};
//
// Siv3D Functions
//
float4 Transform2D(float2 pos, float2x4 t)
{
return float4((t._13_14 + (pos.x * t._11_12) + (pos.y * t._21_22)), t._23_24);
}
}
//
// Constant Buffer
//
cbuffer VSConstants2D : register(b0)
{
row_major float2x4 g_transform;
float4 g_colorMul;
}
cbuffer PSConstants2D : register(b0)
{
float4 g_colorAdd;
float4 g_sdfParam;
float4 g_sdfOutlineColor;
float4 g_sdfShadowColor;
float4 g_internal;
}
cbuffer UneuneConstants : register(b1)
{
float g_time;
}
//
// Functions
//
s3d::PSInput VS(s3d::VSInput input)
{
s3d::PSInput result;
result.position = s3d::Transform2D(input.position, g_transform);
result.color = input.color * g_colorMul;
result.uv = input.uv;
return result;
}
float4 PS_Shape(s3d::PSInput input) : SV_TARGET
{
return (input.color + g_colorAdd);
}
float4 PS_Texture(s3d::PSInput input) : SV_TARGET
{
// 1ピクセルの大きさ
const float PW = 1.0 / 800.0;
const float PH = 1.0 / 600.0;
float2 uv = input.uv;
// X座標をうねうねさせる
// amount: うねうねさせる量
float amount = 0.3 * sin(g_time * 0.8);
uv.x += amount * sin((g_time * 8.0) + (uv.y * 2 * 3.14 * 7));
// はみ出したら反対側へ
uv.x = fmod(uv.x + 1.0, 1.0);
float4 texColor = g_texture0.Sample(g_sampler0, uv);
return ((texColor * input.color) + g_colorAdd);
}