「ドローコール」の版間の差分

提供:MonoBook
 
(同じ利用者による、間の9版が非表示)
1行目: 1行目:
'''ドローコール'''(英語:draw call)とは、[[CPU]]から[[GPU]]に描画依頼を行うことをいう。
'''ドローコール'''(英語:draw call)とは、[[CPU]]から[[GPU]]に「描画依頼」を行うことをいう。最近は[[GPGPU]]などの登場で「描画を伴わないドローコール」も増えており、どちらかというと「実行依頼」といった方がいい感じになりつつある。
 
最近は[[GPGPU]]などの登場で「描画を伴わないドローコール」も増えており、どちらかというと「実行依頼」といった方がいい感じになりつつある。


== 概要 ==
== 概要 ==
ドローコールはとても重たい処理である。[[シェーダー]]で実行したい[[プログラム]]を設定して、シェーダーに渡すモデルや[[テクスチャマップ]]や変数などを設定して、ドローコールをする。
ドローコールはとても重たい処理である。[[シェーダー]]で実行したい[[プログラム]]を設定して、シェーダーに渡すモデルや[[テクスチャマップ]]や変数などを設定して、ドローコールをする。下手をすると[[GPU]]で実行する「主たる処理」そのものよりも「呼び出し」の方が重いこともあるくらい重たい。


下手をすると[[GPU]]での「主たる処理」そのものよりも「呼び出し」の方が重いこともあるくらい重たい。
== ドローコールを減らす手法 ==
1フレームの描画に必要な「ドローコールの数」は、[[フォワードレンダリング]]ではシーン中にある「モデル」と「ライト」の数の掛け算となる。つまりシーン内のオブジェクト数が増えるに従ってどんどん重くなる。


== ドローコールを減らす手法 ==
ドローコールはとても重たい処理である。その数を減らすことができればパフォーマンスが劇的に向上させることができる。涙ぐましい手法が色々と考案されている。
1フレームの描画に必要な「ドローコールの数」は、[[フォワードレンダリング]]ではシーン中にある「モデル」と「ライト」の数の掛け算となる。ドローコールはとても重たい処理である。その数を減らすことができればパフォーマンスが劇的に向上する。


=== インスタンシング ===
=== インスタンシング ===
19行目: 17行目:


=== メッシュベイカー ===
=== メッシュベイカー ===
[[メッシュベイカー]]は背景などに使用される複数のモデルを、事前に「1つのモデル」に結合してしまう手法である。建築物のように動かないモデルだと簡単に実装できる。
[[メッシュベイカー]]は背景などに使用される複数のモデルを、事前に「1つのモデル」に結合してしまう手法である。建築物のように動かないモデルだと比較的簡単に実装できる。


モデルを一通り読み込んだ後に結合すると利便性がよい。
モデルを一通り読み込んだ後に結合すると利便性がよい。
37行目: 35行目:


== その他 ==
== その他 ==
少しでも高速化すべくドローコールを[[キュー]]に積んで実際のドローコールは別[[スレッド]]で行うという「[[GPU]]を休ませない」という手法もある。
少しでも高速化すべくドローコールを[[キュー]]に積んで実際のドローコールは別[[スレッド]]で行うという「[[GPU]]を休ませない」という手法もある。これが当たり前となっている[[フレームワーク]]もあり、それを知らずに「ドローコールしたのに結果が返ってこない」とハマるケースもあるので注意しよう。
 
== 仮想メモリ ==
最近ではVRAMが枯渇した際にメインメモリを仮想メモリ的に利用できるようなデバイスドライバも登場しているが、この際には「VRAMが枯渇してないか」「VRAMの一部をメインメモリに退避しろ」などと状態変化ごとに複数のドローコールが飛び交うことになる。このためVRAMとメインメモリの物理的な速度差以上に大きな速度低下を引き起こすことになる。


これが当たり前となっている[[フレームワーク]]もあり、それを知らずに「ドローコールしたのに結果が返ってこない」とハマるケースもあるので注意しよう。
なお、Intel ARCではVRAM全体を「メインメモリの一部」として扱う手法を採用している。
これにより仮想メモリなどという軟弱な概念がないというか最初から最後まで仮想メモリという方式だ。

2024年7月24日 (水) 07:10時点における最新版

ドローコール(英語:draw call)とは、CPUからGPUに「描画依頼」を行うことをいう。最近はGPGPUなどの登場で「描画を伴わないドローコール」も増えており、どちらかというと「実行依頼」といった方がいい感じになりつつある。

概要[編集 | ソースを編集]

ドローコールはとても重たい処理である。シェーダーで実行したいプログラムを設定して、シェーダーに渡すモデルやテクスチャマップや変数などを設定して、ドローコールをする。下手をするとGPUで実行する「主たる処理」そのものよりも「呼び出し」の方が重いこともあるくらい重たい。

ドローコールを減らす手法[編集 | ソースを編集]

1フレームの描画に必要な「ドローコールの数」は、フォワードレンダリングではシーン中にある「モデル」と「ライト」の数の掛け算となる。つまりシーン内のオブジェクト数が増えるに従ってどんどん重くなる。

ドローコールはとても重たい処理である。その数を減らすことができればパフォーマンスが劇的に向上させることができる。涙ぐましい手法が色々と考案されている。

インスタンシング[編集 | ソースを編集]

複数の同一モデルを1回のドローコールで描画する手法である。モデルは同一だが、「位置」や「向き」や「大きさ」だけが異なるという場合に使用できる。形状が変化しているものには使用できない。

DirectX10以降の世代のGPUでは「GPUインスタンシング」としてハードウェア実装されているので難しいことを考える必要はない。

一方でAndroidなどで主流のOpenGL ES 2.0DirectX9世代相当)では当然ながらGPUインスタンシングは使えない。ソフトウェアで擬似的にインスタンシングを行うことになる。

メッシュベイカー[編集 | ソースを編集]

メッシュベイカーは背景などに使用される複数のモデルを、事前に「1つのモデル」に結合してしまう手法である。建築物のように動かないモデルだと比較的簡単に実装できる。

モデルを一通り読み込んだ後に結合すると利便性がよい。

結合する際にはハードウェア的に「インデックスバッファのサイズは16ビット整数(最大値65535)」と制限されている環境を考慮して65535インデックスの範囲内になるように結合するといい感じである。

遅延レンダリング[編集 | ソースを編集]

遅延レンダリングのように1回(1フレーム)の描画に複数のドローコールを伴う手法もある。

  • Gバッファの初期化
  • 拡散色を計算してGバッファに格納
  • 深度を計算してGバッファに格納
  • 法線を計算してGバッファに格納
  • Gバッファを結合

遅延レンダリングは、一見するとドローコールが増えて見えるが、「ライトが増えても常に一定数のドローコールに収まる」という特徴がある。

その他[編集 | ソースを編集]

少しでも高速化すべくドローコールをキューに積んで実際のドローコールは別スレッドで行うという「GPUを休ませない」という手法もある。これが当たり前となっているフレームワークもあり、それを知らずに「ドローコールしたのに結果が返ってこない」とハマるケースもあるので注意しよう。

 仮想メモリ[編集 | ソースを編集]

最近ではVRAMが枯渇した際にメインメモリを仮想メモリ的に利用できるようなデバイスドライバも登場しているが、この際には「VRAMが枯渇してないか」「VRAMの一部をメインメモリに退避しろ」などと状態変化ごとに複数のドローコールが飛び交うことになる。このためVRAMとメインメモリの物理的な速度差以上に大きな速度低下を引き起こすことになる。

なお、Intel ARCではVRAM全体を「メインメモリの一部」として扱う手法を採用している。 これにより仮想メモリなどという軟弱な概念がないというか最初から最後まで仮想メモリという方式だ。