簡介: 又接到了新的需求泛领,對場景中的物體和燈光進行分組渊鞋,即人物燈光只照人物,場景燈光只照場景锡宋,道具燈光只照道具执俩,等。這個其實不論在哪個版本的引擎里都是最基礎(chǔ)的功能支持尝丐,給物體分層爹袁,然后設(shè)置燈光的CullingMask 即可。也許是項目里的著色器大部分都是自己開發(fā)的譬淳,所以在URP 中面對這種情況時出現(xiàn)了一些 bug。
unity版本: 2022.3.14
管線:URP
背景
需求: 人物和場景分光源照射
結(jié)果: 分層設(shè)置后蛤迎,兩盞光還是會互相影響含友,即場景的燈光依然會照到人身上窘问。使用 urp 自帶的 lit 發(fā)現(xiàn)沒有這個問題。剩下的事情就簡單了把鉴,一路向前追庭砍。
意向中的原理: 在個人淺薄的理解中混埠,這個功能非常簡單钳宪,實屬不應該出錯吏颖。其實現(xiàn)過程基本應該是這樣的:
在繪制物體前,收集影響物體的燈光嫉柴,在這個階段就可以確定哪些光是會影響當前物體的计螺,這時候肯定也做了culling操作,剩下的就是把燈光參數(shù)傳遞到渲染結(jié)果匙握,嗯~ 應該就是這么簡單陈轿,實際在UPR中被啪啪打臉麦射。
分析
經(jīng)過邏輯跟蹤對比潜秋,發(fā)現(xiàn) URP 管線在渲染時,所有的燈光是一起傳遞的罗售,沒有在渲染前對物體所需要的燈光進行 culling 操作寨躁。
在其光源的 GetMainLight 中有這么一個屬性 distanceAttenuation
引擎使用 distanceAttenuation 這個來作為 maskculling 的標記职恳,所以除了主光源(important)之外话肖,其它光源都使用的是 AdditionalLight 邏輯葡幸,而具體當前光生不生效是通過 distanceAttenuation 在作為遮罩的蔚叨,當不生效時直接就是個0蔑水,計算結(jié)果便為黑色搀别。
return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff);
雖然這玩意實現(xiàn)了燈光的分層影響,但是也增加的無用的燈光計算再愈,而且單給物體的燈光影響數(shù)量也會受到現(xiàn)存光的影響护戳。根據(jù)邏輯推測媳荒,這會有幾個問題
- 本來設(shè)置的是一個物體可以接受4盞光缴渊,當場景中存在8盞光分為兩個層鱼炒,一個層四盞的時候(影響權(quán)重都一樣)田柔,按照目前邏輯看硬爆,會有四盞燈在所有物體上都不生效擎鸠,也就是每個層可能都會有燈光不全的現(xiàn)象劣光。
- 再一個就是绢涡,一般開發(fā)的時候 additional light 的光照計算會做簡單處理雄可,所以光照結(jié)果會比主光遜色一些。如果分層的物體不在主光的culling內(nèi)聪舒,則效果可能會打折扣。因為主光占用了它的主要渲染邏輯被辑,但最終因為culling卻給了個黑色敷待。
- 還有一個就是榜揖,沒有必要的計算邏輯依然參與了運算举哟,所以一個物體分層內(nèi)只有一站光潜叛,但它依然要計算其它光威兜,只不過結(jié)果是黑色椒舵。
所以引擎為何要這么設(shè)計呢,他的苦衷是啥呢