相機的種類
上一節(jié)我們了解了threejs繪制一個場景的過程,這一節(jié)我們來認識以下什么是相機
相機分為4種
- 透視相機(PerspectiveCamera)
- 正交相機(OrthographicCamera)
- 全景相機(CubeCamera)
- 3D相機(StereoCamera)
其中最常用的是透視相機和正交相機
透視相機
image.png
透視相機的視口大約是這樣子,相同尺寸的模型在遠處的視角會比近處的視角小,因此看上去也會更小
image.png
image.png
以上是一個模型在距離近面100和1000的時候的場景,很明顯,遠處模型顯得更小,這種相機符合人眼的數視覺規(guī)律
正交相機
image.png
正交相機的視口長這樣,他沒有視角的概念,因此不管距離遠近只要是相同的模型大小都會是一樣的
z軸距離100和1000都是這樣大小
全景相機
全景相機也稱為立方體相機,其本質是一個立方體的模型,在6個面的方向上面都安裝了一個透視相機,
這種相機的作用可以用來做反射比如鏡子
image.png
背對著我們的是我們使用的模型,面對我們的其實并非模型而是全景相機采集到的圖像紋理貼到了一個立方體上面
const cubeCamera = new THREE.CubeCamera(0.1,10000,2048)
const material = new THREE.MeshBasicMaterial({
envMap:cubeCamera.renderTarget.texture,//全景相機的像貼圖成環(huán)境紋理
});
const mirrorMetry = new THREE.BoxGeometry( 10000, 10000, 0 )
const mirror = new THREE.Mesh( mirrorMetry, material )
scene.add( mirror )
scene.add( cubeCamera )
cubeCamera.updateCubeMap( renderer, scene )
renderer.render(scene, camera);//開始渲染
以上就是關鍵代碼
3D相機
這個是2個透視相機的組合,2個相機之間有一定的距離,模擬人眼,可以得到2個稍有不同的像,這樣2個想疊加起來可以做成3D視圖,可以參考現(xiàn)在的3D電影的做法
光源
參考代碼
import objloader from './objloader.js'
import axios from 'axios'
const THREE= window.THREE=require('three')
THREE.OBJLoader = objloader();
const scene = new THREE.Scene();//創(chuàng)建一個場景
/**
* [camera 這是一個透視相機]
* 參數:
* fov:相機垂直視角大小
* aspect:相機水平視角和垂直視角比值,一般設置為場景大小的比值,不然會造成拉伸
* near:近端距離
* far:遠端距離
*/
const camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 10000)
/**
* left:左端距離
* right:右端距離
* top:頂端距離
* bottom:底端距離
* near:近端距離
* far:遠端距離
* 值得注意的是各種上下和左右的比值要和場景的比值一致,不然會造成拉伸
*/
//const camera = new THREE.OrthographicCamera(window.innerWidth/-2, window.innerWidth/2,window.innerHeight/2,window.innerHeight/-2, 0.1, 10000)
camera.position.z=150
camera.position.x=150
camera.position.y=10
camera.lookAt({x:0,y:0,z:-1500})
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//創(chuàng)建一個環(huán)境光:白色,強度:1
const light = new THREE.AmbientLight( '#fff',1);
const cubeCamera = new THREE.CubeCamera(0.1,10000,2048)
const mirrorMetry = new THREE.BoxGeometry( 10000, 10000, 0 );
const material = new THREE.MeshBasicMaterial({
envMap:cubeCamera.renderTarget.texture,
});
const mirror = new THREE.Mesh( mirrorMetry, material );
cubeCamera.position.z = -150
mirror.position.z=cubeCamera.position.z
mirror.position.y=100
scene.add(light)//場景中加入光源
scene.add( camera )
scene.add( mirror )
scene.add( cubeCamera )
let texture = new THREE.Texture()
Promise.all([loadObj('../lib/lux6.obj'),loadImage('../lib/lux6.jpg')]).then(res=>{
texture.image = res[1];
//紋理在創(chuàng)建后發(fā)生了改變(由上一語句引發(fā)),必須設置needsUpdate屬性為true
texture.needsUpdate = true;
let obj = res[0];
obj.traverse(child=>{
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
})
obj.position.y=-100
//obj.rotateY(Math.PI/2)
//obj.rotateZ ( -Math.PI/2 )
scene.add(obj)
cubeCamera.updateCubeMap( renderer, scene );
renderer.render(scene, camera);//開始渲染
})
function loadObj(url){
return new Promise(resolve=>{
new THREE.OBJLoader().load(url, resolve)
})
}
function loadImage(url) {
return new Promise(function (resolve) {
new THREE.ImageLoader().load(url, resolve)
})
}