私は今何日もできない本当に奇妙な問題を抱えていpin down
ます。単純な頂点ごとのライティングを作成しており、 で正常に動作Nvidia
しますが、ライト オンでシェーディングされたものはレンダリングされませんAMD/ATI
。属性、特に色属性に関係する問題を突き止めました。
これは私の頂点シェーダーです:
#version 140
uniform mat4 modelViewProjectionMatrix;
in vec3 in_Position; // (x,y,z)
in vec4 in_Color; // (r,g,b,a)
in vec2 in_TextureCoord; // (u,v)
out vec2 v_TextureCoord;
out vec4 v_Color;
uniform bool en_ColorEnabled;
uniform bool en_LightingEnabled;
void main()
{
if (en_LightingEnabled == true){
v_Color = vec4(0.0,1.0,0.0,1.0);
}else{
if (en_ColorEnabled == true){
v_Color = in_Color;
}else{
v_Color = vec4(0.0,0.0,1.0,1.0);
}
}
gl_Position = modelViewProjectionMatrix * vec4( in_Position.xyz, 1.0);
v_TextureCoord = in_TextureCoord;
}
これはピクセル シェーダーです。
#version 140
uniform sampler2D en_TexSampler;
uniform bool en_TexturingEnabled;
uniform bool en_ColorEnabled;
uniform vec4 en_bound_color;
in vec2 v_TextureCoord;
in vec4 v_Color;
out vec4 out_FragColor;
void main()
{
vec4 TexColor;
if (en_TexturingEnabled == true){
TexColor = texture2D( en_TexSampler, v_TextureCoord.st ) * v_Color;
}else if (en_ColorEnabled == true){
TexColor = v_Color;
}else{
TexColor = en_bound_color;
}
out_FragColor = TexColor;
}
したがって、このシェーダーは、ライトを使用する場合、ライトを使用せずに頂点カラーを使用する場合、およびすべての頂点に単一のカラーを使用する場合の 3 つの状態を許可します。問題を特定の属性まで突き止めたため、簡単な計算コードをすべて削除しました。これはシェーダーからの出力
です: ご覧のとおり、すべてが青色です (したがって、シェーディングまたは色を持たないすべてがレンダリングされます
(en_LightingEnabled == false and en_ColorEnabled == false)
)。
頂点シェーダーでこのコードを置き換えると:
if (en_ColorEnabled == true){
v_Color = in_Color;
}else{
これとともに:
if (en_ColorEnabled == true){
v_Color = vec4(1.0,0.0,0.0,1.0);
}else{
次の結果が得られます:
シェーディングなしですべてをレンダリングすることがわかりますが、ライト ( en_LightingEnabled == true
) を使用するものはすべて緑色でレンダリングされます。そうあるべきです。問題は、in_Color
ライトが有効になっている場合でもアトリビュートが実行されないため、アトリビュートがライトに干渉してはならないことです。また、画像内に赤い部分がないこともわかります。つまり、このシーンen_ColorEnabled
では常にfalse
. ここin_Color
ではまったく役に立ちませんが、論理的にすべきではない場所でバグを引き起こします。そのNvidia
上で正常に動作し、緑色の領域は の有無にかかわらず描画されin_Color
ます。
AMD
サポートされていないものを使用していますか? GLSL
仕様外のものを使用していますか? 私は仕様よりもAMD
厳密であることを知っているので、未定義のことをする可能性があります。コードをできるだけシンプルにしましたが、まだ問題があるため、わかりません。また、頂点属性が無効
になっている場合 (no )、画面上に何も描画されない (青い領域でさえ) ことに気付きましたが、なぜですか? 色も使いません。無効な属性は、仕様によって ( ) を返す必要がありますよね? その色を変更しようとしましたが、それでも黒くなりました。コンパイラとリンカーはエラーや警告を返しません。属性 in_Color は、GL
Nvidia
in_Color
glEnableVertexAttribArray
0,0,0,1
glVertexAttrib4f
glGetAttribLocation
. しかし、私が言ったように、そのブランチは私のコードで実行されることはないので、これは問題ではありません。何か案は?
テスト済みでNvidia660Ti
問題なく動作し、ATI
mobility radeon HD 5000
ラップトップでテストしたところ、このエラーが発生しました。私の唯一の考えは、(属性が多すぎるなど)の機能を超えている可能性があるということでしたがGPU
、コードをこれに減らしたとき、それを信じるのをやめました。ここでは 3 つの属性のみを使用します。
また、私の友人の何人かは、より新しいAMD
カードでテストしたところ、同じ問題が発生しました。
更新 1
頂点属性は次のようにバインドされます。
if (useColors){
glUniform1i(uni_colorEnable,1);
glEnableVertexAttribArray(att_color);
glVertexAttribPointer(att_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, OFFSET(offset));
}else{
glUniform1i(uni_colorEnable,0);
}
また、奇妙さをさらに簡単に表示する方法を見つけました。この頂点シェーダーを使用してください。
void main()
{
v_Color = clamp(vec4(1.,1.,1.,1.) * vec4(0.5,0.5,0.25,1.),0.0,1.0) + in_Color;
gl_Position = modelViewProjectionMatrix * vec4( in_Position.xyz, 1.0);
v_TextureCoord = in_TextureCoord;
}
したがって、分岐はありません。そして、私はこれを取得します:
そのコードを
in_Color
次のように削除して変更すると:
void main()
{
v_Color = clamp(vec4(1.,1.,1.,1.) * vec4(0.5,0.5,0.25,1.),0.0,1.0);
gl_Position = modelViewProjectionMatrix * vec4( in_Position.xyz, 1.0);
v_TextureCoord = in_TextureCoord;
}
私はこれを得る:
この最後のものは私が期待するものですが、前のものは、+
他の代わりに加算 ( ) を行っても何も描画しません。したがって、attrib
がバインドされておらず、( 0,0,0,0
) または ( 0,0,0,1
) が指定されている場合は、何もするべきではありません。それでもまだ失敗します。
また、コンパイル、リンク、および検証のすべてのログは空です。エラーや警告はありません。シェーダーのデバッグ情報AMD/ATI
が提供するものよりもはるかに劣っていることに気付きましたNvidia
が。
更新 2
私が見つけた唯一の修正はattribarray
、すべての場合に有効にすることでした(したがって、基本的に、色が有効になっていないときにジャンクを送信しますGPU
)が、ユニフォームを使用して色をチェックするので、使用しません. したがって、次のようになります。
if (useColors){
glUniform1i(uni_colorEnable,1);
}else{
glUniform1i(uni_colorEnable,0);
}
glEnableVertexAttribArray(att_color);
glVertexAttribPointer(att_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, STRIDE, OFFSET(offset));
なぜそれが起こっているのか、なぜこれを使用する必要があるのか わかりません。私はそれを必要としませんNvidia
。だから、これは遅くて帯域幅を無駄にしていると思いますか? しかし、少なくともそれは機能します...これをより良く行う方法についてのヘルプは役に立ちます。