【Unity】PIXを使って、描画負荷を計測してみる

2022/09/23に公開

はじめに

PIXへの理解を深めるため、Unityのソフトシャドウ・ハードシャドウの描画負荷を計測してみました。

https://docs.unity3d.com/ja/2019.4/Manual/DebuggingShadersWithPIX.html

環境

OS: Windows 10
CPU: AMD Ryzen 9 3900X 12-Core Processor
GPU: NVIDIA GeForce RTX 2080 Ti

PIX Windows Edition
Version 2208.10

Unity 2021.3.9f1
Built-in Render Pipeline

PIXって何?

PIXを利用することで、ドローコールの中身を詳しく解析することができます。
シェーダーを実行した時に、どれくらいの時間がかかったのかを見ることもできます。

※PIXを利用してプロファイリングを行うには、WindowsプラットフォームでDevelopmentビルドする必要があります。
※モバイルには対応していません。

01. Sphereメッシュを描画

シーンを作成し、カメラの正面にSphereを配置します。

FrameDebuggerを見てみる

UnityのFrame Debuggerを利用して、ドローコールを見てみます。

Draw Mesh Sphere というドローコールにて、Sphereメッシュが描画されています。


PIXでドローコールを見る

次に、PIXを利用してキャプチャーしてみます。
Camera.Renderというドローコールにて、シーンの描画が行われています

球を描画するドローコールを見てみる

RenderForward.RenderLoopJob というドローコールで、球が描画されています。
(Pipelineタブにて、描画の途中経過を見ることができます)

Unityのフレームデバッガー上で見れるドローコールとほぼ同じものがPIX上でも見れることが分かるかと思います。

02. PIXで処理負荷を計測する

Click-here to start analysis and collect timing data .と書かれた文字をクリックすることで、処理時間を分析することができます。

結果

計測がうまくいくと、ドローコールの処理にかかった時間が表示されます。

PIXでエラーが発生した場合の対策

PIXでエラーが発生した場合の対策

PIXを初めて使用する場合、ほぼ確実にエラーが発生します。
ここでは、エラーの解決方法を紹介します。


The feature requieres developer mode ~

開発者モードが無効な場合、以下のエラーが出ます。

開発者モードをONにする手順

Windowsスタートメニューで、developer mode と入力すると「デバイスの検出を有効にする」
というメニューが出てくるので、これを選択します。

開発者モードを オンにします。


GPU Plugin Initialization Error

GPUパフォーマンスカウンターのアクセスを許可していない場合、以下のエラーが出ることがあります。


GPUパフォーマンスカウンターのアクセスを許可する手順

スタートメニューに「nvidia control panel」と入力し、 NVIDIA Control Panel を選択します。

「GPUパフォーマンス カウンターへのアクセスをすべてのユーザーに許可する」を選んでおきます。

03. 描画の重いところを調査してみる

Camera.Render

Camera.render に 682304ns かかっています。 (0.682 ms)

Camera.renderの中を見てみます。 Drawingが最も重く、0.5ms程かかっています。

処理負荷の比較

全体(Camera.Render)の中で行われている処理が、どれくらいの割合を占めているのかをまとめてみました。
影の描画が特に重いことが分かります。

ドローコール 処理時間[ms] 割合[%]
D3D11 Event: Camera.Render 0.682 100
D3D11 Event: UpdateDepthTexture 0.02 3.06
D3D11 Event: Shadows.RenderShadowMap 0.122 17.89
D3D11 Event: RenderForwardOpaque.CollectShadows 0.258 37.88
D3D11 Event: RenderForward.RenderLoopJob 0.03 4.75
D3D11 Event: Camera.RenderSkybox 0.09 13.81
D3D11 Event: Camera.ImageEffects 0.15 22.31

補足
RenderShadowMap は、シーンに存在する3Dオブジェクトをシャドウマップに描画するドローコールで、
CollectShadows はシャドウマップを参照して、影をスクリーン上に描画するドローコールです。

04. 影の描画負荷を調査する

Unityのプロファイラーを利用して、影の描画が重い原因を探っていきたいと思います。

FrameDebugger を確認する

FrameDebuggerで CollectShadows を見てみましょう。

Hidden/Internal-ScreenSpaceShadowsSubShader #2 (3番目のSubShader)が実行されています。
シェーダーキーワードは SHADOWS_SPLIT_SPHERES です。

実行シェーダーを確認してみる

Unity公式から Unity2021.3.9f1 の Built-in Shader をダウンロードし、
Internal-ScreenSpaceShadows.shaderを確認します。

https://unity3d.com/get-unity/download/archive


実行されているシェーダーPassは以下になります。(ソフトシャドウの描画を行います)

Internal-ScreenSpaceShadows.shader
Subshader {
    Tags {"ShadowmapFilter" = "PCF_SOFT"}
    Pass {
        ZWrite Off ZTest Always Cull Off

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag_pcfSoft
        #pragma multi_compile_shadowcollector
        #pragma target 3.0

        inline float3 computeCameraSpacePosFromDepth(v2f i)
        {
            return computeCameraSpacePosFromDepthAndVSInfo(i);
        }
        ENDCG
    }
}

シェーダーアセンブリを確認する

シェーダーがどれくらい重いのかを確認するため、シェーダーアセンブリを確認してみます。
アセンブリの行数が多いほど、GPU上で多くの処理が実行されます。

Compile and show code ボタンをクリックすることで、シェーダーコンパイルできます。

ピクセルシェーダー(ps_4_0)のアセンブリ行数は144行となりました。

シェーダーコンパイル結果 (D3D)
//////////////////////////////////////////////////////
Keywords: SHADOWS_SPLIT_SPHERES
-- Hardware tier variant: Tier 1
-- Vertex shader for "d3d11":
// Stats: 19 math, 2 temp registers
Uses vertex data channel "Vertex"
Uses vertex data channel "TexCoord0"
Uses vertex data channel "TexCoord1"

Constant Buffer "UnityPerCamera" (144 bytes) on slot 0 {
  Vector4 _ProjectionParams at 80
}
Constant Buffer "UnityPerCameraRare" (352 bytes) on slot 1 {
  Matrix4x4 unity_CameraInvProjection at 160
}
Constant Buffer "UnityPerDraw" (176 bytes) on slot 2 {
  Matrix4x4 unity_ObjectToWorld at 0
}
Constant Buffer "UnityPerFrame" (368 bytes) on slot 3 {
  Matrix4x4 unity_MatrixVP at 272
}

Shader Disassembly:
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// POSITION                 0   xyzw        0     NONE   float   xyz 
// TEXCOORD                 0   xy          1     NONE   float   xy  
// TEXCOORD                 1   xyz         2     NONE   float   xyz 
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION              0   xyzw        0      POS   float   xyzw
// TEXCOORD                 0   xyzw        1     NONE   float   xyzw
// TEXCOORD                 1   xyz         2     NONE   float   xyz 
// TEXCOORD                 2   xyz         3     NONE   float   xyz 
// TEXCOORD                 3   xyz         4     NONE   float   xyz 
//
      vs_4_0
      dcl_constantbuffer CB0[6], immediateIndexed
      dcl_constantbuffer CB1[14], immediateIndexed
      dcl_constantbuffer CB2[4], immediateIndexed
      dcl_constantbuffer CB3[21], immediateIndexed
      dcl_input v0.xyz
      dcl_input v1.xy
      dcl_input v2.xyz
      dcl_output_siv o0.xyzw, position
      dcl_output o1.xyzw
      dcl_output o2.xyz
      dcl_output o3.xyz
      dcl_output o4.xyz
      dcl_temps 2
   0: mul r0.xyzw, v0.yyyy, cb2[1].xyzw
   1: mad r0.xyzw, cb2[0].xyzw, v0.xxxx, r0.xyzw
   2: mad r0.xyzw, cb2[2].xyzw, v0.zzzz, r0.xyzw
   3: add r0.xyzw, r0.xyzw, cb2[3].xyzw
   4: mul r1.xyzw, r0.yyyy, cb3[18].xyzw
   5: mad r1.xyzw, cb3[17].xyzw, r0.xxxx, r1.xyzw
   6: mad r1.xyzw, cb3[19].xyzw, r0.zzzz, r1.xyzw
   7: mad r0.xyzw, cb3[20].xyzw, r0.wwww, r1.xyzw
   8: mov o0.xyzw, r0.xyzw
   9: mul r0.y, r0.y, cb0[5].x
  10: mul r1.xzw, r0.xxwy, l(0.500000, 0.000000, 0.500000, 0.500000)
  11: mul r0.yzw, r0.yyyy, cb1[11].xxyz
  12: mad r0.xyz, cb1[10].xyzx, r0.xxxx, r0.yzwy
  13: add o1.zw, r1.zzzz, r1.xxxw
  14: mov o1.xy, v1.xyxx
  15: mov o2.xyz, v2.xyzx
  16: add r1.xyz, r0.xyzx, -cb1[12].xyzx
  17: add r0.xyz, r0.xyzx, cb1[12].xyzx
  18: add r0.xyz, r0.xyzx, cb1[13].xyzx
  19: add r1.xyz, r1.xyzx, cb1[13].xyzx
  20: mov r1.w, -r1.z
  21: mov o3.xyz, r1.xywx
  22: mov r0.w, -r0.z
  23: mov o4.xyz, r0.xywx
  24: ret 
// Approximately 0 instruction slots used


-- Hardware tier variant: Tier 1
-- Fragment shader for "d3d11":
// Stats: 113 math, 9 temp registers, 1 textures
Set 2D Texture "_CameraDepthTexture" to slot 0 sampler slot 1
Set 2D Texture "_ShadowMapTexture" to slot 1 sampler slot 0

Constant Buffer "$Globals" (64 bytes) on slot 0 {
  Vector4 _ShadowMapTexture_TexelSize at 0
}
Constant Buffer "UnityPerCamera" (144 bytes) on slot 1 {
  Vector4 _ZBufferParams at 112
  Vector4 unity_OrthoParams at 128
}
Constant Buffer "UnityPerCameraRare" (352 bytes) on slot 2 {
  Matrix4x4 unity_CameraToWorld at 288
}
Constant Buffer "UnityShadows" (416 bytes) on slot 3 {
  Matrix4x4 unity_WorldToShadow[4] at 128
  Vector4 unity_ShadowSplitSpheres[4] at 0
  Vector4 unity_ShadowSplitSqRadii at 64
  Vector4 _LightShadowData at 384
}

Shader Disassembly:
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION              0   xyzw        0      POS   float       
// TEXCOORD                 0   xyzw        1     NONE   float   xy  
// TEXCOORD                 1   xyz         2     NONE   float   xyz 
// TEXCOORD                 2   xyz         3     NONE   float   xyz 
// TEXCOORD                 3   xyz         4     NONE   float   xyz 
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_Target                0   xyzw        0   TARGET   float   xyzw
//
      ps_4_0
      dcl_constantbuffer CB0[1], immediateIndexed
      dcl_constantbuffer CB1[9], immediateIndexed
      dcl_constantbuffer CB2[22], immediateIndexed
      dcl_constantbuffer CB3[25], immediateIndexed
      dcl_sampler s0, mode_comparison
      dcl_sampler s1, mode_default
      dcl_resource_texture2d (float,float,float,float) t0
      dcl_resource_texture2d (float,float,float,float) t1
      dcl_input_ps linear v1.xy
      dcl_input_ps linear v2.xyz
      dcl_input_ps linear v3.xyz
      dcl_input_ps linear v4.xyz
      dcl_output o0.xyzw
      dcl_temps 9
   0: sample r0.xyzw, v1.xyxx, t0.xyzw, s1
   1: mad r0.y, cb1[7].x, r0.x, cb1[7].y
   2: div r0.y, l(1.000000, 1.000000, 1.000000, 1.000000), r0.y
   3: add r0.z, -r0.y, r0.x
   4: mad r0.y, cb1[8].w, r0.z, r0.y
   5: add r0.x, -r0.x, l(1.000000)
   6: add r1.xyz, -v3.xyzx, v4.xyzx
   7: mad r0.xzw, r0.xxxx, r1.xxyz, v3.xxyz
   8: mad r0.xzw, -v2.xxyz, r0.yyyy, r0.xxzw
   9: mul r1.xyz, r0.yyyy, v2.xyzx
  10: mad r0.xyz, cb1[8].wwww, r0.xzwx, r1.xyzx
  11: mul r1.xyzw, r0.yyyy, cb2[19].xyzw
  12: mad r1.xyzw, cb2[18].xyzw, r0.xxxx, r1.xyzw
  13: mad r0.xyzw, cb2[20].xyzw, r0.zzzz, r1.xyzw
  14: add r0.xyzw, r0.xyzw, cb2[21].xyzw
  15: add r1.xyz, r0.xyzx, -cb3[0].xyzx
  16: dp3 r1.x, r1.xyzx, r1.xyzx
  17: add r2.xyz, r0.xyzx, -cb3[1].xyzx
  18: dp3 r1.y, r2.xyzx, r2.xyzx
  19: add r2.xyz, r0.xyzx, -cb3[2].xyzx
  20: dp3 r1.z, r2.xyzx, r2.xyzx
  21: add r2.xyz, r0.xyzx, -cb3[3].xyzx
  22: dp3 r1.w, r2.xyzx, r2.xyzx
  23: lt r1.xyzw, r1.xyzw, cb3[4].xyzw
  24: movc r2.xyz, r1.xyzx, l(-1.000000,-1.000000,-1.000000,0), l(-0.000000,-0.000000,-0.000000,0)
  25: and r1.xyzw, r1.xyzw, l(0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000)
  26: add r2.xyz, r2.xyzx, r1.yzwy
  27: max r1.yzw, r2.xxyz, l(0.000000, 0.000000, 0.000000, 0.000000)
  28: mul r2.xyz, r0.yyyy, cb3[13].xyzx
  29: mad r2.xyz, cb3[12].xyzx, r0.xxxx, r2.xyzx
  30: mad r2.xyz, cb3[14].xyzx, r0.zzzz, r2.xyzx
  31: mad r2.xyz, cb3[15].xyzx, r0.wwww, r2.xyzx
  32: mul r2.xyz, r1.yyyy, r2.xyzx
  33: mul r3.xyz, r0.yyyy, cb3[9].xyzx
  34: mad r3.xyz, cb3[8].xyzx, r0.xxxx, r3.xyzx
  35: mad r3.xyz, cb3[10].xyzx, r0.zzzz, r3.xyzx
  36: mad r3.xyz, cb3[11].xyzx, r0.wwww, r3.xyzx
  37: mad r2.xyz, r3.xyzx, r1.xxxx, r2.xyzx
  38: dp4 r1.x, r1.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
  39: mul r3.xyz, r0.yyyy, cb3[17].xyzx
  40: mad r3.xyz, cb3[16].xyzx, r0.xxxx, r3.xyzx
  41: mad r3.xyz, cb3[18].xyzx, r0.zzzz, r3.xyzx
  42: mad r3.xyz, cb3[19].xyzx, r0.wwww, r3.xyzx
  43: mad r2.xyz, r3.xyzx, r1.zzzz, r2.xyzx
  44: mul r3.xyz, r0.yyyy, cb3[21].xyzx
  45: mad r3.xyz, cb3[20].xyzx, r0.xxxx, r3.xyzx
  46: mad r0.xyz, cb3[22].xyzx, r0.zzzz, r3.xyzx
  47: mad r0.xyz, cb3[23].xyzx, r0.wwww, r0.xyzx
  48: mad r0.xyz, r0.xyzx, r1.wwww, r2.xyzx
  49: mad r1.yz, r0.xxyx, cb0[0].zzwz, l(0.000000, 0.500000, 0.500000, 0.000000)
  50: round_ni r1.yz, r1.yyzy
  51: mad r0.xy, r0.xyxx, cb0[0].zwzz, -r1.yzyy
  52: add r0.z, -r1.x, r0.z
  53: add r0.z, r0.z, l(1.000000)
  54: add r1.xw, -r0.xxxy, l(1.000000, 0.000000, 0.000000, 1.000000)
  55: min r2.xy, r0.xyxx, l(0.000000, 0.000000, 0.000000, 0.000000)
  56: mad r1.xw, -r2.xxxy, r2.xxxy, r1.xxxw
  57: add r1.xw, r1.xxxw, l(2.000000, 0.000000, 0.000000, 2.000000)
  58: mul r2.xy, r1.xwxx, l(0.081632, 0.081632, 0.000000, 0.000000)
  59: mov r3.y, r2.x
  60: max r1.xw, r0.xxxy, l(0.000000, 0.000000, 0.000000, 0.000000)
  61: add r4.xyzw, r0.xxyy, l(0.500000, 1.000000, 0.500000, 1.000000)
  62: mad r1.xw, -r1.xxxw, r1.xxxw, r4.yyyw
  63: mul r4.xyzw, r4.xxzz, r4.xxzz
  64: add r1.xw, r1.xxxw, l(2.000000, 0.000000, 0.000000, 2.000000)
  65: mul r5.z, r1.x, l(0.081632)
  66: mul r6.z, r1.w, l(0.081632)
  67: mad r5.yw, r0.xxxx, l(0.000000, -0.081632, 0.000000, 0.081632), l(0.000000, 0.163264, 0.000000, 0.081632)
  68: mad r1.xw, r4.xxxz, l(0.500000, 0.000000, 0.000000, 0.500000), -r0.xxxy
  69: mul r4.xy, r4.ywyy, l(0.040816, 0.040816, 0.000000, 0.000000)
  70: mul r6.xy, r1.wxww, l(0.081632, 0.081632, 0.000000, 0.000000)
  71: mov r5.x, r6.y
  72: mad r3.xz, r0.xxxx, l(-0.081632, 0.000000, 0.081632, 0.000000), l(0.081632, 0.000000, 0.163264, 0.000000)
  73: mov r3.w, r4.x
  74: mov r2.w, r4.y
  75: add r4.xyzw, r3.xyzw, r5.xyzw
  76: div r3.xyzw, r3.xyzw, r4.xyzw
  77: add r3.xyzw, r3.xyzw, l(-3.500000, -1.500000, 0.500000, 2.500000)
  78: mul r3.xyzw, r3.wxyz, cb0[0].xxxx
  79: mad r6.yw, r0.yyyy, l(0.000000, -0.081632, 0.000000, 0.081632), l(0.000000, 0.163264, 0.000000, 0.081632)
  80: mad r2.xz, r0.yyyy, l(-0.081632, 0.000000, 0.081632, 0.000000), l(0.081632, 0.000000, 0.163264, 0.000000)
  81: add r5.xyzw, r2.xyzw, r6.xyzw
  82: div r2.xyzw, r2.xyzw, r5.xyzw
  83: add r2.xyzw, r2.xyzw, l(-3.500000, -1.500000, 0.500000, 2.500000)
  84: mul r2.xyzw, r2.xwyz, cb0[0].yyyy
  85: mul r6.xyzw, r4.xyzw, r5.xxxx
  86: mov r7.xzw, r3.yyzw
  87: mov r7.y, r2.x
  88: mad r8.xyzw, r1.yzyz, cb0[0].xyxy, r7.xyzy
  89: sample_c_lz r0.x, r8.xyxx, t1.xxxx, s0, r0.z
  90: sample_c_lz r0.y, r8.zwzz, t1.xxxx, s0, r0.z
  91: mul r0.y, r0.y, r6.y
  92: mad r0.x, r6.x, r0.x, r0.y
  93: mad r0.yw, r1.yyyz, cb0[0].xxxy, r7.wwwy
  94: mov r3.y, r7.y
  95: mad r1.xw, r1.yyyz, cb0[0].xxxy, r3.xxxy
  96: sample_c_lz r1.x, r1.xwxx, t1.xxxx, s0, r0.z
  97: sample_c_lz r0.y, r0.ywyy, t1.xxxx, s0, r0.z
  98: mad r0.x, r6.z, r0.y, r0.x
  99: mad r0.x, r6.w, r1.x, r0.x
 100: mul r6.xyzw, r4.xyzw, r5.yyyy
 101: mov r7.y, r2.z
 102: mad r8.xyzw, r1.yzyz, cb0[0].xyxy, r7.xyzy
 103: sample_c_lz r0.y, r8.xyxx, t1.xxxx, s0, r0.z
 104: sample_c_lz r0.w, r8.zwzz, t1.xxxx, s0, r0.z
 105: mad r0.x, r6.x, r0.y, r0.x
 106: mad r0.x, r6.y, r0.w, r0.x
 107: mad r0.yw, r1.yyyz, cb0[0].xxxy, r7.wwwy
 108: mov r3.z, r7.y
 109: mad r1.xw, r1.yyyz, cb0[0].xxxy, r3.xxxz
 110: sample_c_lz r1.x, r1.xwxx, t1.xxxx, s0, r0.z
 111: sample_c_lz r0.y, r0.ywyy, t1.xxxx, s0, r0.z
 112: mad r0.x, r6.z, r0.y, r0.x
 113: mad r0.x, r6.w, r1.x, r0.x
 114: mul r6.xyzw, r4.xyzw, r5.zzzz
 115: mul r4.xyzw, r4.xyzw, r5.wwww
 116: mov r7.y, r2.w
 117: mad r5.xyzw, r1.yzyz, cb0[0].xyxy, r7.xyzy
 118: sample_c_lz r0.y, r5.xyxx, t1.xxxx, s0, r0.z
 119: sample_c_lz r0.w, r5.zwzz, t1.xxxx, s0, r0.z
 120: mad r0.x, r6.x, r0.y, r0.x
 121: mad r0.x, r6.y, r0.w, r0.x
 122: mad r0.yw, r1.yyyz, cb0[0].xxxy, r7.wwwy
 123: mov r2.xzw, r7.xxzw
 124: mov r3.w, r7.y
 125: mad r1.xw, r1.yyyz, cb0[0].xxxy, r3.xxxw
 126: sample_c_lz r1.x, r1.xwxx, t1.xxxx, s0, r0.z
 127: sample_c_lz r0.y, r0.ywyy, t1.xxxx, s0, r0.z
 128: mad r0.x, r6.z, r0.y, r0.x
 129: mad r0.x, r6.w, r1.x, r0.x
 130: mad r5.xyzw, r1.yzyz, cb0[0].xyxy, r2.xyzy
 131: mad r0.yw, r1.yyyz, cb0[0].xxxy, r2.wwwy
 132: mov r3.y, r2.y
 133: mad r1.xy, r1.yzyy, cb0[0].xyxx, r3.xyxx
 134: sample_c_lz r1.x, r1.xyxx, t1.xxxx, s0, r0.z
 135: sample_c_lz r0.y, r0.ywyy, t1.xxxx, s0, r0.z
 136: sample_c_lz r0.w, r5.xyxx, t1.xxxx, s0, r0.z
 137: sample_c_lz r0.z, r5.zwzz, t1.xxxx, s0, r0.z
 138: mad r0.x, r4.x, r0.w, r0.x
 139: mad r0.x, r4.y, r0.z, r0.x
 140: mad r0.x, r4.z, r0.y, r0.x
 141: mad r0.x, r4.w, r1.x, r0.x
 142: add r0.y, -cb3[24].x, l(1.000000)
 143: mad o0.xyzw, r0.xxxx, r0.yyyy, cb3[24].xxxx
 144: ret 
// Approximately 0 instruction slots used

05. ハードシャドウの描画負荷を計測する

ハードシャドウは、ソフトシャドウより軽量に動作するそうです。
負荷にどの程度の違いがあるのか気になるので、PIXで描画負荷を計測してみようと思います。

https://light11.hatenadiary.com/entry/2019/08/30/223811

PIXで処理負荷を計測する

PIXを使って処理負荷を計測し、ソフトシャドウとハードシャドウの処理負荷を比較してみます。

Camera.Render

Drawingの処理時間が20%ほど減少しています。(約0.1ms 減少)

CollectShadows に関しては、処理時間が 約50% になっています。(約0.12ms 減少)

シェーダーを見てみる

FrameDebuggerにて、CollectShadowsドローコールを見てみます。
Hidden/Internal-ScreenSpaceShadowsSubShader #0 (最初のSubShader) が実行されていました。

実行されているシェーダーPassは以下になります。(ハードシャドウの描画を行います)

Internal-ScreenSpaceShadows.shader
// ----------------------------------------------------------------------------------------
// Subshader for hard shadows:
// Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked.

SubShader {
    Tags{ "ShadowmapFilter" = "HardShadow" }
    Pass {
        ZWrite Off ZTest Always Cull Off

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag_hard
        #pragma multi_compile_shadowcollector

        inline float3 computeCameraSpacePosFromDepth(v2f i)
        {
            return computeCameraSpacePosFromDepthAndVSInfo(i);
        }
        ENDCG
    }
}

こちらをシェーダーコンパイルすると、
ピクセルシェーダー(ps_4_0) のアセンブリ行数は54行になります。

ソフトシャドウの場合、アセンブリ行数は144行だったので処理負荷が大幅に軽くなっていると推測できます。

D3Dコンパイル結果
//////////////////////////////////////////////////////
Keywords: SHADOWS_SPLIT_SPHERES
-- Hardware tier variant: Tier 1
-- Vertex shader for "d3d11":
// Stats: 19 math, 2 temp registers
Uses vertex data channel "Vertex"
Uses vertex data channel "TexCoord0"
Uses vertex data channel "TexCoord1"

Constant Buffer "UnityPerCamera" (144 bytes) on slot 0 {
  Vector4 _ProjectionParams at 80
}
Constant Buffer "UnityPerCameraRare" (352 bytes) on slot 1 {
  Matrix4x4 unity_CameraInvProjection at 160
}
Constant Buffer "UnityPerDraw" (176 bytes) on slot 2 {
  Matrix4x4 unity_ObjectToWorld at 0
}
Constant Buffer "UnityPerFrame" (368 bytes) on slot 3 {
  Matrix4x4 unity_MatrixVP at 272
}

Shader Disassembly:
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// POSITION                 0   xyzw        0     NONE   float   xyz 
// TEXCOORD                 0   xy          1     NONE   float   xy  
// TEXCOORD                 1   xyz         2     NONE   float   xyz 
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION              0   xyzw        0      POS   float   xyzw
// TEXCOORD                 0   xyzw        1     NONE   float   xyzw
// TEXCOORD                 1   xyz         2     NONE   float   xyz 
// TEXCOORD                 2   xyz         3     NONE   float   xyz 
// TEXCOORD                 3   xyz         4     NONE   float   xyz 
//
      vs_4_0
      dcl_constantbuffer CB0[6], immediateIndexed
      dcl_constantbuffer CB1[14], immediateIndexed
      dcl_constantbuffer CB2[4], immediateIndexed
      dcl_constantbuffer CB3[21], immediateIndexed
      dcl_input v0.xyz
      dcl_input v1.xy
      dcl_input v2.xyz
      dcl_output_siv o0.xyzw, position
      dcl_output o1.xyzw
      dcl_output o2.xyz
      dcl_output o3.xyz
      dcl_output o4.xyz
      dcl_temps 2
   0: mul r0.xyzw, v0.yyyy, cb2[1].xyzw
   1: mad r0.xyzw, cb2[0].xyzw, v0.xxxx, r0.xyzw
   2: mad r0.xyzw, cb2[2].xyzw, v0.zzzz, r0.xyzw
   3: add r0.xyzw, r0.xyzw, cb2[3].xyzw
   4: mul r1.xyzw, r0.yyyy, cb3[18].xyzw
   5: mad r1.xyzw, cb3[17].xyzw, r0.xxxx, r1.xyzw
   6: mad r1.xyzw, cb3[19].xyzw, r0.zzzz, r1.xyzw
   7: mad r0.xyzw, cb3[20].xyzw, r0.wwww, r1.xyzw
   8: mov o0.xyzw, r0.xyzw
   9: mul r0.y, r0.y, cb0[5].x
  10: mul r1.xzw, r0.xxwy, l(0.500000, 0.000000, 0.500000, 0.500000)
  11: mul r0.yzw, r0.yyyy, cb1[11].xxyz
  12: mad r0.xyz, cb1[10].xyzx, r0.xxxx, r0.yzwy
  13: add o1.zw, r1.zzzz, r1.xxxw
  14: mov o1.xy, v1.xyxx
  15: mov o2.xyz, v2.xyzx
  16: add r1.xyz, r0.xyzx, -cb1[12].xyzx
  17: add r0.xyz, r0.xyzx, cb1[12].xyzx
  18: add r0.xyz, r0.xyzx, cb1[13].xyzx
  19: add r1.xyz, r1.xyzx, cb1[13].xyzx
  20: mov r1.w, -r1.z
  21: mov o3.xyz, r1.xywx
  22: mov r0.w, -r0.z
  23: mov o4.xyz, r0.xywx
  24: ret 
// Approximately 0 instruction slots used


-- Hardware tier variant: Tier 1
-- Fragment shader for "d3d11":
// Stats: 51 math, 4 temp registers, 1 textures
Set 2D Texture "_CameraDepthTexture" to slot 0 sampler slot 1
Set 2D Texture "_ShadowMapTexture" to slot 1 sampler slot 0

Constant Buffer "UnityPerCamera" (144 bytes) on slot 0 {
  Vector4 _ZBufferParams at 112
  Vector4 unity_OrthoParams at 128
}
Constant Buffer "UnityPerCameraRare" (352 bytes) on slot 1 {
  Matrix4x4 unity_CameraToWorld at 288
}
Constant Buffer "UnityShadows" (416 bytes) on slot 2 {
  Matrix4x4 unity_WorldToShadow[4] at 128
  Vector4 unity_ShadowSplitSpheres[4] at 0
  Vector4 unity_ShadowSplitSqRadii at 64
  Vector4 _LightShadowData at 384
}

Shader Disassembly:
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_POSITION              0   xyzw        0      POS   float       
// TEXCOORD                 0   xyzw        1     NONE   float   xy  
// TEXCOORD                 1   xyz         2     NONE   float   xyz 
// TEXCOORD                 2   xyz         3     NONE   float   xyz 
// TEXCOORD                 3   xyz         4     NONE   float   xyz 
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_Target                0   xyzw        0   TARGET   float   xyzw
//
      ps_4_0
      dcl_constantbuffer CB0[9], immediateIndexed
      dcl_constantbuffer CB1[22], immediateIndexed
      dcl_constantbuffer CB2[25], immediateIndexed
      dcl_sampler s0, mode_comparison
      dcl_sampler s1, mode_default
      dcl_resource_texture2d (float,float,float,float) t0
      dcl_resource_texture2d (float,float,float,float) t1
      dcl_input_ps linear v1.xy
      dcl_input_ps linear v2.xyz
      dcl_input_ps linear v3.xyz
      dcl_input_ps linear v4.xyz
      dcl_output o0.xyzw
      dcl_temps 4
   0: sample r0.xyzw, v1.xyxx, t0.xyzw, s1
   1: mad r0.y, cb0[7].x, r0.x, cb0[7].y
   2: div r0.y, l(1.000000, 1.000000, 1.000000, 1.000000), r0.y
   3: add r0.z, -r0.y, r0.x
   4: mad r0.y, cb0[8].w, r0.z, r0.y
   5: add r0.x, -r0.x, l(1.000000)
   6: add r1.xyz, -v3.xyzx, v4.xyzx
   7: mad r0.xzw, r0.xxxx, r1.xxyz, v3.xxyz
   8: mad r0.xzw, -v2.xxyz, r0.yyyy, r0.xxzw
   9: mul r1.xyz, r0.yyyy, v2.xyzx
  10: mad r0.xyz, cb0[8].wwww, r0.xzwx, r1.xyzx
  11: mul r1.xyzw, r0.yyyy, cb1[19].xyzw
  12: mad r1.xyzw, cb1[18].xyzw, r0.xxxx, r1.xyzw
  13: mad r0.xyzw, cb1[20].xyzw, r0.zzzz, r1.xyzw
  14: add r0.xyzw, r0.xyzw, cb1[21].xyzw
  15: add r1.xyz, r0.xyzx, -cb2[0].xyzx
  16: dp3 r1.x, r1.xyzx, r1.xyzx
  17: add r2.xyz, r0.xyzx, -cb2[1].xyzx
  18: dp3 r1.y, r2.xyzx, r2.xyzx
  19: add r2.xyz, r0.xyzx, -cb2[2].xyzx
  20: dp3 r1.z, r2.xyzx, r2.xyzx
  21: add r2.xyz, r0.xyzx, -cb2[3].xyzx
  22: dp3 r1.w, r2.xyzx, r2.xyzx
  23: lt r1.xyzw, r1.xyzw, cb2[4].xyzw
  24: movc r2.xyz, r1.xyzx, l(-1.000000,-1.000000,-1.000000,0), l(-0.000000,-0.000000,-0.000000,0)
  25: and r1.xyzw, r1.xyzw, l(0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000)
  26: add r2.xyz, r2.xyzx, r1.yzwy
  27: max r1.yzw, r2.xxyz, l(0.000000, 0.000000, 0.000000, 0.000000)
  28: mul r2.xyz, r0.yyyy, cb2[13].xyzx
  29: mad r2.xyz, cb2[12].xyzx, r0.xxxx, r2.xyzx
  30: mad r2.xyz, cb2[14].xyzx, r0.zzzz, r2.xyzx
  31: mad r2.xyz, cb2[15].xyzx, r0.wwww, r2.xyzx
  32: mul r2.xyz, r1.yyyy, r2.xyzx
  33: mul r3.xyz, r0.yyyy, cb2[9].xyzx
  34: mad r3.xyz, cb2[8].xyzx, r0.xxxx, r3.xyzx
  35: mad r3.xyz, cb2[10].xyzx, r0.zzzz, r3.xyzx
  36: mad r3.xyz, cb2[11].xyzx, r0.wwww, r3.xyzx
  37: mad r2.xyz, r3.xyzx, r1.xxxx, r2.xyzx
  38: dp4 r1.x, r1.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
  39: mul r3.xyz, r0.yyyy, cb2[17].xyzx
  40: mad r3.xyz, cb2[16].xyzx, r0.xxxx, r3.xyzx
  41: mad r3.xyz, cb2[18].xyzx, r0.zzzz, r3.xyzx
  42: mad r3.xyz, cb2[19].xyzx, r0.wwww, r3.xyzx
  43: mad r2.xyz, r3.xyzx, r1.zzzz, r2.xyzx
  44: mul r3.xyz, r0.yyyy, cb2[21].xyzx
  45: mad r3.xyz, cb2[20].xyzx, r0.xxxx, r3.xyzx
  46: mad r0.xyz, cb2[22].xyzx, r0.zzzz, r3.xyzx
  47: mad r0.xyz, cb2[23].xyzx, r0.wwww, r0.xyzx
  48: mad r0.xyz, r0.xyzx, r1.wwww, r2.xyzx
  49: add r0.z, -r1.x, r0.z
  50: add r0.z, r0.z, l(1.000000)
  51: sample_c_lz r0.x, r0.xyxx, t1.xxxx, s0, r0.z
  52: add r0.y, -cb2[24].x, l(1.000000)
  53: mad o0.xyzw, r0.xxxx, r0.yyyy, cb2[24].xxxx
  54: ret 
// Approximately 0 instruction slots used

Discussion

ログインするとコメントできます