2021/08/30(月) [n年前の日記]
#1 [povray] POV-Rayで任意のオブジェクトをレンダリング対象から外す
POV-Ray 3.7 でレンダリングする際、背景だけをレンダリング対象から外して、背景部分を透明にできないものかとググって調べていたのだけど。
オブジェクトに no_image という命令を付け加えるだけで、そのオブジェクトはレンダリングしないように指定することができる、と知った。
_POV-Ray: Documentation: 2.4.9.7 No_Image, No_Reflection
_11.4-5 物体のイメージスイッチ(no_image) - POV-Ray:11
例えば、以下のようなレンダリング結果が得られる .pov があったとして…。
_40_no_image.pov
床に相当する plane の最後に、no_image を指定してみる。
すると、こうなる。
床相当の plane はレンダリングされず、その部分は透明になった。しかし、球の下半分には、床相当の plane がちゃんと映り込んでいる。
ということで、「このオブジェクトだけレンダリング対象から外したい」と思った時は、no_image が使えますよ、ということで。
しかし、「これで背景をレンダリング対象から外せるのでは?」と期待したものの、そう上手くはいかなくて。
.pov の中に自分で記述した object { - } 等には no_image を追加できるけど、例えば、星空を生成してくれる GALAXY.INC のようなソレに対して no_image を指定する方法が分からなくて。
また、背景球を指定できる sky_sphere に対して no_image を使おうとしたらエラーになった。どうやら、sky_sphere は特殊な扱いなので、no_image はサポートしてないっぽい。
オブジェクトに no_image という命令を付け加えるだけで、そのオブジェクトはレンダリングしないように指定することができる、と知った。
_POV-Ray: Documentation: 2.4.9.7 No_Image, No_Reflection
_11.4-5 物体のイメージスイッチ(no_image) - POV-Ray:11
例えば、以下のようなレンダリング結果が得られる .pov があったとして…。
_40_no_image.pov
床に相当する plane の最後に、no_image を指定してみる。
plane { <0, 1, 0>, 0 texture { pigment { checker color rgb 0.5, color rgb 0.2 } // normal { bumps 0.75 scale 0.025} finish { phong 0.1 reflection 0.8 } } translate <0, -1, 0> no_image }
すると、こうなる。
床相当の plane はレンダリングされず、その部分は透明になった。しかし、球の下半分には、床相当の plane がちゃんと映り込んでいる。
ということで、「このオブジェクトだけレンダリング対象から外したい」と思った時は、no_image が使えますよ、ということで。
しかし、「これで背景をレンダリング対象から外せるのでは?」と期待したものの、そう上手くはいかなくて。
.pov の中に自分で記述した object { - } 等には no_image を追加できるけど、例えば、星空を生成してくれる GALAXY.INC のようなソレに対して no_image を指定する方法が分からなくて。
また、背景球を指定できる sky_sphere に対して no_image を使おうとしたらエラーになった。どうやら、sky_sphere は特殊な扱いなので、no_image はサポートしてないっぽい。
◎ 大きな球に画像を貼り付けて背景代わりにする。 :
背景をレンダリング対象から外せないのかなとググっていたら、「シーンを包む巨大な球に背景画像を貼り付けて背景扱いにすることができるよ」という話を見かけた。
_POV-Ray: Newsgroups: povray.general: HDR Sky_sphere
言われてみれば、大昔に Shade を使って3DCGをやってた頃にも、雑誌でそういう作例を見かけた記憶があるな…。車をぐるりと取り囲む球面を作って、そこに背景っぽいテクスチャを貼ってたっけ…。POV-Ray でも、あのやり方は使えるのだな…。
となると、背景画像として使える画像をゲットしないといけない。今回は、星空を生成できる GALAXY.INC の結果画像のみをゲットする .pov を書いて、その出力画像を背景画像として使ってみよう。
_bg.pov
camera に、spherical を指定しているあたりがポイント。この指定で、球に貼り付ける分には都合が良いテクスチャ画像が得られる。らしい。
こんな見た目の画像が得られた。
実際の画像は以下。4096x2048ドットのpngなので、10MB近くあるので注意。プログラムと乱数で生成された画像だから、Public Domain 扱いでいいんじゃないかな…。
_bg_4096x2048.png (4096x2048, 24bit, 9.67MB)
camera に指定できる種類については、以下のページが参考になった。ありがたや。
_POV-Ray:5
_Types of Cameras in POV-Ray
最初は panoramic を指定してパノラマ画像を得ていたのだけど、その後、「球に貼り付けることが前提の画像が欲しいなら、そのものズバリ spherical のほうが良い」と知って、そちらに変更した次第。
余談。camera に、panoramic と angle 360 を指定した際は、左端と右端が全然繋がってない出力画像が得られた。angle に指定した値がおかしいのだろうか…? それとも、panoramic では左右が繋がった画像が原理的に得られないのだろうか…?
さておき。得られた画像を、大きな球に貼り付けて確認してみる。以下では、scale を使ってめっちゃ大きい球にしている。
_bg_sphere.pov
GALAXY.INC で生成・表示した背景と比べると、無駄に拡大表示されちゃった感じで見た目が荒くなってるけど、あくまで、オブジェクトに反射させるための背景として使うだけだから、これでもイケそうな気がするなと…。
_POV-Ray: Newsgroups: povray.general: HDR Sky_sphere
言われてみれば、大昔に Shade を使って3DCGをやってた頃にも、雑誌でそういう作例を見かけた記憶があるな…。車をぐるりと取り囲む球面を作って、そこに背景っぽいテクスチャを貼ってたっけ…。POV-Ray でも、あのやり方は使えるのだな…。
となると、背景画像として使える画像をゲットしないといけない。今回は、星空を生成できる GALAXY.INC の結果画像のみをゲットする .pov を書いて、その出力画像を背景画像として使ってみよう。
_bg.pov
//#declare galaxy_seed = 541; #declare galaxy_seed = 32; #include "GALAXY.INC" camera { // panoramic spherical location <0, 0, -5> look_at <0, 0, 0> // angle 360 right x*image_width/image_height }
camera に、spherical を指定しているあたりがポイント。この指定で、球に貼り付ける分には都合が良いテクスチャ画像が得られる。らしい。
こんな見た目の画像が得られた。
実際の画像は以下。4096x2048ドットのpngなので、10MB近くあるので注意。プログラムと乱数で生成された画像だから、Public Domain 扱いでいいんじゃないかな…。
_bg_4096x2048.png (4096x2048, 24bit, 9.67MB)
camera に指定できる種類については、以下のページが参考になった。ありがたや。
_POV-Ray:5
_Types of Cameras in POV-Ray
最初は panoramic を指定してパノラマ画像を得ていたのだけど、その後、「球に貼り付けることが前提の画像が欲しいなら、そのものズバリ spherical のほうが良い」と知って、そちらに変更した次第。
余談。camera に、panoramic と angle 360 を指定した際は、左端と右端が全然繋がってない出力画像が得られた。angle に指定した値がおかしいのだろうか…? それとも、panoramic では左右が繋がった画像が原理的に得られないのだろうか…?
さておき。得られた画像を、大きな球に貼り付けて確認してみる。以下では、scale を使ってめっちゃ大きい球にしている。
_bg_sphere.pov
camera { location <0, 0, -2.6> look_at <0, 0, 0> angle 45 right x*image_width/image_height } light_source { <100, 100, -100> color rgb 2.0 } // background sphere object { sphere { <0, 0, 0> 1 texture { pigment { image_map { png "bg_4096x2048.png" map_type 1 } } finish { phong 0 reflection 0.0 } } rotate <0, 0, 0> scale 1000 } }
GALAXY.INC で生成・表示した背景と比べると、無駄に拡大表示されちゃった感じで見た目が荒くなってるけど、あくまで、オブジェクトに反射させるための背景として使うだけだから、これでもイケそうな気がするなと…。
◎ UFOモドキの背景に使ってみる。 :
_昨日
や
_一昨日
の作業に使った、UFOモドキの .pov の背景に使ってみる。
_ufo_sample2.pov
背景相当の巨大球をそのまま表示してみた場合は以下。
結構それっぽい感じに見えている気がする。まあ、環境マッピングみたいなもんだから、それらしく見えるのは当たり前か…。
巨大球に no_image を追加して、レンダリング対象から外してみる。
背景部分が透明になった感じの結果画像が得られた。それでいて、オブジェクトにはちゃんと映り込みが反映されている。
一応、アニメGIFやスプライトシートも作ってみた。1フレーム80x80ドットの大きさ。20フレーム。
_spritesheet.png
ということで、POV-Ray でわざわざ時間をかけて2回レンダリングして、ImageMagick でアルファチャンネルの移植処理なんてしなくても、.pov の書き方を少し工夫するだけで背景部分が透明になった感じの画像を得ることができると分かった。
「お〜い!磯野〜! blender使おうぜ!」
だから誰だよ。まあ、たしかに、blender ならこんなことで悩まずに済むし、この手の頓智(?)も要らないだろうなあ…。
_ufo_sample2.pov
背景相当の巨大球をそのまま表示してみた場合は以下。
結構それっぽい感じに見えている気がする。まあ、環境マッピングみたいなもんだから、それらしく見えるのは当たり前か…。
巨大球に no_image を追加して、レンダリング対象から外してみる。
背景部分が透明になった感じの結果画像が得られた。それでいて、オブジェクトにはちゃんと映り込みが反映されている。
一応、アニメGIFやスプライトシートも作ってみた。1フレーム80x80ドットの大きさ。20フレーム。
_spritesheet.png
ということで、POV-Ray でわざわざ時間をかけて2回レンダリングして、ImageMagick でアルファチャンネルの移植処理なんてしなくても、.pov の書き方を少し工夫するだけで背景部分が透明になった感じの画像を得ることができると分かった。
「お〜い!磯野〜! blender使おうぜ!」
だから誰だよ。まあ、たしかに、blender ならこんなことで悩まずに済むし、この手の頓智(?)も要らないだろうなあ…。
[ ツッコむ ]
#2 [cg_tools] ImageMagick montage の覚書
ImageMagick 7.1.0-5 Q16 x64 を使ってスプライトシートを作ろうとしたけれど、montage に渡す -geometry の値がよく分からなくて少し調べた。
78x78ドットの画像群に対して、周囲に1ドットだけ隙間をつけて、80x80ドットの画像群が並んでる状態の画像を作りたい。この場合、以下のような指定になるのかな。たぶん。
ということで、作業時の注意点としては…。
このあたり、以下のページで説明されてるけど、英語だからよく分からん…。
_Montage -- IM v6 Examples
以下も参考になりそう。
_画像リサイズ処理のうんちく - Qiita
_画像リサイズのうんちく (補間フィルタ) - Qiita
_ImageMagick リサイズ補間アルゴリズム - Qiita
_ImageMagick の geometry 仕様 - Qiita
_ImageMagickでリサイズする方法 - 箱の中の自由粒子
78x78ドットの画像群に対して、周囲に1ドットだけ隙間をつけて、80x80ドットの画像群が並んでる状態の画像を作りたい。この場合、以下のような指定になるのかな。たぶん。
magick montage -geometry +1+1 -background none resize_78x78/*.png spreetsheet.png
- -geometry +1+1 : 上下左右に1ドットの隙間をつける指定。
- -background none : 背景を透明にする。
- -tile NxN は、フツーは指定しなくてもいい。元画像のファイル数に応じて、縦横に並べる個数を ImageMagick がイイ感じに調整してくれる。
- -geometry 80x80+1+1 と指定すると、元画像を 80x80ドットにリサイズしちゃってから周囲に1ドットの隙間を用意してしまうので、82x82ドットの画像が並んでる状態になってしまう。
ということで、作業時の注意点としては…。
- 元画像を、本来欲しい画像サイズから2ドット分小さくした画像サイズにリサイズしておく。
このあたり、以下のページで説明されてるけど、英語だからよく分からん…。
_Montage -- IM v6 Examples
以下も参考になりそう。
_画像リサイズ処理のうんちく - Qiita
_画像リサイズのうんちく (補間フィルタ) - Qiita
_ImageMagick リサイズ補間アルゴリズム - Qiita
_ImageMagick の geometry 仕様 - Qiita
_ImageMagickでリサイズする方法 - 箱の中の自由粒子
◎ 事前にリサイズしなくても良さそう。 :
もしかして、-geometry 78x78+1+1 と指定しておけば、事前にリサイズしなくても済むのではと気が付いた。例えば元画像が 512x512ドットのサイズでも、自動で78x78ドットに縮小して、かつ、上下左右に1ドット追加して、結果、80x80ドットの画像群を並べてくれるのでは…?
試してみたら、たしかにそんな感じになった。
ただ、-geometry でリサイズするのはやめてね、という話もあるっぽい。-resize を指定しておけば、状況に応じて mitchell か lanczoc のどちらかのアルゴリズムを使ってくれる、とのことで…。であれば、-resize を指定したほうがいいのかな。
試してみたら、たしかにそんな感じになった。
ただ、-geometry でリサイズするのはやめてね、という話もあるっぽい。-resize を指定しておけば、状況に応じて mitchell か lanczoc のどちらかのアルゴリズムを使ってくれる、とのことで…。であれば、-resize を指定したほうがいいのかな。
◎ アンシャープマスクを使ったほうが良さそう。 :
-unsharp をつけることでアンシャープマスクが使えるらしい。試してみたら縮小後の画像のクッキリ具合が上がった。
となると、以下のような指定がベストなのかな…。大きいドットサイズ(512x512)の画像群からいきなりスプライトシート(1つ80x80)を作る例。
となると、以下のような指定がベストなのかな…。大きいドットサイズ(512x512)の画像群からいきなりスプライトシート(1つ80x80)を作る例。
magick montage -resize 78x78 -unsharp 10x5+0.7+0 -geometry +1+1 -background none rgba/*.png PNG32:spritesheet.png
- rgba/*.png は 512x512ドットの画像群。
- 出力画像ファイル名の前に PNG32: をつけて、RGBA各8bitの画像を出力させる。ImageMagick Q16 を使ったせいか、何もつけないとRGBA各16bitの画像が出力されてしまった。
◎ フィルタも選べる。 :
-resize 指定時に -filter を指定することもできるらしい。試しに、-filter Lanczos をつけてみた。
-define filter:verbose=1 をつけると利用してる filter を表示してくれるそうで。
確認してみたところ、-filter Lanczos をつけたら filter = SincFast になった。
ちなみに、filter指定をしないと filter = Cubic になった。
magick montage -filter Lanczos -resize 78x78 -unsharp 10x5+0.7+0 -geometry +1+1 -background none rgba/*.png PNG32:spritesheet.png
-define filter:verbose=1 をつけると利用してる filter を表示してくれるそうで。
magick montage -define filter:verbose=1 -filter Lanczos -resize 78x78 -unsharp 10x5+0.7+0 -geometry +1+1 -background none rgba/*.png PNG32:spritesheet.png
確認してみたところ、-filter Lanczos をつけたら filter = SincFast になった。
# Resampling Filter (for graphing) # # filter = SincFast # window = SincFast # support = 3 # window-support = 3 # scale-blur = 1 # practical-support = 3
ちなみに、filter指定をしないと filter = Cubic になった。
# Resampling Filter (for graphing) # # filter = Cubic # window = Box # support = 2 # window-support = 2 # scale-blur = 1 # practical-support = 2 # B,C = 0.333333,0.333333
◎ 変換結果。 :
以下、変換結果。
アンシャープマスクをかけない版。
アンシャープマスクをかけた版。-filter指定無し。(filter = Cubic)
アンシャープマスクをかけた版。-filte Lanczos (filter = SincFast) を指定。
アンシャープマスクを使うとクッキリ具合が全然違う…。また、Lanczos はギラギラ具合が僅かに増えてる気がする。
アンシャープマスクをかけない版。
アンシャープマスクをかけた版。-filter指定無し。(filter = Cubic)
アンシャープマスクをかけた版。-filte Lanczos (filter = SincFast) を指定。
アンシャープマスクを使うとクッキリ具合が全然違う…。また、Lanczos はギラギラ具合が僅かに増えてる気がする。
[ ツッコむ ]
以上、1 日分です。