当前位置: 首页 > news >正文

记录下three.js学习过程中不理解问题①

1、透视相机(persperctive)参数理解

const fov = 75;指的是垂直方向的视野范围。

      摄像机视角(fov = 75)
             👁️
            /   \
           /     \     ← 这个夹角就是 75°
          /       \
         /         \
        /___________\  
     near         far

 

摄像机(你)看向前方:
  👁️ —— fov 是你张开眼睛的角度(决定你能看到多广)
   |
  / \
 /   \       ← 看得见的区域(远处的 pyramid)= frustum
|     |     ← 视锥体(frustum)从 near 到 far 之间才看得见
 near        ← 最近 0.1 米
   |
   |
 far         ← 最远 5 米

参数通俗记忆作用
fov视角开多大决定上下看得多少
aspect屏幕长宽比不设置好画面会拉伸
near最近看多少太近的东西不显示
far最远看多远太远的东西不显示

1. 摄像机默认朝向

  • 摄像机默认看向 Z 轴的负方向(即从 z 正方向往 z 负方向看)。

  • 摄像机“上面”是 Y 轴正方向。

2. 为什么要把摄像机往后移?

  • 你的立方体放在坐标原点 (0,0,0)

  • 如果摄像机位置也是原点,那它就在立方体里面,看不到立方体。

  • 所以要把摄像机沿 z 轴正方向往后移动,比如设置 camera.position.z = 2,让摄像机离立方体远一点,这样才能“看到”立方体。

4. 宽高比对视野的影响

  • 画布宽度是高度的两倍(比如300×150像素),宽高比 = 2。

  • 垂直方向视角是你设置的75度,但水平方向视角会更大,因为画布宽了2倍。

  • 也就是说,水平视角会“拉宽”你的视野,让你能看到更宽的范围。

  • fov=75°是垂直方向的视角;

  • 画布宽高比=2,意味着水平视角比75°更大;

  • 这样才能保证3D画面在宽屏幕上完整显示,不会裁剪或变形。

  • . 视觉效果
  • 这个宽视角有点类似人眼的视野宽度:
    人眼上下视角比左右视角窄,因为你眼睛是水平放置的。

  • 在你的三维场景里,水平视角比75°大(可能是100度、120度等),让你能更广阔地看到左右的物体。

requestAnimationFrame 是浏览器提供的一个高效的动画方法,专门用来让页面里的动画“连续播放”。

工作原理:

  1. 它会告诉浏览器:“我准备好下一帧动画了,帮我安排合适的时间来刷新画面。”

  2. 浏览器会在每一帧合适的时间调用你指定的函数(比如更新旋转角度,重新绘制立方体)。

  3. 这个调用是循环的:每次画完一帧动画后,程序又调用自己,形成了动画的“循环”。为

     为什么不用普通的 setIntervalsetTimeout

  1. requestAnimationFrame 会根据屏幕刷新率来执行动画,动画更流畅,不会卡顿。

  2. 当页面不可见时(切换标签页),它会自动暂停动画,节省性能和电量。

  3. 更适合做基于视觉的动画和绘图。

    function render(time) {time *= 0.001;  // 将时间单位变为秒cube.rotation.x = time;cube.rotation.y = time;renderer.render(scene, camera);requestAnimationFrame(render);
    }
    requestAnimationFrame(render);

 

requestAnimationFrame(render); 的意思就是:

  • 告诉浏览器“请在下次重绘时调用 render 函数”。

  • 浏览器调用 render 时,会自动传入一个时间戳 time 参数,这个时间戳是当前页面从加载开始经过的毫秒数。

所以你不用自己传 time,浏览器帮你传进去,方便你根据时间来做动画计算。

总结一句话:

调用 requestAnimationFrame(render) 后,浏览器会自动给 render 函数传入时间戳 time 参数。

 

弧度和角度的关系

  • 一圈是360度。

  • 360度 = 2π弧度(π ≈ 3.1416)

  • 所以一圈的弧度就是:

2×π≈6.2832弧度

这里旋转角度用弧度表示time是经过time *= 0.001后单位为秒的时间。

也就是说,

  • 当时间为1秒时,旋转角度是1弧度。

  • 当时间为6.2832秒时,旋转角度是6.2832弧度,也就是一整圈。

让相机的视野始终和画布(canvas)保持一致比例,防止拉伸变形。

const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
  • canvas.clientWidth / canvas.clientHeight:获取实际画布宽高比(比如 800px / 400px = 2)

  • camera.aspect:更新相机的宽高比

  • camera.updateProjectionMatrix():重新计算相机的投影矩阵(必须的,不然相机不知道你改了宽高比)

为什么画面会“模糊”或“块状化”?

因为:

canvas 的 CSS显示尺寸像素分辨率(绘图缓冲区)不一致。

<canvas style="width: 800px; height: 600px"></canvas>

如果你没设置它的像素尺寸,浏览器默认是 300x150px
也就是说你让它显示为 800×600,但实际里面的像素分辨率只有 300×150,就像你用一张 300×150 的图片硬撑到 800×600,当然糊了!

正确做法:让 canvas 的像素尺寸 = CSS 尺寸

在 Three.js 中,我们使用这个方法调整 canvas 的 绘图缓冲区 大小:

renderer.setSize(width, height, false);
  • widthheight:用 canvas 的 clientWidthclientHeight

  • false:表示 不要自动改 CSS 大小,让 CSS 控它。

封装一个自动检测并更新的函数

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;
}

 

用法:
在每一帧 render() 里判断画布有没有大小变化,有就更新相机:

function render(time) {time *= 0.001;if (resizeRendererToDisplaySize(renderer)) {const canvas = renderer.domElement;camera.aspect = canvas.clientWidth / canvas.clientHeight;camera.updateProjectionMatrix();}renderer.render(scene, camera);requestAnimationFrame(render);
}
Canvas 实际尺寸CSS 尺寸结果
300x150800x600模糊(块状)
800x600800x600清晰 ✅

以利用 resizeRendererToDisplaySize() 的返回值判断:

“这帧有没有发生尺寸改变?”

  • 如果有,除了设置 renderer,还要更新 camera 的宽高比。

 

相关文章:

  • Springboot项目中minio的使用场景、使用过程(仅供参考)
  • python调用其它程序 os.system os.subprocess
  • 深入浅出Docker
  • 7.2.2_折半查找
  • SQL字符串截取函数全解析:LEFT、RIGHT、SUBSTRING 实战指南
  • 一个简单的德劳内三角剖分实现
  • 湖北理元理律师事务所:债务咨询中的心理支持技术应用
  • IP地址(互联网中设备的唯一逻辑地址标识)
  • ps蒙版介绍
  • EMD算法
  • 移动应用开发专业核心课程以及就业方向
  • Java Smart 系统题库试卷管理模块设计:从需求到开发的实战指南
  • 探秘IBMS系统:能集成哪些建筑子系统实现一体化管理
  • python将图片颜色显示在三维坐标系
  • java报错ncapp生成主子表单据时报错,CarrierRuntimeException
  • 2025年6月|注意力机制|面向精度与推理速度提升的YOLOv8模型结构优化研究:融合ACmix的自研改进方案
  • python怎么读shape文件?
  • RXCDR_CFG参数选择
  • 第23讲、Odoo18 邮件系统整体架构
  • nonlocal 与global关键字
  • 外贸企业招聘/惠州seo推广外包
  • 独立创建网站/五个成功品牌推广案例
  • 上海网站建设 迈若/谷歌搜索引擎官网
  • 苏州做网站最好公司有哪些/网上推广平台
  • wordpress mip 模板/147seo工具
  • 北京有一个公司打电话做网站认证/个人网站该怎么打广告