1)關於_CameraDepthTexture的疑惑
2)貼圖Alpha通道對圖片大小的影響
3)URP要怎麼實現GrabPass的效果
4)如何獲取AssetDatabase加載失敗的Asset的Instance ID
5)如何判斷Bundle文件加載進內存的時機
html
這是第226篇UWA技術知識分享的推送。今天咱們繼續爲你們精選了若干和開發、優化相關的問題,建議閱讀時間10分鐘,認真讀完必有收穫。git
UWA 問答社區:answer.uwa4d.com
UWA QQ羣2:793972859(原羣已滿員)
github
Rendering
Q:一個關於_CameraDepthTexture的疑問。緩存
若是開啓_CameraDepthTexture,Camera就須要渲染一遍場景內全部帶有ShadowCaster的Pass來實現深度圖。網絡
可是場景中的物體在開啓ZWrite的時候就把深度寫進了Depth Buffer中了,直接得到這個Depth Buffer是否是比近乎DrawCall翻倍的方式更有效率呢?仍是Unity在這方面有什麼考慮?編輯器
另外,問一個更實際的問題:
咱們的項目須要渲染場景的中湖水的深度效果,全部不透明的場景物體的材質都是關聯一樣一個Shader,這個Shader是帶有ShadowCaster的。可是隻有個別插入水中的物體須要去渲染ShadowCaster的Pass,有沒有方法在不增長Shader的狀況下,讓沒有插入水裏的物體不渲染Shadow Caster Pass呢?咱們用的是Built-in的渲染管線。
ide
A:第一個問題,能夠參考這個問題中Unity官方人員的回覆。
裏面講了兩個緣由,第一是對於非全屏渲染的狀況,原本是想拿對應相機渲染的深度,可是Depth Buffer是全屏的。第二個緣由是由於不少平臺不支持直接拿Depth Buffer的數據。
函數參考網頁:
https://forum.unity.com/threads/poor-performance-of-updatedepthtexture-why-is-it-even-needed.197455/
測試另外查FrameBufferFetch相關問題的時候看到Unity論壇上另一個貼子裏面的回答。裏面說到Unity支持了FrameBufferFetch,可是不支持DepthBuffer的獲取。fetch
參考網頁:
https://forum.unity.com/threads/pixel-local-storage-and-frame-buffer-fetch-on-mobile-devices.604186/
第二個問題,若是不增長Shader,目前沒想到其餘好的方法。
若是能夠增長Shader,能夠將原來的Shader複製一份,只在ShadowCaster的部分加一個「NeedDepth」這樣的Tag,將水下的物體的材質球換成這個Shader,另外作一個只有ShadowCaster並帶有「NeedDepth」這個Tag的Shader,這個Shader用來作Replace操做。額外增長一個Camera,這個Camera跟隨主相機,或者做爲主相機的子節點,建立一個RT,讓這個Camera渲染到這個RT,在Update裏面使用ReplaceShader去畫一下,那麼只有有那個Tag的ShadowCaster會進行深度渲染,後續能夠對這個RT進行編碼等操做,這個RT記錄的就是水下物體的深度。整個過程看上去沒有特別多的額外工做,以爲能夠一試(我沒有作過測試,但理論上是可行的)。
感謝Xuan@UWA問答社區提供了回答,歡迎你們轉至社區交流:
https://answer.uwa4d.com/question/5fa4f888dc477370c2c1f07f
Texture
Q:在UWA的《紋理優化:不只僅是一張圖片那麼簡單》這篇文章中,描述了圖片含有Alpha通道會對內存有影響。
經過如下的測試資源配置:
- Tga_Alpha - 含有Alpha通道
- Tga_NoAlpha - 不含有Alpha通道
- Png_Trans - 含有透明的圖片
- 進入到Unity中的Format,所有代碼設置爲TextureImporterFormat.ASTC_6x6
測試結果:
- 三張圖片Unity所有Format爲下圖格式
- 三張圖片顯示的內存大小所有同樣
- Texture Importer的Alpha Source設置爲None,對測試結果無影響 問題:圖片是否含有Alpha通道,對於同一個Format格式,內存大小都是同樣的嗎?
Tex.7z
A:原文中的優化建議是去除無心義的Alpha通道(原文中的定義爲Alpha值所有爲1的貼圖),這個確實是對內存優化有幫助的。
題主的測試用例中,不管是png格式仍是tga格式,進入引擎後,都會被引擎轉爲內部的格式(RGBA、ETC、ASTC等)。設想一下,以ETC2爲例,若是沒有Alpha通道,在壓縮質量能夠接受的狀況下,就能夠選用RGB_Compressed_ETC2_4bits,而若是添加了這個無心義的Alpha通道,那麼咱們在批量導入設置時,都會自動選擇RGBA_Compressed_ETC2_8bits。這樣內存就相差了一倍。
而問題中關於ASTC的狀況,在Unity編輯器源碼中的Texture導入格式的定義有這樣一句註釋:// ASTC uses 128bit block of varying sizes (we use only square blocks). It does not distinguish RGB/RGBA,即與是否包含Alpha通道無關。關於ASTC格式的介紹,這裏推薦你閱讀一下Github上的ASTC Format Overview。
而關於你樓上回復中提到的Unity新版本的問題,能夠看下Unity論壇上的這個問題。
可能有人以爲對於項目的貼圖格式都是ASTC來講,去除Alpha的意義不是很大,其實不能一律而論,雖然大小相同,但根據(https://zhuanlan.zhihu.com/p/158740249)中的測試,是否有Alpha通道會必定程度上影響壓縮質量。因此仍是要在項目中合理使用。
感謝範君@UWA問答社區提供了回答
A2:遊戲運行時Texture的Alpha通道要看導入後的狀況,不能看源文件的狀況。UWA本地資源檢測對於Texture的Alpha通道檢測的就是導入後的結果。
圖片源文件的格式,圖形硬件是不支持的,Unity也不直接接管。導入圖片後,會按照Import Settings中的設置對圖片進行處理,將圖片導入成硬件支持的格式(在引擎中的格式),而在運行中使用的資源也是導入後的。
題主將Alpha Source設置爲None,那麼導入時就不對源文件的Alpha通道進行導入,而壓縮格式爲ASTC_6x6,這個格式是包含Alpha通道的。這樣導入後三個資源都會默認生成一個全爲1的Alpha通道。佔用內存大小天然同樣。
感謝Prin@UWA問答社區提供了回答,歡迎你們轉至社區交流:
https://answer.uwa4d.com/question/5fa25e7cdc477370c2c1f015
Rendering
Q:URP如何實現GrabPass的效果?URP管線已經去掉了原先GrabPass的功能,如今有一個扭曲特效的功能,相似熱擾動那種。雖然URP可以直接獲取到實體圖作扭曲效果,可是像是半透明物體(好比:水、其餘特效等)也須要被扭曲就作不到。
A:題主想要徹底實現GrabPass估計不行,可是能夠有替代方案:
GrabPass的意思就是先繪製a物件,而後繪製b物件的時候影響a,繪製c物件的時候影響ab。注意,這最重要的是b物件的擾動影響不了c物件,由於b物件是比c物件先繪製的。
可是若是你可以接受b物件和c物件的擾動同時影響abc,那麼就簡單了,先用一個RT將扭曲的信息存下來(其實就是UV偏移),而後在Uber Shader中將偏移應用在畫面上。這樣扭曲信息就擾動了全部物件(不論是不透明仍是半透明)。
雖然不知道URP怎麼實現的,可是咱們本身改的SRP,就是這麼實現的。
感謝王爍@UWA問答社區提供了回答,歡迎你們轉至社區交流:
https://answer.uwa4d.com/question/5fa5040fdc477370c2c1f080
Editor
Q:如今有一個繼承於ScriptableObject的Asset,不管出於什麼緣由,引用腳本的GUID錯了。那麼經過必定的編輯器腳本能找到這個Asset的Path,可是如何在ProjectView內選中它?
經測試,使用Selection.instanceID是能夠選中的,而Instance ID通常須要經過Object來獲取,可是由於腳本引用錯誤了,因此AssetDatabase是沒法載入這個Object的。有什麼辦法或者API能獲取到這個Instance ID呢?
A:經過查看公開源碼,找到了一個可用的方法:
//assetPath : 某個找不到對應腳本的Asset實例路徑 HierarchyProperty property = new HierarchyProperty(assetPath); Selection.activeInstanceID = property.GetInstanceIDIfImported();這樣能夠在ProjectView內正確選中了。
感謝題主黃程@UWA問答社區提供了回答,歡迎你們轉至社區交流:
https://answer.uwa4d.com/question/5f9fc6fadc477370c2c1efd9
Addressable
Q:當下載好全部的資源後,在一個測試腳本中調用LoadAssetAsync函數,以下圖:
在AssetBundleProvider這裏是第一個疑惑:
既然Addressables所有采用緩存機制來存放AssetBundle包,那此處的File.Exists不是總會爲False嗎?
第二個疑惑在於:
Addressables在WebRequest完成下載後,如何把握把Bundle加載進內存的時機?也多是個人思路有問題,可是在後面的堆棧追蹤裏面沒有發現有相似於LoadFromFile這樣的調用。
A:這兒的File.Exists並非檢查緩存,而是檢查文件在不在StreamingAssets裏面。而全部下載的資源則是經過緩存來獲取的,若緩存裏沒有則下載。而Load這部分已經被封裝在了UnityWebRequestAssetBundle內了。
感謝黃程@UWA問答社區提供了回答,歡迎你們轉至社區交流:
https://answer.uwa4d.com/question/5fa0d4f1dc477370c2c1effc
封面圖來源於網絡
今天的分享就到這裏。固然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,咱們早已在UWA問答網站上準備了更多的技術話題等你一塊兒來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。
官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com 官方技術QQ羣:793972859(原羣已滿員)