2014-06-18 3 views
5

정말 이상한 문제가 있습니다. 지금은 pin down 일 동안은 불가능합니다. 간단한 정점 별 조명을 만들고 있는데 Nvidia에서 제대로 작동하지만 조명으로 음영 처리 된 것은 아무것도 렌더링하지 않습니다 (AMD/ATI). 나는 속성과 관련된 문제, 특히 색 속성을 추적했다. 나는 조명을 사용하지만, 사용하지 않을 때 나는 조명을 사용할 때, -GLSL 셰이더가 AMD/ATI에서 작동하지 않지만 NVIDIA에서 작동합니다.

#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 주 수 : 이것은 픽셀 쉐이더가

#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; 
} 

입니다 :
이 내 버텍스 쉐이더입니다 모든 정점에 대해 하나의 색상을 사용하는 경우. 문제에 대한 속성을 추적했기 때문에 모든 조명 계산 코드를 제거했습니다. 이것은 셰이더의 출력입니다.
Shader with bug 모든 것이 파란색이므로 음영이 있거나 그림자가없는 모든 것을 렌더링합니다 ((en_LightingEnabled == false and en_ColorEnabled == false)). 이와

if (en_ColorEnabled == true){ 
    v_Color = in_Color; 
}else{ 

: 내가 버텍스 쉐이더에서이 코드를 교체 할 때

그래서 당신이 음영없이 모든 것을 렌더링하는 것을 볼 수 있습니다
Without in_Color attribute
:

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 사양을 사용하고 있습니까? AMDGL spec보다 엄격한 것은 Nvidia보다 엄격하다는 것을 알고 있습니다. 그래서 나는 정의되지 않은 것을 할 수 있습니다. 가능한 한 간단하게 코드를 작성했지만 여전히 문제가있어 보지 못합니다.
또한 in_Color vertex 속성이 비활성화되어 있으면 화면에 아무 것도 (파란색 영역조차도) 그릴 수는 없다는 것을 알았지 만 (no glEnableVertexAttribArray), 그 이유는 무엇입니까? 나는 색을 사용하지도 않는다. 사용 중지 된 속성은 사양에 따라 (0,0,0,1)을 반환해야합니까? 나는 그 색깔을 바꾸기 위해 glVertexAttrib4f을 사용하려고 노력했다. 그러나 아직도 검은있어. 컴파일러와 링커는 오류나 경고를 반환하지 않습니다. 속성 in_Color는 glGetAttribLocation으로 문제가 없습니다. 그러나 내가 말했듯이, 그 지점은 결코 내 코드에서 실행되지 않으므로 이것의 어떤 것도 중요하지 않습니다. 어떤 아이디어?

Nvidia660Ti에서 테스트했으며 문제가 없으면 노트북 ATImobility radeon HD 5000에서 테스트했으며이 오류가 있습니다. 내 유일한 생각은 아마도 GPU (너무 많은 특성 등등)의 기능을 초과했을 수도 있지만,이 코드를 줄이면 그 사실을 믿지 않게되었습니다. 여기서 3 가지 속성 만 사용합니다.
또한 일부 친구는 훨씬 더 새로운 AMD 카드를 테스트했으며 같은 문제가 발생했습니다.

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; 
} 

: - :

UPDATE 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); 
} 

을 또한, 난 쉽게 불확실성을 표시하는 방법을 발견 따라서 분기가 없습니다. 그리고 나는 얻을이 : 내가 지금처럼 in_Color을 제거하여 그 코드를 변경하는 경우 Without branching there is still that bug : Without branching as expected

이 마지막 하나는 내가 기대하지만, 이전은 '아무튼 :

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가 제공하는 것이 aw이주는 것보다 훨씬 열등하다는 것을 알았지 만.

업데이트 2

나는 모든 경우 (색상이 사용되지 않을 때 그래서 기본적으로 GPU에 쓰레기를 전송)에 attribarray을 가능하게하는 것이었다 발견 된 경우에만 수정,하지만 난 컬러를 확인하기 위해 유니폼을 사용할 때, 그럼 난 그냥 사용하지 않아. 따라서 다음과 같이됩니다.

나는 왜 그런 일이 일어나고 있는지, 왜 이것을 사용해야하는지에 대해 알지 못합니다. 나는 Nvidia에 그럴 필요가 없다. 그래서 나는 이것이 더 느리고 대역폭을 낭비하고 있다고 생각하니? 하지만 적어도 그것은 작동합니다 ... 어떻게 더 잘하는 것이 도움이 될 것입니다.

+0

정점 속성을 바인딩하는 방법을 보여줍니다. 또한 프로그램의 유효성을 검사하고 유효성 검사 로그를 표시하십시오. – sbabbi

+1

조건부없이 다시 쓰기를 시도하십시오 ... (대신 프로그램을 전환하십시오) ... 저는 방금 인텔 드라이버 및 조건부와 관련하여 문제를 겪었습니다 : http://stackoverflow.com/questions/24222343/glsl-boolean-evaluation-wackiness –

+0

주제를 업데이트했습니다. 따라서 분기가 없어도 문제가 발생합니다. – user1214513

답변

1

셰이더 (in_Position, in_Color 및 in_TextureCoord)에 대해 3 개의 입력 값을 지정했기 때문에이 문제가 발생했을 수 있지만 꼭지점 데이터에 항상 3이 모두 포함되는 것은 아닙니다. 꼭지점 특성이이 형식과 정확하게 일치하지 않으면 정의되지 않은 동작 영역으로 들어가고 각 구현은 원하는대로 할 수 있습니다.

Nvidia 드라이버는 가지고있는 것을 적절한 정점 속성에 바인드하고 렌더링합니다. 이다

, 당신의 데이터는 배열 쉐이더에 다음과 같은 다음 AMD의 드라이버가 아마 색상이 포함되지 않은 경우에도 모든 3 개 속성과 정점 데이터를 해석하려고

in_Position  = Position.xyz 
in_Color   = ??? 
in_TextureCoords = TextureCoords.xy 

. 첫 번째 정점 이후 위치는 데이터 배열의 위치와 동기화되지 않아 어디서나 렌더링됩니다. 나는 그것이 in_Color 속성의 사용을 제거 할 때 AMD에서 작동하는 이유는 셰이더 컴파일러가 사용되지 않는다고보고 당신이 지정한 사실을 최적화하기 때문이라고 생각합니다.

in_Position  = Position[0].xyz 
in_Color   = TextureCoords[0].xy,Position[1].xy 
in_TextureCoords = Position[1].z,TextureCoords[1].x 

가능한 솔루션은 필요하지 않거나 다른 버텍스 속성이 별도의 것들로 버텍스 쉐이더를 분할 따라 적절한 하나를 바인딩 할 때 이미 한 일을 할 쓰레기 컬러 데이터를 지정할 수 있습니다 버텍스 컬러 데이터를 가지고 있는지 여부.