0

一般的な頂点属性は OpenGL で非推奨になっているため、カスタム属性のみを使用して頂点シェーダーを書き直そうとしました。そして、私は私のために働きませんでした。頂点シェーダーは次のとおりです。

attribute vec3 aPosition;
attribute vec3 aNormal;

varying   vec4 vColor;

vec4 calculateLight(vec4 normal) {
    // ...
}

void main(void) {
    gl_Position = uProjectionMatrix * uWorldViewMatrix * vec4(aPosition, 1);
    vec4 rotatedNormal = normalize(uWorldViewMatrix * vec4(aNormal, 0));
    vColor = calculateLight(rotatedNormal);
}

これは OpenGL ES 2.0 で完全に機能します。ただし、OpenGL で使用しようとすると、黒い画面が表示されます。aNormalジェネリックに変更すると、gl_Normalすべて正常に動作します (aPosition両方のコンテキストで正常に動作し、使用する必要がないことに注意してくださいgl_Vertex)。

私は何を間違っていますか?

RenderMonkey を使用してシェーダーをテストし、適切な属性名 (aPosition および aNormal) を使用してストリーム マッピングをセットアップしました。多分それは属性インデックスと関係があります。なぜなら、私はそれらすべてを0? また、「ストリーム マッピング」でのカスタム属性名の設定について、RenderMonkey のドキュメントには次のように記載されています。

「属性名」フィールドには、シェーダ エディタでそのストリームを参照するために使用できるデフォルト名が表示されます。OpenGL ES エフェクトでは、変更された名前を使用してストリームを参照する必要があります。ただし、DirectX または OpenGL 効果では、新しい名前はシェーダー エディターに影響しません。

この問題は RenderMonkey または OpenGL 自体に固有のものなのでしょうか? そして、なぜaPositionまだ機能するのですか?

4

1 に答える 1

1

属性インデックスは一意である必要があります。プログラムをリンクするglBindAttribLocation 前に、特定のインデックスを使用するように OpenGL に指示することができます。いずれにせよ、通常の方法は、 でインデックスをクエリすることglGetAttribLocationです。RenderMonkey で選択できるようですが、その場合は別のものにしてみましたか?

以前、固定関数レンダリングが頂点属性にクロスオーバーするのを見たことがありglVertexPointerます。最初の属性がバインドされていない場合、最初の属性にバインドされる可能性があります (これが再現可能かどうかはわかりません)。

また、属性と固定関数名を試してみると、いくつかの奇妙なことがわかります。を呼び出さずglBindAttribLocationに、次のシェーダーをコンパイルします。

attribute vec4 a;
attribute vec4 b;
void main()
{
    gl_Position = gl_Vertex + vec4(gl_Normal, 0) + a + b;
}

そして、次の場所を取得します(経由glGetActiveAttrib):

a: 1
b: 3
gl_Vertex: -1
gl_Normal: -1

実験すると、 の使用はインデックスを取得し、インデックスを取得するようです(gl_Vertex報告0されていなくても)。と の間にパディング属性を挿入すると(出力で使用することを忘れないでください。そうしないとコンパイルされてしまいます)、機能します。gl_Normal2aPositionaNormal

この場合、位置データが最後に位置 0 に単純にバインドされている可能性があります。ただし、何もバインドされていないことを示す黒い画面aNormal(この場合は常に になります{0, 0, 0})。これは少し一貫性がありません。法線が位置と同じデータにバインドされている場合、正しい色ではないにしても、法線が位置データを持っているため、何らかの色が期待されます。

アプリケーションは、複数のユーザー定義属性変数を同じ汎用頂点属性インデックスにバインドできます。これはエイリアシングと呼ばれ、エイリアシングされたアトリビュートの 1 つだけが実行可能プログラムでアクティブである場合、またはシェーダーを通るパスが同じ場所にエイリアシングされたアトリビュート セットの複数のアトリビュートを消費しない場合にのみ許可されます。

私の感覚では、RenderMonkey は属性の代わりにglVertexPointer/だけを使用しglNormalPointerていると思いますが、両方のインデックスがゼロであると言うので、法線と位置の両方を法線または位置のデータにバインドします。

DirectX または OpenGL 効果では、新しい名前はシェーダー エディターに影響しません。

たぶん、これは「名前付きストリーム」が非 ES OpenGL バージョンでは利用できないことを意味するのでしょうか?

これは関係ありませんが、最近の OpenGL-GLSL バージョンでは#version数字が必要であり、属性はキーワード を使用しますin

于 2014-01-29T09:24:38.450 に答える