threejs-camera&controls&renderer(WebGLRenderer)

发布时间 2023-03-29 14:30:25作者: 努力不搬砖的iori
  • ArrayCamera: 一般用于,展示益、一个场景存在多个物体,每个物体各自拥有自己的视角的这种场景。
  • CubeCamera:一次性创建六个方位的相机(类似于正方体六个面,立方全景图中所有方位)
  • StereoCamera: 立体相机,创建于类似于VR场景的,实现相机视角跟随鼠标的效果
  • OrthographyCamera:  正交相机,用于创建没有透视场景的渲染效果。不会有近大远小的视觉差等效果?
  • PerspectiveCamera: 透视相机, 用于模拟人眼场景的各种场景效果。会有近大远小的视觉差 

 

About  PerspectiveCamera:

  四个参数:

  1. fov:  指的是 垂直方向上的可视角度(vertical vision angle  | in degrees),一般建议设置在45-75之前,此值越大,物体看起来越小,(只增大fov,其他条件不变的话)
  2. aspect:

     

     

  3.  near:小于 near的物体,不会被相机照到
  4.  far:大于 near的物体,不会被相机照到(这里的值可以参考,camera.position.length() 得到一个能看到当前视角全部物体的最小的一个far值来设置!!!)

  

about  OrthographyCamera:此相机,就像一片透明玻璃一样去拍照场景中的物体,如下图。

六个参数:

 

 

 

1.left:

2.right:

3.top:

4.bottom:

5.near:

  • 6.far:

知识点:在其他场景都不变,只改变PerspectiveCamera 为 OrthographicCamera时, 假如在PerspectiveCamera下显示的是一个立方体,但是可能在OrthographicCamera下,看起来是个长方体了,这是因为可能正交相机左右(left right),或者上下(top bottom)给的值没有乘以 PerspectiveCamera的 aspect ratio.设置后,看起来就是个立方体了。

 

 

Controls&Renderer

  1 import * as THREE from 'three'
  2 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'    
  3 import gsap from 'gsap'
  4 // Canvas
  5 const canvas = document.querySelector('canvas.webgl')
  6 
  7 // Scene
  8 const scene = new THREE.Scene()
  9 
 10 
 11 // Object
 12 const geometry = new THREE.BoxGeometry(1, 1, 1)
 13 const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
 14 const mesh = new THREE.Mesh(geometry, material)
 15 scene.add(mesh)
 16 
 17 // animation
 18 const animations = () => {
 19     gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 })
 20     gsap.to(mesh.position, { duration: 1, delay: 2, x: 0 })
 21 }
 22 animations()
 23 // Sizes
 24 const sizes = {
 25     width: window.innerWidth,
 26     height: window.innerHeight
 27 }
 28 
 29 // Camera
 30 const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
 31 camera.position.z = 3
 32 scene.add(camera)
 33 
 34 // controls
 35 
 36 const controls = new OrbitControls(camera, canvas);
 37 controls.enableDamping = true
 38 //开启阻尼,也就是惯性, 然后需要在每一帧进行controls.update()
 39 //
 40 // controls.target.y = 2 //controls target 指向的是对象围绕的焦点
 41 // controls.update()
 42 
 43 // Renderer
 44 const renderer = new THREE.WebGLRenderer({
 45     canvas: canvas
 46 })
 47 const tick = () => {
 48     controls.update()
 49     renderer.render(scene, camera)
 50     window.requestAnimationFrame(tick)
 51     // 动画一定需要配合帧动画请求!!!
 52 }
 53 tick()
 54 let cursor = {
 55     x:0,
 56     y:0
 57 }
 58 // 绑定鼠标事件
 59 window.addEventListener('mousemove', (event) => {
 60     // 这样子会使得x,y 坐标值会归于(-0.5-0.5 这个区间),
 61     cursor.x = event.clientX / sizes.width - 0.5
 62     cursor.y = -(event.clientY / sizes.height - 0.5)
 63     // 不加符号,会使得鼠标上下移动的时候,mesh看起来是跟随鼠标方向的,但是其实移动相机,mesh最终效果是要跟鼠标反向运动(相机向右,以相机为参照物,其实mesh向左)。
 64     //camera.position.x = cursor.x
 65     //camera.position.y = cursor.y
 66 
 67     // 让相机围绕着mesh 旋转(首先要清楚 这里实现旋转,改变位置的话,是 x和z方向旋转)
 68     // camera.position.x = Math.sin(cursor.x * Math.PI * 2) * 3
 69     // camera.position.z = Math.cos(cursor.x * Math.PI * 2) * 3
 70     // camera.position.y = cursor.y * 6
 71     // camera.lookAt(mesh.position)
 72 })
 73 
 74 //window resize handle
 75 window.addEventListener('resize', () => {
 76     sizes.width = window.innerWidth
 77     sizes.height = window.innerHeight
 78 
 79     camera.aspect = sizes.width / sizes.height
 80     camera.updateProjectionMatrix()
 81     //修改相机参数后,需要统计threejs 去更改 projectMatrix, 项目矩阵?
 82 
 83     //renderer 修改画布的size
 84     renderer.setSize(sizes.width, sizes.height)
 85     renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
 86 })
 87 
 88 // 绑定全屏事件
 89 window.addEventListener('dblclick', () => {
 90     // 注意,这个特性,对于 safari 浏览器无效
 91     // if(!document.fullscreenElement) {
 92     //     canvas.requestFullscreen()
 93     // }else {
 94     //     document.exitFullscreen()
 95     // }
 96 
 97     //最终兼容写法
 98     const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement
 99     if(!fullscreenElement) {
100         if(canvas.requestFullscreen) {
101             canvas.requestFullscreen()
102         }else if(canvas.webkitRequestFullscreen) {
103             canvas.webkitRequestFullscreen()
104         }
105     }else {
106         if(document.exitFullscreen) {
107             document.exitFullscreen()
108         }else if(document.webkitExitFullscreen) {
109             document.webkitExitFullscreen()
110         }
111     }
112 })
113 
114 renderer.setSize(sizes.width, sizes.height)
115 // 规定渲染器,设定像素比 为1 or 2  有益于性能!!!
116 renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))