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

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

新規登録して質問してみよう
ただいま回答率
85.50%
OpenGL

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

C++

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

GLSL

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

DirectX

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

Q&A

解決済

3回答

9567閲覧

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

seri

総合スコア422

OpenGL

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

C++

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

GLSL

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

DirectX

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

0グッド

4クリップ

投稿2017/02/07 21:51

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

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

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

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

投稿2017/02/08 00:14

satoren

総合スコア109

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

seri

2017/02/11 12:47

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

0

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

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

投稿2017/02/08 00:21

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

seri

2017/02/11 12:46

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

0

ベストアンサー

この手の話はいろいろとありますが、とりあえず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の処理負荷がかかってしまいます。
ですから、フラグメントシェーダは極限まで最適化すべきです。

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

glsl

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

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


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

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

投稿2017/02/08 16:39

katsuko

総合スコア3462

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

seri

2017/02/11 12:46

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問