threejs-camera&controls&renderer(WebGLRenderer)
- ArrayCamera: 一般用于,展示益、一个场景存在多个物体,每个物体各自拥有自己的视角的这种场景。
- CubeCamera:一次性创建六个方位的相机(类似于正方体六个面,立方全景图中所有方位)
- StereoCamera: 立体相机,创建于类似于VR场景的,实现相机视角跟随鼠标的效果
- OrthographyCamera: 正交相机,用于创建没有透视场景的渲染效果。不会有近大远小的视觉差等效果?
- PerspectiveCamera: 透视相机, 用于模拟人眼场景的各种场景效果。会有近大远小的视觉差
About PerspectiveCamera:
四个参数:
- fov: 指的是 垂直方向上的可视角度(vertical vision angle | in degrees),一般建议设置在45-75之前,此值越大,物体看起来越小,(只增大fov,其他条件不变的话)
- aspect:
- near:小于 near的物体,不会被相机照到
- 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))