关于three.js:threeJs相机

42次阅读

共计 2840 个字符,预计需要花费 8 分钟才能阅读完成。

此篇将 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>

效果图:

正文完
 0