我真的很奇怪的問題,我現在不能pin down
。我正在製作一個簡單的每頂點照明,它在Nvidia
上正常工作,但不會在AMD/ATI
上渲染任何陰影。我追蹤了這個問題與屬性有關 - 特別是顏色屬性。
這是我的頂點着色器:GLSL着色器不適用於AMD/ATI,但適用於NVIDIA
#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
嚴格與GL
規範比Nvidia
,所以這是可能的,我做了一些未定義。我讓代碼儘可能簡單,但仍然存在問題,所以我沒有看到它。
此外,我注意到如果in_Color
頂點屬性被禁用(不是glEnableVertexAttribArray
),它將不會在屏幕上繪製任何東西(即使是藍色區域),但是爲什麼?我甚至不使用這種顏色。禁用的屬性需要返回(0,0,0,1
)的規格權?我嘗試使用glVertexAttrib4f
來改變顏色,但仍然變黑。編譯器和鏈接器不會返回任何錯誤或警告。屬性in_Color在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
唯一的解決方法,我發現是使所有的情況(所以沒有啓用顏色的時候基本上發送垃圾到GPU
)attribarray
,但我使用統一的檢查顏色,那我就不用它了。所以它是這樣的:
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
。所以我猜這是慢的,我浪費帶寬?但至少它的作品...幫助如何更好地做到這一點將是有益的,但。
顯示如何綁定頂點屬性。還要嘗試驗證您的程序並顯示驗證日誌。 – sbabbi
嘗試重寫沒有條件...(切換程序代替)...我剛碰到與英特爾驅動程序和條件的bonkers問題:http://stackoverflow.com/questions/24222343/glsl-boolean-evaluation-wackiness –
我更新了這個話題。所以即使沒有分支我仍然遇到問題。 – user1214513