1)關於Camera.activeTexture和Camera.targetTexture的疑問
2)如何下降動畫文件的浮點數精度
3)使用EasyMovieTexture在Android播放視頻失敗
4)模型頂點色(Color)如何去除
5)多層3D場景尋路方案探討java
UWA 問答社區:answer.uwa4d.com
UWA QQ羣2:793972859(原羣已滿員)android
Rendering
Q:一直有個疑惑,Camera.activeTexture和Camera.targetTexture在Get的時候,Get到的是一個RenderTexture嗎?git
我知道這兩個的區別是一個只能得到當前所正在渲染的RenderTexture,一個是既能夠得到也能夠設置渲染目標,但這樣activeTexture有什麼必要性呢?github
是我對這兩個的理解有錯誤嗎?還有你們平時說的Backbuffer,在我渲染目標一直是屏幕的時候,這兩個方法得到的都是Backbuffer嗎?算法
A:第一個問題:Camera.targetTexture必須在相機指定Render Target纔會非null,Camera.activeTexture獲取到的值和調用的時機有關係。官方文檔中寫着能夠在OnPostRender中獲取到,好比使用了後處理,在OnPostRender中能夠獲取到後處理申請的RenderTexture,在Update中獲取就是null。若是給相機設置了RenderTexture,那麼targetTexture就是設置的RenderTexture。若是沒有開啓HDR,在OnPostRender中activeTexture獲取到的也是這個RenderTexture。若是開啓了HDR,則是一個另外申請的RenderTexture。網絡
第二個問題:推薦使用RenderDoc查看渲染狀態,分爲兩種狀況,在安卓平臺上開啓了Always Blit和沒開啓會不同。開啓了Always Blit,會在最後多一個Present的過程,在Present以前,會將全部的渲染渲染到一個叫tex的RenderTexture上(這裏不考慮後處理以及HDR致使生成了額外的RenderTexture),在Present的時候將tex Copy到Backbuffer裏面。若是沒有開啓AlwaysBlit,好比Blit Type是Never,那麼全部的渲染都是直接渲染到Backbuffer的(這裏一樣不考慮RenderTexture的狀況),Blit Type爲Auto的時候沒有遇到出現Present的狀況,在線性空間也沒出現Present 。Backbuffer和那個用來Present的tex這兩個對象均可以理解爲系統提供的,從C#腳本中是無法獲取到的,並且從Profiler裏面也是看不到這兩個對象的大小的。編輯器
總結起來就是:大部分狀況下Camera.targetTexture都是爲null的,除非相機設置了RenderTarget。ide
對於Camera.activeTexture,這個須要看調用時機,在OnPostRender中調用,若是有使用後處理或者HDR,則能夠獲取到申請到的RenderTexture,在Update裏面獲取是null的,其餘的函數階段沒有詳細測試過。函數
對於Backbuffer,這個系統是提供的,C#腳本是獲取不到的。並且不必定是直接繪製到Backbuffer,就算沒有使用後處理或者HDR,若是開啓了Always Blit,也是會多一箇中間層,在最後階段中間層會Copy到Backbuffer。工具
感謝Xuan@UWA問答社區提供了回答
Animation
Q:動畫文件後處理能夠作兩件事,精度壓縮,Scale曲線剔除。比起用工具修改原始FBX文件,這樣比較靈活。
實際測試,在開啓Optimal壓縮的狀況下,加上這個後處理,能再節省40%左右。
示例代碼和測試結果見知乎專欄:
https://zhuanlan.zhihu.com/p/27378492
void OnPostprocessModel(GameObject g) { // for skeleton animations. List<AnimationClip> animationClipList = new List<AnimationClip>(AnimationUtility.GetAnimationClips(g)); if (animationClipList.Count == 0) { AnimationClip[] objectList = UnityEngine.Object.FindObjectsOfType (typeof(AnimationClip)) as AnimationClip[]; animationClipList.AddRange(objectList); } foreach (AnimationClip theAnimation in animationClipList) { try { //去除scale曲線 foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(theAnimation)) { string name = theCurveBinding.propertyName.ToLower(); if (name.Contains("scale")) { AnimationUtility.SetEditorCurve(theAnimation, theCurveBinding, null); } } //浮點數精度壓縮到f3 AnimationClipCurveData[] curves = null; curves = AnimationUtility.GetAllCurves(theAnimation); Keyframe key; Keyframe[] keyFrames; for (int ii = 0; ii < curves.Length; ++ii) { AnimationClipCurveData curveDate = curves[ii]; if (curveDate.curve == null || curveDate.curve.keys == null) { //Debug.LogWarning(string.Format("AnimationClipCurveData {0} don't have curve; Animation name {1} ", curveDate, animationPath)); continue; } keyFrames = curveDate.curve.keys; for (int i = 0; i < keyFrames.Length; i++) { key = keyFrames[i]; key.value = float.Parse(key.value.ToString("f3")); key.inTangent = float.Parse(key.inTangent.ToString("f3")); key.outTangent = float.Parse(key.outTangent.ToString("f3")); keyFrames[i] = key; } curveDate.curve.keys = keyFrames; theAnimation.SetCurve(curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve); } } catch (System.Exception e) { Debug.LogError(string.Format("CompressAnimationClip Failed !!! animationPath : {0} error: {1}", assetPath, e)); } } }
A1:壓的是文本文件的大小,只是編輯器下更快,不論怎麼處理,內存仍是一個Float。
感謝海的味道@UWA問答社區提供了回答
A2:Mecanim的動畫系統的壓縮確實不是靠改變Float類型來達到的,而是經過下降數值位數後,能夠產生更多的Const曲線,從而讓引擎達到更高效存儲的效果,進而達到所謂的「壓縮」結果。
該問答由UWA提供
A3:裁剪精度產生更多Const Curve,達到縮小體積的目的,這個能夠理解。但除非動畫曲線是動捕出來的,有大量抖動的細節,不然這樣下降的內存頗有限。並且統一暴力降精度在不少時候並不可取。
Unity官方的減幀算法是一套參數針對全部骨骼的,比較低效。推薦細化處理:針對不一樣關節,設置不一樣的偏差閾值,手動作Linear Key Reduction。越靠近根骨骼,所需精度越高,容許的偏差閾值越小。越靠近末端骨骼,偏差閾值越大。對Position和Rotation Curve,使用不一樣的偏差度量方式,面部、手指等關鍵骨骼再加額外配置。
這樣能夠有效大幅減少Clip內存和包體大小,尤爲對於動捕產生的動畫。腳本處理方法僅適用於.anim文件,且因爲會產生額外的EditorCurve,在處理完後資產大小可能會不減反增。但最終EditorCurve會合併入Curve,AssetBundle和運行時內存是會減少的。
感謝zhangji@UWA問答社區提供了回答
Video
Q:使用EasyMovieTexture在Android播放視頻失敗,報錯信息以下:
AndroidJavaException: java.lang.IllegalStateException: Unable to update texture contents (see logcat for details)
java.lang.IllegalStateException: Unable to update texture contents (see logcat for details)
android.graphics.SurfaceTexture.nativeUpdateTexImage(Native Method)
android.graphics.SurfaceTexture.updateTexImage(SurfaceTexture.java:248)
com.EasyMovieTexture.EasyMovieTexture.UpdateVideoTexture(EasyMovieTexture.java:331)
com.unity3d.player.UnityPlayer.nativeRender(Native Method)
com.unity3d.player.UnityPlayer.access600(Unknown Source:0)
com.unity3d.player.UnityPlayer600(UnknownSource:0)com.unity3d.player.UnityPlayerf1.handleMessage(Unknown Source:150) android.os.Handler.dispatchMessage(Handler.java:106) android.os.Looper.loop(Looper.java:219)
com.unity3d.player.UnityPlayer1.handleMessage(UnknownSource:150)android.os.Handler.dispatchMessage(Handler.java:106)android.os.Looper.loop(Looper.java:219)com.unity3d.player.UnityPlayerf.run(Unknown Source:20)
UnityEngine.AndroidJNISafe.CheckException () (at <3c22a197ab60454cb70124c69f2248be>:0)
UnityEngine.AndroidJNISafe.CallVoidMethod (System.IntPtr obj, System.IntPtr methodID, UnityEngine.jvalue[] args) (at <3c22a197ab60454cb70124c69f2248be>:0)
UnityEngine.AndroidJavaObject._Call (System.String methodName, System.Object[] args) (at <3c22a197ab60454cb70124c69f2248be>:0)
UnityEngine.AndroidJavaObject.Call (System.String methodName, System.Object[] args) (at <3c22a197ab60454cb70124c69f2248be>:0)
MediaPlayerCtrl.Call_UpdateVideoTexture () (at :0)
MediaPlayerCtrl.Update () (at :0)
A1:視頻播放建議使用AssetStore中的AVProVideo,功能更強且兼容性更好一些。
感謝範君@UWA問答社區提供了回答
A2:建議使用自帶的視頻播放,兼容性更好。
感謝Robot.Huang@UWA問答社區提供了回答
A3:我以前遇到過一個EasyMovieTexture的問題,並且只出如今某個小米手機上,咱們最後把視頻格式改成mp4,碼率我記得也改的跟EasyMovieTexture示例的視頻同樣而後就行了。
ps:你能夠先用示例的視頻測試一下,若是一樣播放不了,那就是其餘緣由了。
感謝lanyt@UWA問答社區提供了回答
A4:直接用官方本身的VideoPlayer,以下圖:
感謝小輝輝-177865@UWA問答社區提供了回答
Mesh
Q:在UWA中的模型分析頁面中有關於模型頂點色的信息,得知若是不須要此數據,最好在Max中不要導出此屬性,那麼若是清除此屬性呢?
我嘗試過新建一個新的模型,這時此模型是不帶頂點色屬性的,一旦修改頂點色後就沒法再清除此屬性了,求解。
A1:感謝kent的回答,可是他提供的Demo內的exe我這裏打開會報錯,本身嘗試從FBXSDK導出了一個exe。
FbxSDK官網下載,根據VS的使用版原本下載就能夠,不影響下面的教程。
這個教程會教你打開一個Samples,隨便打開一個Sample,而後把Kent提供的main.cxx內容替換到同名文件內,編譯出exe就好。
這裏提供一個本身編譯的,須要配合Kent提供的Demo使用:
感謝高鬆@UWA問答社區提供了回答
A2:我在使用的時候發現有的Fbx文件替換無效,經查是main文件中
只獲取了第一個節點,因此我改爲遍歷獲取
這裏提供main文件和exe文件:
main.cxx
感謝Lim@UWA問答社區提供了回答
Script
Q:目前面臨一個尋路方案的需求,指望有相關經驗的朋友探討一下各類實現方案的優劣和可行性,開闊下思路。
需求抽象以後大體以下:
1. 3D多層場景,可是場景不會很大,幾百米乘以幾百米之內吧;
2. 場景分層,高度上可能有多層重疊,層之間有地面阻擋,挖空的地方有各類穿梭方式;
3. 場景內有箱子、小巷之類的阻擋與道路;
4. 玩家可能會有相似輕功的飛行移動方式。
3D方面可選的方案很少,好比Navmesh、體素化、純物理,目前比較傾向於體素化的方案,純物理的目前測試下來感受性能消耗有點不能接受。固然需求方面也有一些能夠取捨的,想看看各位有經驗的朋友有什麼好的想法和建議。
A:最近看到一些3D尋路的解決方案想到這個問題,掛靠一下:
SVON:基於八叉樹場景劃分+A星尋路的算法實現,有開源庫(Native源碼+Unity工程)見連接。
Mercuna 3D Navigation:看官方介紹相似SVON,對A星算法進行了優化,有UE和Unity的插件,但沒找到相關插件下載,須要聯繫官方。
感謝羽飛@UWA問答社區提供了回答
封面圖來源於網絡
今天的分享就到這裏。固然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,咱們早已在UWA問答網站上準備了更多的技術話題等你一塊兒來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。
官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com 官方技術QQ羣:793972859(原羣已滿員)