three.js创建一个逼真的建筑动态夜景特效案例
时间: 2023-09-28 12:09:51 浏览: 65
以下是一个使用 Three.js 创建逼真的建筑动态夜景特效的案例:
首先,我们需要准备好建筑模型和贴图。我们可以使用 Blender 或其他建模软件来创建建筑模型,并使用 Photoshop 或其他绘图软件来制作贴图。
接下来,我们可以使用 Three.js 来加载建筑模型和贴图。我们可以使用 `GLTFLoader` 来加载 `.glb` 格式的模型,使用 `TextureLoader` 来加载贴图。
```javascript
// 加载模型
const loader = new GLTFLoader();
loader.load('models/building.glb', (gltf) => {
const building = gltf.scene;
scene.add(building);
});
// 加载贴图
const textureLoader = new TextureLoader();
const nightTexture = textureLoader.load('textures/building_night.jpg');
```
接下来,我们可以在夜晚场景中添加灯光。我们可以使用 `PointLight` 和 `AmbientLight` 分别添加点光源和环境光。
```javascript
// 添加点光源
const light = new PointLight(0xffffff, 1, 100);
light.position.set(0, 10, 0);
scene.add(light);
// 添加环境光
const ambientLight = new AmbientLight(0xffffff, 0.3);
scene.add(ambientLight);
```
为了创建逼真的夜景效果,我们可以将模型的材质替换为一个组合材质。该组合材质包含两个材质:一个表示白天的材质和一个表示夜晚的材质。我们可以使用 `MeshStandardMaterial` 来创建这些材质,并使用 `Color` 和 `Texture` 属性来设置它们的颜色和纹理。
```javascript
// 创建白天材质
const dayMaterial = new MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.1,
});
// 创建夜晚材质
const nightMaterial = new MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.1,
emissive: 0xffffff,
emissiveIntensity: 1,
map: nightTexture,
});
// 创建组合材质
const materials = [dayMaterial, nightMaterial];
const buildingMaterial = new MultiMaterial(materials);
```
接下来,我们可以将建筑模型的材质替换为这个组合材质。我们可以使用 `traverse` 方法遍历模型的所有子元素,并将其材质替换为组合材质。
```javascript
// 遍历模型的所有子元素
building.traverse((child) => {
if (child.isMesh) {
// 将材质替换为组合材质
child.material = buildingMaterial;
}
});
```
最后,我们可以使用 `requestAnimationFrame` 循环更新场景中夜景效果的状态。我们可以根据时间的变化来控制灯光和材质的切换。
```javascript
function animate() {
// 控制夜景效果的状态
const time = Date.now() * 0.001;
const intensity = Math.sin(time * 0.5) + 1;
light.intensity = intensity;
if (intensity > 1.2) {
buildingMaterial.materials[0].visible = false;
buildingMaterial.materials[1].visible = true;
} else {
buildingMaterial.materials[0].visible = true;
buildingMaterial.materials[1].visible = false;
}
// 渲染场景
renderer.render(scene, camera);
// 循环更新场景
requestAnimationFrame(animate);
}
```
完整的代码如下:
```javascript
import {
WebGLRenderer,
PerspectiveCamera,
Scene,
PointLight,
AmbientLight,
GLTFLoader,
TextureLoader,
MeshStandardMaterial,
MultiMaterial,
} from 'three';
// 创建渲染器
const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建相机
const camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 20);
// 创建场景
const scene = new Scene();
// 加载模型
const loader = new GLTFLoader();
loader.load('models/building.glb', (gltf) => {
const building = gltf.scene;
scene.add(building);
// 创建白天材质
const dayMaterial = new MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.1,
});
// 创建夜晚材质
const textureLoader = new TextureLoader();
const nightTexture = textureLoader.load('textures/building_night.jpg');
const nightMaterial = new MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.1,
emissive: 0xffffff,
emissiveIntensity: 1,
map: nightTexture,
});
// 创建组合材质
const materials = [dayMaterial, nightMaterial];
const buildingMaterial = new MultiMaterial(materials);
// 遍历模型的所有子元素
building.traverse((child) => {
if (child.isMesh) {
// 将材质替换为组合材质
child.material = buildingMaterial;
}
});
});
// 添加点光源
const light = new PointLight(0xffffff, 1, 100);
light.position.set(0, 10, 0);
scene.add(light);
// 添加环境光
const ambientLight = new AmbientLight(0xffffff, 0.3);
scene.add(ambientLight);
function animate() {
// 控制夜景效果的状态
const time = Date.now() * 0.001;
const intensity = Math.sin(time * 0.5) + 1;
light.intensity = intensity;
if (intensity > 1.2) {
buildingMaterial.materials[0].visible = false;
buildingMaterial.materials[1].visible = true;
} else {
buildingMaterial.materials[0].visible = true;
buildingMaterial.materials[1].visible = false;
}
// 渲染场景
renderer.render(scene, camera);
// 循环更新场景
requestAnimationFrame(animate);
}
animate();
```
以上就是使用 Three.js 创建逼真的建筑动态夜景特效的案例。