web-dev-qa-db-ja.com

WebGLでは、属性、ユニフォーム、可変変数の違いは何ですか?

これらの異なるタイプを比較するとき、またはこれらがどのように機能するかについて考えることができるアナロジーがありますか?

また、行列の均一化とはどういう意味ですか?

67
Skorpius

http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ から直接コピーしました。実際のサイトにはもっと詳細な情報があり、チェックアウトする価値があります。

変数修飾子

修飾子は、変数に特別な意味を与えます。次の修飾子が使用可能です。

  • const –宣言はコンパイル時定数です。
  • 属性–頂点ごとに変化する可能性のあるグローバル変数。OpenGLアプリケーションから頂点シェーダーに渡されます。この修飾子は、頂点シェーダーでのみ使用できます。シェーダーの場合、これは読み取り専用変数です。属性セクションを参照してください。
  • uniform –プリミティブごとに変化する可能性のあるグローバル変数[...]。OpenGLアプリケーションからシェーダーに渡されます。この修飾子は、頂点シェーダーとフラグメントシェーダーの両方で使用できます。シェーダーの場合、これは読み取り専用変数です。均一セクションを参照してください。
  • 変化する-頂点シェーダーとフラグメントシェーダー間の補間データに使用されます。頂点シェーダーでの書き込み、およびフラグメントシェーダーでの読み取り専用で使用できます。さまざまなセクションを参照してください。

類推として、constとuniformはC/C++のグローバル変数のようなもので、1つは定数で、もう1つは設定できます。属性は、色やテクスチャの座標など、頂点に付随する変数です。可変変数は、頂点シェーダーによって変更できますが、フラグメントシェーダーによっては変更できません。したがって、本質的に、変数はパイプラインに情報を渡します。

72
Alfredo Gimenez
  • uniformper-primitiveパラメーター(描画呼び出し全体で一定)です。
  • attributeは、頂点ごとのパラメーター(通常:位置、法線、色、UV、...);
  • varying areper-fragment(またはper-pixel)パラメーター:ピクセルからピクセルへとvary.

varyingが独自のシェーダーをプログラムする方法を理解することが重要です。
頂点シェーダー内の三角形の各頂点に対して可変パラメーターvを定義するとしましょう。この可変パラメーターがfragmentシェーダーに送信されると、その値は描画するピクセルの位置に基づいて自動的に補間されます。

次の画像では、赤色のピクセルが、さまざまなパラメーターvの補間値を受け取りました。それが「変化する」と呼ばれる理由です。

varying parameter being bilinearly interpolated

簡単にするために、上記の例ではbilinear補間を使用します。これは、描画されるすべてのピクセルがカメラから同じ距離にあると想定しています。正確な3Dレンダリングのために、グラフィックデバイスはピクセルの深さを考慮した遠近補正補間を使用します。

45
neeh

OpenGLでは、「プログラム」は「シェーダー」(小さなプログラム)のコレクションであり、パイプラインで互いに接続されています。

// "program" contains a shader pipeline:
//   vertex shader -> other shaders -> fragment shader
//
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);

シェーダーは、3Dモデルのラスタライズに必要な頂点(頂点シェーダー)、ジオメトリ(ジオメトリシェーダー)、テッセレーション(テッセレーションシェーダー)、フラグメント(ピクセルシェーダー)、およびその他のバッチプロセスタスク(計算シェーダー)を処理します。

OpenGL(WebGL)シェーダーは、GLSL(GPU上でコンパイルされたテキストベースのシェーダー言語)で記述されています。

// Note: As of 2017, WebGL only supports Vertex and Fragment shaders

<!-- Vertex Shader -->
<script id="shader-vs" type="x-shader/x-vertex">

  // <-- Receive from WebGL application
  uniform vec3 vertexVariableA;

  // attribute is supported in Vertex Shader only
  attribute vec3 vertexVariableB;

  // --> Pass to Fragment Shader
  varying vec3 variableC;

</script>

<!-- Fragment Shader -->
<script id="shader-fs" type="x-shader/x-fragment">

  // <-- Receive from WebGL application
  uniform vec3 fragmentVariableA;

  // <-- Receive from Vertex Shader
  varying vec3 variableC;

</script>

これらの概念に留意してください:

シェーダーは、パイプラインの次のシェーダー(outinout)にデータを渡すことができ、WebGLアプリケーションまたは以前のシェーダー(in)からデータを受け取ることもできます。

  • VertexおよびFragmentシェーダー(実際には任意のシェーダー)は、uniform変数を使用してWebGLアプリケーションからデータを受信できます。

    // Pass data from WebGL application to shader
    var uniformHandle = gl.glGetUniformLocation(program, "vertexVariableA");
    gl.glUniformMatrix4fv(uniformHandle, 1, false, [0.1, 0.2, 0.3], 0);
    
  • 頂点シェーダーは、必要に応じて有効または無効にすることができるattribute変数を使用して、WebGLアプリケーションからデータを受け取ることもできます。

    // Pass data from WebGL application to Vertex Shader
    var attributeHandle = gl.glGetAttribLocation(mProgram, "vertexVariableB");
    gl.glEnableVertexAttribArray(attributeHandle);
    gl.glVertexAttribPointer(attributeHandle, 3, gl.FLOAT, false, 0, 0);
    
  • 頂点シェーダーは、varying変数を使用してデータをフラグメントシェーダーに渡すことができます。上記のGLSLコードを参照してください(varying vec3 variableC;)。

6
tfmontague

ユニフォームは、CPU上のアプリケーションからGPU上のシェーダーにデータを渡す別の方法ですが、ユニフォームは頂点属性と比較するとわずかに異なります。まず、ユニフォームはグローバルです。グローバル。つまり、均一変数はシェーダープログラムオブジェクトごとに一意であり、シェーダープログラムの任意の段階で任意のシェーダーからアクセスできます。第二に、ユニフォームの値を何に設定しても、ユニフォームはリセットまたは更新されるまで値を保持します

https://learnopengl.com/Getting-started/Shaders の説明が好きです。なぜなら、Wordper-primitive直感的ではない

1
Liu Hao