Bevy0.10更新內(nèi)容(上)

注意,文中所有@對象均為GitHub賬戶名,所有與這一段使用相同引用格式的均為個人補充或其他非原文內(nèi)容,絕大部分情況下()內(nèi)的內(nèi)容也是補充,但性質(zhì)不同,往往是翻譯過程中損失了部分原來的意思亦或者是上下文關(guān)聯(lián)之類的,也有一些題外話,另外b站專欄的標題不能設(shè)置層級,所以各位只能對照一開始的省流版,省流版沒有的就是屬于某個標題下的子標題,部分專業(yè)名詞沒有翻譯,其原因為我不確定翻譯后的名稱是否廣為人知,對于之后翻譯這些技術(shù)類的文章或者博客有什么建議可以之間評論區(qū)提

省流版:

以下是翻譯,前面的粗體不好翻譯(翻譯了有點怪,比較基本都是專業(yè)名詞)
ECS Schedule v3:bevy現(xiàn)在有了一個更簡單,擴展性更強的調(diào)度(可以理解為某些異步運行時中的task),現(xiàn)在系統(tǒng)存儲在同一個調(diào)度中,commands(這個是bevy的類型之一翻譯了反而可能為阻礙理解)現(xiàn)在可以顯式的以apply_system_buffers應(yīng)用,并且做了大量的優(yōu)化和bug修復(fù)
Cascaded Shadow Maps: 更高質(zhì)量的覆蓋更大范圍的陰影map,其質(zhì)量與鏡頭有關(guān)
Environment Map Lighting: 基于360度場景圖片的光照可以很劃算的極大提升視覺效果(這里的劃算是原話cheeply,應(yīng)該是該解決方案的資源占用很少的意思)
Depth and Normal Prepass: 在主渲染之前為場景渲染深度和法線貼圖,從而實現(xiàn)新的效果和(在某些情況下)改進性能。陰影映射使用預(yù)處理著色器,使透明貼圖可以投射陰影
Smooth Skeletal Animation Transitions:?平穩(wěn)地在同時播放的兩個骨骼動畫之間進行過渡!
Improved Android Support:?Bevy 現(xiàn)在可以在更多 Android 設(shè)備上開箱即用(但有一些注意事項)。
Revamped Bloom:?現(xiàn)在 Bloom 效果看起來更好,控制更容易,且視覺殘留現(xiàn)象更少。
Distance and Atmospheric Fog:?使用 3D 距離和大氣霧效果為場景增添深度和氛圍!
StandardMaterial Blend Modes:?通過更多的 PBR 材質(zhì)混合模式實現(xiàn)各種有趣的效果。
More Tonemapping Choices:?為你的 HDR 場景選擇七種流行的色調(diào)映射算法之一,以實現(xiàn)你所期望的視覺風(fēng)格。
Color Grading:?控制每個相機的曝光、伽馬、預(yù)色調(diào)映射飽和度和后色調(diào)映射飽和度。
Parallel Pipelined Rendering:?應(yīng)用邏輯和渲染邏輯現(xiàn)在自動并行運行,大幅提升性能。
Windows as Entities:?現(xiàn)在將窗口表示為Entity而不是Resource,改善了用戶體驗并解鎖了新的場景。
Renderer Optimizations:?我們在這個周期中花費了大量的精力來優(yōu)化渲染器。Bevy 的渲染器比以往更加流暢!
ECS Optimizations:?同樣,我們加速了許多常見的 ECS 操作。進一步提升性能!
接下來是詳細版本:
ECS Schedule v3
authors: @alice-i-cecile, @maiwani, @WrongShoe, @cart, @jakobhellermann, @JoJoJet, @geieredgar and a whole lot more
感謝我們的 ECS 團隊的出色工作,備受期待的“stageless”調(diào)度 RFC 已經(jīng)被實現(xiàn)了?。ㄉ蟼€版本提到過的,在下的bevy相關(guān)教程中也提到過)
調(diào)度器 v3 是大量設(shè)計和實現(xiàn)工作的結(jié)晶。調(diào)度器 API 是?定義了Bevy 開發(fā)者體驗的核心部分,因此我們必須非常慎重和細致地考慮這個 API 的下一個演進。除了 RFC PR,如果您想了解我們的過程和理念,@maniwani 的初始實現(xiàn) PR 和 @alice-i-cecile 的 Bevy 引擎內(nèi)部移植 PR 也是很好的參考資料。正如我們所知,計劃和實現(xiàn)是兩碼事。我們的最終實現(xiàn)與初始 RFC 稍有不同(但是向更好的方向改變)。
改動很多,但我們極力確?,F(xiàn)有程序能相對簡單的遷移到新版本,無需多慮
讓我們來看看 0.10 版本中都有哪些變化!
A Single Unified Schedule
當(dāng)你試圖指定兩個系統(tǒng)的相對運行順序卻收到找不到系統(tǒng)的奇怪警告時,僅僅是因為系統(tǒng)之間運行于不同的階段?
再也不會了!現(xiàn)在,所有在一個Schedule內(nèi)的系統(tǒng)都存儲在一個數(shù)據(jù)結(jié)構(gòu)中,并具有全局感知能力。
這簡化了我們的內(nèi)部邏輯,使您的代碼更加穩(wěn)健以應(yīng)對重構(gòu),并允許插件作者指定高級常量(例如,“運動必須發(fā)生在碰撞檢查之前”),而不會將自己鎖定到確切的調(diào)度位置。

Adding Systems?
Systems(就是正常的rust函數(shù))是我們定義游戲邏輯的方式。于Schedule v3中,添加System的方式依舊:
而且,Schedule v3提供了一些新“花樣”(原文就是這個意思),你現(xiàn)在可以一次添加多個系統(tǒng)(原先是需要使用SystemSet的):
默認情況下,bevy系統(tǒng)并行執(zhí)行(真的并行是無法知道具體先后順序的,這也是某些場景下系統(tǒng)出現(xiàn)意料之外行為的主要原因之一),在之前的版本你需要這樣指定運行順序(注意還必須是同stage的才能這樣指定,但其實執(zhí)行順序不影響在query中分配的數(shù)據(jù),這些數(shù)據(jù)在stage開始之前就完成分配了):
當(dāng)前版本,你依舊可以這樣寫,但考慮以add_systems的寫法就會變成這樣:
before和after這兩個函數(shù)固然好用,但所幸有新的chain函數(shù),現(xiàn)在可以大幅簡化:
chain() 將按照它們定義的順序運行系統(tǒng)也支持每個系統(tǒng)自己的配置:
Configurable System Sets
在 Schedule v3 中,“system set”這一概念已被重新定義,以支持更自然、靈活的控制系統(tǒng)的運行和調(diào)度。舊的“system label”概念已與“set”概念合并,產(chǎn)生了一個簡潔但強大的抽象概念。
SystemSets 是具有相同系統(tǒng)配置的一系列系統(tǒng)的命名集合。對?SystemSet?的排序?qū)?yīng)用于該集合中的所有系統(tǒng),以及每個單獨系統(tǒng)上的任何配置。
事不宜遲,我們直接來看一下SystemSet吧,你可能會這樣定義一個SystemSet:
你可以這樣把系統(tǒng)加入system set:
你可以把上述的新特性結(jié)合起來:
任何系統(tǒng)都可以被多個system set包含:
可以這樣給system set添加配置:
system set可以嵌套于另一個set中,這使得其繼承了parent set(別問為什么不翻譯成父set,問就是怕打拳)的配置:
system set可以多次配置(你可以認為這是為了某些插件作者更方便提供一些自定義功能):
重要的是,系統(tǒng)配置是嚴格累加的:你不能刪除其他地方添加的規(guī)則。這是一種“反意大利面條”(原文就是anti-spaghetti,意思是反對程序像意大利面一樣,這里的意大利面指代程序結(jié)構(gòu)混亂,代碼可讀性低)和“插件隱私”考慮。當(dāng)該規(guī)則與 Rust 健全的類型隱私規(guī)則結(jié)合使用時,插件作者可以謹慎的決定自己需要維護哪些具體的配置,并在不破壞使用體驗的情況下重新組織代碼和系統(tǒng)。
配置規(guī)則必須相互兼容:任何悖論(例如自我包含,順序循環(huán)以及前后均出現(xiàn)同一系統(tǒng)等)都會導(dǎo)致程序崩潰,但所幸會拋出有用的錯誤信息。
Directly Schedule Exclusive Systems
"獨占系統(tǒng)"是一些擁有對ecs中的world類型可變引用的系統(tǒng),因此它們不能與其他系統(tǒng)并行
自bevy誕生以來,開發(fā)人員一直試圖將獨占系統(tǒng)(以及刷新命令)加入普通系統(tǒng)的執(zhí)行續(xù)(原文咋一看有點歧義,但根據(jù)后面一句應(yīng)該是希望兩者能在一起執(zhí)行)
現(xiàn)在可以了,獨占系統(tǒng)現(xiàn)在與執(zhí)行和排序方面與一般系統(tǒng)無異
這一點尤為強大,因為刷新命令(將在系統(tǒng)中添加的命令排隊執(zhí)行,以執(zhí)行生成和銷毀實體等操作)現(xiàn)在只需要在apply_system_buffers獨占系統(tǒng)中執(zhí)行即可。(你可能在看完這句話和下面的代碼以后有些疑惑,沒事,我也一樣,但結(jié)合上下文,應(yīng)該是將上一個系統(tǒng)中的指令直接放在獨占系統(tǒng)中執(zhí)行【獨占系統(tǒng)擁有world的可變所有權(quán),某些指令應(yīng)該更加方便】以期將原本需要排隊執(zhí)行的指令提上進程,當(dāng)然這些是在下的理解,具體的各位還需自己測試)
不過,使用此模式需要小心:很容易就會出現(xiàn)許多排列不當(dāng)?shù)莫氄枷到y(tǒng),導(dǎo)致瓶頸(應(yīng)該是指的性能)和混亂(應(yīng)該是指的數(shù)據(jù))。
你將如何利用這樣強大的功能?我們非常期待看到你的作品?。ㄟ@是原文,并非在下畫蛇添足之作,老實說我倒是挺想試試基于這種模式構(gòu)建一個格斗游戲的指令系統(tǒng)的,就是坑開的太多了還是先填一點吧)
Managing Complex Control Flow with Schedules
那么,如果你打算使用Schedule實現(xiàn)一些“奇思妙想”該怎么辦?例如,一些非線性,多分枝,或者循環(huán)的情況,你該做些什么?
事實上,bevy已然(圈起來)具備一個不錯的解決方案,即在獨占系統(tǒng)內(nèi)部運行的schedules,方法很簡單:
構(gòu)造一個Schedule,用以存放任何你所需的復(fù)雜邏輯
將該Schedule存儲在某個resource內(nèi)部
在一個獨占系統(tǒng)中,符合rust語法的情況下,你將能安排任意你想要的邏輯給schedule執(zhí)行
臨時將schedule從World對象中取出,基于world對象的剩余部分(兩者皆可以修改)執(zhí)行它,事后將它放回去。
在添加了新的Schedule資源和world.run_schedule()的api之后,從未如此符合人體工程學(xué):
這里我簡單的補充一點東西吧,bevy常規(guī)使用system的時候如果需要特別復(fù)雜的system執(zhí)行條件的話,直接add_system會引起較大的資源浪費,因為不管你的系統(tǒng)是否在執(zhí)行時內(nèi)部判斷了條件都會導(dǎo)致bevy為你的系統(tǒng)分配了資源,同時還占用了一次線程調(diào)度。故而即使bevy本身提供了事件系統(tǒng),也不推薦以bevy的事件構(gòu)建reactive性質(zhì)的系統(tǒng)執(zhí)行,而以上的這種方法便是可以解決需要復(fù)雜條件方能執(zhí)行的系統(tǒng)的調(diào)度問題。還需要注意的是,使用獨占系統(tǒng)的方式其實并不是當(dāng)前版本才有的
bevy將這種模式應(yīng)用于五種不同的場景:
startup system:這些系統(tǒng)現(xiàn)在擁有自己的schedule,其僅會于程序開始時執(zhí)行一次
fixed timestep systems: 另一個Schedule?!將有一個運行它的獨占系統(tǒng)來計時,循環(huán)調(diào)用CoreSchedule::FixedUpdate直到所需的計時完成
一系列的schedule,運行著用于進入和退出狀態(tài)變量的邏輯。每個system的集合都被存儲在它自己的schedule中,并根據(jù)apply_state_transitions::<S>的狀態(tài)變化調(diào)用相應(yīng)的schedule。(是否感覺不像人話?我也這么覺得,在下個人很難想到合理的翻譯這個翻譯來自于chatgpt,這里我用我自己的理解描述一下吧,就是有那么一些服務(wù)于enter和exist state的系統(tǒng)調(diào)用,調(diào)用時會根據(jù)apply_state_transitions::<S>中S這個類型參數(shù)來決定調(diào)用的是哪個state的相關(guān)系統(tǒng))
為了讓渲染和游戲邏輯可以異步執(zhí)行,所有的渲染邏輯都擁有自己的schedule
為了達到“startup schedule先執(zhí)行,然后執(zhí)行main schedule”的效果,我們將它們?nèi)糠胚M了一個輕量級的CoreSchedule::Outer,然后以獨占系統(tǒng)來運行它
可以查看CoreSchedule的文檔來獲取更多信息:https://docs.rs/bevy/0.10.0/bevy/app/enum.CoreSchedule.html
Run Conditions
系統(tǒng)可以擁有任意數(shù)量的運行條件,這些條件“實際上”是一些返回bool的系統(tǒng),如果所有的運行條件系統(tǒng)的與為true那么久執(zhí)行該系統(tǒng),否則該系統(tǒng)將在本輪schedule中被跳過:
這種方式是優(yōu)于在系統(tǒng)內(nèi)部判斷的,因為無論你的系統(tǒng)是否滿足運行條件都需要獲取符合條件下執(zhí)行所需的資源
得益于@Jojojet和@Shatur,運行條件也支持使用一系列的“合并”操作:
可以使用not來取反:
可以使用and_then和or_else:
bevy 0.10配套了一份好用的條件集合,你可以輕松的在事件觸發(fā),計時器到期,資源被修改,輸入變化,state改變等情況下運行系統(tǒng)(著得益于@maniwani
,?@inodentry
,?@jakobhellermann
, 以及@jabuwu
)
運行條件也可以用作輕量級的優(yōu)化工具(有點迷惑,但基于optimization這個單詞實在翻譯不出其他意思了),運行條件在主線程中判斷,且每個criteria實際上在每次schedule刷新時判斷一次,即首個依賴該條件的系統(tǒng)執(zhí)行的時候。被該特性禁用的系統(tǒng)將不會產(chǎn)生task(bevy的系統(tǒng)執(zhí)行使用的設(shè)計思路是task manager,故而每個任務(wù)均以task為單位進行執(zhí)行,具體的自行搜索一下task manager即可),這可能會對系統(tǒng)產(chǎn)生深遠的影響(這里從原文并未指出具體的影響,但根據(jù)后文來說應(yīng)該是這種改動帶來了系統(tǒng)執(zhí)行時的性能變化)。當(dāng)然還得看benchmark(我猜測是性能相關(guān)的,但字面意思是基準測試)
運行條件已然替代了舊版bevy中的“run criteria”。我們終于可以擺脫可怕的“l(fā)ooping run criteria”(這里如果深入使用過bevy舊版的系統(tǒng)的可能就能在無任何補充的情況下理解,不能的話就需要各位自行去查找一下了,三兩句說不清楚的)!ShouldRun::YesAndAgain并不能很直觀的被引擎和用戶理解(原文就帶有引擎,雖然我也不清楚引擎如何“理解”)。如果你希望使用更復(fù)雜的控制流:使用上文提到的“獨占系統(tǒng)中的schedule”。對于其他幾乎99%情況下,使用更簡單的基于bool的運行條件更佳。
Simpler States
schedule v3引入了一個全新的更加簡單的“state system”(直接翻譯感覺會和某些東西同名因此導(dǎo)致歧義,這里的state與很多gui中的state類似,你可以理解成游戲中的不同場景的狀態(tài)存儲)。States可以讓你更簡單的基于當(dāng)前“state”配置不同的程序邏輯。
你可以這樣定義state(看到enum中的#[default],如果你的rust編譯器提示你這是nightly標準,那么你是時候升級rust了):
其中的每個值代表當(dāng)前程序的一個不同state
你可以這樣注冊該state:
這將會設(shè)置你的程序使用給出的state,該操作會把該state放入state資源以便你查找當(dāng)前state:
另外,add_state會為為每個可能的值創(chuàng)建一個OnUpdate,你可以在之后添加一系列系統(tǒng)來處理這個事件。這些系統(tǒng)會在更新時運行,但僅當(dāng)程序處于某個state時才會執(zhí)行(該功能和以前版本想必只是變易用了):
同時該功能也會每個state創(chuàng)建OnEnter和OnExit兩個Schedules,這使得你可以定義切換state時的邏輯:
另外,這還引入了一個NextState的資源,可以將state change進行隊列化:
該特性作為bevy之前版本十分難用的state系統(tǒng)的替代品。此前的state系統(tǒng)包含一個state棧,復(fù)雜的切換隊列,以及一個大多數(shù)人都會直接unwrap掉的錯誤處理。這玩意兒學(xué)習(xí)起來特別復(fù)雜,而且容易出現(xiàn)讓人惱火的bug,而且大多數(shù)情況下都被忽略了(不是很清楚這里被忽略指代的是bug還這個state stack)。
從結(jié)果來看,當(dāng)前版本的bevy已經(jīng)“stackless”:每種狀態(tài)只有一個排隊狀態(tài)(這里直接翻譯的很奇怪,我想了很久也沒有想出靠譜的翻譯,這個翻譯來源于chatgpt,我只能大致說一下我的理解,應(yīng)該是同一時間只會考慮一個state的狀態(tài)隊列)。經(jīng)過大量的α測試,我們確信遷移到新模式并不會很難。如果您正在使用state stack,有很多備選方案:
在引擎提供的state系統(tǒng)上層自建一個stack
將你的state細化成多個能捕獲程序狀態(tài)的獨立模塊(這里的翻譯不知道是否符合原文意思,但我的理解是這里的state和某些immediate gui的state有點相似)
基于bevy以前的版本的state stack抽象實現(xiàn)自己的版本。新版本的state邏輯并沒有寫死!如果你真的這么做了,讓社區(qū)里的其他人知道以便你參與項目(https://bevyengine.org/assets)
Base Sets: Getting Default Behavior Right
聰明的讀者可能會發(fā)現(xiàn):
bevy會自動并行執(zhí)行系統(tǒng)
系統(tǒng)的執(zhí)行順序在未指定的情況下是未知的
所有的系統(tǒng)現(xiàn)在都會以Schedule的形式存儲,Schedule之間沒有壁壘(原文就是這樣,我不清楚具體情況,可能是Schedule之間數(shù)據(jù)的關(guān)系,也可能是運行順序的關(guān)系)
系統(tǒng)可以所屬于任意數(shù)量的系統(tǒng)集,每個系統(tǒng)集都可以定義自己的行為
bevy是一個擁有很多內(nèi)置系統(tǒng)的強大引擎
那么這樣真的不會導(dǎo)致在解決排序問題時導(dǎo)致程序混亂不堪嗎(原文用了一個徹底混亂和一個意大利面式來表達,應(yīng)該是結(jié)構(gòu)和運行效果都混亂的意思)?很多用戶喜歡stage,這能幫助他們理解程序的結(jié)構(gòu)
好吧,我們很感謝你的提議,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,我不確定是否該翻譯成杠精或者其他什么,就用了原文)。為了減少混亂,當(dāng)前版本的bevy引入了一種全新的由默認插件集提供的系統(tǒng)集:CoreSet,StartupSet和RenderSet。這些系統(tǒng)集與舊版的幾個stage有著相似的名字(就是ctrl+f Stage => Set)。就像stage一樣,在不同系統(tǒng)集之間有著command刷新點(command flush point是否真的如此翻譯我還真的不確定),現(xiàn)有的系統(tǒng)可以之間無縫遷移。
以stage為核心的架構(gòu)中的某些部分確實不錯:清晰的high-level結(jié)構(gòu),刷新點的協(xié)調(diào)(以減少性能問題),以及良好的默認行為。為了保持這些優(yōu)點(同時去除糟粕)。我們引入了新的關(guān)于Base Set的標準(由@cart添加)。Base Set除了下面這些以外就是一些普通系統(tǒng)集:
每個系統(tǒng)中從屬于一個Base Set
不符合某個base set的系統(tǒng)將會被放進schedule的默認base set中(當(dāng)然該schedule得有這樣一個set)
讓我來告訴你一個故事,發(fā)生在沒有Base Sets的世界的故事(原文就這個意思,其實更好的翻譯大概會是假設(shè)沒有Base Sets會怎么樣):
某個新用戶往程序里面添加了一個make_player_run的系統(tǒng)
有時候這個在獲取用戶輸入之前就運行了,導(dǎo)致了隨機的指令丟失問題。有時候在渲染以后才執(zhí)行,造成了詭異的閃爍(這里原文使用的是flickers,但此類問題更多表現(xiàn)為掉幀或者畫面斷層,我也不清楚如何從flickers中翻譯出別的意思來)
在經(jīng)歷了一些挫折之后,他發(fā)現(xiàn)這些問題的根源是“系統(tǒng)的執(zhí)行順序不明確”
然后該用戶使用了專門的追蹤工具,深入引擎源碼,了解到這些系統(tǒng)相對于引擎的系統(tǒng)集如何運行,然后為每個系統(tǒng)這樣實現(xiàn)(原文的continues on their merry way直譯過來太生草,個人英文水平有限實在想不出該怎么翻譯,好在不影響整體的意思)
bevy更新了(或者某個第三方插件更新了),讓這個可憐的用戶的系統(tǒng)再次失效
該例子旨在說明一個問題,大多數(shù)的gameplay(不翻譯是因為gameplay這個詞其實很常用,以至于很多人都適應(yīng)了這個詞,另外現(xiàn)今的軟件行業(yè)中英混合的講話方式已然很常見,但主要的還是gameplay同樣可以指代某個游戲開發(fā)的崗位)系統(tǒng)無需知道bevy的內(nèi)部細節(jié)
實踐出真知,有三種廣泛存在的系統(tǒng):第一種是gameplay系統(tǒng),絕大部分用戶系統(tǒng)都歸類在這一類,第二種是類似事件清理(由于event和cleanup之間沒有逗號所以我就這樣翻譯了)和用戶輸入處理這些需要在gameplay執(zhí)行之前執(zhí)行的系統(tǒng),以及最后一種需要在gameplay之后運行的邏輯,像是渲染啊,音頻啊這些。
通過Base Sets我們對Schedule進行了符合上述情況的排序,bevy程序在沒有犧牲其擴展性和明確性的情況下?lián)碛辛肆己玫哪J行為和清晰的high-level結(jié)構(gòu)。告訴我們你將如何使用它!
Improved System Ambiguity Detection
我們認為,當(dāng)多個系統(tǒng)同時試圖訪問某個ecs資源,且沒有明確的先后順序時,就觸發(fā)了標題所說的“ambiguity”。如果你的程序存在該問題,可能會引起bug。我們顯著優(yōu)化了我們在該問題上的反饋,該反饋可以在新的ScheduleBuildSettings中配置(查看docs.rs以獲得更多信息:https://docs.rs/bevy/0.10.0/bevy/ecs/schedule/struct.ScheduleBuildSettings.html)。如果你還不曾試用過:你得試試看!
Single Threaded Execution
你現(xiàn)在可以簡單的通過SingleThreadExecutor將一個Schedule變?yōu)閱尉€程執(zhí)行,如果你不希望或者不需要并行。
Cascaded Shadow Maps
authors: @danchia, Rob Swain (@superdump)
bevy使用“shadow maps”來為光線和物體投射陰影。以前版本的bevy為定向光源使用一個簡單但功能很有限的實現(xiàn)方案。對于給定的光源,你可以為其定義分辨率和通過手動設(shè)置“view projection”來決定如何投射陰影。該方案有些許缺點:
分辨率是固定的,這意味著我們只能在高清晰度和大范圍中擇其一
分辨率無法自適應(yīng)鏡頭位置,這導(dǎo)致陰影在不同位置的質(zhì)量不一
“view projection”必須手動設(shè)置,這極大的增加了為一個給定的場景設(shè)置陰影的難度
新版本加入了“Cascaded Shadow Maps”,它將鏡頭的視錐拆分為了多個可配置的“Cascades”,這些“Cascades”擁有各自的陰影map。這使得離鏡頭較近的陰影細節(jié)更好,較遠的陰影則可以適當(dāng)降低細節(jié)來覆蓋更大的范圍(對應(yīng)上述缺點的第一條)。由于這種方案使用了鏡頭的視錐來定義陰影投影,故而不論鏡頭如何移動陰影的質(zhì)量都能保持不變。這同樣意味著用戶不再需要自己定義陰影投影了。它們將由計算自行得出!
?原文的視頻我無法直接放進專欄這里放一個鏈接各位自行查看吧https://bevyengine.org/news/bevy-0-10/shadow_cascades.mp4
可以看到近距離的陰影擁有更高的細節(jié),而遠處的則更少,畢竟原創(chuàng)的陰影細節(jié)不那么重要。
雖然該方案解決了重要的問題,但也帶來了新的問題。你應(yīng)該用多少cascades map?陰影在鏡頭前的最小和最大有效距離是多少?陰影直接會有多少重疊?請務(wù)必選擇合適你場景的這些數(shù)值
Environment Map Lighting
authors: @JMS55
Environment maps是一種常用且計算量小的能顯著提升場景光照質(zhì)量的方法。該方法使用了一個立方體的貼圖提供了360度的全方位光照(可能不是很好理解,但很多引擎都是這樣做的,各位也可以查看一下其他引擎對此的解釋,或許能更好的理解)。這在reflective surfaces的表現(xiàn)尤為明顯,但亦適用于所有材質(zhì)。
一下是pbr材質(zhì)在沒有使用該特性時的效果:

以及啟用該特性后的PBR材質(zhì)看起來這樣:

對于譬如室外場景等需要固定光照的場景,該特性算是很不錯的解決方案了。并且正因為environment maps可以是任何圖片,美術(shù)人員可以對場景光照的特點有很好的把控。
Depth and Normal Prepass
authors: @icesentry, Rob Swain (@superdump), @robtfm, @JMS55
此處的視頻鏈接https://bevyengine.org/news/bevy-0-10/force_field.mp4
bevy現(xiàn)在擁有處理深度和法線(這里的原文是normal,但normal texture是指某個surface的normalized vector,即法線的向量表示方式)材質(zhì)的能力。這意味著現(xiàn)在這兩種材質(zhì)將在一個運行于主渲染通道前的渲染通道中生成。這使得各種各樣的特效像是屏幕空間環(huán)境光遮蔽、時間反走樣(這兩個的翻譯來自于chatgpt,我是真的不知道如何翻譯)等等的實現(xiàn)都將成為可能,這些特效目前仍在開發(fā)中,預(yù)計在下個版本就可以用了


使用預(yù)處理通道本質(zhì)上其實是你將所有東西渲染了兩次。預(yù)處理通道要塊很多,畢竟它相對主通道來說工作量小了很多。預(yù)處理通道的結(jié)果可以用于減少主通道中的overdraw問題,但如果你本未面臨該問題,這種方案反而會降低性能。還有許多需要優(yōu)化的地方,我們也將朝著這個方向繼續(xù)努力。正如所有性能攸關(guān)的事情一樣,需要根據(jù)你的實際使用場景進行測試,以確定是否有效。
這個預(yù)處理通道在實現(xiàn)需要法線或者深度材質(zhì)的特效時依然十分實用,因此如果你需要使用該功能,你可以直接將DepthPrepass和NormalPrepass這兩個組件添加到你的鏡頭對象上
Shadow Mapping using Prepass Shaders
authors: @geieredgar
此前的版本,用于shadow mapping的shader是寫死了的,它無法處理材質(zhì),只能處理mesh。當(dāng)前版本,一個材質(zhì)對象的深度預(yù)處理shader會被用于shadow mapping。這意味著這些shaders可以自定義!
此外,在shadow mapping期間可以獲取材質(zhì)信息意味著我們可以馬上啟動alpha mask shadows以使得植被可以根據(jù)其alpha值投射陰影而非僅憑據(jù)其幾何形狀。

Smooth Skeletal Animation Transitions
authors: @smessmer
你現(xiàn)在可以絲滑的在兩中骨骼動畫間切換!
原文中此處的視頻鏈接https://bevyengine.org/news/bevy-0-10/animation_transition.mp4
基于新版本的AnimationPlayer組件中的play_with_transition方法,你現(xiàn)在可以設(shè)置一個過度時間,新的骨骼動畫會和當(dāng)前的動畫進行線性混合,兩者之間的權(quán)重將逐漸向新動畫傾斜直至原動畫的權(quán)重為0.0。
Improved Android Support
authors: @mockersf, @slyedoc

bevy現(xiàn)版本可以在更多安卓設(shè)備上開箱即用了。匹配安卓系統(tǒng)的onResume()的回調(diào)機制,等待Resumed事件而非在程序啟動時創(chuàng)建窗口使得這成為可能。
為了按照推薦的方式處理Suspend事件,bevy暫時會在收到該事件后退出。這種情況將持續(xù)到bevy可以在resumed的時候重新創(chuàng)建渲染資源為止。
還望各位在自己的設(shè)備上測試一二并給我們提供你可能會遭遇到的正負面情況?。ㄎ野凑兆约旱恼Z氣翻譯了原文,但意思應(yīng)該是沒有差太多),目前已知的一個問題是有部分設(shè)備的軟件按鈕存在觸摸位置的問題(應(yīng)該是按鈕的位置和事件位置不同?原文沒有給出具體說明,感興趣的去官方的issues搜索看看吧),其原因是winit目前還沒有暴露inset size屬性,目前只有inner size屬性可用。
由于bevy現(xiàn)在離完全支持安卓已經(jīng)很接近了,所以對于所有人來說都不再需要為安卓和ios分別準備例子了。這些例子將會被重整為“移動端”例子,對兩者的相關(guān)說明也同步更新了。
下面是相同的例子在ios的效果:

Revamped Bloom
authors: @StarLederer, @JMS55
泛光效果經(jīng)歷了一些重大的改進,現(xiàn)在看起來好用多了;現(xiàn)在更易于控制,并降低了人工視覺的含量(不清楚具體指的是什么,原文是visual artifact)。結(jié)合新的色調(diào)映射選項,bloom比之前的版本有了很大的改進!(下面的每一條對應(yīng)之后對應(yīng)序號的圖片)
在0.9版本中bloom的效果是這樣
將色調(diào)映射切換到類似AcesFitted已然是很大的進步了
在當(dāng)前版本中,泛光效果看起來是這樣??煽匦愿?,不再那般繁瑣
為了增強泛光效果,我們不該直接設(shè)置BloomSettings中的強度,而是提升每個cube自身的光強
最后,如果你需要類似舊版算法中的極強的泛光效果,你可用把BloomSettings中的從composite_mode從EnergyConserving切換到Additive
使用新的bloom_3d(和bloom_2d)示例在交互式播放區(qū)中探索新的泛光設(shè)置。






Distance and Atmospheric Fog
author: Marco Buono (@coreh)
當(dāng)前版本的bevy可以呈現(xiàn)距離和大氣霧效果,使得場景更具深度和氛圍感,讓物體在遠離視野的位置看起來更加昏暗。

作用于每個鏡頭的霧效果都可以通過FogSettings組件來設(shè)置。我們在設(shè)計可配置項的時候特別注意,以便你可以完全掌控霧的外觀,包括通過控制霧顏色的Alpha通道來控制霧的淡入淡出能力。
這里的FogFalloff枚舉控制著霧在不同距離下的表現(xiàn)。所有“傳統(tǒng)”的霧衰減模式都受支持,包括OpenGL 1.x/DirectX 7時代的固定函數(shù)模式:
FogFalloff::Linear 在開始和結(jié)束兩個參數(shù)之間,從0線性增加至1

FogFalloff::Exponential根據(jù)一個受密度參數(shù)影響的指數(shù)/逆指數(shù)公式增長:

FogFalloff::ExponentialSquared顧名思義,上面一種的平方版本

此外,還有一種更復(fù)雜的FogFalloff::Atmospheric模式可以用,該模式通過分別考慮光的消光和內(nèi)散射,它提供了更準確的物理結(jié)果。
通過directional_light_color和directional_light_exponent參數(shù),所有霧模式也支持DirectionalLight(docs鏈接:https://docs.rs/bevy/0.10.0/bevy/pbr/struct.DirectionalLight.html)影響,模擬在陽光明媚的室外環(huán)境中看到的光線分散效果。

由于非線性情況下需要手動設(shè)置密度參數(shù),且很難正確,故而我們提供了一些基于氣象能見度(https://en.wikipedia.org/wiki/Visibility)的輔助函數(shù),例如FogFalloff::from_visibility():
霧在PBR片段shader上應(yīng)用了“前向渲染風(fēng)格”,而不是作為后處理效果,這使得它可以正確處理半透明的mesh。
大氣霧的實現(xiàn)很大程度上是基于Shadertoy的聯(lián)合創(chuàng)始人Inigo Quilez和computer graphics legend的這篇優(yōu)秀文章(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)在當(dāng)前版本得到了擴展,支持了標準材質(zhì)的加法混合和乘法混合功能。這兩種混合模式是“經(jīng)典”(非基于物理的)計算機圖形學(xué)工具包的基本組成部分,通常用于實現(xiàn)各種效果。
原文此處的視頻鏈接:https://bevyengine.org/news/bevy-0-10/demo-ruins.mp4
demo演示了彩色玻璃和火焰特效(源代碼鏈接:https://github.com/coreh/bevy-demo-ruins)
此外,還添加了半透明貼圖的支持,通過專門的 alpha 模式實現(xiàn)預(yù)乘 alpha 的效果。
以下是新模式們的一些high-level預(yù)覽:
AlphaMode::Add(docs鏈接:https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html#variant.Add)——將片段顏色與背景顏色相加,產(chǎn)生更亮的結(jié)果,類似于光。常用于火焰、全息圖、幽靈、激光和其他能量束等效果。在圖形軟件中也被稱為“線性疊加”。
AlphaMode::Multiply(docs鏈接:https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html#variant.Multiply)——使用乘法過程將片段的顏色與其背后的顏色相結(jié)合(類似于顏料),產(chǎn)生較暗的結(jié)果。這對于模擬部分光線透過的效果非常有用,比如彩色玻璃、車窗貼膜和某些有色液體。在圖形軟件中也被稱為“線性減淡”。
AlphaMode::Premultiplied(docs鏈接:https://docs.rs/bevy/0.10.0/bevy/pbr/enum.AlphaMode.html#variant.Premultiplied)——與混合模式具有類似的表現(xiàn),但假定顏色通道有預(yù)乘透明度??梢杂脕肀苊馐褂闷胀╝lpha混合紋理時出現(xiàn)的脫色"輪廓"偽像,或者巧妙地在單個紋理中組合加性和常規(guī)alpha混合材質(zhì),因為對于常數(shù)RGB值,預(yù)乘透明度模式在接近1.0的alpha值時更像混合模式,在接近0.0的alpha值時更像加法模式。

注意:使用新的混合模式的網(wǎng)格將繪制在現(xiàn)有的Transparent3d渲染階段上,因此與AlphaMode::Blend相同,需要考慮/限制深度排序。
由于篇幅太長了,這里將分為兩篇專欄發(fā)布,另外從這個版本開始bevy已經(jīng)越來越像一個真正的引擎了,所有之后的更新日志可能會量更大,更專業(yè),所以以我個人的能力很難能即使對新版本的更新日志進行翻譯,個人如果有什么相關(guān)建議可以告訴我