Three.Camera

Camera是所有相机的抽象基类, 在构建新摄像机时,应始终继承此类. 常见的相机有两种类型: PerspectiveCamera(透视摄像机)或者 OrthographicCamera(正交摄像机)。

Camera子类型有ArrayCamera, CubeCamera, OrthographicCamera, PerspectiveCamera, StereoCamera, 这些相机中, 我认为比较有趣的是CubeCamera, 它包含6个PerspectiveCameras(透视摄像机)的立方摄像机, 拍出来的照片可以作为贴图使用, 先看看它的效果吧 !

1. CubeCamera

整个环境成为了球的表面, 这个功能是不是很容易扩展呢. 将环境放在任意物体上, 还十分炫酷

步骤

1. 创建cubeCamera

     //cubeCamera
cubeCamera = new THREE.CubeCamera(1, 10000, 128);
scene.add(cubeCamera);

说明: CubeCamera( near : Number, far : Number, cubeResolution : Number )

near -- 远剪切面的距离
far -- 近剪切面的距离
cubeResolution -- 设置立方体边缘的长度

2. 创建物体表面材质并将cubeCamera照出的环境作为材质的贴图

     material = new THREE.MeshBasicMaterial( {
envMap: cubeCamera.renderTarget.texture
} );

3. 创建物体, 将第二步的材质赋予物体

     let sphere = new THREE.Mesh( new THREE.IcosahedronBufferGeometry( 20, 3 ), material );
scene.add( sphere );

4. 更新材质贴图内容

     cubeCamera.update( renderer, scene );

那么, 带有环境的物体就做好了, 是不是很想试一试呀!

2. perspectiveCamera

这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。

使用时需要注意: 在PerspectiveCamera大多数属性发生改变之后,需要调用.updateProjectionMatrix来使得这些改变生效。

相机的使用步骤都十分类似, 第一步, 写构造函数, 第二步, 改变位置, 第三步, 添加至场景, 第四步, 改变相机位置.

对于perspectiveCamera, 它的特点是像人眼, 距离越远, 物体越小, 它与OrthographicCamera最大的区别就在于此, OrthographicCamera看到的物体无论距离多远, 物体看上去的大小一样.

使用流程

     //1.创建相机
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
//2.添加相机至场景
scene.add(camera);
//3.改变相机位置
camera.position.set( 100, 50, 150);
//4.改变相机朝向
camera.lookAt(scene.position);

PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )

fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面

注意点: renderer.render(scene, camera);

在渲染时, 参数选中的camera就相当于眼睛了, 选中哪个哪个就是眼睛.

效果如第一张图片所示, 看到的是透视相机拍出来的

3. OrthographicCamera

注意它的构造函数就行, 其他与PerspectiveCamera类似

OrthographicCamera( left : Number, right : Number, top : Number, bottom : Number, near : Number, far : Number )

left — 摄像机视锥体左侧面。
right — 摄像机视锥体右侧面。
top — 摄像机视锥体上侧面。
bottom — 摄像机视锥体下侧面。
near — 摄像机视锥体近端面。
far — 摄像机视锥体远端面。

4. ArrayCamera与StereoCamera

这两种我还没使用过, 这里就简单描述下, 后面用到了再补充

ArrayCamera 用于更加高效地使用一组已经预定义的摄像机来渲染一个场景。这将能够更好地提升VR场景的渲染性能。
一个 ArrayCamera 的实例中总是包含着一组子摄像机,应当为每一个子摄像机定义viewport(边界)这个属性,这一属性决定了由该子摄像机所渲染的视口区域的大小。

双透视摄像机(立体相机)常被用于创建3D Anaglyph(3D立体影像)或者Parallax Barrier(视差效果)。

5. 总结

相机想使用不难, 如何灵活运用相机达到想要的效果就比较难了

6. 代码

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style> </head>
<body>
<script src="/js/three.js"></script>
<script src="/js/OrbitControls.js"></script>
<script src="/js/libs/stats.min.js"></script>
<script src="/js/libs/inflate.min.js"></script>
<script src="/js/loaders/FBXLoader.js"></script>
<script src="/js/exporters/GLTFExporter.js"></script>
<script>
let renderer, scene, camera, light, cubeCamera; let container, stats; init();
animation(); function init() {
//container
container = document.createElement("div");
document.body.appendChild(container); //status
stats = new Stats();
container.appendChild(stats.domElement); //renderer
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff);
container.appendChild(renderer.domElement); //scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcce0ff );
scene.fog = new THREE.Fog( 0xcce0ff, 500, 10000 ); //3_相机
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight);
scene.add(camera);
camera.position.set( 100, 50, 150);
camera.lookAt(scene.position); //cubeCamera
cubeCamera = new THREE.CubeCamera(1, 10000, 128);
scene.add(cubeCamera); material = new THREE.MeshBasicMaterial( {
envMap: cubeCamera.renderTarget.texture
} ); //
let sphere = new THREE.Mesh( new THREE.IcosahedronBufferGeometry( 20, 3 ), material );
scene.add( sphere );
let geometry = new THREE.BoxGeometry( 1, 1, 1 );
let meterial2 = new THREE.MeshBasicMaterial( {
vertexColors: THREE.VertexColors,
// wireframe: true
});
let cube = new THREE.Mesh(
geometry,
meterial2
);
geometry.faces.forEach(face => {
// 设置三角面face三个顶点的颜色
face.vertexColors = [
new THREE.Color(0xffff00),
new THREE.Color(0x0000ff),
new THREE.Color(0x00ff00),
]
});
scene.add(cube); // light
scene.add( new THREE.AmbientLight( 0x666666 ) ); light = new THREE.DirectionalLight( 0xdfebff, 1 );
light.position.set( 50, 200, 100 );
light.position.multiplyScalar( 1.3 ); light.castShadow = true; light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024; let d = 300;
light.shadow.camera.left = - d;
light.shadow.camera.right = d;
light.shadow.camera.top = d;
light.shadow.camera.bottom = - d; light.shadow.camera.far = 1000; scene.add( light ); // ground
var loader = new THREE.TextureLoader();
var groundTexture = loader.load( '/textures/terrain/grasslight-big.jpg' );
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set( 25, 25 );
groundTexture.anisotropy = 16; var groundMaterial = new THREE.MeshLambertMaterial( { map: groundTexture } ); var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
mesh.position.y = - 250;
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh ); //辅助工具
// scene.add(new THREE.AxesHelper(20)); // controls
var controls = new THREE.OrbitControls( camera, renderer.domElement );
// controls.maxPolarAngle = Math.PI * 0.5;
// controls.minDistance = 1000;
// controls.maxDistance = 5000; } function animation(){
stats.update();
cubeCamera.update( renderer, scene );
render();
requestAnimationFrame(animation);
} function render() { renderer.render(scene, camera); }
</script>
</body>
</html>

随机推荐

  1. AMD模块介绍(翻译)

    http://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html Dojo支持以异步模型定义(AMD)方式编写的模块,让会让 ...

  2. fir.im Weekly - 94 个 iOS 开发资源推荐

    距离 2016 年还有 17 个日夜,而你和回家只隔了一张 12306 验证码的距离,祝大家抢票顺利.本期 fir.im Weekly 收集了一些优秀的 GitHub 源码.开发工具和动画特效,希望对 ...

  3. IP隧道基础研究

    static char banner[] __initdata = KERN_INFO "IPv4 over IPv4 tunneling driver\n"; static st ...

  4. StringBuffer&amp;Runtime demo

    public class StringBufferDemo02 {     public static void main(String[] args) {         StringBuffer ...

  5. rabbitmq的构架和原理(三)

    前面两篇博文已经将环境安装和相关配置介绍了,现在开始正式学习rabbitmq的使用了: rabbitMQ的构架 rabbitmq作为消息队列,一条消息从发布到订阅消费的完整流程为: 消息 --> ...

  6. ios 传递JSON串过去 前面多了个等号

    先说下我的问题 后台让我这边把请求的参数弄成一个实体转化成 json 串放body里传给他,当然header也有设置,提前设置好了, 但是后来了解 所谓的把实体转成json串的本质就是先把实体用run ...

  7. C++11 并发指南一(C++11 多线程初探)

    引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧, ...

  8. Asp.net 之 window 操作命令

    命令:cmd  打开执行窗口 命令:inetmgr.打开iis管理器 命令:dcomcnfg 打开组件服务 命令:regedit   打开注册表

  9. Adapter.notifyDataSetChanged()源码分析以及与ListView.setAdapter的区别

    一直很好奇,notifyDataSetChanged究竟是重绘了整个ListView还是只重绘了被修改的那些Item,它与重新设置适配器即调用setAdapter的区别在哪里?所以特地追踪了一下源码, ...

  10. 搭建Nexus本地仓库

    1 下载nexus安装包  网址:http://www.sonatype.org/nexus/   建议下载最新的版本,最新的版本支持比较新的jdk版本, 1.6 肯定是不行的,必须是1.7及其以上. ...