Unityはどのようにデプスバッファを直接取得するか

1)Unityはどのようにデプスバッファを直接取得するか

2)UnityEditorでのSpriteAtlasの読み込みの問題

3)GameObjectをProjectウィンドウからSceneViewウィンドウにドラッグできない

4)UGUIのイベント応答の問題

5)iOS設定Texture2DのmipMapBiasが無効です


 

Rendering

Q:いくつかの情報を確認したところ、Unityは深度テクスチャを取得するために各オブジェクトをもう1回レンダリングする必要があるようですが、このレンダリングを省略して深度バッファに直接取得する方法はありますか?または、深度バッファを直接コピーします。

 

A:できますよ。主な手順は次のとおりです。

  1. Camera.SetTargetBuffersを介してカメラの色と深度のBufferを新しいRT(ColorBufferRT、DepthBufferRT)に再ポイントします。
  2. AfterForwardOpaqueイベントをCommandBufferに追加し、ColorBufferRTとDepthBufferRT Blitを新しいRTにレンダリングします(後者のレンダリングは直接使用できます)。
  3. CommandBufferを介してAfterEverythingイベントとBlitColorBufferRTをCameraTargetに追加します(画面が正しくようにするため)。

詳細については、

https://blog.csdn.net/linjf520/article/details/104964803を参照してください。


 

Texture

Q:使用されているバージョンはUnity 2018.3.6f1です。Unity EditorモードでPrefabを編集すると、画像がメモリに読み込まれます。その結果、ゲームの開始時に関連するアトラスSpriteAtlasManager.atlasRequestedが事前にコールされ、アトラスの読み込みエラーが発生します。

 

上図は、早すぎたアトラスのロードで、失敗時に検出したメモリにロードされた画像です。ゲームの実行中に、プレハブを編集するときにメモリ内の画像アトラス、をクリアする方法はありますか?

補足:ゲームを実行せずにメモリ表示のインターフェイスを呼び出し、メモリにまだ多くの画像がロードされていることを確認します。

 

A:この問題の本質は、Atlasに参照したSpriteをロードするときに、メモリにAtlasがない場合、アトラスをロードするための「リクエスト」(atlasRequested)がトリガーされることです。EditorでPrefabを編集すると、このリクエストが生成されます。ゲームの最初のフレームで、このリクエスト関数がコールされ、このリクエストはNativeレイヤーによって発するため([RequiredByNativeCode])、これを制御する方法はありません。メモリにあるアセットをアンロードすることと関係ありません。

このリクエストはランタイムの最初のフレームでのみコールするため、最初のフレームでatlasRequestedイベントを登録しないでください。最初のフレームの後、対応するPrefabをロードする必要があるときに関数を登録したりしないでください。このようにすると、ゲームを起動時にこの関数をコールすることが避けられます。


 

Editor

Q:最近、Unityは会社のプロジェクトを開いたときにGameObjectをProjectウィンドウからSceneViewウィンドウにドラッグできないことがわかりましたが、新しいプロジェクトを作成したらドラッグすることはできるようになりました。特定のツールによるものなのか、プラグインによるものなのかを推測しますが、プラグインやツールが多すぎるので、ひとつひとつチェックするのは時間の無駄です。使用されているUnityのバージョンは2019.4です。

 

通常のプロジェクトでは、GameObjectをプロジェクトウィンドウからSceneViewウィンドウにドラッグしたら、アイコンは次のようになります。

 

異常な時、以下のようになってしまいました:

 

現在、外部ツールまたはプラグインのSceneView.duringSceneGuiおよびDragAndDropの関連コードはコメント化されており、問題は依然として存在します。

 

A:この問題の理由は、GameObjectのEditorを書き直し、OnSceneDrag関数を実装しなかったためです。この関数が実装されていない場合、オブジェクトをProjectWindowからSceneViewにドラッグできません。


 

UGUI

 

Q:UGUI RayCastのNoDrawRayCastはPCでは問題なくクリックできますが、Androidスマホになったら浸透(penetration)し、クリックして応答することはできません。透明チャンネルが0であるImageを使用する時は問題ありません。

 

スクリプトは次のとおりです。

 

A:Imageの半透明度を0に設定し、CanvasRendererでのCullTransparent Meshを選択して、描画せずにクリックイベントに応答できるようにすることができます。(さらに、問題主のコードをテストしました結果、Xiaomi 9では問題ありません。)


 

Texture

Q:iOSデバイスでTextureMipmapStreamingを使用すると、Texture2DのmipMapBiasの設定が無効になります。このTextureはMaterialから取得したmainTextureですが、Editorで有効になります(画像がぼやけになったり鮮明になたっりできます)。

バージョンはUnity2018.4.13です。関連する設定を次の図に示します。

 

 

A:これにつき、Texture.streamingTextureDiscardUnusedMips = trueを有効にする必要があります。そうしないと、メモリが十分である場合、高精度のテクスチャは破棄されません。


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

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

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

Addressableエディタに関連する開発の問題

1)Addressableエディタに関連する開発の問題

2)Addressableは更新アドレスを動的に設定する

3)Addressableはネットワークが悪い環境でアセットをダウンロードする

4)Android ETC2 Fallbackに関する質問

5)内蔵Shaderの「Dependency」の定義


Addressable

Q:エディタスクリプトで以下のオプションを自動的にインポートして選択し、関連するKeyを自分で設定できるようにしたいのですが。参考プロジェクトやコードサンプルはありますか?

 

A:AssetDatabase.AssetPathToGUIDとAddressableAssetSettings.CreateOrMoveEntryを使用してください。


 

Addressable

 

Q:Addressableによって動的に配置されたホットアップデートアドレスは、ドキュメント内の静的変数(赤枠のところ)を使用します。Addressableの開始後に取得されたCatalogs.Countは常にゼロです。アドレスに問題があると思われますが、このクラスも静的である必要がありますか?

 

デッドアドレスを割り当てると、次のように更新できます。

 

この更新はテストに合格しました。最初のパッケージを生成した後、RemoteLoadPathを動的に変更したいと思います。

 

A: RemoteLoadPathはstaticのpropertyを指し、このpropertyは構成テーブルからアセット更新のアドレスを返します。

 

Addressable

 

Q:アセットのホットアップデートにはAddressableを使用しています。これで、ネット環境が悪い状況で、アセットのダウンロードステータをシミュレートします。Windowsでパケット損失をシミュレートするソフトウェアを使用してネットワーク環境がシミュレートして、パケット損失率が30%に設定されます。

 

Addressableのダウンロードは一定の割合で停止し、DownloadDependenciesAsyncのCompletedイベントはトリガーされないため、AsyncOperationHandleのstatusから失敗したか成功したかを判断することはできません。

 

Logによって報告されたエラーは次のとおりです。

 

この状況に対する良い解決策はありますか?

 

A:後で、いくつかのアセットのTime Out値の設定が大きすぎて、常に待機していることが判明したため、プログレスバーが動かなくなっていました。解決策は、Time Out値を小さく設定し、retry回数を増やすことです。

Time Outは20に設定されています。長すぎないようにしてください。長すぎると、ダウンロードの進行状況がタイムアウトしたときに長時間停止します。短すぎると、モバイルネットワークが貧弱になり、タイムアウトしてダウンロードが失敗することがよくあります。


 

Editor

Q:エミュレータでしばらく実行するとゲームがクラッシュしますが、画像がRGBA32に解凍されているため、過剰なメモリが原因だと思います。Android ETC2 Fallbackを16bitに設定して、ローエンドの実機のメモリ使用量を大幅に削減できますか?

 

また、Build SettingでETC2 Fallbackを選択した後、Project Settingに変更はありませんが、この値はどこに保存されますか?どのようにアップロードしますか? (バージョン:Unity 2018.4.31)

 

A:シミュレータには通常、十分なメモリがあります。メモリの問題が心配な場合は、シミュレータに割り当てられているメモリを調整できます。メモリの問題か、32ビットまたは64ビットのアプリケーションの問題か、または64ビットのLuaJitの問題か、Logcatに接続してLogで確認してください。この値は、Library\EditorUserBuildSettings.assetファイルにあります。


 

Shader

Q:TerrainのShaderをカスタマイズしようとしていますが、内蔵のShaderの最後に以下の二行があることがわかりました。その中の「Dependency」とは何か、そして後で指定するShaderの機能は何ですか?

 

Dependency “AddPassShader” = “Hidden/TerrainEngine/Splatmap/Diffuse-AddPass”

Dependency “BaseMapShader” = “Diffuse”

 

A:Dependencyは、シェーダーの依存関係を指定するために使用される文書化されていないキーワードであり、実の機能は2つあります。

パッケージ化時に依存関係を見逃すことはなく、AssetBundleBrowserで確認できます。

Unity 2019以降、等号の右側にあるShader名は、C#インターフェイスのShader.GetDependency(等号の左側にある依存関係の名前)から取得できます。

地形システムは、3つのライティングモデルがあるため、これを行います。GetDependency(依存関係名)は、一部のShader名のハードコーディングを減らすことができ、依存関係名はインターフェイスとして機能します。


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

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

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

AssetBundleをダウンロードするMonoメモリ問題

1)AssetBundleをダウンロードするMonoメモリ問題

2)Unity 2019の実行中に、Hierarchyのプレハブアセットを取得するパス

3)複数のSubmeshesモデルをマージした後の表示問題

4)ToLuaのアクセスTime.deltaTimeは0

5)CacheServerは接続が切れる


 

Memory

Q:コルーチン+ UnityWebRequestを使用してBundleをダウンロードするときに割り当てられたメモリは解放できません。

 

ダウンロード手順は次のとおりです。

1.コルーチン+ UnityWebRequestを使用してBundleをダウンロードする。

2.BinaryWriterを使用して、UnityWebRequest.downloadHandler.dataのデータをマシンに書き込みます。

3.UnityWebRequestのDispose関数をコールします。

4.Resources.UnloadUnusedAssets()、UnityWebRequest.ClearCookieCache()、およびSystem.GC.Collect()をコールします。

 

各Bundleをダウンロードするたびに上記のプロセスを実行しますが、Profilerで実機をデバッグした結果、割り当てられたメモリを解放できないことを検出します。これにより、Monoメモリがどんどん大きくなります。

 

A:以前にも同様の問題が発生しました。当時使用しているUnityのバージョンは2018.4.31です。

以前のWWWであろうと現在のWebRequestであろうと、そのメンバーであるDownloadHandlerを使用してダウンロードしたのです。「.data」プロパティにアクセスすると、実際には「GetData()」関数のラッパーにアクセスします。この関数はnative-memory data bufferのコピーに返します。これは根本的な原因です。

最適化できる一つ目は、「。data」の使用を減らし、一時変数でキャッシュすることです。

2つ目は、DownloadHandlerを置き換えることです。UnityはさまざまなDownloadHandlerを提供しています。当時は画像をダウンロードしていたため、DownloadHandlerTextureを使用しました。問題に応じて、DownloadHandlerAssetBundleを試すことができます。

参照:https://docs.unity3d.com/ScriptReference/Networking.DownloadHandlerAssetBundle-ctor.html


 

Editor

Q:アーティストは、エディターの実行時にシーンGameObjectインスタンスに対応するプレハブのパスを取得したいと考えています。Unity2017では、var pRoot = PrefabUtility.GetPrefabParent(go); return AssetDataBase.GetAssetPath(pRoot)を介してランタイムプレハブパスを取得できました。

 

最近2019にアップグレードしたところ、インターフェイスが更新されていることがわかりました。PrefabUtility.GetPrefabInstanceHandle(targetGameObject)、PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)、およびその他のインターフェイスは、Unityの実行中にHierarchy内のGameObjectパスを取得できません。

問題点は、実行状態です。つまり、[再生]をクリックして、Hierarchyのプレハブストレージパスを取得します。 PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)は、再生をクリックせずに取得できます。再生後したらProjectのプレハブストレージパスのみが取得できるようになりました。

 

A:PrefabUtility.GetNearestPrefabInstanceRoot:最も近いプレハブインスタンスのRootを取得します。

PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot:プレハブパスを取得します。

if (PrefabUtility.IsPartOfPrefabInstance(seletedGo))
{
    string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(seletedGo);
}

GetPrefabAssetPathOfNearestInstanceRootはパスを取得できるが、「PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)」インターフェイスは、Prefab部分ではなく、インスタンスを渡します。

そうでない場合は、Editorでスクリプトをハングアップするか、他の方法でマッピングを作成してから、Runtimeで実行します。


 

Mesh

Q:Skinmeshのマージ機能をテストしたところ、Meshに複数のSubmeshesが含まれていると、マージが成功した後はレンダリング効果が表示できなくなりました。

 

テストされたMeshにSubmeshesが含まれていない場合、マージして表示できます。 CombineMeshesは、Submeshesを含まないMeshのみをマージできますか?問題はどこにあるのかわかりませんか?解決策はありますか?

 

注:「r.sharedMesh.CombineMeshes(combineInstances.ToArray()、false、false);」を使用してすべてのマテリアルを取得するか、「r.sharedMesh.CombineMeshes(combineInstances.ToArray()、true、false);」を使用して一枚のテクスチャマテリアルをコンバインするか、複数のSubmeshesを持つモデルはコンバインのみ可能で、レンダリングして表示できません。複数のSubmeshesがないモデルは、正常にコンバインし表示できます。

 

A:テストした結果、複数のSubmeshesを含むモデルを通常どおり表示するには、CombineInstanceごとに三角形の面を再指定する必要があることがわかりました。

このコードのように:

foreach (SkinnedMeshRenderer smr in allSkineMeshList)
    {
        for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++)
        {
            CombineInstance ci = new CombineInstance();
            ci.mesh = smr.sharedMesh;
            ci.mesh.triangles = smr.sharedMesh.triangles; //ここで再指定

            ci.subMeshIndex = sub;
            ci.transform = matrix * smr.transform.localToWorldMatrix;
            combineInstances.Add(ci);
        }

    }

 

Lua

Q:ToLuaでUnityのTime.deltaTimeにアクセスしたら、常にnilであり、Lua変数に割り当てられた値も0です。

PS:静的バインディングはToLuaがUnity APIにアクセスする前に実行されており、Luaは他のAPIに通常どおりアクセスできます。

 

ToLuaでアクセスしたTime.deltaTimeが0であるのはなぜですか?

A:Luaのバインディングは、Lua仮想マシンの起動後に書き込む必要があります。

 


 

Editor

Q:クライアントがCache Serverパネルを開いてConnectionをテストすると、接続できないことがわかります。次に、サーバーのコンソールをクリックすると、Enterをクリックしたら次のことが表示されます。

その後、クライアントは再接続できます。フォーカスが失われたように感じますが、その理由は何ですか。

 

A:Windowsでは、サーバーのコンソールを右クリックしてプロパティ/デフォルトを設定し、「クイック編集モードのチェックを外します」。


 

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

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

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

Addressableアセットのホットアップデートに関する疑問

1)Addressableアセットのホットアップデートに関する疑問

2)遠い所のメッシュ線がぼやけにならない方法

3)シェーダーでのいくつかの特別な画像の使用について

4)Lightmapがメモリに繰り返しロードされる

5)Unity2020.2.1パッケージAPKの問題


 

Addressable

Q:Addressableアセットのホットアップデートは、CRC Mismatchと提示し、ホットアップデートする必要があるアセットをCDNの対応するディレクトリにアップロードされ、ゲームの開始時にエラーが報告されます:

A:私たちのプロジェクトでも以前に同じ問題が発生しました。具体的には、パッケージがインクリメントされた後、BundleのHashが変更されていないが、CRCが変更されたため、ロードエラーが発生しました。

ここには2つの処理法があります。

1、Unityの公式によった「SchemaでCRCCheckを無効にする」方法を採用します。でもこの方法は、Bundleダウンロードの整合性と正確性を検証する際に問題が発生する可能性があります。

2、HashとCRCの二重テストをホットアップデートプロセスに追加します。いずれかの値が変わったと検出した場合、Bundleを更新する必要があると判断し、最新のCatalogファイルをリロードじます。同じく、この方法も、このバンドルのコンテンツが更新されていない場合でも、Bundleが大量に追加される可能性があります。


 

Texture

 

Q:メッシュ線の効果を出したいのですが、遠くの線がぼやけしますが、それはなぜでしょうか?これは正方形のMeshであり、UVスケーリングを使用してn個の小さなメッシュをカバーし、画像を[Repeat]に設定し、Mipmapをオフにします。しかし、遠くの線は相変わらずぼやけになります。何か解決方法はありますか?

 

A1:TextureのAniso Levelを上げてみてください。

Aniso Levelは、地面をローアングルから見るために使用されます。さらに、Filter ModeをTrilinearに設定している場合、部分的な効果がなくなりました。でもそのようにすると、コストは大分大きくなります。

 

A2:以下のように調整すると、問題は解決します。


 

Shader

Q:下図のように、他の場所からアセットをダウンロードしているため、詳しい説明はありませんが、TAの観点からこのような写真が何に使われているのか知りたいのですが。 T_M_Body_Msa_b.png、T_M_Body_Msa_g.png、T_M_Body_Msa_Mtl.pngは、それぞれどちらのシェーダーに使用されたんでしょうか?

A:それぞれb(Bump)、g(Glossness)和Mtl(Metallic)です。


 

Rendering

 

Q:次の図に示すように、Lightmap在Profileに重複に表示されるのはなぜですか?それぞれが40MBだと思いますが、それを最適化する方法はありますか?また、対応する参照スクリプトでは、Lightmapへの参照が見つかりませんでした。

A:各Lightmapが2つロードされているようです。Lightmapを管理するメカニズムを自分で作成しましたか?一度に2つロードしますか、それともシーンを切り替えたりLightmapを変更したりするときにそれらをアンインストールしませんか?シーンをロードするときにLoadSceneMode.Additiveを使用しましたか?これにより、前のアセットをアンロードせずにシーンが累加的にロードしまいます。

Lightmapへの参照数は非常に多いですね。どこのスクリプトによってインデックスされていたのか、対応するコンポーネントが常に常駐しているかどうかを確認してください。アンインストールするときは、インデックスをクリアする必要があります。

このウィンドウには、GameObjectとMonobehaviourの相互参照関係が表示されますが、直接参照ではありません。非常に複雑で、特定するのがかなり難しいです。Unityが提供する特別なMemoryProfilerで試すことができます。


 

Script

Q1:Unity 2020.2.1 + HubによってダウンロードされたSDK、NDK、JDK、およびBuildToolsが正しくパッケージ化されていません。

関連するエラーメッセージには、価値がある情報が記載されていません。

 

検証後:streammingAssetsファイルには680の制限があり、制限を超えるとパッケージ化できません。サフィックス名の有無に関係ありません。個人バッジョンには制限があるということでしょうか?

 

A1:おそらくそうではありません。何万ものファイルがテストされており、問題はありません。

 

A2:Custom Gradle properties templateを選択し、ファイル内でunityStreamingAssets = .unity3d * STREAMING_ASSETS *をunityStreamingAssets = .unity3dに変更したら済みます。

圧縮しない特別なファイルタイプが必要な場合は、コンマ “,”で区切って自分で追加してください。unityStreamingAssets = .unity3d、.bundleのようです。

U3Dは、2020.2.3以降、aaptOptionsのパッケージパラメータを変更しました。aaptOptionsの最大配列は255です。

aaptOptions 
{
    noCompress = [’.ress’, ‘.resource’, ‘.obb’] + unityStreamingAssets.tokenize(’, ')

    ignoreAssetsPattern = “!.svn:!.git:!.ds_store:!.scc:.:!CVS:!thumbs.db:!picasa.ini:!*~”
}

*PACKAGING_OPTIONS*

 

Q2:streamingAssetsを非圧縮にし、ファイルにサフィックスを付けないようにする場合、どのように記述しますか?

 

A:U3D 2020.2はunityStreamingAssets変数を使用する必要があるため、プロジェクトをエクスポートしてから、すべてのファイルが圧縮されないようにaaptOptionsを変更する必要があります。

参照:https://developer.android.google.cn/reference/tools/gradleapi/4.1/com/android/build/api/dsl/AaptOptions


 

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

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

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

ビッグワールドツリーシャドウスキームコレクション

一、要求

 

UnityエンジンによるTerrainの木の影の処理はちょっと粗末なので、プロジェクトの要件を満たさないことがよくあります。動的オブジェクトがLight Probeをサンプリングする場合、デフォルトでは、木に対してLightmapをベイクしません。しかし、このような大きな動的オブジェクトのlight probe proxy volume(サポートしない、サポートに変更するとスタックする)でさえ、間接光と大規模なオクルージョンが豊富にしただけ、セルフシャドウ効果を効果的に表現できません。リアルタイムの影の距離になると、画像ははるかに悪くなります。そして、手元にある「生と死の狙撃兵2」は、4億の研究開発を投資した大規模なプロジェクトです。グラフィックスレンダリング技術の担当者として、私は当然、多くの技術的解決策を試して比較する必要があります。

 

具体的には、50メートル以内でShadowmapを使用することです。50〜1500メートル以内に平行光の影が必要であり、平行光は静的です。

 

このニーズを満たす7つのスキーマを次に示します。

 

1、インスタンスで再利用可能な無方向間接光の影をベイクする

2、ベーキングインスタンスの再利用+回転可能な指向性ライトシャドウ

3、低精度の事前計算された静的シャドウマップシャドウ

4、スパースオクトツリーボクセル化静的シャドウ

5、画面スペースの接触リアルタイムシャドウ

6、低精度の高さマップに基づくリアルタイムのシャドウ

7、距離フィールド加速光線マーチングシャドウ


 

スキーマ1:インスタンスで再利用可能な無方向間接光の影をベイクする

 

これは一番簡単な方法で、3DsMaxで空の光を使用してAOに似た影をベイクます。これにより、木は任意の角度の回転や任意の角度の太陽光に交換性があり、アセットの再利用率も高くなります。しかし、平行光の影は、少しアンリアルで適合性にも乏しい。このようなベイク図を取得してから、木の2セットのUVに作用します。コードも非常に簡単で、SpeedTreeCommon.cginc内にUV1パスを追加し、最後に*をAlbedoに追加するだけです。これは、AOが間接光に十分な効果がないためです。

Max-bakedによってベイクされたAO図を木のPrefabにバインディングして再利用する。Unityベイクは再利用できず、方向性もある。

リアルタイムシャド内

リアルタイムシャドウの外

このスキーマの効果

利点:シンプルで使いやすく、4行のコードで実現され、高性能で、低解像度の画像が1回サンプリングされます。

 

欠点:方向光は考慮されず、シャドウはそれ自体でのみ改善でき、木の下の動的オブジェクトを遮ることができません(静的ならShadowmaskをベイク処理できます)。


 

スキーマ2:インスタンスで再利用可能な+回転可能な平行光の影をベイクする

 

前のスキームより、方向も考慮に入れたのです。このような8つの並列ライトベイキングマップをベイク処理します。

木インスタンスのさまざまな方向に応じてさまざまなAOマップが設定されますが、木は地形に設定するのが不便であるため、配列またはアトラスに作成できます。Shaderでは、方向に応じてIndexまたはOffsetを取得します。効果が前の効果と似ていますが、方向性が優れています。各方向は比較的正規分布です。8方向では不十分だと思われる場合は、2方向の補間や16方向のマップを作成できます。

このスキームの効果

利点:シンプルで使いやすく、高性能で、低解像度のアトラスが1〜2回サンプリングされ、回転をサポートし、方向性シャドウがあります。

 

欠点:太陽の角度が異なるマップでは、別のテクスチャセットが必要になる場合があります。シャドウを改善できるのは自分だけで、木の下の動的オブジェクトを遮ることはできません(静的ならShadowmaskをベイク処理できます)。


 

スキーム3:精度の低い事前計算された静的Shadowmapシャドウ

 

まず、リアルタイムシャドウ内の効果を比較します。葉のセルフシャドウは悪くありませんが、2番目、リアルタイムシャドウ外になるとダメです。

4M静的Shadowmaskの効果:

原理:シーンに対し、深度マップを記録するShadowmap、ライトカメラを記録するmatrix_vpをオフラインで撮影します。ただ、このような大規模な撮影では深度精度が足りないので、16ビットではなく、RGBA32で深度を圧縮します。だから、縞模様に見えました。

 

利点:影があるだけでなく、遠くにいるキャラクターなどの動的なオブジェクトを遮るすることもできます。実装が簡単で、実行時にDraw Callsを節約でき、遠くのシーンを繰り返し撮影する必要がありません。

 

欠点:ビデオメモリが大きい。

 

アップグレードし続けるスキーム:仮想テクスチャに基づく静的ShadowmapまたはTexture streamingのShadowmap。

 

前のプロジェクト:https://github.com/jackie2009/ScrollingStaticShadowmap


 

スキーマ4:スパースオクトリーでボクセル化された静的シャドウを実現する

 

0.9Mで影をボクセル化する効果:

 

原理:0.5メートルごとに1つの立方体、0または1を記録して影にあるかどうかを示します、オクトリーのノードとします。次に、ツリー圧縮によってメモリを節約します。

 

利点:影があるだけでなく、遠くのキャラクターなどの動的オブジェクトを遮ることもできます。実行時にDraw Callを節約でき、遠くのシーンを繰り返し撮影する必要がありません。Shadowmapよりビデオメモリが節約られます。

 

欠点:実装はより複雑であり、事前計算の書き込みは、同時実行性が高い場合にのみ高速になります。Shaderは、結果を照会するために複数のサンプリングを必要とします。

 

プロジェクトファイル:https://github.com/jackie2009/ocTreeVoxelizedShadows/

 

スキーム5、6、および7:各デモ開発はより複雑であり、後で更新されるか、別の記事になります。


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

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

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

RenderTextureによるUIスクリーンのぼやけ問題

1)RenderTextureによるUIスクリーンのぼやけ問題

2)Unity 2019ToLuaエクスポートParticleSystemが異常

3)Android 10でのUWAGOTスクリーンショットの問題

4)Addressables.CheckForCatalogUpdatesおよびAddressables.GetDownloadSizeAsyncに関する問題

5)RenderDocでHuaweiのフレームをキャプチャすることはできない


 

Rendering

Q:UIスクリーンのぼやけを確認するにはどうすればよいですか?緑が表示され、紫も点滅しています。下の図に示すように、黒の背景と紫が点滅しており、スクリーンショットを撮ることができません。これは実機にしか表示されません。エミュレータでは問題なく表示されます。

 

この黒い背景は、SRPによって実装されたRenderTextureのBlur効果であり、使用されるデバイスはXiaomiK30です。

A1:FrameDebuggerで問題がある実行Shaderを特定することをお勧めします。問題があるのは、Shaderのレンダリング実行順序が間違っている可能性があります。RenderPassEvent設定が正しいかどうかを確認してください。

 

A2:問題が見つかりました。RenderTexture.GetTemporaryが使用され、depthBufferパラメーターが16に渡されますが、0なら問題なくなります。


Lua

Q:下図に示すように、Unity 2019 ToluaによってエクスポートされたParticleSystemは異常になります。

ここのTypeはnullであるため、ParticleSystemをエクスポートできません。

 

A:1.0.8.595でUnityランタイムライブラリ[out]でout以外のパラメータをマークする問題に対処し、公式Webサイトにアクセスして更新してください。

https://github.com/topameng/tolua/commits

topameng committed on 19 Jun 2020


 

Android

Q:UWAはAndroid 10でスクリーンショット機能を正常に使用できません。ドキュメントに従ってManifestを配置しました。

 

A:これは、UWA GOT Onlineパッケージ化のWrite権限の問題に対する解決策であり、スクリーンショットの問題を解決することはできません。現在、Android 10システムを搭載した実機では、APKによって設定されたTargetSDKVersion <= 28の場合にのみスクリーンショットすることができます。TargetSDKVersionは<= 28(28はAndroid 9)に設定されており、APKは引き続きAndroid10で実行できます。


 

Addressable

Q:Addressables.CheckForCatalogUpdatesAddressables.GetDownloadSizeAsyncが常にAsyncOperationStatus.Succeededを返すのはなぜですか?

 

httpサーバーを開いていませんが、それでも成功に返します。元々、Addressables.CheckForCatalogUpdates

とAddressables.GetDownloadSizeAsyncを使用して、アセットを更新する必要があるかどうかを判断しましたが、httpサーバーさえ開いていませんが、正常に返され、更新する必要がないことが検出されました。どのように対処しますか?

 

Addressableバージョン1.16.15

Unity 2018.4.14f

 

A1:コードをチェックした最後、CheckCatalogsOperationのExecuteメソッドに、直接にComplete(result、true、null);のように返したため、常に成功していることがわかりました。

 

A2:Addressables.CheckForCatalogUpdatesは、「catalog ids」のリストを返し、更新があるかどうかを判断します。リストが存在するかどうかを判断するのに十分です。

httpサーバーが開いていない場合は、更新する必要はなく、更新することもできません。GetDownloadSizeAsyncは、最新のCatalogのAssetBundleのhashとダウンロードされたAssetBundleのhashと比較して、ダウンロードする必要があるかどうかを判断し、ダウンロードする必要がある場合はSizeを累積します。catalogは更新されていないため、当然、カタログとは関係ありません。

どのように対処するかは、ビジネスレイヤーがどのように設計したいかによって異なります。例えば:

更新サーバーが開いているかどうかにかかわらず、ゲームに入ったのは、現在のCheckForCatalogUpdatesリターンリストが空で、更新する必要はないと見なされ、実行を続行します。

更新サービスがオンラインである必要がある場合、外部プログラムでサーバーが働いてしているかどうかを判断し、ゲーム更新ロジックに入ります。


 

Rendering

Q:最近、レンダリング深度が正しくないという問題が発生しました。 Snapdragonモデルでのレンダリングが間違っており(エディターと一致していない)、HuaweiモデルとiOSでのレンダリングが正しいです。そこで、RenderDocを使用してフレームをキャプチャして両者の違いを比較します。どちらのステップが異なるかを確認したいと思います。

 

同じパッケージをSnapdragonモデル(約数十MBのデータを含む.rdcファイル)ではキャプチャできますが、Huaweiモデル(約3MBのデータのみを含む.rdcファイル)ではキャプチャされたのは黒いであることがわかりました。

 

RenderDocのIssueにそれと似た問題を見つけました。おそらくこの問題が解決されていないようです。

https://github.com/baldurk/renderdoc/issues/2106

 

テスト環境:

Unity 2018.4 / Unity 2019.4

OpenGL ES3(Vulkanを使用している場合は、Huaweiで通常どおりフレームをキャプチャすることもできます)

 

1プラスのフレームキャプチャ結果:

Huaweiのフレームキャプチャ結果:

A: Mali Gpuを搭載したOPPOがフレームキャプチャができると発見しました、Huaweiでこの問題を確認し続けることはできません。

ただし、考察するうちに、改訂されたRenderDocはHuaweiでフレームをキャプチャできると発見しました。

https://developer.huawei.com/consumer/cn/forum/topic/0203337632069160300


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

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

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

ShaderLabの使用に関する質問

今回の話題:

1)ShaderLabの使用に関する質問

2)AndroidでのARM64とARMV7に関する質問

3)ILRuntime関連のパフォーマンス検出ツールについて

4)フォントの読み込みの問題

5)LZ4圧縮モードでのアセットパッケージ


 

Shader

Q:公式サイトから内蔵Shaderをダウンロードし、インターフェイスのマテルアルが内蔵Shaderを参照していないことを確認し、Standard Shaderもクリアしました。 メモリからはそのようなことはありませんが、ShaderLabの占有率はまだ少し大きく、メインシーンでは47MBになっています。

 

A1:バリアントが多すぎるので、キーワードが多いShaderをよく確認してください。

 

A2:A1の通りです。数年前に作成されたスキャンプロジェクトのShaderバリアントのコードを共有し、スキャンして、Top数個のShaderを変更して大幅に削減します。

[MenuItem("Find/GetAllShaderVariantCount", false, 20)]
    public static void GetAllShaderVariantCount()
    {
        #if UNITY_5_6
        Assembly asm = Assembly.LoadFile(@"D:\Program Files\Unity_5.6.5f1\Editor\Data\Managed\UnityEditor.dll");
        System.Type t2 = asm.GetType("UnityEditor.ShaderUtil");
        MethodInfo method = t2.GetMethod("GetComboCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        #elif UNITY_2017_1_OR_NEWER
        Assembly asm = Assembly.LoadFile(@"D:\Program Files\Unity_2018.3.0f2\Editor\Data\Managed\UnityEditor.dll");
        System.Type t2 = asm.GetType("UnityEditor.ShaderUtil");
        MethodInfo method = t2.GetMethod("GetVariantCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        #endif
        var shaderList = AssetDatabase.FindAssets("t:Shader");

        var output = System.Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory);
        string pathF = string.Format("{0}/ShaderVariantCount.csv", output);
        FileStream fs = new FileStream(pathF, FileMode.Create, FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);

        EditorUtility.DisplayProgressBar("統計ファイルの書き込み", "統計ファイルを書き込み中... ", 0f);
        int ix = 0;
        sw.WriteLine("ShaderFile,VariantCount");
        foreach (var i in shaderList)
        {
            EditorUtility.DisplayProgressBar("統計ファイルの書き込み", "統計ファイルを書き込み中... ", 1f * ix / shaderList.Length);
            var path = AssetDatabase.GUIDToAssetPath(i);
            Shader s = (Shader)AssetDatabase.LoadAssetAtPath(path,typeof(Shader));
            var variantCount = method.Invoke(null,new System.Object[]{ s,true});

            sw.WriteLine(path + ","+variantCount.ToString());
            ++ix;
        }
        EditorUtility.ClearProgressBar();   //プログレスバーをクリア
        sw.Close();
        fs.Close();
    }

A3:URPには一連のバリアントトリミングコードがあり、それを変更し、パッケージングプロセスに追加して、不要なバリアントをトリミングします(キーワードをあまり使用しないため、大幅に削減する必要があります)。

 

A4:UWAのローカルアセット検出を使用して、どのShaderにさらにバリアントがあるか、バリアントの問題であるかどうかを確認してから、Shaderに冗長性があるかどうかを確認してください。

 

Build

Q:AndroidでのARM64とARMV7の問題に関して、経験から、同じUnityゲームでこれら2つのアーキテクチャの実行効率に違いはありますか?レンダリング効率はCPUアーキテクチャの影響を受けますか?

 

A:ARM64は、メモリ割り当て中の不十分なアドレス空間とアドレスの競合によって引き起こされるメモリ割り当て障害の多くの問題を解決できます。典型的な例は、QualcommのAdrenoのビデオメモリの不足、または辞書タイプの広範な使用によって引き起こされるメモリリークの問題です。ただし、付随する問題も発生します。同じパッケージの64ビットは32ビットよりも大きいです。メモリの要件が厳しいゲームの場合、メモリの最適化はすでに面倒なことであるのに、64ビットになったらさらに面倒になってしまいました。効率の問題については、テストも比較もしていませんが、FPS、温度、エネルギー消費量などの違いを測定することをお勧めします。

 

ILRuntime

 

Q:UWAはすでにLuaのパフォーマンス分析をリリースしています。新しいプロジェクトでは、代わりにILRuntimeを使用し、AwaitとAsyncでネットワーク通信の「同期」コードを実現します。バトルパートのロジックコードもILRuntimeでの実装を計画しています(強CPU計算は可能な限りC#で実装されます)が、パフォーマンスについては少し懸念があります。パフォーマンス分析ツール、特にC#との対話型の部分がある場合は、初期段階で技術的なフレームワークを設定することができれば安心です。

 

さらに、ILRuntimeによってオンラインで正常に適用されたプロジェクトはありますか?それに、安定性の観点から、Luaを引き継ぐことができますか?

 

A1:日常使用にすれば十分だと思います。実際、基本的なメカニズムはLuaに似ており、開発の習慣と言語ははるかに快適になります。汎用モジュールの補足として使用すると便利だと思います、またはホットアップデート機能も非常に優れています。ただし、パフォーマンスの面では、ターゲットを絞ったテストはなく、現在、プロジェクトのニーズを満たしているとしか言えません。大量処理の観点から、ILRuntimeで多くのことを行うことはまだ推奨されていません。基本的な理由は、実際にはLuaの問題と非常によく似ています。

使用に関しては、Adapterの定義に注意してください。ホットアップデートに関しては、異なるコードノードがILRuntimeのホットアップデートパッケージを分離する必要がある場合があります。これはパッケージ管理の観点からは面倒ですが、統合開発言語にはまだ多くの利点があります。

 

A2:実際、パフォーマンスについてあまり心配する必要はありません。私の経験を共有しましょう。

1、必ずReleaseメソッドを使用してDLLをコンパイルし、DISABLE_ILRUNTIME_DEBUGマクロを開いてください。

2、解訳の実行のために、実行効率と直接実行の間には自然に20〜100倍のギャップがあり、複雑すぎる計算は間違いなく機能しません。

3、実行時も純粋なC#であるため、いくつかのパフォーマンスの問題はUWAツールで検出できます。

4、私たちのプロジェクトで使用されているネイティブDLLはLuaよりも確実に高速で、iOSでテストしたらLuaよりも低速ですが、AppleデバイスとIL2CPPのパフォーマンスは良好であるため、フルフレームで実行することもできます。

5、オブジェクト内の構造体への割り当てには必然的なGCがあります。最初にローカル変数に変換するか、V3をXYZに直接格納することをお勧めします。

6、ForeachはGCを生成します。書き込み時には使用しないでください。

 

A3:計算集約型はLuaを使用できます。

1、コアコードはC#を使用します。

2、バトルライブラリのロジックレイヤーは、Luaを使用します。

3、ビジネスロジックはILRuntimeを使用します。

4、Injectfixの別のレイヤーを配置し、非BurstのC#を修復します。

 

A4:ILRuntimeはC#で実装されているため、Profilerを見るとパフォーマンスの消費を直接確認できます。

 

Resource

Q:現在、実機でテストしていますが、メモリに2つのフォントがロードされていることがわかりました。1つはログインインターフェイス、またはフォント自体を含む他のシーンでは、元のFontを参照しています。もう1つはプレハブがシーンに読み込まれると、フォントのコピーが参照されます。これを解決する方法は?

 

A:プレハブがAssetBundleからロードされているが、シーンがAssetBundleからロードされていない場合、通常のシーンパッケージとAssetBundleは異なるパスを取り、同じフォントアセットを参照できません。1つはシーンのSharedassetsからのもので、もう1つはAssetBundleからのものです。したがって、シーンもAssetBundleによってパッケージ化されるか、フォントを使用するシーンのUI部分がAssetBundleから動的にロードされるかになっています。

 

Addressable

Q:LZ4圧縮モードでは、AddressablesがBundleをロードするにはHeadersのみをメモリにロードするので、すべてのアセットをBundleにパッケージ化できますか?このようにして、アセットの粒度とアセットの繰り返しのパッケージ化の問題を回避できますか?

 

A1:ファイルレベルのアセット更新で、しかもAssetBundleが非常に大きい場合、パッケージ全体を再ダウンロードすることと大差ありません。アセットの粒度は、主に更新アセット量を減らすことです。

 

A2:全体的な考え方を共有します。

AddressableですべてのアセットをBundleにパッケージ化し、固定の読み取りパスはUnityEngine.Application.persistentDataPathです。つまり、ローカルは常に読み取られます。実際の経験では、プレイ中にダウンロードするとフリーズが頻繁に発生します。

最初のパッケージは小さなパッケージをリリースします。ゲームが起動されると、アセットの更新がチェックされ、アセットBundle(後続のインクリメンタルパッケージを含む)がC#のHttpWebRequest(ダウンロードを単独で管理)を介してダウンロードされます。、persistentDataPathに一律にダウンロードされます。終了後にゲームのプロセスに入ります。

利点:

1、アセット管理は簡単です。

2、アセット分割の粒度に関係なく。

3、アセットの繰り返しのパッケージ化を考慮する必要はありません。

4、最初の起動時にダウンロードするBundleが多すぎるためにダウンロード速度が遅くなることを心配する必要はありません。

欠点:

まだ考えられず、皆様の指摘をお願いします。

 

A3:アセットのアンインストールの観点からは不合理です。Addressableは、参照カウントによるアンロードを処理します。これは、AssetBundleの参照カウントが0になった場合にのみトリガーされます。トリガーされると、AssetBundle.Unload(true)がコールされます。したがって、この大きなAssetBundleに常駐メモリが必要なアセットの場合、AssetBundleも常駐メモリが必要であることを意味します。そうすれば、短時間の使用後にアンインストールできるテクスチャなどのような未使用のアセットは、アンインストールできません。もちろん、Addressableのロード・アンロードインターフェイスでアセットをロードおよびアンロードすることを前提にしています。

 


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

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

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