光学迷彩の実験
かなりいい加減で実用段階ではない。
法線マップは他の画像に適用できないし、シェーダもいい加減だが、こんな感じで2Dゲーでも光学迷彩ができる可能性があることは確認した。
背景に良い絵がなかったので前に使ったトランジション画像を使った。
宇宙人が隠れているのがわかるだろうか。
あ、RenderTarget関連でいくつかバグがあったので、いまの公開しているDXRuby1.1.11devでは動かないので注意。
#!ruby -Ks require 'dxruby' image = Image.load("image/enemy3.png", 0, 0, 48,48).dup normalmap = Image.new(image.width, image.height) def count_w(x, y, image) c = 0 while (image[x, y][0] != 0 and x < image.width ) x += 1 c += 1 end return c end def count_h(x, y, image) c = 0 while (image[x, y][0] != 0 and y < image.height ) y += 1 c += 1 end return c end for y in 0..47 x = 0 while (x < image.width) do if image[x, y][0] != 0 c = count_w(x, y, image) for temp in 0..c normalmap[x + temp, y] = [255, 255.0 / (c + 1) * (temp + 1), normalmap[x + temp, y][2], normalmap[x + temp, y][3]] end x += c end x += 1 end end for x in 0..47 y = 0 while (y < image.height) do if image[x, y][0] != 0 c = count_h(x, y, image) for temp in 0..c normalmap[x, y + temp] = [255,normalmap[x, y + temp][1], 255.0 / (c + 1) * (temp + 1), normalmap[x, y + temp][3]] end y += c end y += 1 end end hlsl = <<EOS texture Tex0; texture Tex1; texture Tex2; sampler Samp0 = sampler_state { Texture =<Tex0>; }; sampler Samp1 = sampler_state { Texture =<Tex1>; }; sampler Samp2 = sampler_state { Texture =<Tex2>; }; struct PixelIn { float2 UV : TEXCOORD0; }; struct PixelOut { float4 Color : COLOR0; }; PixelOut PS(PixelIn input) { PixelOut output; float2 temp = tex2D( Samp1, input.UV ).xy; float image = tex2D( Samp2, input.UV ).a; if (image == 0.0f) { output.Color = tex2D( Samp2, input.UV ); } else { output.Color = tex2D( Samp0, input.UV + (0.5 - temp.xy)*10/48.0 ); } return output; } technique TShader { pass P0 { PixelShader = compile ps_2_0 PS(); } } EOS shader = Shader.new(hlsl, "TShader") transition = Image.load("puwa-35s.jpg") rt = RenderTarget.new(640, 480) rt2 = RenderTarget.new(640, 480) x = 0 y = 0 Window.loop do x += Input.x*2 y += Input.y*2 Window.draw(0,0,transition) Window.update(rt) Window.draw(0, 0, rt) Window.update(rt2) rt2.x = x rt2.y = y rt2.width = image.width rt2.height = image.height i = rt2.to_image Window.draw(0,0,rt) Window.drawShader(x, y, [i, normalmap, image], shader) GC.start end
おまけ。
ソースをアレコレ修正して、もう一つの敵も描画してみた。
法線マップがいい加減なのが見てわかる。俺にはまだまだ難しい技術だ。