Skip to content

Commit

Permalink
Translatioin ja materials (mrdoob#126)
Browse files Browse the repository at this point in the history
* translate ja of materials
  • Loading branch information
NayuTS committed Sep 6, 2020
1 parent 9c8ea3a commit 4a30893
Showing 1 changed file with 307 additions and 0 deletions.
307 changes: 307 additions & 0 deletions threejs/lessons/ja/threejs-materials.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
Title: Three.js マテリアル
Description: Three.jsのマテリアル
TOC: マテリアル

この記事はthree.jsについてのシリーズ記事の一つです。
最初の記事は[Three.jsの基礎知識](threejs-fundamentals.html)です。
まだ読んでない人は、そちらから先に読んでみるといいかもしれません。

Three.jsはいくつかの種類のマテリアルを提供しています。
これらは、オブジェクトがどのようにシーンに表示されるかを定義します。
どのマテリアルを使うべきかは、皆さんが何をしたいかによります。

マテリアルの属性の設定方法は、だいたい2つです。
一つは、表示される前の作成時です。


```js
const material = new THREE.MeshPhongMaterial({
color: 0xFF0000, // red (can also use a CSS color string here)
flatShading: true,
});
```

もう一つは作成後です。

```js
const material = new THREE.MeshPhongMaterial();
material.color.setHSL(0, 1, .5); // red
material.flatShading = true;
```

`THREE.Color`型の属性は設定方法が複数あることに注意してください。

```js
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文字列を渡すことができます。

```js
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によるハイライトもサポートします。
<div class="spread">
<div>
<div data-diagram="MeshBasicMaterial" ></div>
<div class="code">Basic</div>
</div>
<div>
<div data-diagram="MeshLambertMaterial" ></div>
<div class="code">Lambert</div>
</div>
<div>
<div data-diagram="MeshPhongMaterial" ></div>
<div class="code">Phong</div>
</div>
</div>
<div class="spread">
<div>
<div data-diagram="MeshBasicMaterialLowPoly" ></div>
</div>
<div>
<div data-diagram="MeshLambertMaterialLowPoly" ></div>
</div>
<div>
<div data-diagram="MeshPhongMaterialLowPoly" ></div>
</div>
</div>
<div class="threejs_center code">同じマテリアルでポリゴン数を変えたモデル</div>
`MeshPhongMaterial``shininess`設定は特定のハイライトの*輝き*を決めます。デフォルトは30です。
<div class="spread">
<div>
<div data-diagram="MeshPhongMaterialShininess0" ></div>
<div class="code">shininess: 0</div>
</div>
<div>
<div data-diagram="MeshPhongMaterialShininess30" ></div>
<div class="code">shininess: 30</div>
</div>
<div>
<div data-diagram="MeshPhongMaterialShininess150" ></div>
<div class="code">shininess: 150</div>
</div>
</div>
`MeshLambertMaterial``MeshPhongMaterial`のどちらかで、colorに対して`emissive`属性を設定し、
色を黒(phongなら`shininess`を0)に設定すると、ちょうど`MeshBasicMaterial`のように見えることに注意してください。
<div class="spread">
<div>
<div data-diagram="MeshBasicMaterialCompare" ></div>
<div class="code">
<div>Basic</div>
<div>color: 'purple'</div>
</div>
</div>
<div>
<div data-diagram="MeshLambertMaterialCompare" ></div>
<div class="code">
<div>Lambert</div>
<div>color: 'black'</div>
<div>emissive: 'purple'</div>
</div>
</div>
<div>
<div data-diagram="MeshPhongMaterialCompare" ></div>
<div class="code">
<div>Phong</div>
<div>color: 'black'</div>
<div>emissive: 'purple'</div>
<div>shininess: 0</div>
</div>
</div>
</div>
`MeshPhongMaterial``MeshBasicMaterial``MeshLambertMaterial`と同じようにできるのに、なぜ3種もあるのでしょうか。
理由は、より洗練されたマテリアルは、描写するのにGPUパワーを必要とするためです。
携帯電話といった、遅いGPCでは、より簡単なマテリアルを使うことで、描画に必要なGPUパワーを削減できるかもしれません。
また、余計な機能を必要としないなら、一番シンプルなマテリアルを使用するとよいです。
光源やspecularによるハイライトが不要なら、`MeshBasicMaterial`を使うこともできます。
`MeshToonMaterial``MeshPhongMaterial`に似ていますが、一点大きな違いがあります。
連続的にシェーディングするのではなく、グラデーションマップ(X×1のテクスチャー)を使ってシェーディングの方法を決めます。
デフォルトは明るさの始まりが70%、終わりが100%のグラデーションマップを適用しますが、自分で決めたグラデーションマップを適用することもできます。
これにより、まるでアニメのようなツートーンになります。
<div class="spread">
<div data-diagram="MeshToonMaterial"></div>
</div>
続いて2つの*物理ベースレンダリング*のマテリアルがあります。
物理ベースレンダリングはよくPBRと略します。
上記のマテリアルは、3Dに見えるマテリアルを簡単な数学で作っていますが、
これは現実世界で本当に起きている現象にのっとっていません。
2つのPBRマテリアルはもっと複雑な数学を使い、現実世界に近づいています。
一つ目は`MeshStandardMaterial`です。`MeshPhongMaterial``MeshStandardMaterial`
最大の違いは、異なるパラメータを使っていることです。
`MeshPhongMaterial``shininess`設定があります。
`MeshStandardMaterial``roughness``metalness`の2つの設定があります。
基本的に、[`roughness`](MeshStandardMaterial.roughness)は`shininess`の逆です。
野球ボールがほとんど反射しないように、とても粗いのものがある一方で、
とても光沢があるビリヤード玉のように、粗くないものもあります。
roughnessは0から1の間をとります。
もう一つの設定で、[`metalness`](MeshStandardMaterial.metalness)は、マテリアルの金属っぽさです。
金属は非金属と異なった振る舞いをします。
0は非金属で、1は金属です。
ここに、`MeshStandardMaterial`のサンプルがあります。
右に行くにつれて、`roughness`は0から1に変わります。
下に行くにつれて、`metalness`は0から1に変わります。
<div data-diagram="MeshStandardMaterial" style="min-height: 400px"></div>
`MeshPhysicalMaterial`は、`MeshStandardMaterial`と同様ですが、
`clearcoat`パラメータが追加されています。このパラメータは、0から1につれて、
clearcoat光沢層が適用されます。
また、`clearCoatRoughness`パラメータも追加されていて、これは光沢層の粗さを決定します。
ここに、上と同じ`metalness``roughness`のグリッドがあります。
ただし、`clearcoat``clearCoatRoughness`の設定が付いています。
<div data-diagram="MeshPhysicalMaterial" style="min-height: 400px"></div>
様々な標準のマテリアルのうち、高速なものから低速なものを並べると、
`MeshBasicMaterial``MeshLambertMaterial``MeshPhongMaterial`
`MeshStandardMaterial``MeshPhysicalMaterial`になります。
低速なマテリアルは、より現実味のある見た目のシーンを作ることができますが、
パワーが低いデバイスやモバイル端末では、より高速なマテリアルを使うようにコードを設計する必要があります。
続いて、特別な用途に使う3つのマテリアルがあります。
`ShadowMaterial`は影から作られたデータを得るのに使われます。
まだ影については説明していませんでしたね。
その際には、このマテリアルを使って、シーンの裏で何が起きているのか、のぞいてみたいと思います。
`MeshDepthMaterial`は各ピクセルの深度を描写します。
カメラの負の[`near`](PerspectiveCamera.near)にあるピクセルは0、負の[`far`](PerspectiveCamera.far)にあるピクセルは1です。
また別の機会に、特定の特殊効果がこのデータを使うかもしれません。
<div class="spread">
<div>
<div data-diagram="MeshDepthMaterial"></div>
</div>
</div>
`MeshNormalMaterial`はジオメトリの*法線*を表示します。
*法線*は、特定の三角形かピクセル表面の方向です。
`MeshNormalMaterial`は見えている空間の法線を描画します(法線はカメラに依存します)。
<span style="background: red;" class="color">xは赤</span>、
<span style="background: green;" class="dark-color">yは緑</span>そして
<span style="background: blue;" class="dark-color">zは青</span>なので、
物体の右側は<span style="background: #FF7F7F;" class="color">pink</span>、
左側は<span style="background: #007F7F;" class="dark-color">aqua</span>、
上側は<span style="background: #7FFF7F;" class="color">light green</span>、
下側は<span style="background: #7F007F;" class="dark-color">purple</span>、
そして画面側は<span style="background: #7F7FFF;" class="color">lavender</span>になるでしょう。
<div class="spread">
<div>
<div data-diagram="MeshNormalMaterial"></div>
</div>
</div>
`ShaderMaterial`は、three.jsのシェーダーシステムを使ったカスタムマテリアルを作るためのものです
`RawShaderMaterial`は、three.jsの補助なしで、完全に独自シェーダーを作るためのものです。
これらのトピックはどちらも大きいため、後ほど説明します。
全てのマテリアルは`Material`によって決められた設定を共有しています。
それらは[ドキュメントを見てください](Material)。けれども、最も一般的に使われる2つの属性について説明しましょう。
[`flatShading`](Material.flatShading):物体の面が分割されて見えるか、滑らかに見えるか。デフォルトは`false`です。
<div class="spread">
<div>
<div data-diagram="smoothShading"></div>
<div class="code">flatShading: false</div>
</div>
<div>
<div data-diagram="flatShading"></div>
<div class="code">flatShading: true</div>
</div>
</div>
[`side`](Material.side):三角形の両面を表示するか。デフォルトは`THREE.FrontSide`です。
ほかのオプションは `THREE.BackSide``THREE.DoubleSide`(両面)です。
threeで描写されるほとんどの3Dオブジェクトは、たぶん不透明な固体です。
そのため、裏面(固体の内側を向いている面)は描画する必要はありません。
`side`を設定する最も一般的な理由は、平面やほかの固体ではないオブジェクトのためです。
これらは、三角形の裏面を見ることが普通だからです。
ここに、`THREE.FrontSide``THREE.DoubleSide`で描画された6つの平面があります。
<div class="spread">
<div>
<div data-diagram="sideDefault" style="height: 250px;"></div>
<div class="code">side: THREE.FrontSide</div>
</div>
<div>
<div data-diagram="sideDouble" style="height: 250px;"></div>
<div class="code">side: THREE.DoubleSide</div>
</div>
</div>
マテリアルについては、本当にたくさん考えることがあり、実際にはもっとたくさんの説明したいパラメータがあります。
特に、私たちは多くのオプションの話につながる、テクスチャーをほとんど無視していました。
テクスチャーを説明する前に、休憩を取って、[開発環境のセットアップ](threejs-setup.html)を説明する必要があります。
<div class="threejs_bottombar">
<h3>material.needsUpdate</h3>
<p>
このトピックはめったにthree.jsアプリに影響しませんが、単にFYIのつもりで...。
Three.jsはマテリアルが"使われた"ときに設定を適用します。
"使われた"は"マテリアルを使って何かが描画される"ということです。
マテリアルの設定はたった一度だけ適用されます。変更するとthree.jsに多くの仕事が必要になります。
変更するケースでは、three.jsに変更を伝えるため、<code>material.needsUpdate = true</code>を設定する必要があります。
マテリアルを試用した後で、<code>needsUpdate</code>の設定を必要とする一般的な設定はこのようになります:
</p>
<ul>
<li><code>flatShading</code></li>
<li>テクスチャーの追加や削除
<p>
テクスチャーの変更はOKですが、テクスチャーを使わない状態から使う状態に変更したり、
テクスチャーを使っている状態から使わない状態に変更したいとすると、
<code>needsUpdate = true</code>を設定する必要があります。
</p>
<p>テクスチャーありからテクスチャーなしに変更するケースでは、
1x1ピクセルのホワイトテクスチャーを使うことがよいです。</p>
</li>
</ul>
<p>この問題は、ほとんどのアプリには関係ありません。
ほとんどのアプリではフラットシェードありとフラットシェードなしを切り替えません。
また、ほとんどのアプリは、与えられたマテリアルにテクスチャーか固定の色のどちらかを使い、
めったに一方からもう一方に切り替えたりしません。
</p>
</div>
<canvas id="c"></canvas>
<script type="module" src="resources/threejs-materials.js"></script>

0 comments on commit 4a30893

Please sign in to comment.