2014-10-18 6 views
0

glDrawElements 기능을 사용하여 씬을 그립니다. 상황을 달성하고 싶기 때문에, 무승부 콜이 완전한 장면을 그리는 곳이면, 쉐이더의 「재질」을 전환하는 쉐이더를 만들 필요가 있습니다. 재료에 soubroutine을 사용하기로 결정했습니다. 여기 내 조각 쉐이더가 있습니다.soubroutine을 사용하는 OpenGL 아티클

#version 440 

layout(location = 0) flat in uvec2 inID_ShaderData; 
layout(location = 1) in vec4 inPosition; 
layout(location = 2) in vec2 inUV; 

subroutine void shaderType(void); 
subroutine uniform shaderType shaders[2]; 

uniform sampler2D texture0; 

layout(location = 0) out vec4 outColor; 
layout(location = 1) flat out uint outID; 

subroutine(shaderType) void shader_flatColor(void) 
{ 
outColor = vec4(1,0,0,1); // test red color 
// outColor = unpackUnorm4x8(inID_ShaderData.y & 0x00ffffff); // this should be here normally 
} 

subroutine(shaderType) void shader_flatTexture(void) 
{ 
    outColor = vec4(0,0,1,1); // test blue color 
// outColor = texture(texture0, inUV); // this should be here normally 
} 

void main() 

{  
    uint shader = (inID_ShaderData.y >> 24) & 0xff; // extract subroutine index from attributes 
    shaders[ shader ](); // call subroutine - not working, makes artifacts 

/* calling subroutine this way works ok 
    if (shader == 0) shaders[ 0 ](); 
    if (shader == 1) shaders[ 1 ](); 
*/ 

outID = inID_ShaderData.x; 

if (outID == -1) // this condition never happens 
    outColor = texture(texture0, inUV); // needed here to not to optimize out texture0, needed in soubroutine 

} 

질문 1 : shaders [ shader ]();을 사용하여 다음에 그려진 쿼드 픽셀 이슈가있다. IF를 사용할 때 제대로 작동합니다. 드라이버 버그입니까, 아니면 잘못하고 있습니까? IF없이 서브 루틴을 사용하면 어떻게 될까요? (Windows 8 64 비트에 Radeon 7850이 있음)

질문 2 : 두 번째 soubroutine에서는 질감을 사용하고 싶습니다. 그러나이 샘플러 변수를 main()에 사용하지 않으면 서브 루틴과 CPU 쪽에서 컴파일러가 "보지 못합니다"라는 오류가 발생합니다. glUniform 함수가 실패합니다. 올바른 방법이 있습니까? 컴파일러 요령없이, 예를 들면. 절대로 상황이 발생하지 않습니까?

P .: 미안하지만 유물이있는 이미지를 게시 할 수 없습니다. 빨간색 사각형은빨간색 사각형이며 대부분 구석의 일부 5 %에 ​​무작위 파란색 픽셀이 있습니다. 파란색 사각형에는 빨간색 픽셀이 있습니다.

답변

0

당신은 그렇게 할 수 없습니다. 속성별로 속성 서브 루틴을 전환 할 수 없습니다. GLSL 스펙은 시도에 대해 할 말이이 있습니다

서브 루틴 변수 가 동적으로 균일 한 표현으로 인덱싱 할 수있는 명시 적 크기의 배열을 선언 할 수있다.

GPU의 작동 방식에 대해 생각해 보면이 제한이 완전히 이해됩니다. 하나의 쉐이더 호출마다 별도의 제어 흐름이 없으며 훨씬 더 큰 그룹에 대해서만 있습니다.

시도 할 때 if 시도하면 상수 색인을 사용하는 물론 물론 동적으로 동일합니다. 당연히 입력 속성을 기반으로 브레칭을 시도 할 수도 있지만, 이렇게하면 균일하지 않은 제어 흐름을 강요하면 성능이 완전히 저하 될 수 있습니다. 최악의 경우, 항상 모든 서브 루틴 함수를 실행하고 결과를 일부 배열에 저장하고 색인을 사용하여 해당 배열에서 최종 결과를 선택하는 것보다 훨씬 효율적이지는 않습니다.

+0

역동적으로 통일 된 표현에 관해서는이 기사 (https://www.opengl.org/wiki/Example/Dynamically_Uniform_Expression)를 확인했습니다. 감사. – quantumfoam