简单例子

这个例子,是在一个视图中,看到照相机的辅助线,也就是,一个照相机的观察访问

这样,就需要两个照相机,一个是主照相机,一个是加有辅助线的照相机(有两种,正交和透视,这里辅助的使用的是正交的)

设置两个照相机位置:注意,辅助的子照相机要在主照相机里面,这样才能在主照相机的镜头下看到辅助照相机的观察范围

 //场景、摄像机、渲染器、实体var scene, camera, renderer, cameraHelper;var cube, controls;//在页面加载完,进行绘制渲染页面window.onload = function() {init(); //数据初始化setSize(); //设置大小画布cube(); //绘制实体animate(); //动画渲染
    };//初始化摄像机,场景,渲染器,以及一些工具,比如摄像机辅助线,控制器
    function init() {scene = new THREE.Scene();camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,500);camera.position.set(10, 5, 20);camera.lookAt(new THREE.Vector3(0, 0, 0));//正交投影照相机camera2 = new THREE.OrthographicCamera(-1, 1, 1, -1, 5, 10);renderer = new THREE.WebGLRenderer({ alpha: true });camera2.position.set(0, 0, 5);camera2.lookAt(new THREE.Vector3(0, 0, 0));//renderer = new THREE.WebGLRenderer();//camera.position.z = 10;controls = new THREE.OrbitControls(camera);controls.autoRotate = true;//照相机帮助线cameraHelper = new THREE.CameraHelper(camera2);scene.add(cameraHelper);}//设置画布大小,这个设置为整个视图,就不需要剪切了
    function setSize() {renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);}//普通的四方体
    function cube() {var geometry = new THREE.BoxGeometry(1, 1, 1);var material = new THREE.MeshNormalMaterial({ color: 0x00ff00 });cube = new THREE.Mesh(geometry, material);//设置位置cube.position.set(0, 0, -1.5);scene.add(cube);}function animate() {requestAnimationFrame(animate); //一帧帧动画cube.rotation.x += 0.005;cube.rotation.y += 0.005;cube.rotation.z += 0.005;camera.updateProjectionMatrix();controls.update();cameraHelper.update();renderer.render(scene, camera); //渲染}

看完简单的例子,看看复杂的,

左边是一个视图,用一个小的照相机渲染出来的就是右边辅助线的照相机,

右边是两个照相机渲染出来的,右边,外面有个大的照相机,看到里面有个小的照相机,并且通过辅助线看到里面照相机的观察区域。

html部分:是,一个Canvas ,然后拆分为左右两个视图

<canvas id="c"></canvas><div class="split"><div id="view1" tabindex="1"></div><div id="view2" tabindex="2"></div></div><script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>

css

html, body {margin: 0;height: 100%;
}
#c {width: 100%;height: 100%;display: block;
}
.split {position: absolute;left: 0; top: 0; width: 100%; height: 100%; display: flex; } .split>div { width: 100%; height: 100%; }

js,他是有两个照相机,

1.一个透视作为主照相机,

2.一个正交作为辅助照相机,

在正交照相机加上辅助线,然后把辅助线弄到场景里面,

这样我们就可以在一个照相机(主照相机下)下看到另一个照相机(另一个有辅助线的照相机)的作用范围(辅助线范围)

var renderer,scene,camera,camera2,cameraHelper,canvas,view1Elem,view2Elem;
function init() {renderer = new THREE.WebGLRenderer({ canvas });const size = 1;const near = 5;const far = 50;//正交投影照相机camera = new THREE.OrthographicCamera(-size, size, size, -size, near, far); //透视投影照相机 camera2 = new THREE.PerspectiveCamera( 60, // fov 2, // aspect 0.1, // near 500 // far  ); //照相机帮助线 cameraHelper = new THREE.CameraHelper(camera); scene = new THREE.Scene(); scene.background = new THREE.Color("black"); scene.add(cameraHelper); } function setCarema() { camera.zoom = 0.2; camera.position.set(0, 10, 20); //旋转控制器 const controls = new THREE.OrbitControls(camera, view1Elem); controls.target.set(0, 5, 0); controls.update(); camera2.position.set(16, 28, 40); camera2.lookAt(0, 5, 0); //旋转控制器 const controls2 = new THREE.OrbitControls(camera2, view2Elem); controls2.target.set(0, 5, 0); controls2.update(); } function drawObj() { //面的绘制  { const planeSize = 40; const loader = new THREE.TextureLoader(); const texture = loader.load( "https://threejsfundamentals.org/threejs/resources/images/checker.png" ); texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.magFilter = THREE.NearestFilter; const repeats = planeSize / 2; texture.repeat.set(repeats, repeats); const planeGeo = new THREE.PlaneBufferGeometry(planeSize, planeSize); const planeMat = new THREE.MeshPhongMaterial({ map: texture, side: THREE.DoubleSide }); const mesh = new THREE.Mesh(planeGeo, planeMat); mesh.rotation.x = Math.PI * -0.5; scene.add(mesh); } //正方体的绘制  { const cubeSize = 4; const cubeGeo = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize); const cubeMat = new THREE.MeshPhongMaterial({ color: "#8AC" }); const mesh = new THREE.Mesh(cubeGeo, cubeMat); mesh.position.set(cubeSize + 1, cubeSize / 2, 0); scene.add(mesh); } //球体的绘制  { const sphereRadius = 3; const sphereWidthDivisions = 32; const sphereHeightDivisions = 16; const sphereGeo = new THREE.SphereBufferGeometry( sphereRadius, sphereWidthDivisions, sphereHeightDivisions ); const sphereMat = new THREE.MeshPhongMaterial({ color: "#CA8" }); const mesh = new THREE.Mesh(sphereGeo, sphereMat); mesh.position.set(-sphereRadius - 1, sphereRadius + 2, 0); scene.add(mesh); } //光线的设置  { const color = 0xffffff; const intensity = 1; const light = new THREE.DirectionalLight(color, intensity); light.position.set(0, 10, 0); light.target.position.set(-5, 0, 0); scene.add(light); scene.add(light.target); } } //重新渲染 渲染器的大小,如果canvas的大小不是renderer的大小,就重新设置大小 canvas的大小,这个是因为 function resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement; const width = canvas.clientWidth; const height = canvas.clientHeight; const needResize = canvas.width !== width || canvas.height !== height; if (needResize) { renderer.setSize(width, height, false); } return needResize; } //剪刀,用来切割canvas 到两个view中,通过view切割计算,找到view的位置,然后进行渲染 function setScissorForElement(elem) { const canvasRect = canvas.getBoundingClientRect(); //包围盒的正方体 const elemRect = elem.getBoundingClientRect(); // compute a canvas relative rectangle const right = Math.min(elemRect.right, canvasRect.right) - canvasRect.left; const left = Math.max(0, elemRect.left - canvasRect.left); const bottom = Math.min(elemRect.bottom, canvasRect.bottom) - canvasRect.top; const top = Math.max(0, elemRect.top - canvasRect.top); const width = Math.min(canvasRect.width, right - left); const height = Math.min(canvasRect.height, bottom - top); // setup the scissor to only render to that part of the canvas const positiveYUpBottom = canvasRect.height - bottom; renderer.setScissor(left, positiveYUpBottom, width, height); renderer.setViewport(left, positiveYUpBottom, width, height); // return the aspect return width / height; } function render() { resizeRendererToDisplaySize(renderer); // turn on the scissor 开启剪刀,可以进行切割 renderer.setScissorTest(true); // render the original view  { const aspect = setScissorForElement(view1Elem); // update the camera for this aspect camera.left = -aspect; camera.right = aspect; camera.updateProjectionMatrix(); cameraHelper.update(); // don't draw the camera helper in the original view cameraHelper.visible = false; scene.background.set(0x000000); renderer.render(scene, camera); } // render from the 2nd camera  { const aspect = setScissorForElement(view2Elem); // update the camera for this aspect camera2.aspect = aspect; camera2.updateProjectionMatrix(); // draw the camera helper in the 2nd view cameraHelper.visible = true; scene.background.set(0x000040); renderer.render(scene, camera2); } requestAnimationFrame(render); } window.onload = function() { canvas = document.querySelector("#c"); view1Elem = document.querySelector("#view1"); view2Elem = document.querySelector("#view2"); init(); setCarema(); drawObj(); requestAnimationFrame(render); };

上面这个例子有点小复杂,因为涉及到,剪刀进行切割视图的计算

转载于:https://www.cnblogs.com/xuqp/p/11060268.html

threejs CameraHelper 查看照相机的观察范围相关推荐

  1. threejs灯光阴影

    threejs设置阴影有三个注意点 1.只有支持阴影的灯光才可以 pointLight,spotlight,directionallight 2.添加摄像机辅助器 THREE.CameraHelper ...

  2. 模拟ARP报文发送,通过改变拓扑结构,观察报文发送方法以及途径

    首先创建合适的拓扑结构 输入各PC端的IP地址 观察PC0的观察窗口,可以看到ARP并没有什么,顺便查看了IP地址: 查看PC1的观察窗口 由PC0向PC1传送一个简单文件,观察ARP的运行过程 从上 ...

  3. 游戏mod(组模)模型,材质查看制作入门经典教程

    最近玩起了,模拟人生,战地2等游戏,发现他们都有mod包或者是网友自制的模型.   本文由于篇幅限制,只能讲解模型和音乐.材质等制作和修改,文章中提到工具可以找到很多教程以及下载资源,本文就不提了(不 ...

  4. Linux 知识点归纳(一) 进程概念 以及 查看进程的方法

    进程概念    什么叫做进程?我们在了解这个概念之前先要明白计算机CPU的工作原理,我们的程序在执行时,先将程序加载到内存中,之后CPU进行分时处理,那么什么又是分时处理呢,如果只有一个内核的情况下, ...

  5. three.js绘制过程(二)

    2019独角兽企业重金招聘Python工程师标准>>> 同一个场景中可以有多个摄像机,同一个屏幕缓冲区可以分块绘制不同的物体. WeblGLRender 中autoClear 设定为 ...

  6. 利用OpenCV实现抖音最强变脸术 | CSDN原力计划

    作者 | 亓斌 来源 | CSDN原力计划获奖作品 (*点击阅读原文,查看作者更多文章) 最近一个"最强变脸术"又火爆抖音啦,还不知道的朋友建议先打开抖音,搜索"最强变脸 ...

  7. 如何在 Python 中开始机器学习?(小白必看)

    其实学习机器学习的最好方法是设计和完成小项目. Python 是一种流行且功能强大的解释型语言.与 R 不同,Python 是一种完整的语言和平台,可用于研究和开发以及开发生产系统. 还有很多模块和库 ...

  8. mysql隐藏密码_MySQL在Linux系统中隐藏命令行中的密码的方法

    在命令行中输入命令并不是一个好主意,会造成安全问题.但是如果你决定去写一个应用,而这个应用需要在命令行中使用密码或者其他敏感信息.那么,你能通过以下方法禁止系统的其他用户轻易的看到这些敏感数据 呢?, ...

  9. 《Adobe Fireworks CS6中文版经典教程》——1.2工具面板

    本节书摘来自异步社区<Adobe Fireworks CS6中文版经典教程>一书中的第1 章,第1.2节,作者:[美]Adobe公司 更多章节内容可以访问云栖社区"异步社区&qu ...

最新文章

  1. 用程序消除一道概率题的二义性
  2. 简单使用gridlayout
  3. Web群集与日志管理Haproxy搭建
  4. vue项目发布时去除console语句
  5. deep-sort 代码阅读(https://github.com/nwojke/deep_sort)
  6. java请假系统毕业设计_jsp企业员工考勤管理系统
  7. win10无法正常弹出移动硬盘/U盘
  8. 树莓派驱动数码管c 语言,用树莓派驱动八段数码管实现倒计时
  9. 怎么查看电脑的电池损耗情况?
  10. 如何给自己的U盘自定义图标
  11. 定价的艺术:苹果和网飞对最优订阅价格的理解
  12. C语言进阶剖析 13 接续符和转义符
  13. 调焦后焦实现不同距离成像_相机的“对焦”和“变焦”,这二者有什么区别?...
  14. 给h264帧增加start code和sps/pps
  15. 求x的y次方,结果模10007
  16. Avaya陈蔚:新技术优化保险业务流程
  17. np.einsum(爱因斯坦求和约定)
  18. LabVIEW练习5
  19. 国产linux视频播放软件下载,JMPlayer:开发中的国产Linux音乐播放器
  20. 短网址生成php源码

热门文章

  1. 如何下载HLS视频到本地(m3u8)
  2. Spring+Struts集成(方案一)
  3. Quote Form OnLoad Implement Add Leftnav, count Activities
  4. 一个axios的简单教程
  5. LeetCode(122)——买卖股票的最佳时机 II(JavaScript)
  6. 计算机网络学习笔记(9. 报文交换与分组交换③)
  7. cpu 被挂起和阻塞_同步异步阻塞非阻塞并发并行讲解
  8. 为什么要从vmware切换到kvm?
  9. 酒局中同事说“不把这杯酒喝了就是不给我面子”,我该怎么办?
  10. 高瓴突然清仓阿里巴巴、蔚来、理想、小鹏,是怎么回事?