Slide 1

Slide 1 text

2 0 2 4 Unity 6 シェーダー Warmupガイド

Slide 2

Slide 2 text

講演者 Unity Technologies Japan パートナーエンジニア ブーシェ ロビン晃

Slide 3

Slide 3 text

シェーダー Warmup やってますか?

Slide 4

Slide 4 text

オブジェクトの初回描画でシェーダーコンパイルスパイクが発生 Shader Compile よくある光景

Slide 5

Slide 5 text

シェーダー Warmup をしよう ShaderVariantCollection.WarmUpを使えばいいはず? // Warmupしたいシェーダーバリアントを含んだ ShaderVariantCollection public ShaderVariantCollection shaderVariantCollection; // Warmup! shaderVariantCollection.WarmUp(); // 終わり! カンタン! 参考マニュアル ● https://docs.unity3d.com/ScriptReference/ShaderVariantCollection.WarmUp.html

Slide 6

Slide 6 text

しかし、マニュアルをよく見ると・・・

Slide 7

Slide 7 text

Warning: 警告: この方法は DX11とOpenGLで完全にサポート されています。 DX12、Vulkan、および Metal では、頂 点レイアウトおよび/またはレンダー ターゲットの設定が、プリウォームに使用したデータと異なる場合、グ ラフィックスドライ バはまだ作業を実行する必要があるかもしれません。 これは無駄な作業と GPU メモリの浪費につながり、アプリケーショ ンに目に見えるストールを残します。 ShaderWarmupはすべてのグラフィックスAPIでサポートされています。 ???

Slide 8

Slide 8 text

ShaderVariantCollection.WarmUp の罠 実は、Vulkan・Metal・DX12だとShaderVariantCollection.WarmUpは機能しない。 Android・iOSでシェーダーWarmupを行っているつもりなのにシェーダーコンパイルの スパイクがなくならない・・・という悩みがよくある。

Slide 9

Slide 9 text

Vulkan ・Metal ではどうする? Shader Loadingマニュアル Unity 2022.3以前) ● https://docs.unity3d.com/2022.3/Documentation/Manual/shader-loading.html 「正確な頂点データレイアウト」がポイント

Slide 10

Slide 10 text

Vulkan・Metalでの シェーダー Warmup

Slide 11

Slide 11 text

「正確な頂点データレイアウト」 Vulkan・Metal・DX12でシェーダーWarmupを行う場合、実際に対象のオブジェクトが 描画される時の頂点データレイアウトを把握し、 Warmup実行時に指定する必要がある。 頂点データとは頂点シェーダーに渡されるデータのこと ● POSITION ● NORMAL ● UV0/1/2… ● COLOR ● etc… 間違った頂点データで Warmupした場合、描画時に正しいデータで改めて シェーダーコンパイルが実行されるため、結局スパイクが発生することになる。

Slide 12

Slide 12 text

ShaderWarmup API Experimental.Rendering.ShaderWarmup ● Unity 2021.3より追加された新しいシェーダー Warmup API ● Warmup時に頂点データを指定できる ○ ShaderWarmupSetupより 参考マニュアル ● https://docs.unity3d.com/ScriptReference/Experimental.Rendering.ShaderWarmup. html

Slide 13

Slide 13 text

頂点データの指定 頂点データはVertexAttributeDescriptorで定義する ● https://docs.unity3d.com/ScriptReference/Rendering.VertexAttributeDescriptor.html Attribute ● データタイプ POSITION・TEXCOORD・COLORなど) Format ● データの型 Float32・Float16・UNorm8など) Dimension ● データの次元 2  XY、3  XYZ、4  XYZWなど) 例: POSITIONは Float32  3 XYZ で指定されることが多い

Slide 14

Slide 14 text

// 頂点データレイアウト指定 ShaderWarmupSetup setup = new ShaderWarmupSetup(); setup.vdecl = new VertexAttributeDescriptor[] { new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3), new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3), new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4), new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2), }; // Warmup実行 ShaderWarmup.WarmupShader(shader, setup); コード

Slide 15

Slide 15 text

肝心の頂点データは どこから取得できる?

Slide 16

Slide 16 text

頂点データの取得 正確な頂点データを Warmupに提供したい場合、 Warmup対象のシェーダーで描画されるすべてのオブジェクト Mesh等) の 頂点データレイアウトを把握している必要がある。 (プロジェクト規模によりますが、大体 20パターン以内のケースが多いです )

Slide 17

Slide 17 text

Meshの場合 Inspectorから確認 POSITION ● Float32  3 XYZ NORMAL ● Float32  3 XYZ TANGENT ● Float32  4 XYZW UV0 TEXCOORD0 ● Float32  3 XY

Slide 18

Slide 18 text

ParticleSystem の場合 Renderer → Custom Vertex Streams から確認 POSITION ● Float32  3 XYZ NORMAL ● Float32  3 XYZ COLOR ● UNORM8  4 RGBA UV TEXCOORD0 ● Float32  3 XY

Slide 19

Slide 19 text

struct Attributes { float3 positionOS : POSITION; float3 normalOS : NORMAL; float2 uv : TEXCOORD0; // シェーダーでは Tangentが使われていない }; シェーダーも確認 頂点シェーダーのコードで実際に使用している頂点データのチェックも忘れずに! MeshのデータではTANGENTがあるが、シェーダーでは使っていないため、 TANGENTが入っていないシェーダーの頂点データレイアウトが正しい

Slide 20

Slide 20 text

確実に正確なデータを取得するには GPUデバッガーを活用する ● RenderDocなどのツールからフレームのキャプチャーを取り、頂点データを確認する ● Warmup対象オブジェクトすべての描画を地道に確認する R8G8B8A8_UNORM  UNORM8  4 COLOR

Slide 21

Slide 21 text

めんどくさい!

Slide 22

Slide 22 text

GraphicsStateCollectionを使う

Slide 23

Slide 23 text

GraphicsStateCollection API Unity 6からGraphicsStateCollection APIが登場 ● デバイスで実行中に描画の PSOを記録できる ● 描画されたシェーダーバリアント・頂点データを自動的にトラッキング ● 記録したデータをアセット (.graphicsstate) として保存 ● .graphicsstateアセットを元にWarmupができる 参考マニュアル ● https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Experimental.Ren dering.GraphicsStateCollection.html ● https://discussions.unity.com/t/graphicsstatecollection-tracing-and-warmup-in-unit y-6/951031

Slide 24

Slide 24 text

PSOを記録 GraphicsStateCollection.BeginTrace GraphicsStateCollection.EndTrace GraphicsStateCollection.SaveToFile (通常通りゲームを実行 ) 記録開始 描画されるオブジェクトの シェーダーバリアント・頂点データを記録 記録終了 記録結果を.graphicsstateアセットに保存

Slide 25

Slide 25 text

.graphicsstate アセットと Warmup .graphicsstateアセットを元に GraphicsStateCollection.WarmUpで Warmupを行う 確実に正確な頂点データレイアウトで Warmupできる

Slide 26

Slide 26 text

// 記録する.graphicsstateアセット public GraphicsStateCollection graphicsStateCollection; // 記録開始 graphicsStateCollection.BeginTrace(); // 記録終了 graphicsStateCollection.EndTrace(); // アセット保存 graphicsStateCollection.SaveToFile(filePath); // Warmup! graphicsStateCollection.WarmUp(); // 終わり! カンタン! コード

Slide 27

Slide 27 text

すべてのプラットフォームで 正確なシェーダーWarmupが楽に!

Slide 28

Slide 28 text

2 0 2 4 Thank you