Three.js - 透视相机(PerspectiveCamera)(三)

news2024/11/17 23:44:52

简介

three.js中,摄像机的作用就是不断的拍摄我们创建好的场景,然后通过渲染器渲染到屏幕中。想通过不同的角度观看场景,就需要修改摄像机的位置来拍摄场景。本文详细介绍的是透视相机(PerspectiveCamera) 它是用来模拟人眼所看到的景象,它也是3D场景的渲染中使用得最普遍的投影模式。

透视相机(PerspectiveCamera)

  • 根据视锥的范围给渲染器提供需要渲染的场景范围。
  • 实例化new THREE.PerspectiveCamera() 接受4个参数来确认视锥的范围。只要在视锥范围内的场景才会渲染。
  1. fov 摄像机视锥体垂直视野角度。
  2. aspect 摄像机视锥体长宽比。
  3. near 摄像机视锥体近端面。
  4. far 摄像机视锥体远端面。

1.jpg

属性

  • 大多数属性发生改变之后,都需要调用.updateProjectionMatrix()来使得这些改变生效。
  • 常见属性:
  1. .fov、.aspect、.near、.far 后期可修改这四个参数,来实现动画效果。
  2. .zoom 获取或者设置摄像机的缩放倍数,默认值为1

方法

  • 常见方法:
  1. .setViewOffset() 设置偏移量,对于多窗口或者多显示器的设置是很有用的。
  2. .clearViewOffset() 清除任何由.setViewOffset()设置的偏移量。
  3. .getEffectiveFOV() 结合.zoom(缩放倍数),以角度返回当前垂直视野角度。
  4. .updateProjectionMatrix() 更新摄像机投影矩阵。在任何参数被改变以后必须被调用。

位置

PerspectiveCamera对象的基类是Object3D,它具有:

  1. .position 设置相机在三维坐标中的位置。
 camera.position.set(0,0,0);
  1. .up 设置相机拍摄时相机头顶的方向。
 camera.up.set(0,1,0);
  1. .lookAt 设置相机拍摄时指向的方向。
camera.lookAt(0, 0, 0);

开始使用

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>学习</title>
  </head>
  <body>
    <canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
    <script type="module">
      import * as THREE from 'https://threejs.org/build/three.module.js'

      const canvas = document.querySelector('#c2d')
      // 渲染器
      const renderer = new THREE.WebGLRenderer({ canvas })

      const fov = 40 // 视野范围
      const aspect = 2 // 相机默认值 画布的宽高比
      const near = 0.1 // 近平面
      const far = 1000 // 远平面
      // 透视投影相机
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
      camera.position.set(0, 10, 20)
      camera.lookAt(0, 0, 0)

      // 场景
      const scene = new THREE.Scene()
      scene.background = new THREE.Color('black')

      {
        // 地面 平铺
        const planeSize = 20
        const loader = new THREE.TextureLoader()
        const texture = loader.load('https://threejs.org/manual/examples/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.PlaneGeometry(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.BoxGeometry(cubeSize, cubeSize, cubeSize)
        const cubeMat = new THREE.MeshPhongMaterial({ color: '#8f4b2e' })
        const mesh = new THREE.Mesh(cubeGeo, cubeMat)
        mesh.position.y = 2
        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)
      }

      // 渲染
      function render() {
        renderer.render(scene, camera)
        requestAnimationFrame(render)
      }

      requestAnimationFrame(render)
    </script>
  </body>
</html>

image.png

  • 本节我们详细了解透视相机,其他内容只需要先熟悉。

修改相机

  • 在页面上添加按钮,修改相机。
  • 需要注意的是透视相机的矩阵信息修改后,都需要执行.updateProjectionMatrix()来应用改变。
    ...
    <canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
    <input id="onPosition" type="button" value="移动位置" />
    <input id="onView" type="button" value="修改视野范围" />
    ...
    
    // 透视投影相机
    ...
    
    // 点击 移动相机
    document.querySelector('#onPosition').addEventListener('click', function () {
        camera.position.set(0, 20, 20)
    })

    // 点击 修改相机 视野范围
    document.querySelector('#onView').addEventListener('click', function () {
        camera.fov = 20
        camera.updateProjectionMatrix()
    })
    
    ...

1.gif

添加相机控件

  • Three.js提供了许多控件OrbitControls是最常用的相机控件。
... 
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'
...

// 透视投影相机
...

// 控制相机
const controls = new OrbitControls(camera, canvas)
...

// 渲染
function render() {
    controls.update()
    ...
}

1.gif

添加相机辅助线

  • Three.js提供了一个函数(CameraHelper)用于模拟相机视锥体。要展示模拟相机视锥体,需要两个相机才能查看。
...
<input id="cameraBol" type="button" value="切换相机" />

...
// 场景
...
// 辅助相机
const camera1 = new THREE.PerspectiveCamera(20, aspect, 10, 50)
camera1.position.set(0, 5, 20)
camera1.lookAt(0, 0, 0)
const cameraHelper = new THREE.CameraHelper(camera1)
// 辅助线加入 场景
scene.add(cameraHelper)
let cameraBol = true
// 点击 切换相机
document.querySelector('#cameraBol').addEventListener('click', function () {
cameraBol = !cameraBol
})
...

// 渲染
function render() {
    ...

    cameraHelper.update()
    if (cameraBol) {
      renderer.render(scene, camera)
    } else {
      renderer.render(scene, camera1)
    }

    ...
}

1.gif

  • 黄色线的范围表示相机视锥体的范围
  • 这里通过切换渲染器传入的相机参数,来展示辅助相机需要渲染的内容。

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

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

相关文章

React Hooks(钩子函数)

React Hooks什么是Hooks?UseState()useReducer()useContext()useEffect()useRef()自定义钩子函数React Hooks中可以对性能进行优化的函数useMemo()useCallback()useMemo()和useCallback()的区别什么是Hooks? 首先&#xff1a;React的组件创建方式&#xff0c;一种是类组件&a…

划水日常(16.5)关于出版图书有偿征集书名 ~

关于摸鱼日常已经断更两个月了&#xff0c;前段时间一直忙在项目上&#xff0c;再加上搭了个网站&#xff0c;你要说有事儿吧&#xff0c;其实事儿也不多。你要说没事儿吧&#xff0c;我就是不更。原因其实很简单&#xff0c;我懒&#xff01; 可直接跳过目录一&#xff0c;直至…

web自动化测试入门篇02——selenium安装教程

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

授予渔,从0开始搭建一个自己想要的网页

文章目录视频展示&#xff1a;张娜英网页一.开始阶段1.1考虑出基本的架构1.2填充思路1.3前提准备二.实现阶段2.1导航栏实现2.2点击切换视频2.3 左右特效2.4照片墙2.5视频轮播2.6底部2.7点击切换全局变量3.总结全部代码&#xff1a;☀️作者简介&#xff1a;大家好我是言不及行y…

【实战】React 必会第三方插件 —— Cron 表达式生成器(qnn-react-cron)

文章目录一、引子二、配置使用1.安装2.使用&#xff08;1&#xff09;直接调用&#xff08;2&#xff09;赋值到表单&#xff08;Form&#xff09;&#xff08;3&#xff09;自定义功能按钮&#xff08;4&#xff09;隐藏指定 Tab&#xff08;5&#xff09;其他三、常见问题及解…

【JavaScript 进阶教程】数组新增遍历方法的说明与使用

文章已收录专栏&#xff1a;JavaScript 进阶教程 作者&#xff1a;卡卡西最近怎么样 文章导读&#xff1a; 欢迎来到 JavaScript 进阶的学习&#xff0c;ES5 对 JS 的数组&#xff0c;字符串等内置对象的方法均有扩充。这篇文章我们要掌握的是新增的几个 Array 内置对象的常用迭…

【Web理论篇】Web应用程序安全与风险

目录&#x1f332;1.Web应用程序的发展历程&#x1f342;1.1 Web应用程序的常见功能&#x1f342;1.2 Web应用程序的优点&#x1f332;2.Web安全&#x1f342;2.1Web应用程序常见漏洞&#x1f342;2.2未对用户输入做过滤&#x1f342;2.3 造成这些漏洞的原因是什么呢&#xff1…

【实战分享】js生成word(docx),以及将word转成pdf解决方案分享

本文将记录如何用js生成word文件&#xff0c;并在node服务器端将word转换成pdf。记录的代码均是在真实业务场景中使用成功的代码&#xff0c;没有记录中间踩坑的过程。想直接抄答案的家人们可以跳转到1.2 程序编写部分&#xff0c;最终效果图可在1.2 程序编写部分中4. 效果展示…

【解决前端报错】Bad Request: Required request parameter ‘id‘ for method parameter type Long is not present

后端查询列表接口返回的对象里包含Long id,前端获取到这个id,执行通过Long id删除操作。这时删除操作报错400&#xff0c;大意是没找着Long类型的id. swagger相关接口截图&#xff1a; Long类型的在swagger显示是integer64 &#xff0c; integer是integer32. 这是前端请求后…

微信公众号 - 实现 H5 网页在微信内置浏览器中下载文件,可预览和下载 office 文件(doc / xls / ppt / pdf 等)适用于任何前端技术栈网站,兼容安卓和苹果系统!

前言 网上的教程都是让你写页面 “引导” 右上角三个点里,让用户自己去浏览器打开,其实这样用户体验并不好。 本文实现了 最新微信公众号 H5 网页(微信内置浏览器中),预览下载 office 文件,安卓和苹果全都支持! 您可以直接复制代码,移植到自己项目中去,任何前端项目(…

全网超详细的【Axure】Axure RP 9的下载、安装、中文字体、授权

文章目录1. 文章引言2. 下载Axure93. 安装Axure94. Axure9中文5. Axure9授权1. 文章引言 最近在学习原型图&#xff0c;针对画原型图的工具&#xff0c;反复对比墨刀、Axure、xiaopiu后&#xff0c;最终选择了Axure。 接下来&#xff0c;我便从Axure RP 9的下载、安装、中文字…

VUE实现微信扫码登录

获取access_token时序图&#xff1a; public中index.html引入 <script src"https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script> 微信登录操作 new WxLogin({// 以下操作把请求到的二维码嵌入到id为"weixin"的标签中i…

走进Vue【三】vue-router详解

目录&#x1f31f;前言&#x1f31f;路由&#x1f31f;什么是前端路由&#xff1f;&#x1f31f;前端路由优点缺点&#x1f31f;vue-router&#x1f31f;安装&#x1f31f;路由初体验1.路由组件router-linkrouter-view2.步骤1. 定义路由组件2. 定义路由3. 创建 router 实例4. 挂…

VUE3 子传父 父传子 双向传递

组件参数传递 父传子 father.vue <template > <!-- 父传子实现 2.向vue页面中的子组件传递该属性 :传给子组件的名字&#xff08;自定义&#xff09;“对应定义在父组件的属性名” --><Header :openpagevaria"openpagevaria" ></Header&g…

使用vue-cli-plugin-electron-builder创建electron+vue项目

文章目录一、nvm环境二、安装vue-cli、yarn三、使用vue项目管理器创建项目四、使用vue项目管理器安装插件五、进入my-electron-vue目录&#xff0c;启动electron六、安装VueDevtools&#xff0c;解决Vue Devtools failed to install: Error: net::ERR_CONNECTION_TIMED_OUT——…

npm install xxxx --legacy-peer-deps命令是什么?

本文分享自华为云社区《npm install xxxx --legacy-peer-deps命令是什么&#xff1f;为什么可以解决下载时候产生的依赖冲突呢&#xff1f;》&#xff0c;作者&#xff1a; gentle_zhou 。 在日常使用命令npm install / npm install XX下载依赖的操作中&#xff0c;我经常会遇…

npm 报错“A complete log of this run can be found in:”解决方法

npm 启动项目 npm run serve/dev的时候报了个错&#xff1a;再次记录一下 ! code ELIFECYCLE npm ERR! errno 1 npm ERR! new0.1.0 serve: vue-cli-service serve npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the new0.1.0 serve script. npm ERR! This is probably n…

【CSS 文字渐变、背景渐变实现方式】

CSS 文字渐变&#xff0c;背景渐变的几种实现方式 在我们日常页面开发当中&#xff0c;使用合适的css渐变效果能让我们的界面更加美观&#xff0c;赏心悦目。 一、CSS 文字渐变&#xff1a; 首先&#xff0c;文字渐变实际上是通过背景渐变裁剪成文字的前景色&#xff0c;然后…

【微信小程序】初入微信小程序

大家好我依旧是山鱼&#x1f41f;&#xff0c;对于初入小程序的同学来说本篇依旧是你的不二选择&#xff0c;它详细的介绍了小程序及小程序&开发者工具的使用&#xff0c;大家快快学起来吧&#xff01; 目录 一&#xff0c;小程序简介 1.1 什么是微信小程序 1.2小程序与…

前端实现一个名言生成器

The sand accumulates to form a pagoda✨ 写在前面✨ JS是什么&#xff1f;✨ 名言生成器✨ 页面搭建✨ 功能实现✨ 写在前面 在上周我们通过HTML、CSS实现了一个简单的‘我的相册‘页面的搭建&#xff0c;很多伙伴呢跟我说难道前端就只能做一些页面搭建的工作吗&#xff1f;…