2021/06/28(月) [n年前の日記]
#1 [love2d] ogvファイルとアルファチャンネル
love2d は .ogv (Theora + Vorbis)フォーマットの動画を再生できると知ったのだけど。
だったら、アラビアンファイトの必殺技シーンのような見せ方もできるかな、と夢想したものの、そういう見せ方をするためには動画にアルファチャンネルが含まれていないといかんよなと気づいたわけで。後ろのほうでスプライトをたくさん描画しておいて、その手前に動画を表示するわけだから…。例えば、動画内のキャラの背景が抜けた状態じゃないといけない。
では、.ogv はアルファチャンネルを持てるのだろうか? これが残念なことに、アルファチャンネルなんて持てない動画フォーマットのようで…。
_Theora.pdf
love2dのフォーラムでも、「動画ファイルでアルファチャンネル使えないかな?」という話題を見つけたけど。
_Does Love 2D support video with an alpha channel for video overlay? - LoVE
「動画はアルファチャンネル持てないから無理」「love2dがAPNGをサポートしてくれたらいいのに」「特定色を透明として扱うshaderを書けばなんとかなるのかもしれん」みたいなやり取りに見えた。
だったら、アラビアンファイトの必殺技シーンのような見せ方もできるかな、と夢想したものの、そういう見せ方をするためには動画にアルファチャンネルが含まれていないといかんよなと気づいたわけで。後ろのほうでスプライトをたくさん描画しておいて、その手前に動画を表示するわけだから…。例えば、動画内のキャラの背景が抜けた状態じゃないといけない。
では、.ogv はアルファチャンネルを持てるのだろうか? これが残念なことに、アルファチャンネルなんて持てない動画フォーマットのようで…。
_Theora.pdf
The Theora format does not support interlaced material, variable framerates, bit-depths larger than 8 bits per component, nor alternate color spacessuch as RGB or arbitrary multi-channel spaces.「インターレース素材、可変フレームレート、8bit以上のbit深度、RGBなどの色空間、マルチチャンネルには対応してない」と書いてあるように見える。
love2dのフォーラムでも、「動画ファイルでアルファチャンネル使えないかな?」という話題を見つけたけど。
_Does Love 2D support video with an alpha channel for video overlay? - LoVE
「動画はアルファチャンネル持てないから無理」「love2dがAPNGをサポートしてくれたらいいのに」「特定色を透明として扱うshaderを書けばなんとかなるのかもしれん」みたいなやり取りに見えた。
◎ 減算と加算でどうにかならんか。 :
今のところ、動画にアルファチャンネルを持たせて手前に描画するというのは、そのままでは無理っぽいけど、工夫すればどうにかできんかなと…。
例えばだけど、RGB画像と、合成したいところだけ黒にするためのマスク画像を用意して、BlendMode で減算(subtract)と加算(add)でどうにかできないものか…。
試してみた。環境は Windows10 x64 20H2 + love2d 11.3。
まず、アルファチャンネルを持った画像をGIMPで作成してみる。
その画像から、アルファチャンネルを元にした白黒画像と、RGB画像を作成。どちらの画像もアルファチャンネルは持ってない。
これを、背景(BG)画像の上に描画する。
描画の仕方は…。
画像で示したほうが分かりやすいだろうか。
ソースは以下。
_main.lua
_conf.lua
動作には、bg.jpg、sub.png、add.png が必要。
_bg.jpg
_sub.png
_add.png
実行すると、こうなった。
上手くいったような気がする。
であれば…。アルファチャンネルを元にして作った白黒の動画と、透明部分は真っ黒にしてある動画の2つを用意すれば、動画でもアルファチャンネルを持っているかのように処理できるのだろうか…。
しかしそのためには、RGBAの動画を最初に作成して、そこからアルファチャンネルだけを取り出して動画を作成して、更に、RGB=(0,0,0) の背景にRGBA動画を合成した動画を作成しないといけない。何のツールを使えば目的が果たせるだろうか?
例えばだけど、RGB画像と、合成したいところだけ黒にするためのマスク画像を用意して、BlendMode で減算(subtract)と加算(add)でどうにかできないものか…。
試してみた。環境は Windows10 x64 20H2 + love2d 11.3。
まず、アルファチャンネルを持った画像をGIMPで作成してみる。
その画像から、アルファチャンネルを元にした白黒画像と、RGB画像を作成。どちらの画像もアルファチャンネルは持ってない。
これを、背景(BG)画像の上に描画する。
描画の仕方は…。
- 最初に、背景画像(BG)を、フツーのBlendMode (seBlendMode("alpha")) で描画。
- 次に、アルファチャンネルを元にした白黒画像を、setBlendMode("subtract") で ―― 減算で描画。これにより、白い部分が背景画像から引かれて真っ黒になる。
- 次に、RGB画像を settBlendMode("add") で ―― 加算で描画。描画されてほしい部分は、事前に減算描画したことで真っ黒になっているはずなので、そのまま加算描画すれば、描画色がそのまま出るはず。
画像で示したほうが分かりやすいだろうか。
ソースは以下。
_main.lua
function love.load() bgimg = love.graphics.newImage("bg.jpg") subimg = love.graphics.newImage("sub.png") addimg = love.graphics.newImage("add.png") end function love.update(dt) end function love.draw() -- canvas clear love.graphics.clear(0, 0, 0, 1) -- draw bg love.graphics.setColor(1, 1, 1, 1) love.graphics.setBlendMode("alpha") love.graphics.draw(bgimg, 0, 0) -- draw sub image love.graphics.setBlendMode("subtract") love.graphics.draw(subimg, 0, 0) -- draw add image love.graphics.setBlendMode("add") love.graphics.draw(addimg, 0, 0) -- draw text love.graphics.setBlendMode("alpha") love.graphics.print("ESC to exit.", 8, 4) end function love.keypressed(key, scancode, isrepeat) if key == "escape" then love.event.quit() end end
_conf.lua
function love.conf(t) t.window.width = 1280 t.window.height = 720 t.window.title = "Draw sub and add" t.window.fullscreen = false -- t.window.fullscreentype = "exclusive" end
動作には、bg.jpg、sub.png、add.png が必要。
_bg.jpg
_sub.png
_add.png
実行すると、こうなった。
上手くいったような気がする。
であれば…。アルファチャンネルを元にして作った白黒の動画と、透明部分は真っ黒にしてある動画の2つを用意すれば、動画でもアルファチャンネルを持っているかのように処理できるのだろうか…。
しかしそのためには、RGBAの動画を最初に作成して、そこからアルファチャンネルだけを取り出して動画を作成して、更に、RGB=(0,0,0) の背景にRGBA動画を合成した動画を作成しないといけない。何のツールを使えば目的が果たせるだろうか?
[ ツッコむ ]
以上、1 日分です。