学习threejs,PerspectiveCamera透视相机和OrthographicCamera正交相机对比

news2024/12/28 10:49:17

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师

文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE.PerspectiveCamera透视相机
    • 1.2 ☘️THREE.OrthographicCamera正交相机
  • 二、🍀PerspectiveCamera透视相机和OrthographicCamera正交相机对比
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中PerspectiveCamera透视相机和OrthographicCamera正交相机进行对比,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE.PerspectiveCamera透视相机

THREE.PerspectiveCamera这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。
构造函数:
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面
这些参数一起定义了摄像机的viewing frustum(视锥体)。
属性:
在这里插入图片描述
方法:
在这里插入图片描述

1.2 ☘️THREE.OrthographicCamera正交相机

THREE.OrthographicCamera正交相机在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。
这对于渲染2D场景或者UI元素是非常有用的。
构造函数:
OrthographicCamera( left : Number, right : Number, top : Number, bottom : Number, near : Number, far : Number )
left — 摄像机视锥体左侧面。
right — 摄像机视锥体右侧面。
top — 摄像机视锥体上侧面。
bottom — 摄像机视锥体下侧面。
near — 摄像机视锥体近端面。
far — 摄像机视锥体远端面。
这些参数一起定义了摄像机的viewing frustum(视锥体)。
属性:
在这里插入图片描述
方法:
在这里插入图片描述

二、🍀PerspectiveCamera透视相机和OrthographicCamera正交相机对比

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景scene。
  • 3、初始化PerspectiveCamera透视相机camera,定义相机位置 camera.position。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源。创建THREE.DirectionalLight平行光源directionalLight,设置平行光源位置,scene场景加入平行光源。
  • 5、加载几何模型:创建THREE.PlaneGeometry平面几何体planeGeometry,创建THREE.MeshLambertMaterial漫反射材质planeMaterial,传入参数planeGeometry和planeMaterial创建平面几何体网格对象plane,设置plane投影,设置plane的位置和旋转角度,场景scene中加入plane。在plane上循环创建立方体网格对象cube,将plane铺满,具体代码参考代码样例。
  • 6、加入gui控制,实现PerspectiveCamera透视相机和OrthographicCamera正交相机的切换,进行效果对比。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>

<html>

<head>
    <title>PerspectiveCamera透视相机和OrthographicCamera正交相机对比</title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <script type="text/javascript" src="../libs/stats.js"></script>
    <script type="text/javascript" src="../libs/dat.gui.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">

    // once everything is loaded, we run our Three.js stuff.
    function init() {

        var stats = initStats();

        // create a scene, that will hold all our elements such as objects, cameras and lights.
        var scene = new THREE.Scene();

        // create a camera, which defines where we're looking at.
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.x = 120;
        camera.position.y = 60;
        camera.position.z = 180;

        // create a render and set the size
        var renderer = new THREE.WebGLRenderer();

        renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
        renderer.setSize(window.innerWidth, window.innerHeight);

        // create the ground plane
        var planeGeometry = new THREE.PlaneGeometry(180, 180);
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);


        // rotate and position the plane
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 0;
        plane.position.y = 0;
        plane.position.z = 0;

        // add the plane to the scene
        scene.add(plane);

        var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);

        for (var j = 0; j < (planeGeometry.parameters.height / 5); j++) {
            for (var i = 0; i < planeGeometry.parameters.width / 5; i++) {
                var rnd = Math.random() * 0.75 + 0.25;
                var cubeMaterial = new THREE.MeshLambertMaterial();
                cubeMaterial.color = new THREE.Color(rnd, 0, 0);
                var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
                cube.position.z = -((planeGeometry.parameters.height) / 2) + 2 + (j * 5);
                cube.position.x = -((planeGeometry.parameters.width) / 2) + 2 + (i * 5);
                cube.position.y = 2;
                scene.add(cube);
            }
        }


        var directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
        directionalLight.position.set(-20, 40, 60);
        scene.add(directionalLight);


        // add subtle ambient lighting
        var ambientLight = new THREE.AmbientLight(0x292929);
        scene.add(ambientLight);

        // add the output of the renderer to the html element
        document.getElementById("WebGL-output").appendChild(renderer.domElement);

        // call the render function
        var step = 0;

        var controls = new function () {
            this.perspective = "Perspective";
            this.switchCamera = function () {
                if (camera instanceof THREE.PerspectiveCamera) {
                    camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
                    camera.position.x = 120;
                    camera.position.y = 60;
                    camera.position.z = 180;
                    camera.lookAt(scene.position);
                    this.perspective = "Orthographic";
                } else {
                    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
                    camera.position.x = 120;
                    camera.position.y = 60;
                    camera.position.z = 180;

                    camera.lookAt(scene.position);
                    this.perspective = "Perspective";
                }
            };
        };

        var gui = new dat.GUI();
        gui.add(controls, 'switchCamera');
        gui.add(controls, 'perspective').listen();

        // make sure that for the first time, the
        // camera is looking at the scene
        camera.lookAt(scene.position);
        render();

        function render() {

            stats.update();
            // render using requestAnimationFrame
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }

        function initStats() {

            var stats = new Stats();

            stats.setMode(0); // 0: fps, 1: ms

            // Align top-left
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.left = '0px';
            stats.domElement.style.top = '0px';

            document.getElementById("Stats-output").appendChild(stats.domElement);

            return stats;
        }
    }
    window.onload = init


</script>
</body>
</html>

效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2266880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

apifox

请求头head 如果传json串的话&#xff0c;需要将Content-Type覆盖为application/json 请求体body 有一个场景&#xff1a;我先创建任务&#xff0c;返回值为任务id&#xff0c;接着我要去根据任务id 删除这个任务 如果创建任务api的返回值中&#xff0c;任务id是以数组/ 对象…

虚幻引擎结构之ULevel

在虚幻引擎中&#xff0c;场景的组织和管理是通过子关卡&#xff08;Sublevel&#xff09;来实现的。这种设计不仅提高了资源管理的灵活性&#xff0c;还优化了游戏性能&#xff0c;特别是在处理大型复杂场景时。 1. 场景划分模式 虚幻引擎采用基于子关卡的场景划分模式。每个…

基于SpringBoot在线音乐系统平台功能实现十七

一、前言介绍&#xff1a; 1.1 项目摘要 随着互联网技术的迅猛发展和普及&#xff0c;人们对音乐的获取和欣赏方式发生了巨大改变。传统的音乐播放方式&#xff0c;如CD、磁带或本地下载的音乐文件&#xff0c;已经不能满足用户日益增长的需求。用户更希望通过网络直接获取各…

圣诞树的装饰挑战:非线性分析能阻止圣诞树倒塌吗?

节日带来了独特的机会让我们看到工程原理可以在意想不到的地方大展身手&#xff0c;比如装饰圣诞树。 实际上&#xff0c;Altair 技术专家 Matthew Sauer 在装饰他家的圣诞树时就遇到了这样的机会。从一个节日传统开始&#xff0c;很快就变成了一个引人入胜的非线性分析案例研究…

线性代数行列式

目录 二阶与三阶行列式 二元线性方程组与二阶行列式 三阶行列式 全排列和对换 排列及其逆序数 对换 n阶行列式的定义 行列式的性质 二阶与三阶行列式 二元线性方程组与二阶行列式 若是采用消元法解x1、x2的话则得到以下式子 有二阶行列式的规律可得&#xff1a;分…

京东零售数据可视化平台产品实践与思考

导读 本次分享题目为京东零售数据可视化平台产品实践与思考。 主要包括以下四个部分&#xff1a; 1. 平台产品能力介绍 2. 业务赋能案例分享 3. 平台建设挑战与展望 作者&#xff1a;梁臣 京东 数据产品架构师 01平台产品能力介绍 1. 产品矩阵 数据可视化产品是一种利用…

对外发PDF设置打开次数

在线 Host PDF 文件并对链接进行限制——保障文件安全的最佳解决方案 在数字化办公和远程协作日益普及的今天&#xff0c;如何安全高效地分享 PDF 文件成为许多用户关注的重点。MaiPDF 作为一款功能强大的在线工具&#xff0c;不仅支持在线 host PDF 文件&#xff0c;还提供多…

在国产电脑上运行PDFSAM软件使用pdf分割合并交替混合处理pdf文档

软件下载地址: https://sourceforge.net/projects/pdfsam/files/ 需要注意事项&#xff0c;系统需要java环境&#xff0c;确认系统有java环境&#xff0c;根据软件版本需求安装对应的java运行环境。 下载pdfsam-4.3.4-linux.tar.gz安装包&#xff0c;解压&#xff0c;将runt…

leetcode-42.接雨水-day19

思路&#xff1a;将一整个区域分成若干个小区域看&#xff0c;高低起伏 1.记录每个板子上的雨水数量&#xff0c;最后相加求和。h板高 2.-->由于每个板子区间能装多少水取决于他的最大前缀板高和最大后缀板高&#xff0c; 3. 然后根据短板效应&#xff0c;则每个板子区间最多…

Postman接口测试02|接口用例设计

目录 六、接口用例设计 1、接口测试的测试点&#xff08;测试维度&#xff09; 1️⃣功能测试 2️⃣性能测试 3️⃣安全测试 2、设计方法与思路 3、单接口测试用例 4、业务场景测试用例 1️⃣分析测试点 2️⃣添加员工 3️⃣查询员工、修改员工 4️⃣删除员工、查询…

自定义kali:增加60+常用渗透工具,哥斯拉特战版,cs魔改应有尽有,菜单栏启动

前言&#xff1a; 集合了六十多个工具&#xff0c;有师傅说需要&#xff0c;特搞来&#xff0c;我是脚本小子我爱用 介绍&#xff1a; 主要在菜单增加了非常多别人现成的工具&#xff0c;工具名单&#xff1a; 信息收集&#xff1a; 密探渗透测试工具 水泽 ehole 灯塔 …

数据结构(Java)——链表

1.概念及结构 链表是一种 物理存储结构上非连续 存储结构&#xff0c;数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 2.分类 链表的结构非常多样&#xff0c;以下情况组合起来就有 8 种链表结构&#xff1a; &#xff08;1&#xff09;单向或者双向 &#xff08;…

Linux 文件的特殊权限—Sticky Bit(SBIT)权限

本文为Ubuntu Linux操作系统- 第十九期~~ 其他特殊权限: 【SUID 权限】和【SGID 权限】 更多Linux 相关内容请点击&#x1f449;【Linux专栏】~ 主页&#xff1a;【练小杰的CSDN】 文章目录 Sticky&#xff08;SBIT&#xff09;权限基本概念Sticky Bit 的表示方式举例 设置和取…

PPT画图——如何设置导致图片为600dpi

winr&#xff0c;输入regedit打开注册表 按路径找&#xff0c;HKEY_CURRENT_USER\Software\Microsoft\Office\XX.0\PowerPoint\Options&#xff08;xx为版本号&#xff0c;16.0 or 15.0或则其他&#xff09;。名称命名&#xff1a;ExportBitmapResolution 保存即可&#xff0c;…

小米汽车加速出海,官网建设引领海外市场布局!

面对国内市场的饱和态势&#xff0c;中国企业出海步伐纷纷加速&#xff0c;小米也是其中的一员。Canalys数据显示&#xff0c;2024年第三季度&#xff0c;小米以13.8%的市场份额占比&#xff0c;实现了连续17个季度位居全球前三的成绩。 据“36 氪汽车”报道&#xff0c;小米汽…

Cocos Creator 试玩广告开发 第二弹

上一篇的项目是2d的&#xff0c;现在谈谈对于3d试玩项目的一些经历。 相对于2d来说&#xff0c;3d的项目更接近于Unity的开发&#xff0c;但是也有很多不一样的地方&#xff0c;具体的也可以参考Cocos给他官方示例。 Unity 开发者入门 Cocos Creator 快速指南 | Cocos Creator…

CTFshow—爆破

Web21 直接访问页面的话会弹窗需要输入密码验证&#xff0c;抓个包看看&#xff0c;发现是Authorization认证&#xff0c;Authorization请求头用于验证是否有从服务器访问所需数据的权限。 把Authorization后面的数据进行base64解码&#xff0c;就是我们刚刚输入的账号密码。 …

docker-开源nocodb,使用已有数据库

使用已有数据库 创建本地数据库 数据库&#xff1a;nocodb 用户&#xff1a;nocodb 密码&#xff1a;xxxxxx修改docker-compose.yml 默认网关的 IP 地址是 172.17.0.1&#xff08;适用于 bridge 网络模式&#xff09;version: "2.1" services:nocodb:environment:…

UGUI简单动画制作

一、最终效果 UI简单动画制作 二、制作过程 1、打开动画制作窗口 2、新建一个动画 3、给一个对象制作动画 4、创建动画控制器进行不同动画变换控制 5、书写脚本&#xff0c;通过按钮来进行不同动画切换 using System.Collections; using System.Collections.Generic; using U…

[SAP ABAP] 程序备份

备份当前程序到本地的方式如下&#xff1a; 1.复制粘贴 Ctrl A 、Ctrl V 2.【实用程序】|【更多实用程序】|【上载/下载】|【下载】 ​ 3.快捷键&#xff0c;支持多种格式导出(.abap .html .pdf 等) 在事务码SE38(ABAP编辑器)屏幕右下角&#xff0c;点击【Options选项】图…