在 Three.js 中,我們可以通過
MeshStandardMaterial
材質配合多張貼圖來實現真實的地面效果。這種方式模擬了物理世界中光照與表面材質的復雜交互,常用于構建高質量場景,如數字孿生、建筑可視化、游戲等。本文將以一個完整示例為基礎,詳細講解每一類貼圖的作用、用法和注意事項。
什么是 PBR 材質貼圖?
PBR(Physically Based Rendering)物理渲染模型支持多種紋理貼圖,每種貼圖都在模擬真實世界中的一個屬性:
貼圖類型 Three.js 屬性名 作用說明 顏色貼圖 map
表面基礎顏色(必備) 環境遮蔽貼圖 aoMap
模擬局部陰影區域(如縫隙) 粗糙度貼圖 roughnessMap
控制表面的粗糙程度(影響高光模糊) 法線貼圖 normalMap
模擬表面細節凹凸而不改變幾何形狀 位移貼圖 displacementMap
根據灰度值真實改變網格的頂點高度
加載五種貼圖創建地面
// 燈光設置 const ambientLight = new THREE.AmbientLight(0xffffff, 0.3); // 環境光 const directionLight = new THREE.DirectionalLight(0xffffff, 0.5); // 平行光 directionLight.position.set(3, 3, 3); scene.add(ambientLight, directionLight);// 紋理加載器 const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('infinity-10537028.jpg'); // 示例用一張圖// 創建地面 const planeGeometry = new THREE.PlaneGeometry(10, 10, 100, 100); // 位移貼圖需要較多頂點 const planeMaterial = new THREE.MeshStandardMaterial({map: texture, // 基礎顏色貼圖aoMap: texture, // 環境遮蔽貼圖roughnessMap: texture, // 粗糙度貼圖normalMap: texture, // 法線貼圖displacementMap: texture, // 位移貼圖displacementScale: 0.5 // 位移高度控制 });const plane = new THREE.Mesh(planeGeometry, planeMaterial);// 貼圖生效關鍵步驟:設置第二套 UV 給 aoMap 使用 plane.geometry.setAttribute('uv2', new THREE.BufferAttribute(plane.geometry.attributes.uv.array, 2));// 地面旋轉使其水平 plane.rotation.x = -Math.PI / 2; scene.add(plane);
📌 注意事項
1.
aoMap
環境遮蔽貼圖需要第二套 UVThree.js 默認只創建一套 UV 坐標(
uv
),而aoMap
使用的是uv2
。必須手動復制一份:plane.geometry.setAttribute('uv2', new THREE.BufferAttribute(plane.geometry.attributes.uv.array, 2));
2.
displacementMap
位移貼圖要求幾何體有更多細分(segments)否則視覺上無效果,因為頂點太少無法形變:
new THREE.PlaneGeometry(10, 10, 100, 100); // 加細分
3. 所有貼圖建議使用專屬圖(顏色、法線、AO、粗糙、位移各自一張),格式推薦
.jpg
或.png
,尺寸為 2 的冪次(如 512、1024)以便兼容性更好。
可免費獲取完整 PBR 貼圖集的網站包括:
ambientCG - Free Textures, HDRIs and Models
https://polyhaven.com/textures
ambientCG - Free Textures, HDRIs and Models
搜索關鍵詞如
asphalt
,tile
,metal
,wood
即可獲取對應材質的五張貼圖。
屬性 控制什么 map
顏色 roughnessMap
粗糙程度(影響高光) normalMap
表面細節(比如劃痕) metalnessMap
是否是金屬表面 aoMap
縫隙暗影(更立體) displacementMap
真實變形(起伏) ?