r74のアップデートが2016年2月にありました。このアップデートには「物理ベースレンダリング」が含まれています。このシリーズで紹介するサンプルは次のリポジトリにまとめてあります。併せて、参照してください。GitHubなお、本記事はthree.jsに少し触れたことがある人に向けた内容です。three.jsを含むWebGLの基本については、次のシリーズで解説していますので、併せて参照してください。「WebGLの基礎」シリーズ物理ベースレンダリングとはthree.jsのマテリアル(表面材質)は、これまで長くに渡りMeshPhongMaterial(フォン・シェーディング)とMeshLambertMaterial(ランバート・シェーディング)が中心となって活躍してきました。この2つのマテリアルは光の当たり方や影を表現できるものの、あくまでも「それっぽく見せる」ことができる技術であり、見栄えの向上のためには経験による数値の微調整や、作り込まれたディフューズテクスチャー(色テクスチャー)に頼るなどの必要がありました。影などが書き込まれたディフューズテクスチャー(ソースコード:/grapple-girl.html)このデモの色として適用したディフューズテクスチャーは次の図のようになります。シェーダーは影をもちろん表現できますが、それでは表現しきれない部分に、あらかじめテクスチャー側で色を塗っておくわけです。このデモの色として適用したディフューズテクスチャーたとえば、服のしわや角、物体同士が近い場所などは影が付きやすい性質があります。これをオクルージョンといいます。そこにあらかじめ色を塗っておいたり、光が当たっていそうな部分は明るくしておいたりして、レンダリングしたときに雰囲気が出るようにしています。本来、影を付けるためのシェーダーの仕事ですが、人間が頑張って色を塗っておいているのです。Shading)が注目を集めています。2010年頃からディズニー映画(リンク先のPDFは7MB近くあるのでご注意ください)などで利用され、最近では3Dゲーム開発でも採用されるようにもなっています。物理ベースレンダリングとは、光の反射や散乱など現実の物理現象を再現するレンダリング手法です。three.jsに物理ベースレンダリングが登場したことにより、つるつるであっても、ざらざらであっても、入力値を変更するだけでその違いを再現することができ、かつ、フォンシェーディングやランバートシェーディングよりも現実味のある表現が可能になりました。物理ベースレンダリングが適用されると、同一の指定であってもライティング環境が異なるシーンでは、指定に応じた適切なレンダリング結果を得ることができます。上が金属、下が非金属。変化を見るために、11個の玉をループで自動で作る際に少しずつラフネスの値を上げている。左側の玉が0で、そのとなりは0.1、0.2......と0.1ずつ上げており、一番右側の玉は1に設定した。数値を変えただけで、さまざまな材質の表現が可能になることがわかる。(ソースコード:demo1.html)「物理」と付くため難しく聞こえるかもしれませんが、用意された機能を利用するだけなら、とても簡単です!一方で、物理ベースレンダリングでは、従来のレンダリング方式のように、影などが描き込まれたディフューズテクスチャーは正確な光の計算の邪魔になってしまいます。そのため、物理ベースレンダリングで色を表現するためには純粋に「色のみ」のディフューズテクスチャーを用意し、アルベド(Albedo、反射する色)の値として利用することになります。three.jsを含むいくつかの物理ベースレンダリングではディフューズ(カラー)入力がアルベド(反射する色)として利用されます。これにより結果的にディフューズの色が物体の色のベースとなります。加えて、どれくらい鋭く(鈍く)光を反射するのかの値、金属であるのか否かなどによって物体の表示結果が決まります。アルベド白い光のもとで赤く見える物体の例。アルベドは入射光に対して反射する光の割合であり、他のレンダリング手法におけるディフューズ(カラー)とは少し異なる。Engineでもすでに利用できましたが、three.jsでもr74からMeshStandardMaterialという名前で、ついに物理ベースのリアルタイムレンダリングが利用できるようになりました(r74で初めて追加されたばかりの機能であるため、今後のthree.jsのアップデートでコンストラクター名や利用できるプロパティ名が変更される可能性があります)。#7381というプルリクエストや#5847などのissueで論議を重ね、できるだけ多くのthree.jsユーザーが扱いやすく感じる名前としてMeshPhysicalMaterialではなく、MeshStandardMaterialが採用されました。難しくなり過ぎないように、必要最低限の物理ベースレンダリングに関するプロパティを追加して実装されました。MeshStandardMaterialで利用する主なプロパティは、次の通りです。物体への映り込みに使われるキューブテクスチャーMeshStandardMaterialを利用するための基本的なコードの書き方を見てみましょう。図のような映り込みがあるような金属を例とします。いつものようにシーン、カメラなどを用意していきます。通常、私達が使う画面では、色がsRGBに補正されています。リニア色空間での処理する必要があります。色の調整が必要になります。`true`にすることでthree.jsが自動で色空間の調整を行ってくれます。すべての物体は「光を反射」をします。反射の材料となるキューブマップを用意しておきます。オプションとして、マテリアルのインスタンスを用意します。three.jsをこれまで使ったことがあるのであれば、難しくはないでしょう。この他にもMeshStandardMaterialには多数のプロパティがサポートされており、nomalMap(法線マップ)やaoMap(アンビエントオクルージョン)などを合わせて利用することによりさらに質感が向上します。物理ベースレンダリングを利用する際には、現実世界での計測値が公開されているので参考になります。roughnessはツールによって値の名称がsmoothnessやglossinessになることもあります。その場合、値の扱いも異なることがあるので、計測値の資料を参考にする際には適宜当てはめてみてください。左から、鉄、銀、アルミ、金、銅、クロミウム、ニッケル、チタン、コバルト、プラチナ(ソースコード:demo3.html)入力にテクスチャーを使うMeshStandardMaterialのroughnessやmetalnessは、メッシュ全体に一様に適用される数値の代わりにグレースケールのテクスチャー画像による入力も受け付けています。その場合、roughnessMap、metalnessMapのプロパティを利用します。左上:アルベド、右上:ラフネス、右下:メタルネス、左下:ノーマル画像を一度ロードしてテクスチャーとしてキャッシュさせれば、「テクスチャーの色」に応じて、複雑なメッシュでも、部分ごとにさまざまな質感を適用することができます。これにより、「ざらざら」や「つるつる」が混ざり合った質感のオブジェクトであっても、1回のドローコールで表示することができます。3Dモデリング時にテクスチャーを作り込む必要がありますが、パフォーマンス向上が必要な際には、ぜひ検討したいポイントとなるでしょう。MeshStandardMaterialでサポートされているプロパティ現時点でのMeshStandardMaterialでサポートされているプロパティをまとめると以下の通りです。r74から登場したMeshStandardMaterialによりマテリアルの選択肢が増え、よりリアルな表現を手軽に利用することができるようになりました。いえ、MeshStandardMaterialにはフレネルやクリアコートなど、本格的な物理ベースレンダリングには少し足りない機能があります。床に注目すると、視点が垂直に近いほど反射されているのがわかる。車の表面はコーティングの層と塗装の層の性質の異なるレイヤーがあるため、2つの反射が組み合わさっている。今後、より本格的な物理ベースレンダリングが利用できるMeshPhysicalMaterialが登場する可能性もあります。そのときに備える意味でも、MeshStandardMaterialに触れ、物理ベースレンダリングの基本を体感してみてはいかがでしょうか。晃浩フロントエンド・エンジニア2006年よりWeb制作会社にてUI実装や運用業務を経験した後、2010年よりフロントエンド・エンジニアとして株式会社ピクセルグリッドに入社。これまでの経験の大半は大規模Webサイトの壊れにくいHTML/CSS設計、及び実装。WebGLの扱いも得意としている。外部に向けたアウトプットも積極的に行っており、カンファレンスでの講演などを多数こなしている。Meetupの主催者。プロフェッショナルガイド』(共著:毎日コミュニケーションズ、2011年5月28日)』などがある。特定商取引法に基づく。