조각 셰이더는 픽셀 색상에 사용할 변수를 어떻게 알 수 있습니까?


82

다양한 조각 셰이더를 볼 수 있습니다.

#version 130

out vec4 flatColor;

void main(void)
{
    flatColor = vec4(0.0,1.0,0.0,0.5);
}

그리고 그들은 모두 "out color"(이 경우 flatColor) 에 대해 다른 변수를 사용합니다 . 그렇다면 OpenGL은 사용자가하려는 작업을 어떻게 알 수 있습니까?

으로 flatColor정의 된 유일한 변수 이기 때문에 이것이 작동 out한다고 생각하지만 더 많은 out변수 를 추가 할 수 있습니다. 아니면 그냥 충돌할까요?


실제로 테스트로 방금 실행했습니다.

#version 330

in vec2 TexCoord0;

uniform sampler2D TexSampler;

out vec4 x;
out vec4 y;

void main()
{
    y = texture2D(TexSampler, TexCoord0.xy);
}

내가 사용 x하든 y.


또한 미리 정의 된 gl_FragColor. 차이점은 무엇이며 사람들은 일반적으로 자신의 변수를 사용하도록 고집하는 이유는 무엇입니까?

답변:


142

또한 미리 정의 된 gl_FragColor가 있습니다.

이것부터 시작합시다. 아니, 당신은 하지 않는 미리 정의 된 있습니다 gl_FragColor. 핵심 OpenGL 3.1 이상에서 제거되었습니다. 호환성을 사용하지 않는 한 (이 경우 3.30 셰이더가 #version 330 compatibility맨 위에 표시되어야 함) 이것을 사용해서는 안됩니다.

이제 사용자 정의 프래그먼트 셰이더 출력으로 돌아갑니다. 그러나 먼저 빠른 비유입니다.

버텍스 쉐이더에서 어떻게 입력이 있는지 기억하십니까? 그리고 이러한 입력은 속성 인덱스 정점 당신이 전달하는 숫자 표현 glVertexAttribPointerglEnableVertexAttribArray등과? 어떤 입력이 어떤 속성에서 가져 오는지 설정합니다. GLSL 3.30에서는 다음 구문을 사용합니다.

layout(location = 2) in color;

이렇게하면 color버텍스 셰이더 입력이 속성 위치 2에서 오도록 설정 됩니다. 3.30 이전 (또는 ARB_explicit_attrib_location없이) glBindAttrbLocation이전에는 연결하기 전에 이를 명시 적으로 설정 하거나를 사용하여 속성 인덱스에 대해 프로그램을 쿼리해야합니다 glGetAttribLocation. 속성 위치를 명시 적으로 제공하지 않으면 GLSL은 위치를 임의로 할당합니다 (예 : 구현 정의 방식).

셰이더에서 설정하는 것이 거의 항상 더 나은 옵션입니다.

어쨌든 조각 셰이더 출력은 거의 동일한 방식으로 작동합니다. 프래그먼트 셰이더는 여러 출력 색상에 쓸 수 있으며 자체적으로 프레임 버퍼의 여러 버퍼에 매핑됩니다 . 따라서 어떤 출력이 어떤 조각 출력 색상으로 이동하는지 표시해야합니다.

이 프로세스는 조각 출력 위치 값으로 시작됩니다. 버텍스 셰이더 입력 위치와 매우 유사하게 설정됩니다.

layout(location = 1) out secColor;

API 함수도 있습니다 glBindFragDataLocationglGetFragDataLocation유사하다, glBindAttribLocation하고 glGetAttribLocation.

명시 적 할당을 수행하지 않으면 일반적으로 구현에서 출력 변수 중 하나를 위치 0에 할당합니다. 그러나 OpenGL 표준은 이 동작을 요구 하지 않으므로 이에 의존해서는 안됩니다.

이제 공정하게 말하면, 다른 출력 위치를 얻지 못한 두 개의 출력을 사용할 때 프로그램이 링크에 실패 했을 것입니다. 아마 컴파일러가 작성하지 않은 것을 최적화했기 때문에 링커 오류를 확인할 때가되었을 때 잊어 버렸습니다.


4
+1 이상 줄 수 있으면 좋겠어요. 멋진 대답. 조각 출력 위치가 어떻게 작동하는지 궁금합니다. :)
kevintodisco

Ahh .. 그래서 gl_FragColor쓸 버퍼를 선택하는 더 많은 유연성을 제공하기 위해 더 이상 사용되지 않습니까? 말이된다. 다시 한 번 감사드립니다!
mpen

3
@Mark : "지원 중단"은 "계속 사용할 수 있지만 이후 버전에서는 제거 될 수 있습니다."라는 의미입니다. "삭제"수단 제거 . 차이가 있습니다. GL 3.0에서 deprecated로 표시된 것은 3.1 에서 제거 되었습니다 (몇 가지를 위해 절약).
Nicol Bolas 2012

3
@NicolBolas : "GL 3.3 이상 (이전 버전에서 변경됨)은 모두 위치 0에 할당합니다." 이것이 사양에 의해 보장되는 곳이 궁금합니다. 3.3은 "프로그램이 연결될 때 바인딩이 지정되지 않았거나 셰이더 텍스트 내에 명시 적으로 설정되지 않은 가변 변수는 자동으로 GL에 의해 조각 색상 및 인덱스에 바인딩됩니다. 이러한 모든 할당은 다음의 색상 인덱스를 사용합니다. 제로.". 마지막 문장은 3.2에 없습니다. 그러나 인덱스는 색상 번호가 아니라 듀얼 소스 블렌딩 인덱스 (3.3에서 추가됨)만을 나타냅니다.
derhass dec

1
@NicolBolas 감사합니다, 훌륭한 답변입니다! 그래서 저는 아직 완전히 이해하지 못했고 "질문없이"만들고 싶습니다. 셰이더에서는 layout (location = 0) out vec4 outColor바인딩 된 항목 (대부분 FBO가 아닌 "화면")에 그릴 때 항상 지정 합니다. 따라서 기본적으로 glDrawBuffers를 사용하여 FBO (또는 다른 버퍼)를 바인딩하지 않고를 지정 location = 0하면 항상 화면에 올바르게 그릴까요?
AzP

9

GLSL_ES_3.10 링크 를 사용하는 OpenGLES 3.1에 대해 이것을 지정하고 싶습니다 .

§4.4.2

[조각 셰이더에] 단일 출력 만있는 경우 위치를 지정할 필요가 없습니다.이 경우 기본값은 0입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.