2017-07-10 5 views
3

OpenGLでサークルを作成する方法を見てきましたが、「ファン」メソッド(またはその派生物)を使用して、以下のメソッドを使用したことがありません。さまざまな位置に基づいて円を作成するのではなく、OpenGLファンを使用する利点は何ですか?

そうのような頂点:

#version 330 core 

in vec3 apos; 
in vec2 abound; 

out vec3 ourColor; 
out vec2 ourBound; 

void main() { 
    gl_Position = vec4(apos, 1.0); 
    ourBound = abound; 
} 

がfiguに補間境界値をとり、次のフラグメントシェーダの作成:

float vertices[] = { 
      0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right 
      0.5f, -0.5f, 0.0f, 1.0f, -1.0f, // bottom right 
      -0.5f, -0.5f, 0.0f, -1.0f, -1.0f,// bottom left 
      -0.5f, 0.5f, 0.0f, -1.0f, 1.0f// top left 
}; 

は、フラグメントシェーダに変化する形式の境界情報を渡し、次の頂点シェーダを作成します中心から現行断片距離を再

#version 330 core 

in vec2 ourBound; 

uniform vec4 setColor; 

void main() { 
    float dist = sqrt((ourBound.x * ourBound.x) + (ourBound.y * ourBound.y)); 
    vec4 color_used = vec4(vec3(1.0), 0.0); 
    if(dist < 1.0){ 
     color_used = setColor; 
    } 
    gl_FragColor = color_used; 
} 
  • ロードシェーダ
  • 初期VBO/EBOはAPOS(= 0、ストライド= 5 *のはsizeof(フロート)をオフセット)とするためのためのオブジェクトブレンド有効
  • Intialize colorLocation
  • ストアVBAで
(= 3、ストライド= 5 *のはsizeof(フロート)をオフセット)たくさんありますドローループ・ロード・プログラムで

glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glUseProgram(shader_program); 
    glUniform4f(colorLocation, 0.0f, 1.0f, 0.0f, 1.0f); 
    glBindVertexArray(VAO); 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 

マイ結果 enter image description here

は私の代わりにファンを作成するための利点を理解していません。パフォーマンス上のメリットはありますか?それは確かに簡単ではないようです。私はここでは、Google以外のソリューションを見つけることができません。

+0

プログラム可能なパイプラインにアクセスできず、ピクセルごとの 'incircle()'チェックを実行できない場合はどうなりますか? – genpfault

+0

@genpfault何を意味していますか?どのような状況でこれが当てはまり、それでも古くはないOpenGL標準、特に3.3+コアに適合していますか?それはあなたがシェイダーを作ることさえできないことを暗示します。このファンのパターンは、OpenGLのバージョンにかかわらず、何とか教えられているようです。 – snb

+0

あなたがシェイダーを持っていないなら、あなたは* incircle()を使うことはできません。三角ファン方式は、固定機能パイプラインとプログラム可能パイプラインの両方で機能します。 – genpfault

答えて

6

代わりにファンを作成するメリットがわかりません。

チュートリアルです。チュートリアルの目的は、何か特別なスキルを教えることです。何かをする最善の方法を提示する必要はありません。チュートリアルで重要なことは必ずしも結果ではなく、達成方法です。

円を作成する2つの方法は、大きく異なるスキルを必要とします。頂点法では円の端にある点を計算するためにsin/cosを使用し、バッファにそのようなデータをアップロードしてそのバッファを使ってレンダリングする方法が含まれます。あなたの詐称者の方法は、2D詐欺師を作成する方法と、ポイントが(円)の中にあるかどうかを確認する方法を示しています。

円内点を行う方法を知っている人は、sincosを円上の点を計算する方法を知らない。それで、あなたが球をやることに移ったら、sincosについてそれらを教えなければなりません。一方、以前に頂点を介してサークルをしていたのであれば、彼らは一歩前進しており、既に知っているものの延長として球座標系について学ぶことができます。

さらに、頂点法は、より多くの頂点がより滑らかな結果を作成できることをユーザーに教える簡単な方法です。また、解像度に依存していることを知るのに役立ちます。あなたが頂点ベースの円から離れているほど、頂点の数は少なくなります。これを使用して、フレームごとに頂点を再計算する動的LOD処理の方法を教えることさえできます。これには、オブジェクトを動的にバッファリングするためのストリーミングデータが含まれます。

単なる円の中でダイナミックLODを使用することは決してありません。重要なのは、ユーザーがバッファストリーミングの仕方を学んだことです。

これらは2種類のスキルです。どちらのセットも意味があり便利ですが、とは異なるです。どちらの方法でも本質的に間違ったものはありません。それはあなたが教えようとしているスキルの問題です。

確かに単純ではないようです。

どのように「より簡単に」定義するかによって異なります。チュートリアルで三角レンダリングを理解するようにユーザーに教えようとしている場合、詐称者ベースのアプローチは単純ではありません。また、三角レンダリングを教えていません。

あなたの方法では、ユーザーはフラグメントレベルで何が起こっているかを正式に理解する必要があります。そして、私を間違えないでください。それは良いことですです。詐欺師の作成方法をユーザーに教えることは、非常に優れたツールです。しかし、ユーザーは開発のその時点で学習する準備ができているというツールですか?

さらに、シェーダのアプローチはより限定されています。このサークルにテクスチャを追加したいとします。頂点アプローチでは、頂点にテクスチャ座標を追加し、それらをフラグメントシェーダに渡し、テクスチャからフェッチさせるという通常のことを行います。シェーダのアプローチでは、FSはテクスチャからサークルへの特定のマッピングを作成する必要があります。

これは、このマッピングを変更する必要がある場合はいつでも、FSを変更する必要があることを意味します。スケーリングされたマッピングのバリエーションをサポートするためにいくつかのパラメータをFSに追加することができますが、これはマッピングパラメータを変更するために三角バッチを分割する必要があることを意味します。頂点アプローチでは、(頂点の再起動のおかげで)単一の描画呼び出しで任意の数のファンをレンダリングすることができます。ただし、マップを頂点データにベイク処理するだけです。

確かに、頂点アプローチでは、他のどのようなシェイプと同じようにサークルにも同じシェーダを使用できます。シェーダのアプローチでは、異なるものをレンダリングするためにシェーダを変更する必要があります。

個人的には、チュートリアルでは詐称者の方法を先に教えるべきだと私は思います。しかし、私はサークル詐欺師が最善の方法だとは思わない。

パフォーマンス上のメリットはありますか。

これは、アンチエイリアスの観点から見ればわかります。フラグメントベースの方法では、マルチサンプリングを使用するための特別なコーディングが必要になります。正しく行うには、各サンプル位置の距離を計算し、それに対応するサンプルマスクを出力する必要があります。または、サンプルごとのシェーディングを呼び出します。いずれにせよ、これは少し遅くなります。

しかし、それは面白いレッスンになります。

+0

+1実際に質問に答えるために+1 :)マルチサンプリングのアイデアも意味があり、それについては考えていないでしょう(私はCUDA/OpenCLのバックグラウンドから来ています。 GPUができます)適切な計算ユーティリティにアクセスできれば、これは問題ではありませんが、OpenGLではこれを扱うのは簡単ではないと思います。 – snb

+0

@snb:問題はありません。マルチサンプリングは、三角ラスタライズの副産物です。 「適切な計算ユーティリティ」で直接呼び出すことはできません。フラグメントシェーダは、サンプルマスクを設定するために必要なすべてのツールを提供します。あなたはまだ各サンプルの計算を行う必要があるので、* free *ではありません。 –

+0

@snb: "*私はCUDA/OpenCLのバックグラウンドから来ています*"ということは、実際には頂点メソッドをもっと重要なものにしています。あなたの本来の本能は、あなたが最もよく知っていることであるため、「シェイダーで解決する」ことです。あなたがグラフィックを学びたいなら、あなたはそのような本能を脇に置く必要があります。はい。グラフィックスパイプラインにはシェーダが含まれていますが、それ以上のものも含まれています。また、良いグラフィックスプログラマは使用可能なツールをすべて使用する方法を知る必要があります。この場合、詐欺師がより良い解決策であっても、一般的に正解にはならないからです。 –

0

パフォーマンス上の利点はありますか?

頂点ファンはもっと良いかもしれませんが、フラグメントシェーダを次のように変更すると、それと同等の速さでなければなりません。

#version 330 core 

in vec2 ourBound; 

uniform vec4 setColor; 

void main() { 
    //no sqrt required 
    float dist = dot(ourBound,ourBound); 

    //discard pixels on the outside. 
    //We can leave blending disabled. 
    if(dist > 1.0){ 
     discard; 
    } 
    vec4 color_used = vec4(vec3(1.0), 0.0); 
    gl_FragColor = color_used; 
} 

私の代わりにファンを作成するための利点を理解していません。

2Dサークルを表示したいだけの場合は、メリットはないと思います。

代替方法:

あなたが簡単な2Dの円を表示するようにあなたのクワッドをレンダリングし、その上にアルファチャンネルにテクスチャを置くことができるようですので。これにより、非常に美しいアンチエイリアスサークルや他の2Dオブジェクトを簡単に取得できます。

+0

テクスチャ方法の問題は、私の四角形の位置/縮尺を変更すると縮尺が変わらないということです(四角形が四角形であり、四角形が四角形であれば、四角形は四角形で、四角形は四角形でなければ簡単です)どんな情報も失わず、テクスチャのようなエイリアシングアーティファクトがありません。 – snb

+0

また、 'ドット'についての情報に感謝しています。 – snb

関連する問題