circle-loader
by
43/ 0

今回の話題:

1)Camera.activeTextureおよびCamera.targetTextureに関する質問

2)アニメーションファイルの浮動小数点精度を下げる方法

3)EasyMovieTextureを使用してAndroidでビデオを再生できませんでした

4)モデルの頂点の色(Color)を削除する方法

5)多層3Dシーンパスファインディングスキームに関する議論


Rendering

Q:私はいつも疑問を持っていました。Camera.activeTextureとCamera.targetTextureがGetするとき、GetしたのはRenderTextureですか?

この両者には、現在レンダリングされているRenderTextureのみを取得できるか、レンダリングターゲットを取得および設定できるかという違いがありますが、activeTextureは必要性ですか?

またはこのような理解は間違っていますか?またレンダリングターゲットが常に画面である場合、この両者にはどちらでもBackbufferを取得しますか?

A:質問1:Camera.targetTextureは、カメラのRender Targetを指定する際さえ非nullになり、 Camera.activeTextureによって取得される値は、呼び出しのタイミングに関連しています。公式ドキュメントには、OnPostRenderで取得できると記載されています。たとえば、後処理を使用する場合、、後処理で申し込んだRenderTextureはOnPostRenderで取得でき、Updateで取得する場合はnullになります。 RenderTextureがカメラに設定されている場合、targetTextureは設定されたRenderTextureです。 HDRがオンになっていない場合、OnPostRenderのactiveTextureによって取得されたのもこのRenderTextureです。HDRがオンになっている場合、個別に申し込んだRenderTextureになります。

質問2:レンダリングステータスを表示するには、RenderDocを使用することをお勧めします。2つの状況があります。AndroidプラットフォームでAlways Blitがオンになっている場合と、オンになっていない場合とは異なります。Always Blitをオンにすると、最後にもう1つのPresentプロセスがあります。Presentする前に、すべてのレンダリングはtexと呼ばれるRenderTextureにレンダリングされます(後処理とHDRによって生成された追加のRenderTextureについては、一応考慮しない) 。Presentしている時texをBackbufferにCopyします。AlwaysBlitがオンになっていない場合、たとえば、Blit TypeがNeverの場合、すべてのレンダリングが直接Backbufferにレンダリングされます(ここでも、RenderTextureの場合を考慮しない)。BlitTypeがAutoの場合、Presentの状況に当たったことありません。そして線形空間にもPresentが現れませんでした。Backbufferと Presentに使用されるtexとのどちらも、システムによって提供されるものとして理解でき、C#スクリプトから取得することはできません。また、これら2つのオブジェクトのサイズもProfilerからは見えません。

要約すると、カメラにRenderTargetが設定されていない限り、ほとんどの場合、Camera.targetTextureはnullです。

Camera.activeTextureの場合、これは呼び出しのタイミングによって異なります。OnPostRenderで呼び出された時、後処理またはHDRを使用すると、申し込んだRenderTextureを取得できます。Updateで取得した場合、nullになります。他の関数ステージについては、まだ詳しくテストしてません。

Backbufferの場合、これはシステムによって提供され、C#スクリプトから取得できません。また、Backbufferに直接描画すると限りません。後処理やHDRを使用しない場合でも、Always Blitがオンになっていると、追加の中間レイヤーが作成され、最終段階に中間レイヤーはBackbufferにコピーされます。

 

Animation

Q:アニメーションファイルの後処理では、高精度の圧縮とScaleカーブのカリング、という2つのことができます。これは、ツールで元の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があります。

 

A2:Mecanimのアニメーションシステムの圧縮は、Floatタイプを変更することによって実際に達成されるのではなく、桁数を減らすことによって、より多くのConst曲線を生成できるため、エンジンはより効率的なストレージを実現し、いわゆる「圧縮された」効果が実現されます。

 

A3:体積短縮を達成するために、精度をクロップすることにより、より多くのConst Curveが生成されたのは理解できますが、アニメーション曲線が動的にキャプチャされ、ブレした詳細がたくさんない限り、この方法で削減されるメモリは非常に限られています。さらに、多くの場合、一括して精度を削減するのは望ましくありません。

Unityの公式フレームリダクションアルゴリズムは、すべてのボーンのパラメータセットであり、比較的非効率的です。推奨される改良処理:ジョイントごとに異なるエラーしきい値を設定し、手動でLinear Key Reductionを実行します。ルートボーンに近いほど、必要な精度が高くなり、許容誤差しきい値が小さくなります。エンドボーンに近いほど、誤差しきい値が大きくなります。PositionとRotation Curveの場合は、さまざまな誤差測定方法を使用し、顔や指などの主要なボーンに対しては、追加的な配置を実行します。

これにより、特に動的なキャプチャによって生成されたアニメーションの場合、Clipメモリ​​とパッケージ本体のサイズを効果的に減らすことができます。スクリプト処理方法は.animファイルにのみ適用し、さらに追加のEditorCurveが生成されるため、アセットサイズは処理後に減少せず、増加する可能性があります。ただし、最終的にEditorCurveはCurveにマージされ、AssetBundleとランタイムメモリが削減されます。

CompressAnimationClips.cs

 

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を使用することをお勧めします。これは、機能が強化され、互換性が向上します。

 

A2:互換性を高めるために、ネイティブのビデオ再生アプリを使用することをお勧めします。

 

A3:以前にEasyMovieTextureの問題が発生しましたが、特定のXiaomiデバイスでのみ発生しました。最終的にビデオ形式をmp4に変更しました。ビットレートがEasyMovieTextureの例のビデオと同じになるように変更します。

ps:最初にサンプルビデオでテストしてみたらどうでしょう。同じく再生できない場合は、他の理由があることを説明しています。

 

A4:以下に示すように、公式のVideoPlayerを直接使用します。

 

Mesh

QUWAのモデル分析ページにモデルの頂点の色に関する情報があります。このデータが不要な場合は、この属性をMaxにエクスポートしないのが最善であることがわかりました。この属性がクリアされた場合はどうなりますか?

新しいモデルを作成しようとしましたが、現時点では、モデルに頂点カラー属性がありません。頂点カラーが変更されると、この属性をクリアできなくなります。

A1: FBXSDKからexeファイルをエクスポートしようとしました。

FbxSDKの公式サイトからダウンロードしてください。使用しているVSのバージョンに応じてダウンロードすれば順調になり、次のチュートリアルには影響しません。

FbxSDKおよびVisualStudio環境のビルド

このチュートリアルでは、Samplesを開き、任意的にあるSampleを開き、main.cxxコンテンツを同じ名前のファイルに置き換えて、exeをコンパイルしたら済みます。

ここで、自己コンパイルされたものを提供します。Demoと合わせて使用します。

ClearUVClr.exe

A2:使用したところ、一部のFbxファイルの置換が無効であることがわかりました。調査の結果、mainファイルに含まれていました。

最初のノードしか取得できなかったので、トラバースに変更して取得しました。

mainファイルとexeファイルは次のとおりです。

main.cxx

ClearUVClr.exe

 

Script

Q:現在、パスファインディングソリューションの必要性に直面していますが、関連する経験を持つ人が、さまざまな実装ソリューションの長所、短所、実現可能性について話し合い、考えを広げてくれることを願っています。

要件を抽象化すると、おおまかに次のようになります。

1.3D多層シーンですが、シーンはそれほど大きくはありません。数百メートル×数百メートル以内にある必要があります。

2.シーンはレイヤー化されており、高さが複数のレイヤーに重なっている可能性があり、レイヤー間にグラウンドブロッキングがあり、くり抜かれた場所でさまざまなシャトル方法があります。

3.シーンには、ボックスや路地などのブロックや道路があります。

4.プレイヤーは、忍者に似た飛んでいて移動できるかもしれません。

Navmesh、ボクセル化、純粋な物理など、3Dのオプションは多くありません。現在、ボクセル化の採用を検討中です。純粋な物理は、テストではパフォーマンスのコストに少し許容できないと感じています。もちろん、需要の面は選択取捨があります。これに対し、何かご提案がありますか?

 

A:最近、私はいくつかの3Dパスファインディングソリューションを見て、リンクを提供します:

  1. SVON:octreeシーン分割+Aスターパスファインディングアルゴリズムの実装に基づいて、オープンソースライブラリ(Nativeソースコード+ Unityプロジェクト)があります。リンクを参照してください。

2.Mercuna 3D Navigation:SVONに似た公式の紹介を確認した際、Aスターアルゴリズムを最適化しました。UEとUnity用のプラグインがありますが、ダウンロードする関連プラグインは見つかりません。公式に連絡する必要があります。


 

UWA公式サイト:https://jp.uwa4d.com

UWA公式ブログ:https://blog.jp.uwa4d.com

UWA公式Q&Aコミュニティ(中国語注意):https://answer.uwa4d.com