この記事はthree.jsについてのシリーズ記事の一つです。 最初の記事はThree.jsの基礎知識です。 まだ読んでない人は、そちらから先に読んでみるといいかもしれません。
Three.jsはいくつかの種類のマテリアルを提供しています。 これらは、オブジェクトがどのようにシーンに表示されるかを定義します。 どのマテリアルを使うべきかは、皆さんが何をしたいかによります。
マテリアルの属性の設定方法は、だいたい2つです。 一つは、表示される前の作成時です。
const material = new THREE.MeshPhongMaterial({
color: 0xFF0000, // red (can also use a CSS color string here)
flatShading: true,
});
もう一つは作成後です。
const material = new THREE.MeshPhongMaterial(); material.color.setHSL(0, 1, .5); // red material.flatShading = true;
THREE.Color型の属性は設定方法が複数あることに注意してください。
material.color.set(0x00FFFF); // same as CSS's #RRGGBB style
material.color.set(cssString); // any CSS color, eg 'purple', '#F32',
// 'rgb(255, 127, 64)',
// 'hsl(180, 50%, 25%)'
material.color.set(someColor) // some other THREE.Color
material.color.setHSL(h, s, l) // where h, s, and l are 0 to 1
material.color.setRGB(r, g, b) // where r, g, and b are 0 to 1
作成時に、16進数かCSS文字列を渡すことができます。
const m1 = new THREE.MeshBasicMaterial({color: 0xFF0000}); // red
const m2 = new THREE.MeshBasicMaterial({color: 'red'}); // red
const m3 = new THREE.MeshBasicMaterial({color: '#F00'}); // red
const m4 = new THREE.MeshBasicMaterial({color: 'rgb(255,0,0)'}); // red
const m5 = new THREE.MeshBasicMaterial({color: 'hsl(0,100%,50%)'); // red
では、three.jsのマテリアルの設定の説明をしましょう。
MeshBasicMaterialは光源の影響を受けません。
MeshLambertMaterialは頂点でのみ光を計算します。
一方で、MeshPhongMaterialは全てのピクセルで光を計算します。
MeshPhongMaterialは、specularによるハイライトもサポートします。
MeshPhongMaterialのshininess設定は特定のハイライトの輝きを決めます。デフォルトは30です。
MeshLambertMaterialかMeshPhongMaterialのどちらかで、colorに対してemissive属性を設定し、
色を黒(phongならshininessを0)に設定すると、ちょうどMeshBasicMaterialのように見えることに注意してください。
MeshPhongMaterialはMeshBasicMaterialやMeshLambertMaterialと同じようにできるのに、なぜ3種もあるのでしょうか。
理由は、より洗練されたマテリアルは、描写するのにGPUパワーを必要とするためです。
携帯電話といった、遅いGPCでは、より簡単なマテリアルを使うことで、描画に必要なGPUパワーを削減できるかもしれません。
また、余計な機能を必要としないなら、一番シンプルなマテリアルを使用するとよいです。
光源やspecularによるハイライトが不要なら、MeshBasicMaterialを使うこともできます。
MeshToonMaterialはMeshPhongMaterialに似ていますが、一点大きな違いがあります。
連続的にシェーディングするのではなく、グラデーションマップ(X×1のテクスチャ)を使ってシェーディングの方法を決めます。
デフォルトは明るさの始まりが70%、終わりが100%のグラデーションマップを適用しますが、自分で決めたグラデーションマップを適用することもできます。
これにより、まるでアニメのようなツートーンになります。
続いて2つの物理ベースレンダリングのマテリアルがあります。 物理ベースレンダリングはよくPBRと略します。
上記のマテリアルは、3Dに見えるマテリアルを簡単な数学で作っていますが、 これは現実世界で本当に起きている現象にのっとっていません。 2つのPBRマテリアルはもっと複雑な数学を使い、現実世界に近づいています。
一つ目はMeshStandardMaterialです。MeshPhongMaterialとMeshStandardMaterialの
最大の違いは、異なるパラメータを使っていることです。
MeshPhongMaterialはshininess設定があります。
MeshStandardMaterialはroughnessとmetalnessの2つの設定があります。
基本的に、roughnessはshininessの逆です。
野球ボールがほとんど反射しないように、とても粗いのものがある一方で、
とても光沢があるビリヤード玉のように、粗くないものもあります。
roughnessは0から1の間をとります。
もう一つの設定で、metalnessは、マテリアルの金属っぽさです。
金属は非金属と異なった振る舞いをします。
0は非金属で、1は金属です。
ここに、MeshStandardMaterialのサンプルがあります。
右に行くにつれて、roughnessは0から1に変わります。
下に行くにつれて、metalnessは0から1に変わります。
MeshPhysicalMaterialは、MeshStandardMaterialと同様ですが、
clearcoatパラメータが追加されています。このパラメータは、0から1につれて、
clearcoat光沢層が適用されます。
また、clearCoatRoughnessパラメータも追加されていて、これは光沢層の粗さを決定します。
ここに、上と同じmetalnessとroughnessのグリッドがあります。
ただし、clearcoatとclearCoatRoughnessの設定が付いています。
様々な標準のマテリアルのうち、高速なものから低速なものを並べると、
MeshBasicMaterial ➡ MeshLambertMaterial ➡ MeshPhongMaterial ➡
MeshStandardMaterial ➡ MeshPhysicalMaterialになります。
低速なマテリアルは、より現実味のある見た目のシーンを作ることができますが、
パワーが低いデバイスやモバイル端末では、より高速なマテリアルを使うようにコードを設計する必要があります。
続いて、特別な用途に使う3つのマテリアルがあります。
ShadowMaterialは影から作られたデータを得るのに使われます。
まだ影については説明していませんでしたね。
その際には、このマテリアルを使って、シーンの裏で何が起きているのか、のぞいてみたいと思います。
MeshDepthMaterialは各ピクセルの深度を描写します。
カメラの負のnearにあるピクセルは0、負のfarにあるピクセルは1です。
また別の機会に、特定の特殊効果がこのデータを使うかもしれません。
MeshNormalMaterialはジオメトリの法線を表示します。
法線は、特定の三角形かピクセル表面の方向です。
MeshNormalMaterialは見えている空間の法線を描画します(法線はカメラに依存します)。
xは赤、 yは緑そして zは青なので、 物体の右側はpink、 左側はaqua、 上側はlight green、 下側はpurple、 そして画面側はlavenderになるでしょう。
ShaderMaterialは、three.jsのシェーダーシステムを使ったカスタムマテリアルを作るためのものです
RawShaderMaterialは、three.jsの補助なしで、完全に独自シェーダーを作るためのものです。
これらのトピックはどちらも大きいため、後ほど説明します。
全てのマテリアルはMaterialによって決められた設定を共有しています。
それらはドキュメントを見てください。けれども、最も一般的に使われる2つの属性について説明しましょう。
flatShading:物体の面が分割されて見えるか、滑らかに見えるか。デフォルトはfalseです。
side:三角形の両面を表示するか。デフォルトはTHREE.FrontSideです。
ほかのオプションは THREE.BackSideとTHREE.DoubleSide(両面)です。
threeで描写されるほとんどの3Dオブジェクトは、たぶん不透明な固体です。
そのため、裏面(固体の内側を向いている面)は描画する必要はありません。
sideを設定する最も一般的な理由は、平面やほかの固体ではないオブジェクトのためです。
これらは、三角形の裏面を見ることが普通だからです。
ここに、THREE.FrontSideとTHREE.DoubleSideで描画された6つの平面があります。
マテリアルについては、本当にたくさん考えることがあり、実際にはもっとたくさんの説明したいパラメータがあります。 特に、私たちは多くのオプションの話につながる、テクスチャをほとんど無視していました。 テクスチャを説明する前に、休憩を取って、開発環境のセットアップを説明する必要があります。