CPUとGPUはコンピュータグラフィックスのレンダリングにどのように相互作用しますか?
あなたのコンピュータの中央処理装置(CPU)とグラフィックス処理装置(GPU)はあなたがあなたのぱりっとしたそして敏感な視覚的インタフェースを届けるためにあなたがあなたのコンピュータを使用している時はいつでも相互作用します。一緒にどのように機能するかをよりよく理解するために読んでください.
写真提供 ssnelnel.
本日の質疑応答セッションでは、コミュニティ主導のQ&A Webサイトのグループである、Stack Exchangeの1部門であるSuperUserのご好意により、当社にお越しいただきます。.
質問
SuperUserの読者Sathyaが質問を投げかけた。
ここでは、OpenGL APIをベースにした回転三角形を含むTriangle.exeという小さなC ++プログラムのスクリーンショットを見ることができます。.
確かに非常に基本的な例ですが、私はそれが他のグラフィックカード操作に適用可能であると思います.
私は好奇心が強く、三角形がモニタ上で回転するのを見ることができるまで、Windows XPの下でTriangle.exeをダブルクリックすることから全体のプロセスを知りたかったです。何が起こるか、CPU(最初に.exeを処理する)とGPU(最後に画面に三角形を出力する)がどのようにやり取りするのか?
この回転する三角形を表示することに関わるのは、主に次のようなハードウェア/ソフトウェアです。
ハードウェア
- HDD
- システムメモリ(RAM)
- CPU
- ビデオメモリ
- GPU
- 液晶ディスプレイ
ソフトウェア
- オペレーティング・システム
- DirectX / OpenGL API
- Nvidiaドライバー
誰もがプロセスを説明できるでしょうか。?
すべてのステップを網羅するような複雑な説明ではないはずですが(それは範囲を超えています)、中間のIT担当者が従うことができる説明です。.
私は、ITプロフェッショナルとも呼ばれる多くの人々がこのプロセスを正しく説明できなかったと確信しています。.
答え
複数のコミュニティーメンバーが質問に答えましたが、Oliver Salzburgはさらに一歩進んで詳細な回答だけではなく優れた添付グラフィックでも答えました。.
JasonCによる画像、壁紙として入手可能です.
彼は書く:
私はプログラミングの側面とコンポーネント同士のやりとりについて少し書くことにしました。多分それは特定の領域にいくつかの光を当てるでしょう.
プレゼンテーション
あなたがあなたの質問に投稿した、その単一の画像を画面上に描画することさえするために何が必要ですか?
画面に三角形を描く方法はたくさんあります。簡単にするために、頂点バッファが使用されなかったと仮定しましょう。 (A 頂点バッファプログラムが単純にグラフィックス処理パイプラインに行内のすべての単一の頂点(頂点は単なる空間内の座標)について通知したとしましょう。.
しかし, 私たちが何かを描くことができる前に、我々は最初に何らかの足場を実行しなければなりません。見るでしょう なぜ 後:
//スクリーンとデプスバッファをクリアするglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //現在のモデルビュー行列をリセットするglMatrixMode(GL_MODELVIEW); glLoadIdentity(); //三角形を使用した描画glBegin(GL_TRIANGLES); // Red glColor3f(1.0f、0.0f、0.0f); // Top Of Triangle(前面)glVertex3f(0.0f、1.0f、0.0f); //緑色のglColor3f(0.0f、1.0f、0.0f); //三角形の左(正面)glVertex3f(-1.0f、-1.0f、1.0f); // Blue glColor3f(0.0f、0.0f、1.0f); //三角形の右側(正面)glVertex3f(1.0f、-1.0f、1.0f); //描画完了glEnd();
だからそれは何をしましたか?
グラフィックスカードを使いたいプログラムを書くときは、通常、ドライバへのある種のインターフェースを選ぶでしょう。ドライバへのよく知られたインタフェースは次のとおりです。
- OpenGL
- Direct3D
- CUDA
この例では、OpenGLを使い続けます。今、あなたの ドライバへのインタフェース あなたがあなたのプログラムを作るのに必要なすべてのツールをあなたに与えるものです トーク グラフィックスカード(またはドライバ)に 話し合い カードへ).
このインターフェースは確実にあなたを与えるためにバインドされています 道具. これらのツールは、プログラムから呼び出すことができるAPIの形を取ります。.
そのAPIは、上の例で使われているものです。詳しく見てみましょう.
足場
実際に実際の描画を行う前に、次の手順を実行する必要があります。 セットアップ. ビューポート(実際にレンダリングされる領域)、パースペクティブ( カメラ (あなたの世界に)、どのようなアンチエイリアシングを使用するか(あなたの三角形のエッジを滑らかにするために)…
しかし、私たちはそれについて見ません。私たちはあなたがしなければならないものを覗くだけです すべてのフレーム. 好きです:
画面をクリアする
グラフィックスパイプラインは、フレームごとに画面をクリアするわけではありません。あなたはそれを言わなければならないでしょう。どうして?これが理由です:
画面をクリアしない場合は、単純に 引く それはすべてのフレームです。それが私たちが呼ぶ理由です glClear
とともにGL_COLOR_BUFFER_BIT
セット。他のビット(GL_DEPTH_BUFFER_BIT
OpenGLに 深さバッファ。このバッファは、どのピクセルが他のピクセルの前面(または背面)にあるかを判断するために使用されます。.
変換
画像ソース
変換は、すべての入力座標(三角形の頂点)を取得してModelView行列を適用する部分です。これは、 説明する どうやって モデル (頂点)は回転、拡大縮小、平行移動(移動).
次に、射影行列を適用します。これはすべての座標を移動させ、それらが私たちのカメラに正しく向くようにします.
今度はビューポート行列を使ってもう一度変換します。私達は私達のスケールを変えるためにこれをします モデル 私達のモニターのサイズに。今すぐレンダリングする準備ができている頂点のセットがあります!
少し後で変換に戻ります.
図
三角形を描くには、OpenGLに新しいものを始めるように指示するだけです。 三角形のリスト 電話で glBegin
とともに GL_TRIANGLES
定数.
あなたが描くことができる他の形もあります。三角ストリップや三角扇風機のように。これらは同じ量の三角形を描画するためにCPUとGPU間の通信が少なくて済むため、主に最適化です。.
その後、各三角形を構成する3つの頂点のセットのリストを提供できます。すべての三角形は3つの座標を使用します(私たちが3D空間にいるように)。さらに、私はまた提供します 色 各頂点に対して、glColor3f
前 呼びかけ glVertex3f
.
3つの頂点(三角形の3つの角)の間の色合いはOpenGLによって計算されます。自動的に. 多角形の面全体に色を補間します.
インタラクション
さて、あなたがウィンドウをクリックすると。アプリケーションはクリックを知らせるウィンドウメッセージをキャプチャするだけです。それからあなたはあなたが望むあなたのプログラムの中でどんな行動でも実行することができます.
これは ロット 3Dシーンとのやり取りを始めたい場合はさらに困難.
最初に、ユーザーがウィンドウをクリックしたピクセルを明確に知る必要があります。その後、あなたの 見通し考慮に入れると、あなたはあなたのシーンへのマウスクリックのポイントから光線の方向を計算することができます。あなたはそれからあなたのシーンの中にオブジェクトがあるかどうかを計算できます 交差する その光線で。これで、ユーザーがオブジェクトをクリックしたかどうかがわかります.
だから、どのようにあなたはそれを回転させるのですか?
変換
一般的に適用される2種類の変換を知っています。
- マトリックスベースの変換
- 骨ベースの変形
違いは 骨格 シングルに影響を与える 頂点. 行列は常に描画されたすべての頂点に同じように影響します。例を見てみましょう.
例
以前、私達は私達のをロードしました 単位行列 三角形を描く前に単位行列は単に次のものを提供するものです。 変形なし まったくですから、私が描くものは何でも、私の見方によってのみ影響を受けます。だから、三角形はまったく回転しません.
今回転させたいのであれば、自分自身で(CPU上で)計算することも、単純に呼び出すこともできます。 glVertex3f
とその他の 座標(回転している)または、GPUにすべての作業を任せることもできます。 glRotatef
描く前に:
//三角形をY軸上で回転させるglRotatef(amount、0.0f、1.0f、0.0f);
量
もちろん、固定値です。あなたがしたい場合は アニメート, あなたは追跡する必要があります 量
そしてフレームごとにそれを増やす.
それで、待ってください、すべてのマトリックスの話が以前に起こったこと?
この簡単な例では、行列を気にする必要はありません。我々は単に呼ぶ glRotatef
そしてそれは私達のためにすべての面倒を見る.
glRotate
の回転を生成します角度
ベクトルx y zの周りの角度。次の行列を引数としてifglMultMatrixが呼び出されたように、現在の行列(seeglMatrixMode)に回転行列が掛けられ、その積が現在の行列を置き換えます。【数1】ここで、x 2 -c + cx y 1 -c - z sx z 1 -c + y s 0 y 1 -c + z sy 2 1 - c + cy zである。 1 − c − x s 0 x z 1 − c − y sy z 1 − c + x sz 2 1 − c + c 0 0 0 1 1
まあ、それをありがとう!
結論
明らかになったことは、たくさんの話があります に OpenGLしかしそれは言っていない 米国 何でも。コミュニケーションはどこですか?
この例でOpenGLが言っていることは、OpenGLだけです。 終わったら. すべての操作にはある程度の時間がかかります。いくつかの操作は信じられないほど長い時間がかかります、他は信じられないほど速いです.
頂点を送る GPUにはとても速くなるでしょう、私はそれを表現する方法さえ知りません。 1フレームごとに、CPUからGPUに何千もの頂点を送信しても、ほとんど問題はありません。.
画面をクリアする ビューポートの大きさにもよりますが、1ミリ秒以上かかる場合があります(各フレームを描画するのに通常は約16ミリ秒しかかかりません)。それをクリアするために、OpenGLはあなたがクリアしたい色ですべての単一のピクセルを描画しなければなりません。.
それ以外に、私たちはグラフィックスアダプタの機能について、OpenGLにほとんど尋ねることができます(最大解像度、最大アンチエイリアシング、最大色深度など)。.
しかし、それぞれが特定の色を持つピクセルでテクスチャを塗りつぶすこともできます。したがって、各ピクセルは値を保持し、テクスチャはデータで埋められた巨大な「ファイル」です。それを(テクスチャバッファを作成することによって)グラフィックスカードにロードしてから、シェーダをロードし、そのシェーダにテクスチャを入力として使用するように指示し、「ファイル」に対して非常に重い計算を実行することができます。.
計算結果を(新しい色の形で)新しいテクスチャに「レンダリング」することができます。.
それが、GPUを他の方法で機能させる方法です。私はCUDAがその側面と同じように機能すると思いますが、私はそれを使用する機会がありませんでした.
私たちは本当に全体の話題に少しだけ触れました。 3Dグラフィックスプログラミングは獣の地獄です.
画像ソース
説明に追加するものがありますか?コメントの中で消してください。他の技術に精通したStack Exchangeユーザーからの回答をもっと読みたいですか?こちらのディスカッションスレッドをチェックしてください。.