汽車模型加載
我們在sktechfab上下載的汽車是glb的文件格式,所以使用gltfLoader進行加載。這里將小車直接加載進來看看效果;import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
....其余代碼省略
const gltfLoader = new GLTFLoader();
gltfLoader.load("/src/assets/models/su7.glb", (gltf) => {const model = gltf.scene;scene.add(model);
});
我們會發現小車是黑的,這是因為我們當前場景中并沒有光照信息,我們需要為場景添加光照。
無光照時的模型
const ambientLight = new THREE.AmbientLight(0xf7f8fc, 0.2);
scene.add(ambientLight);const directionalLight = new THREE.DirectionalLight(0xf7f8fc, 1);
directionalLight.position.set(0, 5, 0);
scene.add(directionalLight);
添加光照之后小車有了顏色,但是細微觀察還缺少了一些效果,比如汽車漆面上的反射效果。
表面反射
我們可以給當前的場景設置環境屬性,來為場景中所有的物體添加環境反射,這需要我們準備一張**全景圖**全景圖概念
全景圖的原理其實很簡單,如下圖所示,假設我們所處的空間在一個很大的立方體內部,那么全景圖就是用六張圖片,賦予立方體六個面的紋理,我們在立方體內部觀察,每個方向的圖片都不一樣,這樣就有了身臨其境的感覺全景圖下的觀察效果
一般全景圖是由6張圖片組成,也可以使用hdr格式的壓縮圖片,兩者都可以實現全景圖
本案例中給大家提供的是hdr的全景圖,我們使用RGBELoader來進行加載,并且設置環境屬性,注意不要設置背景
const texture = new THREE.CubeTextureLoader().setPath('/src/assets/texture/park/').load(['posx.jpg','negx.jpg','posy.jpg','negy.jpg','posz.jpg','negz.jpg',])
// 創建一個紋理加載器, 加載紋理圖片
const texture = new RGBELoader().load('/src/assets/hdr/city.hdr', () => {texture.mapping = THREE.EquirectangularReflectionMappingscene.background = texture
})
可以看到我們的油漆表面有了一層反射效果
細心的同學不難發現,我們的小車一部分在地下,這是建模的問題,我們可以在three中進行調整,將平面往下走0.02個單位即可
mesh.position.set(0, -0.02, 0);
我們還可以觀察到,和懂車帝官網對比,我們的su7沒有在地面上展示出來陰影,接下來我們設置一下陰影效果。
添加陰影
添加陰影需要幾個步驟 1. 設置渲染器支持陰影貼圖 2. 設置物體支持投射陰影 3. 設置平面能夠接受陰影 4. 設置燈光支持投射陰影 5. 設置平面為standard材質 這五個步驟對應的源碼為:renderer.shadowMap.enabled=true
我們的模型是不能直接設置投射陰影的,模型是一棵樹的結構,需要遍歷到每一個葉子節點,然后設置投射陰影
gltfLoader.load("/src/assets/models/su7.glb", (gltf) => {const model = gltf.scene;model.traverse((mesh) => {if (mesh.isMesh) {mesh.castShadow = true;}});scene.add(model);
});
const geom = new THREE.CircleGeometry(20, 150);
const material = new THREE.MeshStandardMaterial({color: new THREE.Color(0xffffff),side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geom, material);
mesh.rotation.x -= (90 * Math.PI) / 180;
mesh.position.set(0, -0.02, 0);
scene.add(mesh);
mesh.receiveShadow=true
directionalLight.castShadow=true
實現效果,我們發現和懂車帝官網的陰影比較起來,第一是顏色不夠深,第二是邊緣沒有進行柔滑,我們很難和懂車帝做的一模一樣,只能盡量去模擬這個效果,因為懂車帝官網的效果是用一張圖片做的,我們沒有這樣的圖片資源
懂車帝官網效果
提高陰影的質量
陰影本質上其實是一張貼圖,貼圖的分辨率是最能提高質量的方法 提高之后可以看到陰影更細致了,但是顏色還沒有加深我們可以通過aoMap加深陰影顏色
aoMap叫做環境遮擋貼圖,通過設置aoMap,我們可以加深陰影的顏色,這個aoMap我們需要設置在地板上
可以看到陰影的顏色更深了,這是aoMap的功勞
const floorTexture = new THREE.TextureLoader().load("/src/assets/images/changjing2.jpg"
);
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set(1, 1);const geom = new THREE.CircleGeometry(20, 29);
const material = new THREE.MeshStandardMaterial({// 強制three使用雙面渲染這個平面side: THREE.DoubleSide,transparent: true,
// aoMap能讓有陰影的地方更明顯aoMap: floorTexture,aoMapIntensity:1.5
});
const mesh = new THREE.Mesh(geom, material);
mesh.position.set(0, -0.02, 0);
scene.add(mesh);
mesh.rotation.x -= (90 * Math.PI) / 180;
mesh.receiveShadow = true;
然后我們設置一下柔和陰影,讓其邊緣變的模糊
directionalLight.shadow.radius = 8; // 柔化陰影邊緣
陰影的最終效果到這里差不多了,剩下的參數大家可以自己調整一下