質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • C++

    3759questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenGL

    174questions

    OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

  • DirectX

    72questions

    DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

  • GLSL

    52questions

    GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

3Dレンダリング高速化について。

解決済

回答 3

投稿

  • 評価
  • クリップ 4
  • VIEW 1,939

seri

score 386

最近のPCゲームは本物と同じくらいリアルなものが増えていますが、拡散色や法線から始まり、フレームバッファや遅延シェーディング等の内部処理をしている事には変わりはないですよね
あらかじめ用意されたテクスチャによるオブジェクト表現やライトマップもあるとしても、格納されるバッファの数だけ高速な処理が必要かと思います

OpenGlで似たような処理をしてみようとしてみたのですが、重くなってしまいます。(ゲームのようなキャラクターの動きやゲームイベントではなく、レンダリング周りの話です。)

おそらくバッファの使い方がまだ甘いのだろうな、とは思っています

glBindBuffer()glBindBufferBase()等を使って、法線やアンビエントオクルージョン等はシェーダで行っています

いったいどうすれば早く出来るのでしょうか。。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+5

まずNVIDIA PerfKitのようなプロファイルツールを使用してボトルネックとなっている箇所を特定しましょう。
ツールによっては改善点などを教えてくれる機能もあります。それに従って最適化を進めるといいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/11 21:47

    実際にプロファイルツールを試してみて、改善点が見えてきました、ありがとうございます。

    キャンセル

+3

一般的にゲームにおける高速化に効くポイントをいくつか挙げておきます。

  • 一番効くのはポリゴン数を減らすことです。ポリゴンが増えれば増えるほどピクセルに対する計算の回数は莫大に増えます。なので、ゲームのキャラクターなどは極力低ポリゴンで表現されるようになっています。きれいに見せたいシーンやアップのときだけ高ポリゴンのモデルに入れ替えて使うなどの工夫がされています。
  • 解像度を下げることです。解像度が上がればフラグメントシェーダの仕事の回数が爆発的に増えます。
  • 厳密なライティングをしないで、すでにある程度「陰」を書き込んだテクスチャを重ねて表示したりします。常に明かりが上から照らすシーンなら、体にできる陰はほとんどいつも同じなので、案外気付かないです。
  • カメラに映っていないものの処理を明示的に止めることです。OpenGLのカリングやクリッピング任せにしても、頂点計算の回数は減らないのでプログラム側で描画物そのものを減らすことも重要です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/11 21:46

    解凍ありがとうございます、とてもわかりやすく、理解させていただきました。

    キャンセル

checkベストアンサー

+2

この手の話はいろいろとありますが、とりあえず2点ほど書いておきます。
ちなみに、glBindBufferBaseの名前が出てきているということはOpenGL3.0以降が対象だと思いますが、自分はOpenGL2.0までしか知りません。しかし、おそらく3.0以降で通用する話だと思います。

 ドローコールの削減

CPU/GPU間のデータ転送は、OpenGLの非常に大きなボトルネックになります。
と一言で言っても、気にかけるべき点はたくさんあるのですが、その中でも注意すべきは、
ドローコール(glDrawなんちゃらの呼び出し)です。
これが想像以上に処理負荷がかかります。

例えば、サイコロを100体描画します。
テクスチャは、1から6の面それぞれに用意します。
サイコロ一体に対して、一回ドローコールします。

…と、簡単にプログラムするとこんな感じになりますが、これだと6面☓100体=合計600回のドローコールを行うことになりますが、これだと非常に重い描画になります。
(試していないけど、まぁほぼ間違いなく)

テクスチャとシェーダが同じであればまとめてドローコールできるので、まず100体全ての1の面の頂点をまとめて、1回のドローコールで描画します。

続けて2の面、3の面、…と描画すると、6回のドローコールで処理が完結することになります。

更に、6枚のテクスチャを面ごとに用意していましたが、これをひとつのテクスチャにまとめます。
すると、6回のドローコールが一回で済みます。
(一般的にこの手の手法は「テクスチャアトラス」と呼ばれているようです)

描画する頂点数は変わりませんが、600回のドローコールと1回のドローコールでは雲泥の差になります。
まぁ、実際はこんなにうまく行くはずもありませんが、一般的にはこのようなドローコールの呼び出し回数を軽減する努力をします。

 フラグメントシェーダの軽減化

他の方も少し話を出していますが、フラグメントシェーダの処理も処理軽減化の目安になります。

フラグメントシェーダは、描画するピクセル単位で処理を行うシェーダですので、例えば640x480の矩形領域に描画を行った際には、640☓480=307200回処理を行うことになります。

これだけ多いと、掛け算一つ、条件判定一つ増やしただけでも、GPUの処理負荷がかかってしまいます。
ですから、フラグメントシェーダは極限まで最適化すべきです。

場合によっては、演算や条件判定を増やすぐらいであれば、シェーダを別にしてしまうのも一つの考えです。
例えば、テクスチャと頂点カラーをブレンドして描画するシェーダがあったとします。

uniform sampler2D tex;  // テクスチャ
varying vec2 uv;  // UV
varying vec4 color;  // 頂点カラー
void main()
{
  gl_FragColor = texture2D(tex, uv) * color;
}

でも実際は、ほとんど頂点カラーはvec4(1.0, 1.0, 1.0, 1.0)で、テクスチャの色をそのまま表示するものばかりだった場合は、このシェーダは非常に無駄が多いことになります。
ですので、頂点カラーを使わないシェーダも使って分けて描画すれば、この無駄を削減することができます。


と書きましたが、矛盾点に気が付かれたかもしれません。
最後に「シェーダを増やせばいい」なんて書きましたが、シェーダを増やせばその分だけドローコールも増えることになるので、これらは(単純には)両立しないということです。
状況に応じて処理の軽減化を図る必要があります。
(例えば、CPU負荷がかかっているがGPUの処理には余裕があるならば、シェーダに負荷をかけてでもドローコールを減らす、など)

他にも、ミップマップテクスチャを使ったり、カメラの遠近によって処理を変えたり、いろいろと手段はあります。
市販のPCゲームレベルとなると、一筋縄では行かないと思いますので、いろいろと調べてみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/11 21:46

    解凍ありがとうございます、とてもわかりやすく、理解させていただきました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C++

    3759questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenGL

    174questions

    OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

  • DirectX

    72questions

    DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

  • GLSL

    52questions

    GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。