返回介绍

Three.js浏览器窗口尺寸变化(自适应渲染)

发布于 2021-07-10 20:14:16 字数 3025 浏览 1104 评论 0 收藏 0

开发的过程中你可能会遇到这样一个问题,通过鼠标拖动使浏览器的窗口变大,因为Threejs渲染器的渲染尺寸范围没有跟着变化,出现局部空白区域。对于这种情况要做的就是重新获取浏览器窗口新的宽高尺寸,然后通过新的宽高尺寸更新相机Camera和渲染器WebGLRenderer的参数即可。

视图矩阵.matrixWorldInverse和投影矩阵.projectionMatrix

所谓相机对象Camera本质上就是视图矩阵.matrixWorldInverse和投影矩阵.projectionMatrix,Threejs渲染场景的时候调用相机对象的视图矩阵和投影矩阵值对顶点进行矩阵变换。

上节课讲解过正投影相机OrthographicCamera和透视投影相机PerspectiveCamera,其实对相机对象一些参数的设置本质上就是设置相机对象的视图矩阵.matrixWorldInverse和投影矩阵.projectionMatrix属性,因为Threejs渲染的时候会通过你设置的相机参数按照一定的算法计算出来投影和视图矩阵值,至于如何计算的,如果你想深入研究,你可以学习计算机图形学或者查看OrthographicCamera和PerspectiveCamera类封装的代码。如果你不想深入研究,只要知道相机参数会影响视图矩阵和投影矩阵就行,至于内部如何影响的可以当成黑箱。

影响视图矩阵.matrixWorldInverse计算的相关代码,无论透视投影相机还是正投影相机都一样。

camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

影响投影矩阵.projectionMatrix计算相机参数的相关代码

// 正投影相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
// 透视投影相机对象
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);

正投影相机OrthographicCamera自适应渲染

比如全屏渲染的时候,为了适应窗口的大小变化,要重新设置相机对象和渲染器对象的参数,不需要在渲染函数render中周期性更新,只需要通过窗口事件window.onresize来触发一个函数,然后在函数中更新相机Camera和渲染器WebGLRenderer的参数。

渲染区域变化了,要通过Three.js渲染器.setSize()方法重置渲染器渲染尺寸。

// onresize 事件会在窗口被调整大小时发生
window.onresize=function(){
  // 重置渲染器输出画布canvas尺寸
  renderer.setSize(window.innerWidth,window.innerHeight);
  // 重置相机投影的相关参数
  k = window.innerWidth/window.innerHeight;//窗口宽高比
  camera.left = -s*k;
  camera.right = s*k;
  camera.top = s;
  camera.bottom = -s;
  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
  // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
  camera.updateProjectionMatrix ();
};

渲染区域尺寸变化,相机的相关参数自然也需要变化,改变相机的参数后,注意需要执行相机对象.updateProjectionMatrix ()方法更新相机对象的投影矩阵.projectionMatrix,之所以需要手动更新,是因为Threejs为了提高渲染效率,Threejs系统每次执行渲染器WebGLRenderer渲染方法.rener()的时候不会读取相机相关的参数重新计算一次投影矩阵.projectionMatrix,Threejs系统只会首次渲染的时候计算一次投影矩阵,所以当你改变影响相机投影矩阵的属性,自然需要调用.updateProjectionMatrix ()更新相机对象的投影矩阵.projectionMatrix

透视投影相机PerspectiveCamera自适应渲染

// onresize 事件会在窗口被调整大小时发生
window.onresize=function(){
  // 重置渲染器输出画布canvas尺寸
  renderer.setSize(window.innerWidth,window.innerHeight);
  // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
  camera.aspect = window.innerWidth/window.innerHeight;
  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
  // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
  camera.updateProjectionMatrix ();
};

Three.js自适应渲染不一定就是窗口变化,本质上还是你要渲染的区域宽高尺寸变化了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文