此篇将 threeJs 相机的应用做一下记录,简略的封装为 vue 组件,以备参考。
之后缓缓欠缺此文。
一、立方相机 cubeCamera
cubeCamera,结构一个蕴含 6 个 PerspectiveCameras(透视摄像机)的立方摄像机,并将其拍摄的场景渲染到一个 WebGLCubeRenderTarget 上,生成指标纹理 (WebGLCubeRenderTarget.texture)。
render target 是一个缓存,缓存显卡为正在后盾渲染的场景绘制的像素。被用于不同的成果,例如用在一个图像渲染到屏幕上之前先做一些前期解决。
此处,将 WebGLCubeRenderTarget.texture 作为某个具备 envMap 属性材质的模型的环境贴图,即此模型反射的环境图案。
CubeCamera.vue
<template>
<div>
<div id="canvasContainer" style="width: 900px; height: 800px"></div>
</div>
</template>
<script setup>
import {onMounted} from 'vue'
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
let scene, camera, renderer, width, height, controls
onMounted(() => {init()
})
function init() {const canvasContainer = document.querySelector('#canvasContainer')
width = canvasContainer.clientWidth
height = canvasContainer.clientHeight
// 1、创立场景
scene = new THREE.Scene()
// 2、创立渲染器
renderer = new THREE.WebGLRenderer()
// renderer.setClearColor('#FFFFFF') // 设置渲染器的背景色
renderer.setClearColor('#88b4e1')
renderer.setSize(width, height) // 设置渲染区域尺寸
canvasContainer.appendChild(renderer.domElement) // 将渲染器创立的 canvas 元素增加到容器元素
// 3、创立透视相机,用于拍摄主场景
camera = new THREE.PerspectiveCamera(fov, width / height, 0.1, 1000)
camera.position.set(100, 50, 200) // 设置相机地位
camera.lookAt(scene.position) // 设置相机方向(指向的场景对象)
// 4、创立立方相机
cubeCamera() // 为具备镜面反射成果的模型 A 拍摄反射的图形,而后作为 A 的环境贴图
// 要先创立 renderer,因为 cubeCamera.update(renderer, scene)
// 5、其余
pointLight() // 点灯光
initControls() // 用鼠标管制透视相机的拍摄角度
axisHelper() // 坐标辅助器
animate()}
// 循环动画渲染
function animate() {requestAnimationFrame(animate)
renderer.render(scene, camera)
}
// 轨道控制器,使得相机围绕指标进行轨道静止
function initControls() {controls = new OrbitControls(camera, renderer.domElement)
}
// 辅助三维坐标系
function axisHelper() {const axis = new THREE.AxesHelper(250)
scene.add(axis)
}
// 创立一个虚构的球形网格 Mesh 的辅助对象来模仿点光源 PointLight
function pointLight() {const pointLight = new THREE.PointLight(0xffffff, 1, 1000)
pointLight.position.set(100, 150, 100) // 点光源地位
scene.add(pointLight)
// 创立点光源辅助对象模仿点光源
const pointLightHelper = new THREE.PointLightHelper(pointLight, 1)
scene.add(pointLightHelper)
}
let sphere, box
// 创立立方相机
function cubeCamera() {
// 创立 cube 相机的渲染指标
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(128, {
format: THREE.RGBAFormat,
generateMipmaps: true,
minFilter: THREE.LinearMipmapLinearFilter
});
// 创立 cube 相机
const cubeCamera = new THREE.CubeCamera(1, 100000, cubeRenderTarget)
scene.add(cubeCamera)
// 创立具能反射环境的模型
const sphereGeometry = new THREE.SphereGeometry(50)
const sphereMaterial = new THREE.MeshPhongMaterial({
color: 0xff0000,
envMap: cubeRenderTarget.texture
});
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.set(80, -50, 0)
scene.add(sphere)
// 创立被反射的模型
const boxGeometry = new THREE.BoxGeometry(20, 20, 20)
const boxMaterial = new THREE.MeshPhongMaterial({color: 0x00ff00})
box = new THREE.Mesh(boxGeometry, boxMaterial)
box.position.set(80, 100, 0)
scene.add(box)
// 更新渲染指标对象
sphere.visible = false
cubeCamera.position.copy(sphere.position)
cubeCamera.update(renderer, scene)
// 能够渲染场景了
sphere.visible = true
}
</script>
效果图: