2016/04/27(水) [n年前の日記]
#1 [prog] three.jsでビルボード
3種類のやり方で実験してみたり。ソースも画像も CC0 / Public Domain ってことで。
ビルボードとは…。 _ビルボードとYビルボードについて - YouTube という動画が分かりやすいかもしれず。
ビルボードとは…。 _ビルボードとYビルボードについて - YouTube という動画が分かりやすいかもしれず。
◎ THREE.PlaneGeometry()を使う方法。 :
THREE.PlaneGeometry(横幅, 縦幅, 横分割数, 縦分割数); を使うと、矩形ポリゴンを1枚作れる。(正確には、三角形ポリゴン2枚で矩形ポリゴンを1枚作ってる状態。) 生成時にサイズを指定することができるので、それぞれ違うサイズで生成できる。割り当てるマテリアルに応じて、光源やフォグを反映させることもできる。
そのままだとビルボードにならないけれど、カメラの位置・角度等を決定した後、レンダリング前にカメラの回転行列(?)を利用して、PlaneGeometry がカメラ側を向いているように回転させてやればビルボードっぽくなるのだとか。
試してみたのが以下。ソースを見たいときは、htmlソースを表示のこと。
_billboard_test1.html (DEMO)
しかし、何故かテクスチャの透過部分・透明部分の見た目がおかしなことに…。カメラから遠くにある PlaneGeometry の透明部分が、背景色・フォグ色で塗り潰されてしまって、透けて見えるはずの地面テクスチャが見えなくなってる。元テクスチャの透明部分は黒なので、透明部分が無効になってるわけではないのだろうけど。
解決策をググってみたら、renderOrder とやらに0以外を指定しておくと良いという話が。
試してみたのが以下。
_billboard_test1_b.html (DEMO)
改善できたように見えるけど、それでもまだ問題が。どうも時々、あちこちの PlaneGeometry が、チラチラする…。
前後関係が変わってチラチラしてるのかと思ったけど、よく見てみると一瞬透明部分が背景色で置き換わってるようで。結局、この不具合に対する解決策は見つからなかった。
そのままだとビルボードにならないけれど、カメラの位置・角度等を決定した後、レンダリング前にカメラの回転行列(?)を利用して、PlaneGeometry がカメラ側を向いているように回転させてやればビルボードっぽくなるのだとか。
// ビルボード相当をカメラを向くように回転 for (var i = 0; i < trees.length; i++) { // trees[i].quaternion.copy(camera.quaternion); trees[i].rotation.setFromRotationMatrix(camera.matrix); }rotation.setFromRotationMatrix(camera.matrix) でカメラ側に向かせることができるけど、quaternion.copy(camera.quaternion) でも同じ効果が得られるらしい。
試してみたのが以下。ソースを見たいときは、htmlソースを表示のこと。
_billboard_test1.html (DEMO)
しかし、何故かテクスチャの透過部分・透明部分の見た目がおかしなことに…。カメラから遠くにある PlaneGeometry の透明部分が、背景色・フォグ色で塗り潰されてしまって、透けて見えるはずの地面テクスチャが見えなくなってる。元テクスチャの透明部分は黒なので、透明部分が無効になってるわけではないのだろうけど。
解決策をググってみたら、renderOrder とやらに0以外を指定しておくと良いという話が。
var geom = new THREE.PlaneGeometry(w, w, 1, 1); var tree = new THREE.Mesh(geom, mat); // これを入れないと透過部分がおかしくなる tree.renderOrder = 1;
試してみたのが以下。
_billboard_test1_b.html (DEMO)
改善できたように見えるけど、それでもまだ問題が。どうも時々、あちこちの PlaneGeometry が、チラチラする…。
前後関係が変わってチラチラしてるのかと思ったけど、よく見てみると一瞬透明部分が背景色で置き換わってるようで。結局、この不具合に対する解決策は見つからなかった。
◎ THREE.Points()を使う方法。 :
パーティクルを描画する時によく使われるらしい、THREE.Points() を使ってみた。2D的なポリゴンを描画してくれるので、カメラの回転行列を利用して云々はしなくていい。光源は反映されないが、フォグを反映させることはできる。
サイズはマテリアル側、THREE.PointsMaterial() の中で指定できる。
試してみたのが以下。
_billboard_test2.html (DEMO)
透過部分・透明部分が、とんでもなくおかしな状態になってる…。また、位置(y座標)の指定も上手くいかない…。どんな座標値を指定すれば地面に設置してくれるのやら…。
通常、パーティクル表現等に THREE.Points() を使う場合は、加算合成などを指定して使うので、透明部分がおかしくなっても問題にならないのだろうけど。この手のビルボードとして使うとなると、なかなか難しいということだろうか…。
サイズはマテリアル側、THREE.PointsMaterial() の中で指定できる。
var mat = new THREE.PointsMaterial({ size: w * 2, map: texTrees[Math.floor(Math.random() * texTrees.length)], transparent: true, fog: true, });複数のテクスチャ種類の使い分けは、Points を1つ作るたびに、対応する Geometry と PointsMaterial を毎回生成して割り当てて解決した。
試してみたのが以下。
_billboard_test2.html (DEMO)
透過部分・透明部分が、とんでもなくおかしな状態になってる…。また、位置(y座標)の指定も上手くいかない…。どんな座標値を指定すれば地面に設置してくれるのやら…。
通常、パーティクル表現等に THREE.Points() を使う場合は、加算合成などを指定して使うので、透明部分がおかしくなっても問題にならないのだろうけど。この手のビルボードとして使うとなると、なかなか難しいということだろうか…。
◎ THREE.Sprite()を使う方法。 :
THREE.Sprite() を使うことでも、2D的なポリゴン描画ができるらしい。これも光源は反映されない。フォグは反映させることができる。
位置とサイズは、THREE.Sprite の position と scale を使って指定できる。
試してみたのが以下。
_billboard_test3.html (DEMO)
これなら大丈夫そう。光源が反映されない点がちょっと気になるけど。
位置とサイズは、THREE.Sprite の position と scale を使って指定できる。
var tree = new THREE.Sprite(mat); tree.position.set(x, y, z); // 位置指定 tree.scale.set(w, w, 1); // サイズ(スケール)指定複数のテクスチャ種類の使い分けは、Sprite を1つ作るたびに、対応する THREE.SpriteMaterial() を毎回生成して割り当てて解決した。
試してみたのが以下。
_billboard_test3.html (DEMO)
これなら大丈夫そう。光源が反映されない点がちょっと気になるけど。
◎ 参考ページ。 :
_three.js webgl - particles - sprites
_three.js webgl - sprites
_javascript - Three.js - billboard effect, maintain orientation after camera pans - Stack Overflow
_Edit fiddle - JSFiddle
_optimization - three.js: how to control rendering order - Stack Overflow
_three.js - Transparent objects in Threejs - Stack Overflow
_transparency - Transparent textures behaviour in WebGL - Stack Overflow
_render - using renderOrder in three.js - Stack Overflow
_three.js webgl - sprites
_javascript - Three.js - billboard effect, maintain orientation after camera pans - Stack Overflow
_Edit fiddle - JSFiddle
_optimization - three.js: how to control rendering order - Stack Overflow
_three.js - Transparent objects in Threejs - Stack Overflow
_transparency - Transparent textures behaviour in WebGL - Stack Overflow
_render - using renderOrder in three.js - Stack Overflow
[ ツッコむ ]
#2 [comic] 「絶対可憐チルドレン」(椎名高志著)、44巻まで読んだ
妹が以下略。展開が気になって、現在の最新刊まで読んでしまった…。これぞまさしく少年漫画、てな印象。
雰囲気が何かに似てるなと思ったけれど、最初のあたりは「うる星やつら」に近いのかもしれないなと。女の子が常時ふわふわ飛んでるし、主人公が若干浮気っぽいことをすると特殊能力でDVされるし…。
それにしても、ちょっと長い…。小学生編、中学生編、高校生編と区切りはついているものの、この巻数は…。後のほうになると見開きページが若干増えてきて、大ゴマ病の気配も微妙に感じられる、ような。
そういえば本編内で源氏物語についてほとんど言及してないな、と思ったけれど。考えてみたらほとんどのキャラの名前が源氏物語から持ってきてるように思えてきて。いわば、SF版源氏物語なのだなと。その設定だけでも面白い、ような気がする。
随分前にアニメ化もされたらしいけど、映像化は大変だったんじゃないのかと今頃心配を。サイコキネシスにしろ、テレポーテーションにしろ、テレパシーにしろ、映像としてどう表現するかを妄想すると、楽しいけど、悩む…。例えば「AKIRA」では、それぞれをどう表現してたっけか…。思い出せない…。「ミラクルガールズ」の、色の残像を使ったテレポーテーションぐらいしか思い出せないな…。
主人公がヒロイン達からDVされる1コマだけでも、どう映像化すればいいのか悩みそう。「うる星やつら」原作の最後のコマのように、各キャラが別々に台詞を喋りながら、ソレを遠巻きに見て感想を漏らしてる上司や同僚の図。並列してキャラ描写がされているけど、コレを映像にすると各キャラの台詞を直列で並べていくことになって、テンポが悪くなる。視聴者にちゃんと聞かせたい台詞と、聞き取れなくてもOKな台詞に分類して見せる、等々何かしら工夫が必要になるよなと。しかも主人公は「AKIRA」並みの描写で壁にめり込んでいくわけで、絵を描く方々も大変。原作内ではなんてことのない1コマですら、漫画ならではの見せ方を活用しまくってる作品だから…アニメ化は大変だったんじゃないのかなと。いや、実際見てないから結果がどうなったのかは分からないけど。
雰囲気が何かに似てるなと思ったけれど、最初のあたりは「うる星やつら」に近いのかもしれないなと。女の子が常時ふわふわ飛んでるし、主人公が若干浮気っぽいことをすると特殊能力でDVされるし…。
それにしても、ちょっと長い…。小学生編、中学生編、高校生編と区切りはついているものの、この巻数は…。後のほうになると見開きページが若干増えてきて、大ゴマ病の気配も微妙に感じられる、ような。
そういえば本編内で源氏物語についてほとんど言及してないな、と思ったけれど。考えてみたらほとんどのキャラの名前が源氏物語から持ってきてるように思えてきて。いわば、SF版源氏物語なのだなと。その設定だけでも面白い、ような気がする。
随分前にアニメ化もされたらしいけど、映像化は大変だったんじゃないのかと今頃心配を。サイコキネシスにしろ、テレポーテーションにしろ、テレパシーにしろ、映像としてどう表現するかを妄想すると、楽しいけど、悩む…。例えば「AKIRA」では、それぞれをどう表現してたっけか…。思い出せない…。「ミラクルガールズ」の、色の残像を使ったテレポーテーションぐらいしか思い出せないな…。
主人公がヒロイン達からDVされる1コマだけでも、どう映像化すればいいのか悩みそう。「うる星やつら」原作の最後のコマのように、各キャラが別々に台詞を喋りながら、ソレを遠巻きに見て感想を漏らしてる上司や同僚の図。並列してキャラ描写がされているけど、コレを映像にすると各キャラの台詞を直列で並べていくことになって、テンポが悪くなる。視聴者にちゃんと聞かせたい台詞と、聞き取れなくてもOKな台詞に分類して見せる、等々何かしら工夫が必要になるよなと。しかも主人公は「AKIRA」並みの描写で壁にめり込んでいくわけで、絵を描く方々も大変。原作内ではなんてことのない1コマですら、漫画ならではの見せ方を活用しまくってる作品だから…アニメ化は大変だったんじゃないのかなと。いや、実際見てないから結果がどうなったのかは分からないけど。
[ ツッコむ ]
以上、1 日分です。