マテリアル
ジオメトリの「見た目」を担当する。ライトに反応するか、PBR か、で選ぶのが基本軸。
選び方の早見表
| やりたいこと | マテリアル |
|---|---|
| UI/HUD/影なしのフラット表示 | MeshBasicMaterial |
| 軽い影あり | MeshLambertMaterial |
| 古典的なハイライトあり | MeshPhongMaterial |
| 定番 PBR(デフォルトはこれ) | MeshStandardMaterial |
| ガラス・クリアコート・スポンジ等の高度な PBR | MeshPhysicalMaterial |
| セルシェーディング | MeshToonMaterial |
| キャプチャベースの質感(ライト不要で金属/有機) | MeshMatcapMaterial |
| 法線可視化 | MeshNormalMaterial |
| 深度マップ | MeshDepthMaterial / MeshDistanceMaterial |
| 線 | LineBasicMaterial / LineDashedMaterial |
| 点群 | PointsMaterial |
| ビルボード(カメラ向く板) | SpriteMaterial |
| 完全自作シェーダ | ShaderMaterial / RawShaderMaterial |
共通プロパティ
すべてのマテリアルが受ける主なオプション。
| プロパティ | 意味 |
|---|---|
color | 基本色("#fff" / 0xffffff / new THREE.Color(...)) |
opacity | 不透明度。使うには transparent: true も必須。 |
transparent | 半透明を有効化 |
alphaTest | このαより小さい所を破棄(葉っぱ・髪型に有効、影も抜ける) |
side | FrontSide(既定)/ BackSide / DoubleSide |
wireframe | ワイヤフレーム表示 |
visible | 非表示 |
depthWrite | 深度バッファ書き込み(パーティクル/ガラスで false) |
depthTest | 深度テスト |
blending | NormalBlending / AdditiveBlending / MultiplyBlending |
vertexColors | 頂点カラーを使う |
toneMapped | レンダラのトーンマッピングを適用するか(HUD は false) |
ライト無視系
MeshBasicMaterial
ライトに一切反応しない。常に同じ色。デバッグや HUD、輪郭線で使う。
new THREE.MeshBasicMaterial({ color: "#7dd3fc", wireframe: true })
MeshNormalMaterial
面法線を RGB として可視化。デバッグ用。
MeshDepthMaterial
深度を白黒で可視化。シャドウマップの内部実装でも使われる。
MeshMatcapMaterial
matcap(球状にプレレンダされたライト・反射)画像をテクスチャとして渡す。ライト不要でリッチに見える。 プロトタイプや軽量シーンで重宝する。
const matcap = new THREE.TextureLoader().load("/matcaps/clay.png")
matcap.colorSpace = THREE.SRGBColorSpace
new THREE.MeshMatcapMaterial({ matcap })
ライト反応系(PBR系)
MeshLambertMaterial
拡散反射(マット)。ハイライト無し。軽量だが古臭い。
MeshPhongMaterial
Lambert + 鏡面ハイライト。shininess と specular。古典的な見た目。
MeshStandardMaterial ★定番
現代的な PBR。roughness(ラフネス)と metalness(金属度)の2軸で材質を表現。
環境光(IBL)に反応する。
new THREE.MeshStandardMaterial({
color: "#9bd1ff",
roughness: 0.4, // 0=鏡面、1=完全拡散
metalness: 0.0, // 0=非金属、1=金属
envMapIntensity: 1.0,
})
テクスチャマップで質感を作り込む:
| マップ | 役割 |
|---|---|
map | カラー(ベースカラー) |
normalMap | 法線マップ(凹凸) |
roughnessMap | ラフネスマップ |
metalnessMap | 金属度マップ |
aoMap | アンビエントオクルージョン(要 uv2) |
emissiveMap + emissive | 自発光 |
alphaMap | α マップ |
displacementMap | 頂点を実際に動かす(要セグメント) |
bumpMap | 擬似凹凸(normal map のほうが良い) |
envMap | 環境マップ(普通は scene.environment でまとめて指定) |
MeshPhysicalMaterial
Standard を拡張。クリアコート(車のクリア塗装)、トランスミッション(ガラス)、シーン(布の艶)、 反射面の異方性などをサポート。
| 追加プロパティ | 意味 |
|---|---|
clearcoat / clearcoatRoughness | クリアコート層 |
transmission | 透過(ガラス)。thickness + ior も使う |
ior | 屈折率(ガラス 1.5、水 1.33) |
iridescence | 玉虫色(CD裏、シャボン玉) |
sheen / sheenColor | 布の艶 |
specularIntensity / specularColor | スペキュラの色(非金属) |
anisotropy | 異方性反射(ヘアラインや髪) |
new THREE.MeshPhysicalMaterial({
transmission: 1.0,
thickness: 0.5,
roughness: 0.05,
ior: 1.5,
metalness: 0,
})
MeshToonMaterial
セルシェーディング。gradientMap で諧調を段階的にする。
const grad = new THREE.TextureLoader().load("/grad/three.jpg")
grad.minFilter = THREE.NearestFilter
grad.magFilter = THREE.NearestFilter
new THREE.MeshToonMaterial({ color: "#fbbf24", gradientMap: grad })
線・点・スプライト
LineBasicMaterial / LineDashedMaterial
const geom = new THREE.BufferGeometry().setFromPoints([
new THREE.Vector3(-1, 0, 0),
new THREE.Vector3( 1, 0, 0),
])
const mat = new THREE.LineBasicMaterial({ color: "white", linewidth: 1 })
const line = new THREE.Line(geom, mat)
linewidth はWebGL の制約で大半のブラウザで無効(常に1px)。
太い線が欲しい時は addons の Line2 を使う。
PointsMaterial
new THREE.PointsMaterial({
size: 0.02,
sizeAttenuation: true, // カメラから遠いほど小さく
color: "white",
map: pointTexture, // 各点をテクスチャに
transparent: true,
depthWrite: false,
})
SpriteMaterial
カメラに常に正面を向く板(ビルボード)。HUD ラベルや UI に。
const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: tex }))
sprite.scale.set(1, 1, 1)
ShaderMaterial / RawShaderMaterial
自分で GLSL を書きたいときの脱出口。シェーダ・ポストプロセスに詳しく書く。
共有して使い回す
マテリアルとジオメトリは複数の Mesh で共有可能。インスタンスを再利用するとメモリと コンパイル時間を節約できる。
const sharedGeom = new THREE.BoxGeometry()
const sharedMat = new THREE.MeshStandardMaterial({ color: "#7dd3fc" })
for (let i = 0; i < 100; i++) {
const m = new THREE.Mesh(sharedGeom, sharedMat) // 共有
m.position.x = i * 0.5
scene.add(m)
}
マテリアルの更新
プロパティの一部は変更後に再コンパイルが必要。
通常 material.needsUpdate = true をセットして次フレームで反映。
material.map = newTexture
material.needsUpdate = true
ホットパスで needsUpdate を頻繁に立てない。
コンパイルが走り画面がカクつく。
onBeforeCompile で既存マテリアルを拡張
標準マテリアルに少しだけシェーダ追記したい場合の常套手段。シェーダ参照。
dispose() を
マテリアルはシェーダプログラムをキャッシュしている。シーンから外すだけでは GPU リソースが
残り続ける。material.dispose() + 内部のテクスチャも dispose()。