簡易エッジ抽出シェーダー
ふと思いついたのでテキトーに作ってみた。テキトーすぎてあまり品質はよろしくない。
α値が変化している部分を残す方法なので、アンチエイリアスがかかった画像だと綺麗にならない。どんな絵でもうまくできるようにするのも大変だから、どっちかというと絵にあわせてロジックを変えたほうが簡単だが汎用性はなくなる。難しいもんだ。
require 'dxruby' hlsl = <<EOS float g_width, g_height; texture tex0; sampler Samp0 = sampler_state { Texture =<tex0>; AddressU=BORDER; AddressV=BORDER; }; struct PixelIn { float2 UV : TEXCOORD0; }; struct PixelOut { float4 Color : COLOR0; }; PixelOut PS(PixelIn input) { PixelOut output; float c[9]; c[0] = tex2D( Samp0, input.UV ).a; c[1] = tex2D( Samp0, input.UV - float2(1/g_width, 0) ).a; c[2] = tex2D( Samp0, input.UV + float2(1/g_width, 0) ).a; c[3] = tex2D( Samp0, input.UV - float2(0, 1/g_height) ).a; c[4] = tex2D( Samp0, input.UV + float2(0, 1/g_height) ).a; c[5] = tex2D( Samp0, input.UV - float2(1/g_width, 1/g_height) ).a; c[6] = tex2D( Samp0, input.UV + float2(1/g_width, 1/g_height) ).a; c[7] = tex2D( Samp0, input.UV + float2(1/g_width, -1/g_height) ).a; c[8] = tex2D( Samp0, input.UV + float2(-1/g_width, 1/g_height) ).a; if( c[0] == c[1] && c[1] == c[2] && c[2] == c[3] && c[3] == c[4] && c[4] == c[5] && c[5] == c[6] && c[6] == c[7] && c[7] == c[8] ) { output.Color = float4(0,0,0,0); } else { output.Color = tex2D( Samp0, input.UV ); } return output; } technique Edge { pass P0 { PixelShader = compile ps_2_0 PS(); } } EOS core = Shader::Core.new( hlsl, { :g_width => :float, :g_height => :float, } ) Window.width = 300 Window.height = 300 shader = Shader.new(core,"Edge") shader.g_width = 200 shader.g_height = 200 image = Image.load("logo.png").set_color_key([0,0,0]) Window.loop do Window.draw_shader(50,30,image,shader) end