Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
ホラー風文字描画
# encoding: utf-8
require 'dxruby'
class HorrorText < DXRuby::Shader
# シェーダコアのHLSL記述
hlsl = <<EOS
// (1) グローバル変数
float waveAmpU;
float waveAmpV;
float wavePhaseU;
float wavePhaseV;
float waveLength;
float2 texelSize;
texture tex0;
// (2) サンプラ
sampler Samp0 = sampler_state
{
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
Texture =<tex0>;
};
// (3) 入出力の構造体
struct PixelIn
{
float2 UV : TEXCOORD0;
};
struct PixelOut
{
float4 Color : COLOR0;
};
// (4) ピクセルシェーダのプログラム
PixelOut PS_P0_Main(PixelIn input)
{
PixelOut output;
output.Color = tex2D(Samp0, input.UV) * 0.75f;
float ampU = sin(radians(input.UV.x * waveLength + wavePhaseU)) * texelSize.x;
float ampV = sin(radians(input.UV.x * waveLength + wavePhaseV)) * texelSize.y;
// エフェクト処理
input.UV.x += ampU * waveAmpU;
input.UV.y += ampV * waveAmpV;
// フィルター処理
float2 offsetU = float2(texelSize.x, 0);
float2 offsetV = float2(0, texelSize.y);
output.Color += tex2D(Samp0, input.UV + offsetU) * 0.09f;
output.Color += tex2D(Samp0, input.UV - offsetU) * 0.09f;
output.Color += tex2D(Samp0, input.UV + offsetU * 2) * 0.05f;
output.Color += tex2D(Samp0, input.UV - offsetU * 2) * 0.05f;
output.Color += tex2D(Samp0, input.UV + offsetV) * 0.19f;
output.Color += tex2D(Samp0, input.UV + offsetV * 2) * 0.17f;
output.Color += tex2D(Samp0, input.UV + offsetV * 3) * 0.15f;
output.Color += tex2D(Samp0, input.UV + offsetV * 4) * 0.13f;
output.Color += tex2D(Samp0, input.UV + offsetV * 5) * 0.11f;
output.Color += tex2D(Samp0, input.UV + offsetV * 6) * 0.09f;
output.Color += tex2D(Samp0, input.UV + offsetV * 7) * 0.07f;
output.Color += tex2D(Samp0, input.UV + offsetV * 8) * 0.05f;
//output.Color = tex2D(Samp0, input.UV);
return output;
}
// (5) technique定義
technique ScanShift
{
pass P0
{
PixelShader = compile ps_2_0 PS_P0_Main();
}
}
EOS
# シェーダコアの作成
@@core = DXRuby::Shader::Core.new(
hlsl,{
:waveAmpU => :float,
:waveAmpV => :float,
:wavePhaseU => :float,
:wavePhaseV => :float,
:waveLength => :float,
:center => :float,
:texelSize => :float,
:blurPower => :float,
}
)
attr_accessor :duration
def initialize(duration = 60, wave_amp_u = 1.0, wave_amp_v = 0.0, wave_length = 8.0,
wave_speed_u = 1.0, wave_speed_v = 1.0)
super(@@core, "ScanShift")
@count = 0
@duration = duration
@mode = 0
@wave_amp_u = wave_amp_u
@wave_amp_v = wave_amp_v
@wave_phase_u = 0
@wave_phase_v = 0
@wave_length = wave_length
@wave_speed_u = wave_speed_u
@wave_speed_v = wave_speed_v
self.waveAmpU = @wave_amp_u
self.waveAmpV = @wave_amp_v
self.wavePhaseU = @wave_phase_u
self.wavePhaseV = @wave_phase_v
self.waveLength = @wave_length
self.texelSize = 0.05, 0.05
end
def update
@count = @count + (@mode == 0 ? 1 : - 1) if update?
self.wavePhaseU = (self.wavePhaseU + @wave_speed_u) % 360
self.wavePhaseV = (self.wavePhaseV + @wave_speed_v) % 360
self.waveAmpU = @wave_amp_u * @count / @duration
self.waveAmpV = @wave_amp_v * @count / @duration
self.waveLength = 360.0 / (@wave_length * self.texelSize[1])
end
def update?
@mode == 0 && @count < @duration || @mode == 1 && @count > 0
end
def start
@count = @mode == 0 ? 0 : @duration
end
def set_texel(image)
self.texelSize = 1.0 / image.width, 1.0 / image.height
end
end
img = Image.new(640, 200)
img.draw_font(32,64, "むかしむかしあるところに、おじいさんとおばあさんがおったそうな。", Font.new(20), [255,0,0])
shader = Shader::HorrorText.new(60, 2.0, 2.0, 16.0, 1.25, 1.0)
shader.set_texel(img)
shader.start
mes_win = Sprite.new
mes_win.x, mes_win.y = 0, 320
mes_win.image = img
mes_win.shader = shader
Window.loop do
shader.update
mes_win.update
mes_win.draw
Window.update
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment