關於Camera.activeTexture和Camera.targetTexture的疑問

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和運行時內存是會減少的。

CompressAnimationClips.cs

感謝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的使用版原本下載就能夠,不影響下面的教程。

FbxSDK與VisualStudio環境搭建

這個教程會教你打開一個Samples,隨便打開一個Sample,而後把Kent提供的main.cxx內容替換到同名文件內,編譯出exe就好。

這裏提供一個本身編譯的,須要配合Kent提供的Demo使用:

ClearUVClr.exe

感謝高鬆@UWA問答社區提供了回答

A2:我在使用的時候發現有的Fbx文件替換無效,經查是main文件中

只獲取了第一個節點,因此我改爲遍歷獲取

這裏提供main文件和exe文件:
main.cxx

ClearUVClr.exe

感謝Lim@UWA問答社區提供了回答


Script

Q:目前面臨一個尋路方案的需求,指望有相關經驗的朋友探討一下各類實現方案的優劣和可行性,開闊下思路。

需求抽象以後大體以下:
1. 3D多層場景,可是場景不會很大,幾百米乘以幾百米之內吧;
2. 場景分層,高度上可能有多層重疊,層之間有地面阻擋,挖空的地方有各類穿梭方式;
3. 場景內有箱子、小巷之類的阻擋與道路;
4. 玩家可能會有相似輕功的飛行移動方式。

3D方面可選的方案很少,好比Navmesh、體素化、純物理,目前比較傾向於體素化的方案,純物理的目前測試下來感受性能消耗有點不能接受。固然需求方面也有一些能夠取捨的,想看看各位有經驗的朋友有什麼好的想法和建議。

A:最近看到一些3D尋路的解決方案想到這個問題,掛靠一下:

  1. SVON:基於八叉樹場景劃分+A星尋路的算法實現,有開源庫(Native源碼+Unity工程)見連接。

  2. Mercuna 3D Navigation:看官方介紹相似SVON,對A星算法進行了優化,有UE和Unity的插件,但沒找到相關插件下載,須要聯繫官方。

感謝羽飛@UWA問答社區提供了回答

封面圖來源於網絡


今天的分享就到這裏。固然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,咱們早已在UWA問答網站上準備了更多的技術話題等你一塊兒來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。

官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com
官方問答社區:answer.uwa4d.com
UWA學堂:edu.uwa4d.com 官方技術QQ羣:793972859(原羣已滿員)

相關文章
相關標籤/搜索