天空盒
- 在3D场景中,为了增强场景表现力,我们通常会为场景添加天空盒。就是在整个场景的上方绘制天空这一类图片。
- 最简单的做法是,制作一个很大的立方体为6个面添加纹理,这里要注意我们渲染的是内部。纹理是特殊处理了的能组合成一个整体。当然还有其他的方式比如创建球体或半圆的穹顶等。
创建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>学习</title>
</head>
<body>
<canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
<script type="module">
import * as THREE from './file/three.js-dev/build/three.module.js'
import { OrbitControls } from './file/three.js-dev/examples/jsm/controls/OrbitControls.js'
const canvas = document.querySelector('#c2d')
const renderer = new THREE.WebGLRenderer({ canvas })
const fov = 40
const aspect = 2
const near = 0.1
const far = 10000
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
camera.position.set(10, 3, 0)
camera.lookAt(0, 0, 0)
const controls = new OrbitControls(camera, canvas)
controls.update()
const scene = new THREE.Scene()
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
</script>
</body>
</html>
- 添加几何体,给每个面设置纹理。
- 需要注意材质要设置
THREE.BackSide
渲染内部,相机的远平面必须大于盒子的长度。directions[]
数组中的图片也是有序的。
{
var directions = [
'./file/18/pos-x.jpg',
'./file/18/neg-x.jpg',
'./file/18/pos-y.jpg',
'./file/18/neg-y.jpg',
'./file/18/pos-z.jpg',
'./file/18/neg-z.jpg'
]
const loader = new THREE.TextureLoader()
const skyGeometry = new THREE.BoxGeometry(5000, 5000, 5000)
const materialArray = []
for (let i = 0; i < 6; i++)
materialArray.push(
new THREE.MeshBasicMaterial({
map: loader.load(directions[i]),
side: THREE.BackSide
})
)
const skyBox = new THREE.Mesh(skyGeometry, materialArray)
scene.add(skyBox)
}
{
const loader = new THREE.CubeTextureLoader()
const texture = loader.load([
'./file/18/pos-x.jpg',
'./file/18//neg-x.jpg',
'./file/18//pos-y.jpg',
'./file/18//neg-y.jpg',
'./file/18//pos-z.jpg',
'./file/18//neg-z.jpg'
])
scene.background = texture
}
three.js
中除几张图组合的方式,还可以使用360度的全景图来设置天空。- 使用
WebGLCubeRenderTarget
渲染器的.fromEquirectangularTexture
,把全景图转换为立方体贴图格式。
{
const loader = new THREE.TextureLoader()
const texture = loader.load('./file/18/2.webp', () => {
const rt = new THREE.WebGLCubeRenderTarget(texture.image.height)
rt.fromEquirectangularTexture(renderer, texture)
scene.background = rt.texture
})
}
- 天空盒子在3D场景中,是最常见的一种增强效果的方式。使用那种方式去实现,就需要根据需求来判断什么方式最简单了。