相机的种类
上一节我们了解了threejs绘制一个场景的过程,这一节我们来认识以下什么是相机
相机分为4种
- 透视相机(PerspectiveCamera)
- 正交相机(OrthographicCamera)
- 全景相机(CubeCamera)
- 3D相机(StereoCamera)
其中最常用的是透视相机和正交相机
透视相机
透视相机的视口大约是这样子,相同尺寸的模型在远处的视角会比近处的视角小,因此看上去也会更小
以上是一个模型在距离近面100和1000的时候的场景,很明显,远处模型显得更小,这种相机符合人眼的数视觉规律
正交相机
正交相机的视口长这样,他没有视角的概念,因此不管距离远近只要是相同的模型大小都会是一样的
全景相机
全景相机也称为立方体相机,其本质是一个立方体的模型,在6个面的方向上面都安装了一个透视相机,
这种相机的作用可以用来做反射比如镜子
背对着我们的是我们使用的模型,面对我们的其实并非模型而是全景相机采集到的图像纹理贴到了一个立方体上面
const cubeCamera = new THREE.CubeCamera(0.1,10000,2048)
const material = new THREE.MeshBasicMaterial({
envMap:cubeCamera.renderTarget.texture,//全景相机的像贴图成环境纹理
});
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视图,可以参考现在的3D电影的做法
光源
参考代码
import objloader from './objloader.js'
import axios from 'axios'
const THREE= window.THREE=require('three')
THREE.OBJLoader = objloader();
const scene = new THREE.Scene();//创建一个场景
/**
* [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);
//创建一个环境光:白色,强度: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];
//纹理在创建后发生了改变(由上一语句引发),必须设置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)
})
}