mieki256's diary



2021/06/28(月) [n年前の日記]

#1 [love2d] ogvファイルとアルファチャンネル

love2d は .ogv (Theora + Vorbis)フォーマットの動画を再生できると知ったのだけど。

だったら、アラビアンファイトの必殺技シーンのような見せ方もできるかな、と夢想したものの、そういう見せ方をするためには動画にアルファチャンネルが含まれていないといかんよなと気づいたわけで。後ろのほうでスプライトをたくさん描画しておいて、その手前に動画を表示するわけだから…。例えば、動画内のキャラの背景が抜けた状態じゃないといけない。

では、.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で作成してみる。

source.png

その画像から、アルファチャンネルを元にした白黒画像と、RGB画像を作成。どちらの画像もアルファチャンネルは持ってない。

sub.png

add.png

これを、背景(BG)画像の上に描画する。

bg.jpg

描画の仕方は…。
  • 最初に、背景画像(BG)を、フツーのBlendMode (seBlendMode("alpha")) で描画。
  • 次に、アルファチャンネルを元にした白黒画像を、setBlendMode("subtract") で ―― 減算で描画。これにより、白い部分が背景画像から引かれて真っ黒になる。
  • 次に、RGB画像を settBlendMode("add") で ―― 加算で描画。描画されてほしい部分は、事前に減算描画したことで真っ黒になっているはずなので、そのまま加算描画すれば、描画色がそのまま出るはず。

画像で示したほうが分かりやすいだろうか。

draw_sub_and_add_ss04.png

ソースは以下。

_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

実行すると、こうなった。

draw_sub_and_add_ss.png

上手くいったような気がする。

であれば…。アルファチャンネルを元にして作った白黒の動画と、透明部分は真っ黒にしてある動画の2つを用意すれば、動画でもアルファチャンネルを持っているかのように処理できるのだろうか…。

しかしそのためには、RGBAの動画を最初に作成して、そこからアルファチャンネルだけを取り出して動画を作成して、更に、RGB=(0,0,0) の背景にRGBA動画を合成した動画を作成しないといけない。何のツールを使えば目的が果たせるだろうか?

以上、1 日分です。

過去ログ表示

Prev - 2021/06 - Next
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project