Bevy0.10更新内容(上)
注意,文中所有@对象均为GitHub账户名,所有与这一段使用相同引用格式的均为个人补充或其他非原文内容,绝大部分情况下()内的内容也是补充,但性质不同,往往是翻译过程中损失了部分原来的意思亦或者是上下文关联之类的,也有一些题外话,另外b站专栏的标题不能设置层级,所以各位只能对照一开始的省流版,省流版没有的就是属于某个标题下的子标题,部分专业名词没有翻译,其原因为我不确定翻译后的名称是否广为人知,对于之后翻译这些技术类的文章或者博客有什么建议可以之间评论区提

省流版:

以下是翻译,前面的粗体不好翻译(翻译了有点怪,比较基本都是专业名词)
ECS Schedule v3:bevy现在有了一个更简单,扩展性更强的调度(可以理解为某些异步运行时中的task),现在系统存储在同一个调度中,commands(这个是bevy的类型之一翻译了反而可能为阻碍理解)现在可以显式的以apply_system_buffers应用,并且做了大量的优化和bug修复
Cascaded Shadow Maps: 更高质量的覆盖更大范围的阴影map,其质量与镜头有关
Environment Map Lighting: 基于360度场景图片的光照可以很划算的极大提升视觉效果(这里的划算是原话cheeply,应该是该解决方案的资源占用很少的意思)
Depth and Normal Prepass: 在主渲染之前为场景渲染深度和法线贴图,从而实现新的效果和(在某些情况下)改进性能。阴影映射使用预处理着色器,使透明贴图可以投射阴影
Smooth Skeletal Animation Transitions: 平稳地在同时播放的两个骨骼动画之间进行过渡!
Improved Android Support: Bevy 现在可以在更多 Android 设备上开箱即用(但有一些注意事项)。
Revamped Bloom: 现在 Bloom 效果看起来更好,控制更容易,且视觉残留现象更少。
Distance and Atmospheric Fog: 使用 3D 距离和大气雾效果为场景增添深度和氛围!
StandardMaterial Blend Modes: 通过更多的 PBR 材质混合模式实现各种有趣的效果。
More Tonemapping Choices: 为你的 HDR 场景选择七种流行的色调映射算法之一,以实现你所期望的视觉风格。
Color Grading: 控制每个相机的曝光、伽马、预色调映射饱和度和后色调映射饱和度。
Parallel Pipelined Rendering: 应用逻辑和渲染逻辑现在自动并行运行,大幅提升性能。
Windows as Entities: 现在将窗口表示为Entity而不是Resource,改善了用户体验并解锁了新的场景。
Renderer Optimizations: 我们在这个周期中花费了大量的精力来优化渲染器。Bevy 的渲染器比以往更加流畅!
ECS Optimizations: 同样,我们加速了许多常见的 ECS 操作。进一步提升性能!
接下来是详细版本:
ECS Schedule v3
authors: @alice-i-cecile, @maiwani, @WrongShoe, @cart, @jakobhellermann, @JoJoJet, @geieredgar and a whole lot more
感谢我们的 ECS 团队的出色工作,备受期待的“stageless”调度 RFC 已经被实现了!(上个版本提到过的,在下的bevy相关教程中也提到过)
调度器 v3 是大量设计和实现工作的结晶。调度器 API 是 定义了Bevy 开发者体验的核心部分,因此我们必须非常慎重和细致地考虑这个 API 的下一个演进。除了 RFC PR,如果您想了解我们的过程和理念,@maniwani 的初始实现 PR 和 @alice-i-cecile 的 Bevy 引擎内部移植 PR 也是很好的参考资料。正如我们所知,计划和实现是两码事。我们的最终实现与初始 RFC 稍有不同(但是向更好的方向改变)。
改动很多,但我们极力确保现有程序能相对简单的迁移到新版本,无需多虑
让我们来看看 0.10 版本中都有哪些变化!
A Single Unified Schedule
当你试图指定两个系统的相对运行顺序却收到找不到系统的奇怪警告时,仅仅是因为系统之间运行于不同的阶段?
再也不会了!现在,所有在一个Schedule内的系统都存储在一个数据结构中,并具有全局感知能力。
这简化了我们的内部逻辑,使您的代码更加稳健以应对重构,并允许插件作者指定高级常量(例如,“运动必须发生在碰撞检查之前”),而不会将自己锁定到确切的调度位置。

Adding Systems
Systems(就是正常的rust函数)是我们定义游戏逻辑的方式。于Schedule v3中,添加System的方式依旧:
而且,Schedule v3提供了一些新“花样”(原文就是这个意思),你现在可以一次添加多个系统(原先是需要使用SystemSet的):
默认情况下,bevy系统并行执行(真的并行是无法知道具体先后顺序的,这也是某些场景下系统出现意料之外行为的主要原因之一),在之前的版本你需要这样指定运行顺序(注意还必须是同stage的才能这样指定,但其实执行顺序不影响在query中分配的数据,这些数据在stage开始之前就完成分配了):
当前版本,你依旧可以这样写,但考虑以add_systems的写法就会变成这样:
before和after这两个函数固然好用,但所幸有新的chain函数,现在可以大幅简化:
chain() 将按照它们定义的顺序运行系统也支持每个系统自己的配置:
Configurable System Sets
在 Schedule v3 中,“system set”这一概念已被重新定义,以支持更自然、灵活的控制系统的运行和调度。旧的“system label”概念已与“set”概念合并,产生了一个简洁但强大的抽象概念。
SystemSets 是具有相同系统配置的一系列系统的命名集合。对 SystemSet 的排序将应用于该集合中的所有系统,以及每个单独系统上的任何配置。
事不宜迟,我们直接来看一下SystemSet吧,你可能会这样定义一个SystemSet:
你可以这样把系统加入system set:
你可以把上述的新特性结合起来:
任何系统都可以被多个system set包含:
可以这样给system set添加配置:
system set可以嵌套于另一个set中,这使得其继承了parent set(别问为什么不翻译成父set,问就是怕打拳)的配置:
system set可以多次配置(你可以认为这是为了某些插件作者更方便提供一些自定义功能):
重要的是,系统配置是严格累加的:你不能删除其他地方添加的规则。这是一种“反意大利面条”(原文就是anti-spaghetti,意思是反对程序像意大利面一样,这里的意大利面指代程序结构混乱,代码可读性低)和“插件隐私”考虑。当该规则与 Rust 健全的类型隐私规则结合使用时,插件作者可以谨慎的决定自己需要维护哪些具体的配置,并在不破坏使用体验的情况下重新组织代码和系统。
配置规则必须相互兼容:任何悖论(例如自我包含,顺序循环以及前后均出现同一系统等)都会导致程序崩溃,但所幸会抛出有用的错误信息。
Directly Schedule Exclusive Systems
"独占系统"是一些拥有对ecs中的world类型可变引用的系统,因此它们不能与其他系统并行
自bevy诞生以来,开发人员一直试图将独占系统(以及刷新命令)加入普通系统的执行续(原文咋一看有点歧义,但根据后面一句应该是希望两者能在一起执行)
现在可以了,独占系统现在与执行和排序方面与一般系统无异
这一点尤为强大,因为刷新命令(将在系统中添加的命令排队执行,以执行生成和销毁实体等操作)现在只需要在apply_system_buffers独占系统中执行即可。(你可能在看完这句话和下面的代码以后有些疑惑,没事,我也一样,但结合上下文,应该是将上一个系统中的指令直接放在独占系统中执行【独占系统拥有world的可变所有权,某些指令应该更加方便】以期将原本需要排队执行的指令提上进程,当然这些是在下的理解,具体的各位还需自己测试)
不过,使用此模式需要小心:很容易就会出现许多排列不当的独占系统,导致瓶颈(应该是指的性能)和混乱(应该是指的数据)。
你将如何利用这样强大的功能?我们非常期待看到你的作品!(这是原文,并非在下画蛇添足之作,老实说我倒是挺想试试基于这种模式构建一个格斗游戏的指令系统的,就是坑开的太多了还是先填一点吧)
Managing Complex Control Flow with Schedules
那么,如果你打算使用Schedule实现一些“奇思妙想”该怎么办?例如,一些非线性,多分枝,或者循环的情况,你该做些什么?
事实上,bevy已然(圈起来)具备一个不错的解决方案,即在独占系统内部运行的schedules,方法很简单:
构造一个Schedule,用以存放任何你所需的复杂逻辑
将该Schedule存储在某个resource内部
在一个独占系统中,符合rust语法的情况下,你将能安排任意你想要的逻辑给schedule执行
临时将schedule从World对象中取出,基于world对象的剩余部分(两者皆可以修改)执行它,事后将它放回去。
在添加了新的Schedule资源和world.run_schedule()的api之后,从未如此符合人体工程学:
这里我简单的补充一点东西吧,bevy常规使用system的时候如果需要特别复杂的system执行条件的话,直接add_system会引起较大的资源浪费,因为不管你的系统是否在执行时内部判断了条件都会导致bevy为你的系统分配了资源,同时还占用了一次线程调度。故而即使bevy本身提供了事件系统,也不推荐以bevy的事件构建reactive性质的系统执行,而以上的这种方法便是可以解决需要复杂条件方能执行的系统的调度问题。还需要注意的是,使用独占系统的方式其实并不是当前版本才有的
bevy将这种模式应用于五种不同的场景:
startup system:这些系统现在拥有自己的schedule,其仅会于程序开始时执行一次
fixed timestep systems: 另一个Schedule?!将有一个运行它的独占系统来计时,循环调用CoreSchedule::FixedUpdate直到所需的计时完成
一系列的schedule,运行着用于进入和退出状态变量的逻辑。每个system的集合都被存储在它自己的schedule中,并根据apply_state_transitions::<S>的状态变化调用相应的schedule。(是否感觉不像人话?我也这么觉得,在下个人很难想到合理的翻译这个翻译来自于chatgpt,这里我用我自己的理解描述一下吧,就是有那么一些服务于enter和exist state的系统调用,调用时会根据apply_state_transitions::<S>中S这个类型参数来决定调用的是哪个state的相关系统)
为了让渲染和游戏逻辑可以异步执行,所有的渲染逻辑都拥有自己的schedule
为了达到“startup schedule先执行,然后执行main schedule”的效果,我们将它们全部放进了一个轻量级的CoreSchedule::Outer,然后以独占系统来运行它
可以查看CoreSchedule的文档来获取更多信息:https://docs.rs/bevy/0.10.0/bevy/app/enum.CoreSchedule.html
Run Conditions
系统可以拥有任意数量的运行条件,这些条件“实际上”是一些返回bool的系统,如果所有的运行条件系统的与为true那么久执行该系统,否则该系统将在本轮schedule中被跳过:
这种方式是优于在系统内部判断的,因为无论你的系统是否满足运行条件都需要获取符合条件下执行所需的资源
得益于@Jojojet和@Shatur,运行条件也支持使用一系列的“合并”操作:
可以使用not来取反:
可以使用and_then和or_else:
bevy 0.10配套了一份好用的条件集合,你可以轻松的在事件触发,计时器到期,资源被修改,输入变化,state改变等情况下运行系统(着得益于@maniwani, @inodentry, @jakobhellermann, 以及@jabuwu)
运行条件也可以用作轻量级的优化工具(有点迷惑,但基于optimization这个单词实在翻译不出其他意思了),运行条件在主线程中判断,且每个criteria实际上在每次schedule刷新时判断一次,即首个依赖该条件的系统执行的时候。被该特性禁用的系统将不会产生task(bevy的系统执行使用的设计思路是task manager,故而每个任务均以task为单位进行执行,具体的自行搜索一下task manager即可),这可能会对系统产生深远的影响(这里从原文并未指出具体的影响,但根据后文来说应该是这种改动带来了系统执行时的性能变化)。当然还得看benchmark(我猜测是性能相关的,但字面意思是基准测试)
运行条件已然替代了旧版bevy中的“run criteria”。我们终于可以摆脱可怕的“looping run criteria”(这里如果深入使用过bevy旧版的系统的可能就能在无任何补充的情况下理解,不能的话就需要各位自行去查找一下了,三两句说不清楚的)!ShouldRun::YesAndAgain并不能很直观的被引擎和用户理解(原文就带有引擎,虽然我也不清楚引擎如何“理解”)。如果你希望使用更复杂的控制流:使用上文提到的“独占系统中的schedule”。对于其他几乎99%情况下,使用更简单的基于bool的运行条件更佳。
Simpler States
schedule v3引入了一个全新的更加简单的“state system”(直接翻译感觉会和某些东西同名因此导致歧义,这里的state与很多gui中的state类似,你可以理解成游戏中的不同场景的状态存储)。States可以让你更简单的基于当前“state”配置不同的程序逻辑。
你可以这样定义state(看到enum中的#[default],如果你的rust编译器提示你这是nightly标准,那么你是时候升级rust了):
其中的每个值代表当前程序的一个不同state
你可以这样注册该state:
这将会设置你的程序使用给出的state,该操作会把该state放入state资源以便你查找当前state:
另外,add_state会为为每个可能的值创建一个OnUpdate,你可以在之后添加一系列系统来处理这个事件。这些系统会在更新时运行,但仅当程序处于某个state时才会执行(该功能和以前版本想必只是变易用了):
同时该功能也会每个state创建OnEnter和OnExit两个Schedules,这使得你可以定义切换state时的逻辑:
另外,这还引入了一个NextState的资源,可以将state change进行队列化:
该特性作为bevy之前版本十分难用的state系统的替代品。此前的state系统包含一个state栈,复杂的切换队列,以及一个大多数人都会直接unwrap掉的错误处理。这玩意儿学习起来特别复杂,而且容易出现让人恼火的bug,而且大多数情况下都被忽略了(不是很清楚这里被忽略指代的是bug还这个state stack)。
从结果来看,当前版本的bevy已经“stackless”:每种状态只有一个排队状态(这里直接翻译的很奇怪,我想了很久也没有想出靠谱的翻译,这个翻译来源于chatgpt,我只能大致说一下我的理解,应该是同一时间只会考虑一个state的状态队列)。经过大量的α测试,我们确信迁移到新模式并不会很难。如果您正在使用state stack,有很多备选方案:
在引擎提供的state系统上层自建一个stack
将你的state细化成多个能捕获程序状态的独立模块(这里的翻译不知道是否符合原文意思,但我的理解是这里的state和某些immediate gui的state有点相似)
基于bevy以前的版本的state stack抽象实现自己的版本。新版本的state逻辑并没有写死!如果你真的这么做了,让社区里的其他人知道以便你参与项目(https://bevyengine.org/assets)
Base Sets: Getting Default Behavior Right
聪明的读者可能会发现:
bevy会自动并行执行系统
系统的执行顺序在未指定的情况下是未知的
所有的系统现在都会以Schedule的形式存储,Schedule之间没有壁垒(原文就是这样,我不清楚具体情况,可能是Schedule之间数据的关系,也可能是运行顺序的关系)
系统可以所属于任意数量的系统集,每个系统集都可以定义自己的行为
bevy是一个拥有很多内置系统的强大引擎
那么这样真的不会导致在解决排序问题时导致程序混乱不堪吗(原文用了一个彻底混乱和一个意大利面式来表达,应该是结构和运行效果都混乱的意思)?很多用户喜欢stage,这能帮助他们理解程序的结构
好吧,我们很感谢你的提议,rhetorical skeptic(rhetorical skeptic的英文解释大概是这样的:a person who is being a "rhetorical skeptic" would be someone who is challenging the writer's position, questioning the validity of their arguments, or expressing doubt about their claims, often with the intention of generating discussion or debate,我不确定是否该翻译成杠精或者其他什么,就用了原文)。为了减少混乱,当前版本的bevy引入了一种全新的由默认插件集提供的系统集:CoreSet,StartupSet和RenderSet。这些系统集与旧版的几个stage有着相似的名字(就是ctrl+f Stage => Set)。就像stage一样,在不同系统集之间有着command刷新点(command flush point是否真的如此翻译我还真的不确定),现有的系统可以之间无缝迁移。
以stage为核心的架构中的某些部分确实不错:清晰的high-level结构,刷新点的协调(以减少性能问题),以及良好的默认行为。为了保持这些优点(同时去除糟粕)。我们引入了新的关于Base Set的标准(由@cart添加)。Base Set除了下面这些以外就是一些普通系统集:
每个系统中从属于一个Base Set
不符合某个base set的系统将会被放进schedule的默认base set中(当然该schedule得有这样一个set)
让我来告诉你一个故事,发生在没有Base Sets的世界的故事(原文就这个意思,其实更好的翻译大概会是假设没有Base Sets会怎么样):
某个新用户往程序里面添加了一个make_player_run的系统
有时候这个在获取用户输入之前就运行了,导致了随机的指令丢失问题。有时候在渲染以后才执行,造成了诡异的闪烁(这里原文使用的是flickers,但此类问题更多表现为掉帧或者画面断层,我也不清楚如何从flickers中翻译出别的意思来)
在经历了一些挫折之后,他发现这些问题的根源是“系统的执行顺序不明确”
然后该用户使用了专门的追踪工具,深入引擎源码,了解到这些系统相对于引擎的系统集如何运行,然后为每个系统这样实现(原文的continues on their merry way直译过来太生草,个人英文水平有限实在想不出该怎么翻译,好在不影响整体的意思)
bevy更新了(或者某个第三方插件更新了),让这个可怜的用户的系统再次失效
该例子旨在说明一个问题,大多数的gameplay(不翻译是因为gameplay这个词其实很常用,以至于很多人都适应了这个词,另外现今的软件行业中英混合的讲话方式已然很常见,但主要的还是gameplay同样可以指代某个游戏开发的岗位)系统无需知道bevy的内部细节
实践出真知,有三种广泛存在的系统:第一种是gameplay系统,绝大部分用户系统都归类在这一类,第二种是类似事件清理(由于event和cleanup之间没有逗号所以我就这样翻译了)和用户输入处理这些需要在gameplay执行之前执行的系统,以及最后一种需要在gameplay之后运行的逻辑,像是渲染啊,音频啊这些。
通过Base Sets我们对Schedule进行了符合上述情况的排序,bevy程序在没有牺牲其扩展性和明确性的情况下拥有了良好的默认行为和清晰的high-level结构。告诉我们你将如何使用它!
Improved System Ambiguity Detection
我们认为,当多个系统同时试图访问某个ecs资源,且没有明确的先后顺序时,就触发了标题所说的“ambiguity”。如果你的程序存在该问题,可能会引起bug。我们显著优化了我们在该问题上的反馈,该反馈可以在新的ScheduleBuildSettings中配置(查看docs.rs以获得更多信息:https://docs.rs/bevy/0.10.0/bevy/ecs/schedule/struct.ScheduleBuildSettings.html)。如果你还不曾试用过:你得试试看!
Single Threaded Execution
你现在可以简单的通过SingleThreadExecutor将一个Schedule变为单线程执行,如果你不希望或者不需要并行。
Cascaded Shadow Maps
authors: @danchia, Rob Swain (@superdump)
bevy使用“shadow maps”来为光线和物体投射阴影。以前版本的bevy为定向光源使用一个简单但功能很有限的实现方案。对于给定的光源,你可以为其定义分辨率和通过手动设置“view projection”来决定如何投射阴影。该方案有些许缺点:
分辨率是固定的,这意味着我们只能在高清晰度和大范围中择其一
分辨率无法自适应镜头位置,这导致阴影在不同位置的质量不一
“view projection”必须手动设置,这极大的增加了为一个给定的场景设置阴影的难度
新版本加入了“Cascaded Shadow Maps”,它将镜头的视锥拆分为了多个可配置的“Cascades”,这些“Cascades”拥有各自的阴影map。这使得离镜头较近的阴影细节更好,较远的阴影则可以适当降低细节来覆盖更大的范围(对应上述缺点的第一条)。由于这种方案使用了镜头的视锥来定义阴影投影,故而不论镜头如何移动阴影的质量都能保持不变。这同样意味着用户不再需要自己定义阴影投影了。它们将由计算自行得出!
原文的视频我无法直接放进专栏这里放一个链接各位自行查看吧https://bevyengine.org/news/bevy-0-10/shadow_cascades.mp4
可以看到近距离的阴影拥有更高的细节,而远处的则更少,毕竟原创的阴影细节不那么重要。
虽然该方案解决了重要的问题,但也带来了新的问题。你应该用多少cascades map?阴影在镜头前的最小和最大有效距离是多少?阴影直接会有多少重叠?请务必选择合适你场景的这些数值
Environment Map Lighting
authors: @JMS55
Environment maps是一种常用且计算量小的能显著提升场景光照质量的方法。该方法使用了一个立方体的贴图提供了360度的全方位光照(可能不是很好理解,但很多引擎都是这样做的,各位也可以查看一下其他引擎对此的解释,或许能更好的理解)。这在reflective surfaces的表现尤为明显,但亦适用于所有材质。
一下是pbr材质在没有使用该特性时的效果:

以及启用该特性后的PBR材质看起来这样:

对于譬如室外场景等需要固定光照的场景,该特性算是很不错的解决方案了。并且正因为environment maps可以是任何图片,美术人员可以对场景光照的特点有很好的把控。
Depth and Normal Prepass
authors: @icesentry, Rob Swain (@superdump), @robtfm, @JMS55
此处的视频链接https://bevyengine.org/news/bevy-0-10/force_field.mp4
bevy现在拥有处理深度和法线(这里的原文是normal,但normal texture是指某个surface的normalized vector,即法线的向量表示方式)材质的能力。这意味着现在这两种材质将在一个运行于主渲染通道前的渲染通道中生成。这使得各种各样的特效像是屏幕空间环境光遮蔽、时间反走样(这两个的翻译来自于chatgpt,我是真的不知道如何翻译)等等的实现都将成为可能,这些特效目前仍在开发中,预计在下个版本就可以用了


使用预处理通道本质上其实是你将所有东西渲染了两次。预处理通道要块很多,毕竟它相对主通道来说工作量小了很多。预处理通道的结果可以用于减少主通道中的overdraw问题,但如果你本未面临该问题,这种方案反而会降低性能。还有许多需要优化的地方,我们也将朝着这个方向继续努力。正如所有性能攸关的事情一样,需要根据你的实际使用场景进行测试,以确定是否有效。
这个预处理通道在实现需要法线或者深度材质的特效时依然十分实用,因此如果你需要使用该功能,你可以直接将DepthPrepass和NormalPrepass这两个组件添加到你的镜头对象上
Shadow Mapping using Prepass Shaders
authors: @geieredgar
此前的版本,用于shadow mapping的shader是写死了的,它无法处理材质,只能处理mesh。当前版本,一个材质对象的深度预处理shader会被用于shadow mapping。这意味着这些shaders可以自定义!
此外,在shadow mapping期间可以获取材质信息意味着我们可以马上启动alpha mask shadows以使得植被可以根据其alpha值投射阴影而非仅凭据其几何形状。

Smooth Skeletal Animation Transitions
authors: @smessmer
你现在可以丝滑的在两中骨骼动画间切换!
原文中此处的视频链接https://bevyengine.org/news/bevy-0-10/animation_transition.mp4
基于新版本的AnimationPlayer组件中的play_with_transition方法,你现在可以设置一个过度时间,新的骨骼动画会和当前的动画进行线性混合,两者之间的权重将逐渐向新动画倾斜直至原动画的权重为0.0。
Improved Android Support
authors: @mockersf, @slyedoc

bevy现版本可以在更多安卓设备上开箱即用了。匹配安卓系统的onResume()的回调机制,等待Resumed事件而非在程序启动时创建窗口使得这成为可能。
为了按照推荐的方式处理Suspend事件,bevy暂时会在收到该事件后退出。这种情况将持续到bevy可以在resumed的时候重新创建渲染资源为止。
还望各位在自己的设备上测试一二并给我们提供你可能会遭遇到的正负面情况!(我按照自己的语气翻译了原文,但意思应该是没有差太多),目前已知的一个问题是有部分设备的软件按钮存在触摸位置的问题(应该是按钮的位置和事件位置不同?原文没有给出具体说明,感兴趣的去官方的issues搜索看看吧),其原因是winit目前还没有暴露inset size属性,目前只有inner size属性可用。
由于bevy现在离完全支持安卓已经很接近了,所以对于所有人来说都不再需要为安卓和ios分别准备例子了。这些例子将会被重整为“移动端”例子,对两者的相关说明也同步更新了。
下面是相同的例子在ios的效果:

Revamped Bloom
authors: @StarLederer, @JMS55
泛光效果经历了一些重大的改进,现在看起来好用多了;现在更易于控制,并降低了人工视觉的含量(不清楚具体指的是什么,原文是visual artifact)。结合新的色调映射选项,bloom比之前的版本有了很大的改进!(下面的每一条对应之后对应序号的图片)
在0.9版本中bloom的效果是这样
将色调映射切换到类似AcesFitted已然是很大的进步了
在当前版本中,泛光效果看起来是这样。可控性更高,不再那般繁琐
为了增强泛光效果,我们不该直接设置BloomSettings中的强度,而是提升每个cube自身的光强
最后,如果你需要类似旧版算法中的极强的泛光效果,你可用把BloomSettings中的从composite_mode从EnergyConserving切换到Additive
使用新的bloom_3d(和bloom_2d)示例在交互式播放区中探索新的泛光设置。






Distance and Atmospheric Fog
author: Marco Buono (@coreh)
当前版本的bevy可以呈现距离和大气雾效果,使得场景更具深度和氛围感,让物体在远离视野的位置看起来更加昏暗。

作用于每个镜头的雾效果都可以通过FogSettings组件来设置。我们在设计可配置项的时候特别注意,以便你可以完全掌控雾的外观,包括通过控制雾颜色的Alpha通道来控制雾的淡入淡出能力。
这里的FogFalloff枚举控制着雾在不同距离下的表现。所有“传统”的雾衰减模式都受支持,包括OpenGL 1.x/DirectX 7时代的固定函数模式:
FogFalloff::Linear 在开始和结束两个参数之间,从0线性增加至1

FogFalloff::Exponential根据一个受密度参数影响的指数/逆指数公式增长:

FogFalloff::ExponentialSquared顾名思义,上面一种的平方版本

此外,还有一种更复杂的FogFalloff::Atmospheric模式可以用,该模式通过分别考虑光的消光和内散射,它提供了更准确的物理结果。
通过directional_light_color和directional_light_exponent参数,所有雾模式也支持DirectionalLight(docs链接:https://docs.rs/bevy/0.10.0/bevy/pbr/struct.DirectionalLight.html)影响,模拟在阳光明媚的室外环境中看到的光线分散效果。

由于非线性情况下需要手动设置密度参数,且很难正确,故而我们提供了一些基于气象能见度(https://en.wikipedia.org/wiki/Visibility)的辅助函数,例如FogFalloff::from_visibility():
雾在PBR片段shader上应用了“前向渲染风格”,而不是作为后处理效果,这使得它可以正确处理半透明的mesh。
大气雾的实现很大程度上是基于Shadertoy的联合创始人Inigo Quilez和computer graphics legend的这篇优秀文章(https://iquilezles.org/articles/fog/)。感谢你伟大的写作和灵感!
StandardMaterial Blend Modes
author: Marco Buono (@coreh)
AlphaMode枚举(https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html)在当前版本得到了扩展,支持了标准材质的加法混合和乘法混合功能。这两种混合模式是“经典”(非基于物理的)计算机图形学工具包的基本组成部分,通常用于实现各种效果。
原文此处的视频链接:https://bevyengine.org/news/bevy-0-10/demo-ruins.mp4
demo演示了彩色玻璃和火焰特效(源代码链接:https://github.com/coreh/bevy-demo-ruins)
此外,还添加了半透明贴图的支持,通过专门的 alpha 模式实现预乘 alpha 的效果。
以下是新模式们的一些high-level预览:
AlphaMode::Add(docs链接:https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html#variant.Add)——将片段颜色与背景颜色相加,产生更亮的结果,类似于光。常用于火焰、全息图、幽灵、激光和其他能量束等效果。在图形软件中也被称为“线性叠加”。
AlphaMode::Multiply(docs链接:https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html#variant.Multiply)——使用乘法过程将片段的颜色与其背后的颜色相结合(类似于颜料),产生较暗的结果。这对于模拟部分光线透过的效果非常有用,比如彩色玻璃、车窗贴膜和某些有色液体。在图形软件中也被称为“线性减淡”。
AlphaMode::Premultiplied(docs链接:https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html#variant.Premultiplied)——与混合模式具有类似的表现,但假定颜色通道有预乘透明度。可以用来避免使用普通alpha混合纹理时出现的脱色"轮廓"伪像,或者巧妙地在单个纹理中组合加性和常规alpha混合材质,因为对于常数RGB值,预乘透明度模式在接近1.0的alpha值时更像混合模式,在接近0.0的alpha值时更像加法模式。

注意:使用新的混合模式的网格将绘制在现有的Transparent3d渲染阶段上,因此与AlphaMode::Blend相同,需要考虑/限制深度排序。
由于篇幅太长了,这里将分为两篇专栏发布,另外从这个版本开始bevy已经越来越像一个真正的引擎了,所有之后的更新日志可能会量更大,更专业,所以以我个人的能力很难能即使对新版本的更新日志进行翻译,个人如果有什么相关建议可以告诉我

