Skip to content

Google Summer of Code 2020 结果

动态光照和阴影

学生:Harsimran Virk

该项目的原始提案着重于实现 pixi 库(pixi-layers、pixi-lights 和 pixi-shadows),但我们决定使用现有代码库中的数据结构(b 树)来实现自己的光线投射算法。这样决定是因为这些库没有得到很好的维护,而且它们可能会有很多性能问题。

光照运行时对象

我们为光照定义了一个新的 gdjs.RuntimeObject,它使用 PIXI.Mesh 进行渲染。这个想法非常简单,跟踪光照区域内的所有对象,对它们进行光线投射以定义网格的几何形状,并使用具有一些淡化属性的着色器进行渲染。

  1. PR: GDevelop#1783:这是第一版 PR,我们开始尝试光线投射和渲染。我们需要 Pixi v5 进行渲染,而主分支仍然停留在 v4.8.6。

  2. PR: GDevelop#1825:这是第二版 PR。Pixi v5 已经合并到代码库中(但仍未合并到主分支),我们有一个可用的算法。我们不得不为现有的层系统添加新功能,以支持光照。同时还增加了一些新的用户界面。

  3. PR: GDevelop#1881:这是最终合并到主分支的 PR,是在升级到 pixi v5 后开放的。此外,我们添加了一些文档和测试。然而仍然存在一些问题。

  4. PR: GDevelop#1929:这个 PR 解决了一些问题,我们尝试解决与光照对象的边界框相关的特定问题。

法线贴图

在原始提案中,我们还计划使用 pixi-lights 引入法线贴图,以渲染基于深度的效果。由于我们决定不使用库,我们必须在这里实现自己的解决方案。现在的想法是使用另一个 gdjs.RuntimeObject 来进行基于法线贴图的光线渲染,我们将使用所有法线贴图的渲染纹理,在单个通道中渲染光照。

  1. PR: GDevelop#1932:这是一个用于实验和制作能够与法线贴图一起工作的漫反射渲染的初步 PR。目前仍在进行中,我们将能够在 GSoC 结束后添加这个功能。

挑战

  • 最具挑战性的部分是编写高效的 JS 代码,无论是在时间还是内存方面。我们尝试尽量减少像 map 和 filter 这样创建新数组的函数的使用,因为它们会增加对 GC 的压力。我们还尝试对其他对象(如 Float32Array)使用单个实例。

  • 调试渲染代码是最困难的部分,因为这完全是可视化的。对于那些旨在在屏幕上渲染东西的代码来说,使用“基于文本”的调试技术(例如断点、控制台日志等)是非常困难的,而对于调试屏幕外元素(帧缓冲区、渲染纹理等)来说,这变得更加困难。因此,要找到与渲染故障有关的错误总是具有挑战性的。

可能的改进

  • 一种可能的改进是使用 分离轴定理 来最小化要进行光线投射的数量。

  • 我们尝试为扩展边界框的边缘情况找到解决方案。这对很多情况都有效,但仍有一些情况需要正确处理。

  • 我们需要有更好的测试和基准测试,包括边缘情况。

命令面板和改进的快捷键

学生:Nilay Majorwar

该项目的重点是通过以下方式提高用户的效率和生产力:

  • 构建完整功能的命令面板,类似于 Visual Studio Code 等代码编辑器和其他生产力应用程序。这使用户可以通过键盘快速访问应用程序的大多数主要功能。
  • 添加可定制的键盘快捷键支持。之前,应用程序只支持场景和事件编辑器的一些标准快捷键 - 新快捷键将允许用户通过按快捷键完成几乎任何操作。

结构

我们决定的系统的大致工作方式相当简单:

  • 每个命令主要有一个名称和一个回调处理程序。命令的回调处理程序由相关的 React 组件动态提供。
  • 一个 React 上下文用作在任何时候注册所有命令的中央存储库。自定义钩子使得任何 React 组件可以轻松动态注册和注销命令。命令面板 UI 从中央存储库获取命令列表并显示它。
  • 这些命令也可以有相应的键盘快捷键。事件侦听器监听键盘按键,检查是否按下识别的快捷键,并调用相应的命令。

时间表

该项目大致分为三个阶段:

  1. PR: GDevelop#1821: 基本命令面板

这个阶段是用于设置命令的基本框架 - 为存储创建 React 上下文,为注册和注销创建自定义钩子以及命令面板的 UI。

  1. PR: GDevelop#1864: 添加高级命令

在这个阶段,我致力于添加更强大的命令,比如“编辑对象...”,允许用户直接从命令面板下拉菜单中选择要编辑的对象。这可能是项目中最困难的部分,因为为每个选项维护处理程序稍微难以做到正确。

  1. PR: GDevelop#1938: 可定制的键盘快捷键最后,我添加了对自定义键盘快捷键的支持。由于命令系统已经完全就绪,这个阶段非常简单,只有关于单键快捷键和Electron的一些小问题。还有一个次要的PR,用于添加一个命令和修复一些现有命令。挑战:- 存储带有选项的命令选项:对于每个这样的命令存储并动态更新选项数组很困难,特别是对于具有稍微复杂生命周期的React组件。解决方法是,而是存储一个函数,该函数生成该命令的选项列表,直接从项目或布局对象中 - 这意味着无论何时何地调用该函数,它都会提供最新的结果。- 单键快捷键:单键快捷键稍微棘手,因为它们可能与用户输入冲突。为了解决这个问题,我使用了一点原生JS来检查用户当前是否正在输入,如果是,就忽略任何快捷键按键。- 命令与Electron重叠:某些命令(如“保存项目”)与Electron应用菜单中的菜单项重叠。这意味着按下“Ctrl+S”键,Electron和内部快捷键系统都会尝试保存项目。因此,在Electron应用上,我们传递这些重叠的命令,并允许Electron执行作业。可能的改进:- 缺乏与标签相关的命令和快捷键,比如“下一个标签”。这些快捷键非常有帮助,在生产力应用程序中非常普遍。可以将此类命令和快捷键添加到应用程序中。- 仍然有相当多的键盘生产力功能需要添加到应用程序中 - 例如,事件编辑器不支持使用箭头键导航。添加这一功能将使键盘控制更加直观。- 检测快捷键对话框效果很好,但对于用户来说,在解释为什么某个快捷键不允许,或者某些快捷键可能会造成问题,如与浏览器冲突之外并没有提供帮助。可以改进为在这些情况下显示帮助消息。