Three.js#02#Next Steps

以下内容由GPT辅助生成。

Disposing resources

这段内容主要讲解了在Three.js中如何释放不再使用的对象,以提高性能并避免内存泄漏。

重要的是要注意,Three.js无法自动释放一些与WebGL相关的资源,如缓冲区、着色器程序等。你需要通过特定的API来释放这些资源。

  1. 几何体(Geometries):通过调用BufferGeometry.dispose()方法来释放与几何体相关的资源。
  2. 材质(Materials):通过调用Material.dispose()方法来释放与材质相关的资源。
  3. 纹理(Textures):通过调用Texture.dispose()方法来释放与纹理相关的资源。如果使用ImageBitmap作为纹理的数据源,则还需要调用ImageBitmap.close()以释放CPU侧资源。
  4. 渲染目标(Render Targets):通过调用WebGLRenderTarget.dispose()方法来释放与渲染目标相关的资源。

此外,还有一些其他类(例如控制器或后处理过程),它们也提供了dispose()方法来移除内部事件侦听器或渲染目标。建议检查类的API或文档,并在清理时使用dispose()方法(如果存在)。

这段内容还回答了一些关于Three.js资源管理的常见问题,例如:

  • Three.js无法自动释放对象的原因
  • 从场景中删除一个网格是否会释放其几何体和材质
  • Three.js是否提供关于缓存对象数量的信息
  • 在纹理图片尚未加载时调用dispose()会发生什么
  • 在调用dispose()之后再次使用该对象会发生什么
  • 如何在应用中管理Three.js对象,何时应该释放资源

总之,在Three.js中释放对象资源取决于具体的使用场景,没有绝对的建议。但是,理解何时调用dispose()方法以释放相关资源是很重要的。

  1. 为什么Three.js无法自动释放对象?

    Three.js无法知道用户创建的几何体、材质等实体的生命周期或作用域,这是应用程序的责任。例如,即使一个材质当前未用于渲染,下一帧可能仍然需要。因此,如果应用程序决定某个对象可以被删除,它需要通过调用相应的dispose()方法通知引擎。

  2. 从场景中删除一个网格是否会释放其几何体和材质?

    不会。你需要显式地通过调用dispose()方法来释放几何体和材质。请注意,几何体和材质可以在多个3D对象(如网格)之间共享。

  3. Three.js是否提供关于缓存对象数量的信息?

    是的。你可以查看WebGLRenderer.info属性,该属性提供了关于显存和渲染过程的统计信息。其中包括内部存储的纹理、几何体和着色器程序的数量。如果你发现应用程序性能存在问题,建议调试此属性以轻松识别内存泄漏。

  4. 在纹理图片尚未加载时调用dispose()会发生什么?

    如果纹理图片尚未加载,内部资源尚未分配,因此在调用dispose()时不会发生任何事情。换句话说,不需要执行任何清理操作。

  5. 在调用dispose()之后再次使用该对象会发生什么?

    引擎会再次创建已删除的内部资源。因此,不会发生运行时错误,但在当前帧可能会产生负面的性能影响,尤其是当着色器程序需要重新编译时。

  6. 如何在应用中管理Three.js对象?何时应该释放资源?

    并没有一种通用的建议来说明何时应该调用dispose()方法。这主要取决于具体的使用场景。需要强调的是,无需始终释放对象。例如,一个包含多个关卡的游戏,在切换关卡时释放对象是个不错的选择。应用程序可以遍历旧场景并释放所有不再使用的材质、几何体和纹理。如前所述,如果你释放了实际仍在使用的对象,也不会产生运行时错误。最坏的情况是单帧性能下降。

How to use post-processing

Three.js的很多应用会将3D对象直接渲染到屏幕上。然而,有时候我们可能需要对渲染结果添加一些图形效果,比如景深(Depth-Of-Field)、泛光(Bloom)、胶片颗粒(Film Grain)或各种类型的抗锯齿(Anti-aliasing)。后期处理(Post-processing)是一种实现这些效果的常用方法。首先,场景被渲染到一个渲染目标(Render target),它表示显卡内存中的一个缓冲区。接下来,一个或多个后期处理过程将在最终渲染到屏幕之前,对图像缓冲区应用滤镜和效果。

Three.js通过EffectComposer提供了一个完整的后期处理解决方案来实现这样的工作流程。

首先,从examples目录中导入所需的文件。接下来,通过将WebGLRenderer的实例传递给EffectComposer来创建composer。

使用composer时,需要修改应用程序的动画循环。现在需要使用EffectComposer的相应方法,而不是调用WebGLRenderer的渲染方法。

function animate() {
  requestAnimationFrame(animate);
  composer.render();
}

Three.js提供了许多内置的后期处理通道供你使用。你还可以编写自定义的后期处理着色器,将其包含到后期处理通道链中。

总之,Three.js的后期处理是一种用于在渲染场景到屏幕之前,对图像应用各种图形效果的方法。通过使用EffectComposer,可以创建一个后期处理通道链,对渲染结果进行处理和优化。这使得您可以为3D渲染结果添加诸如景深、泛光、胶片颗粒和抗锯齿等效果。在创建自定义效果时,还可以使用ShaderPass并编写自己的着色器代码。这些功能共同提供了更多的控制和创意自由度,以便根据需要调整渲染结果。

Matrix transformations

在Three.js中,矩阵变换被用于表示3D物体的平移(位置)、旋转和缩放。每个Object3D实例都有一个矩阵,用于存储其位置、旋转和缩放信息。

更新对象的变换有两种方法:

  1. 修改对象的位置、四元数(旋转)和缩放属性,然后让Three.js根据这些属性重新计算对象的矩阵。可以根据需要自动或手动更新矩阵。

  2. 直接修改对象的矩阵。通过这种方式,您需要确保将matrixAutoUpdate属性设置为false,并手动更新矩阵。

对象矩阵与世界矩阵:对象的矩阵存储的是对象相对于其父对象的变换;要获取对象在世界座标系下的变换,需要访问对象的matrixWorld属性。当父对象或子对象的变换发生改变时,可以调用updateMatrixWorld()方法来更新子对象的matrixWorld。

Three.js提供了两种表示3D旋转的方法:欧拉角和四元数。欧拉角容易出现“万向锁”问题,因此对象的旋转信息始终存储在对象的四元数中。在以前的库版本中,有一个useQuaternion属性,但现在已经被弃用。转而使用setRotationFromEuler方法来更新四元数。

Animation system

这段内容主要介绍了Three.js动画系统的概述、组件和它们是如何协同工作的。在Three.js动画系统中,可以对模型的各种属性进行动画处理:有骨架和绑定模型的骨骼、变形目标、不同的材质属性(颜色、不透明度、布尔值)、可见性和变换。动画属性可以淡入、淡出、交叉淡入以及扭曲。同时在同一对象和不同对象上的不同动画的权重和时间尺度可以独立改变。同一对象和不同对象上的各种动画可以同步。

为了在一个统一的系统中实现所有这些功能,Three.js动画系统在2015年进行了全面改变,现在具有类似于Unity/Unreal Engine 4的架构。以下是系统的主要组件以及它们是如何协同工作的简要概述:

  1. 动画片段(Animation Clips):导入一个包含动画的3D对象后,其中应包含一个名为“animations”的数组,其中包含该模型的动画片段。
  2. 关键帧轨迹(Keyframe Tracks):在动画片段中,每个动画属性的数据都存储在一个独立的关键帧轨迹中。一个动画片段可以由许多这样的轨迹组成。
  3. 动画混合器(Animation Mixer):动画混合器控制实际的播放,可以将其视为一个可以同时控制多个动画的动画播放器,混合和合并它们。
  4. 动画操作(Animation Actions):动画混合器由动画操作控制。通过配置动画操作,可以确定何时播放、暂停或停止混合器上的某个动画片段,是否以及多久重复该片段,是否用淡入淡出或时间缩放等方式进行操作。
  5. 动画对象组(Animation Object Groups):如果需要一组对象接收共享的动画状态,可以使用动画对象组。
  6. 支持的格式和加载器(Supported Formats and Loaders):请注意,并非所有模型格式都包含动画(如OBJ),并且只有部分Three.js加载器支持动画片段序列。支持此类动画的一些加载器包括:THREE.ObjectLoader、THREE.BVHLoader、THREE.ColladaLoader、THREE.FBXLoader、THREE.GLTFLoader、THREE.MMDLoader。请注意,3ds Max和Maya目前不能将多个动画(指不在同一时间线上的动画)直接导出到一个文件中。

Color management

色彩空间(color space)是一种特定的色彩组织方式,能够在不同设备和应用之间准确、一致地表示、传输和再现色彩。色彩空间由若干参数定义,包括颜色原色、白点和转换函数。每个色彩空间都旨在支持广泛的颜色范围,同时遵循精度和显示技术的技术约束。

颜色原色(color primaries)定义了色彩空间中使用的基本颜色(例如红、绿、蓝),基于精度限制和可用显示设备的功能进行选择。白点(white point)是为了平衡无色(如白色或灰色)在观察者环境中的感知而指定的。转换函数(transfer functions)定义了数值在色彩空间内外的映射,确定数值是如何表示物理照明或人类感知的。

色彩空间在3D应用和渲染工作流中扮演着各种角色,包括输入色彩空间、工作色彩空间和输出色彩空间。输入色彩空间是指从各种来源(如颜色选择器、纹理或3D模型)提供给应用程序的颜色。工作色彩空间是进行渲染、插值和其他操作的地方,通常采用开放域线性色彩空间,如线性sRGB(Linear-sRGB)。最后,输出色彩空间决定了如何在设备上显示颜色或将其写入图像,通常需要从工作色彩空间转换为另一个色彩空间。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章