17eaa2f
提示词:
/superpowers:brainstorm 我正在优化游戏的 fps 性能问题,前几次提交对chunk的加载性能做了优化,现在性能的瓶颈基本上是在 AO 阴影的绘制上。现在 AO 阴影的绘制是很久之前重构的,经过chunk加载的性能优化后,AO 阴影的绘制已经不太匹配现在的游戏架构,导致玩家在跟主世界互动的时候(新增或者删除方块、或者用mag7消除方块),存在部分方块的 AO 没有正确绘制的现象。所以我想站在性能优先的角度,完全的重构 AO 阴影的实现,完全重新设计并实现,以跟当前的 chunk 加载、删除方块时的及时补面、faceculling、以及 instancedMesh 管理和consolidation时机很好的兼容。做到玩家放置方块、移除方块、tnt炸毁方块、Mag7 批量清除方块、机枪快速删除方块等场景都能很好的跟进 AO 阴影绘制。
所以请你全面review当前代码中的 AO 的实现,不论在主进程中,还是在 worker中,都要完全掌握。在完全掌握的情况下,给出你的重构方案。
我的AO阴影绘制的要求:
- 我对方块AO阴影绘制的实时性要求不高,即当放置方块后,先完成 faceculling,然后完成consolidation,当新放置的方块完成实例化并集成到 blockData 后,方块的数据都同步妥当后,最后执行一次 AO 的绘制。
- AO 阴影的绘制的计算要尽可能的放在 worker 中,对算力的消耗尽量不要干扰主进程的逻辑。
- AO 阴影的绘制的范围,在合理的基础上要尽可能的少,比如玩家跟主世界互动的时候,AO 的绘制应当只覆盖受影响的方块,比如删除方块的邻居,放置方块的相邻和相交的方块。再比如chunk刚加载的时候,如果cpu算力很紧张的话,可以先不绘制 AO 阴影,可以后续流程中补刷 AO 阴影。当然如果能在不影响cpu计算压力的前提下,能在chunk生成时携带AO阴影也可以。
- AO 阴影的绘制应当只绘制必要的 方块面,比如裸露在空气的面应当绘制,非裸露在空气中或者水中的面是不应该有 AO 阴影,因为面不可见。再比如,山体深处的方块的面因为被 faceculling 掉了,也不会有 AO 绘制。
- AO 阴影只在非透明的实心方块的面上才绘制,其他类型的方块的面不做绘制,跟现在的规则一致。
- 还有一种情况,可能不太会出现,有可能极低概率出现,就是一个方块的面有可能会被重复绘制,这种情况要避免,当一个位置的方块的面绘制了AO,如果在方块格局没有变化的情况下,另外一个进程或者逻辑又想重新绘制它,不应当重复绘制,除非出现了方块放置和删除等动作。即方块的面着色的 AO 阴影不应当重叠。
方块坐标的处理要一致,要用整数坐标,不要用浮点坐标。
在实现机制上,玩家放置和删除方块后,我只要求视觉上不要出现空洞,即及时补面的动作要立即完成,后续会有 face culling 和 consolidation 的动作,最后才是 AO 的绘制,尽量遵守这个时序。AO 阴影只影响视觉效果,不影响功能,所以放在时序的最后较为合理。
最后有一个坑,就是避免mag7快速消除方块时,AO 跟不上的bug,之前的AO的绘制的实现花了很大的精力解决这个问题,在这次提交后03bd0158af99ac35563a72f148f5c460ae4255ac当时解决了问题,目前随着功能的迭代,这个问题又出现了,请你考虑新的重构不要再次出现这种遗留问题。
另外还有一个坑,74c1052422e2e54684f54b1bae56f636648ad877 这次提交修复的问题,一个方块会被不同的chunk同时拥有,导致会被绘制多份 AO,目前应该已经修复了,请你顺便检查不要复现这个问题。
请注意 ,方块面的 AO 的绘制,不要受到方块方向的影响。f48ceedf2198408ded5c6ef94710602df21c5153 和 2a6de61 这2次提交修复了AO不受方块方向的影响,且修复了及时补面的问题。
再请注意几个事项:
- 删除一个方块的时候,这个方块紧邻的面不要都是黑色,紧邻的面刚因为没接触空气,不应该有AO阴影,删除时的动作应该是及时补面的面不带AO阴影,待后续刷新时补刷AO阴影。
- AO 刷新应该只刷新跟删除方块相邻的方块的面的 AO 阴影,即以删除方块为中心,前后、上下、左右一共六个方块的AO面要做刷新,不是整个chunk的所有方块的面要做刷新。
- 更新AO阴影的时候,应该直接把新的AO替换到老的 AO,不要先删除再着色,中间间隔了几十毫秒,避免感觉到明显的闪烁。
- 如果玩家连续1秒内删除方块时,删除方块A后,设定了定时器1秒后等consolidation后执行 AO 刷新,在1秒内删除了方块B,应该把删除方块A后设定的定时器删除,同时设定一个新的定时器,等B被删除1秒后等consolidation后执行 AO 刷新,也就是说,连续快速放置或者删除方块后,只在最后一次 consolidation 后执行一遍 AO 刷新。我还是那个原则,不要让 AO 和其他方块操作重叠,等所有方块的处理都完成后,最后再执行 AO 刷新。甚至你可以为了确保时序性,把 AO 定时器比 consolidation 再晚100毫秒都可以。
- 在强调一遍,我不需要玩家在放置和删除方块的时候立即进行AO计算,我也不需要隐藏面(不接触空气的面)进行 AO 着色计算。因此隐藏起来的面(被faceculling的面,接触另外的实心非透明方块的面)都不应该绘制 AO
着色(因为玩家看不到,所以不用AO着色),只有接触空气、水、玻璃等等透明非实心方块的面才会绘制 AO。
- 你的重构不要破坏消除方块时的及时补面的逻辑,这一步是确保基本的视觉元素不破损的关键。当前代码的及时补面的逻辑是正确的,不要破坏当前的及时补面的功能。
- 通常情况,当删除或者放置方块的时候,先移除/或新增 InstancedMesh 中的实例,然后创建动态网格,这个过程会产生闪烁。你的重构请避免这种情况的发生。即当方块被删除时,邻居方块的 AO 值会从旧值变为新值,这个变化过程导致了闪烁。
- 重构过程中最容易忽略的问题就是跨chunk的实体方块的 AO 的绘制容易丢失,这个问题很容易发生在新chunk(特别是玩家奔跑过程中新加载的chunk)携带的跨chunk方块上。也有可能是当 AO 计算需要查找邻居方块时,邻居可能位于另一个 Chunk 中,而当前 Chunk 的 blockMap 中没有那个邻居的数据,这时非常容易出错,请你注意处理好。
重构过程中容易引入的问题是实体被Chunk切割,现在的代码是好的,注意这类实体被chunk切割的问题不要被引入进来。
连续放置和删除方块时(不超过1秒内),当玩家连续不超过1秒间隔删除方块时,要记录被删除方块的位置,放入一个队列,最后统一刷新AO的时候,要依次将1秒内删除方块的队列中的方块位置周边六个方块都要做AO刷新,刷新完成后清空队列。这个动作是防止过快的删除方块或者放置方块时,避免最后刷新AO的方块只刷新最后一次操作的方块的邻居方块的面,而是所有未来得及刷新的操作方块的周边六个方块的面的 AO 都要做刷新,所以需要一个队列来记住快速操作的方块。刷新完后再清空这个队列。
当前代码的 AO 功能上是ok的,只是性能有问题。你的实现需要参照当前AO的逻辑,确保功能上是完整的。核心解决性能问题。我需要你重新实现,实现方式要足够的清,在设计上就要规避多管线冲突的问题,渲染时序的问题,对方块行为依赖的问题等。
请你详细review代码,为我重构AO的实现,要求功能完整,性能最优。
17eaa2f
提示词:
/superpowers:brainstorm 我正在优化游戏的 fps 性能问题,前几次提交对chunk的加载性能做了优化,现在性能的瓶颈基本上是在 AO 阴影的绘制上。现在 AO 阴影的绘制是很久之前重构的,经过chunk加载的性能优化后,AO 阴影的绘制已经不太匹配现在的游戏架构,导致玩家在跟主世界互动的时候(新增或者删除方块、或者用mag7消除方块),存在部分方块的 AO 没有正确绘制的现象。所以我想站在性能优先的角度,完全的重构 AO 阴影的实现,完全重新设计并实现,以跟当前的 chunk 加载、删除方块时的及时补面、faceculling、以及 instancedMesh 管理和consolidation时机很好的兼容。做到玩家放置方块、移除方块、tnt炸毁方块、Mag7 批量清除方块、机枪快速删除方块等场景都能很好的跟进 AO 阴影绘制。
所以请你全面review当前代码中的 AO 的实现,不论在主进程中,还是在 worker中,都要完全掌握。在完全掌握的情况下,给出你的重构方案。
我的AO阴影绘制的要求:
方块坐标的处理要一致,要用整数坐标,不要用浮点坐标。
在实现机制上,玩家放置和删除方块后,我只要求视觉上不要出现空洞,即及时补面的动作要立即完成,后续会有 face culling 和 consolidation 的动作,最后才是 AO 的绘制,尽量遵守这个时序。AO 阴影只影响视觉效果,不影响功能,所以放在时序的最后较为合理。
最后有一个坑,就是避免mag7快速消除方块时,AO 跟不上的bug,之前的AO的绘制的实现花了很大的精力解决这个问题,在这次提交后03bd0158af99ac35563a72f148f5c460ae4255ac当时解决了问题,目前随着功能的迭代,这个问题又出现了,请你考虑新的重构不要再次出现这种遗留问题。
另外还有一个坑,74c1052422e2e54684f54b1bae56f636648ad877 这次提交修复的问题,一个方块会被不同的chunk同时拥有,导致会被绘制多份 AO,目前应该已经修复了,请你顺便检查不要复现这个问题。
请注意 ,方块面的 AO 的绘制,不要受到方块方向的影响。f48ceedf2198408ded5c6ef94710602df21c5153 和 2a6de61 这2次提交修复了AO不受方块方向的影响,且修复了及时补面的问题。
再请注意几个事项:
着色(因为玩家看不到,所以不用AO着色),只有接触空气、水、玻璃等等透明非实心方块的面才会绘制 AO。
重构过程中容易引入的问题是实体被Chunk切割,现在的代码是好的,注意这类实体被chunk切割的问题不要被引入进来。
连续放置和删除方块时(不超过1秒内),当玩家连续不超过1秒间隔删除方块时,要记录被删除方块的位置,放入一个队列,最后统一刷新AO的时候,要依次将1秒内删除方块的队列中的方块位置周边六个方块都要做AO刷新,刷新完成后清空队列。这个动作是防止过快的删除方块或者放置方块时,避免最后刷新AO的方块只刷新最后一次操作的方块的邻居方块的面,而是所有未来得及刷新的操作方块的周边六个方块的面的 AO 都要做刷新,所以需要一个队列来记住快速操作的方块。刷新完后再清空这个队列。
当前代码的 AO 功能上是ok的,只是性能有问题。你的实现需要参照当前AO的逻辑,确保功能上是完整的。核心解决性能问题。我需要你重新实现,实现方式要足够的清,在设计上就要规避多管线冲突的问题,渲染时序的问题,对方块行为依赖的问题等。
请你详细review代码,为我重构AO的实现,要求功能完整,性能最优。