OpenGL 셰이더에 대한 명시 적 및 자동 속성 위치 바인딩


82

OpenGL 셰이더 프로그램의 속성 위치를 설정할 때 다음 두 가지 옵션이 있습니다.

속성 위치를 명시 적으로 정의하기 위해 링크하기 전에 glBindAttribLocation () .

또는

링크 후 glGetAttribLocation () 을 사용하여 자동으로 할당 된 속성 위치를 얻습니다.

다른 하나를 사용하는 유틸리티는 무엇입니까?

그리고 실제로 어떤 것이 선호됩니까?


6
나는 glBindAttribLocation리눅스에서 잘 작동하는 그래픽 엔진에서 사용 하는 것을 귀찮게하지 않았습니다 . 나는 창에 이식하면 정점으로 내 법선을 사용했다 - 내가 명시 적으로 통해 내 쉐이더에서 그것을 변수의 순서를 이야기했다 glBindAttribLocation... 작업에 그걸 얻기 위해
자렛

답변:


93

명시적인 위치 정의 를 선호하는 한 가지 좋은 이유를 알고 있습니다.

Vertex Array Objects 에 지오메트리 데이터를 보유하고 있다고 생각하십시오 . 주어진 객체에 대해 인덱스가 다음과 같은 방식으로 VAO를 만듭니다.

  • 인덱스 0 : 위치,
  • 인덱스 1 : 법선,
  • 인덱스 2 : texcoords

이제 두 개의 다른 셰이더를 사용 하여 하나의 개체를 그리려고한다고 가정합니다 . 한 셰이더에는 위치 및 일반 데이터 가 입력으로 필요하고 다른 셰이더는 위치 및 텍스처 좌표가 필요 합니다.

이러한 셰이더를 컴파일하면 첫 번째 셰이더는 속성 인덱스 0과 법선 1에 위치를 예상 할 것입니다. 다른 셰이더는 0에 위치를 예상하지만 텍스처 좌표는 1에 있어야합니다.

https://www.opengl.org/wiki/Vertex_Shader 인용 :

자동 할당

앞의 두 방법 중 어느 것도 속성 색인에 입력을 할당하지 않으면 프로그램이 링크 될 때 OpenGL에 의해 색인이 자동으로 할당됩니다. 할당 된 인덱스는 완전히 임의적이며 똑같은 버텍스 셰이더 코드를 사용하더라도 연결된 프로그램마다 다를 수 있습니다.

, 두 셰이더에서 VAO를 사용할 수 없습니다. 예를 들어 개체 당 하나의 VAO를 갖는 대신 최악의 경우 셰이더 당 개체 당 별도의 VAO가 필요합니다 .

셰이더가를 통해 고유 한 속성 번호 지정 규칙을 사용하도록 강제하면 glBindAttribLocation이 문제를 쉽게 해결할 수 있습니다. 필요한 것은 속성과 해당 ID 간의 일관된 관계를 유지하고 링크 할 때 셰이더가 해당 규칙을 사용하도록하는 것입니다.

(별도의 VAO를 사용하지 않는 경우 큰 문제는 아니지만 코드를 더 명확하게 만들 수 있습니다.)


BTW :

OpenGL 셰이더 프로그램의 속성 위치를 설정할 때 두 가지 옵션이 있습니다.

OpenGL / GLSL 3.3에는 세 번째 옵션이 있습니다 . 셰이더 코드 에서 직접 위치를 지정합니다 . 다음과 같이 보입니다.

layout(location=0) in vec4 position;

그러나 이것은 GLSL ES 셰이더 언어에는 없습니다.


1
나는 요점을 보지 못한다. VAO는 매우 가볍고 일반적으로 각 프레임에 대해 다시 만듭니다. 귀하의 경우에는 각 셰이더를 호출하기 전에 다른 VAO를 만들 것입니다.
PierreBdR

1
물론 가능합니다. 잘 작동 할 것입니다. 여기서는 규칙에 대해서만 논의합니다. :)
Kos

4
세 번째 옵션은 실제로 GLES2.0에서 사용할 수 있지만 형식은 약간 다릅니다. layout (location = 0) attribute vec4 position; 참고 당신은 또한 당신의 GLSL 파일의 상단이 필요합니다 것을 : #extension의 GL_EXT_separate_shader_objects을 : 가능
개빈 맥클레인

35
"VAO는 정말 가볍고 일반적으로 각 프레임에 대해 다시 생성합니다. 귀하의 경우에는 각 셰이더를 호출하기 전에 다른 VAO를 생성 할 것입니다. 그렇지 않습니까?" -아니오, 일반적으로 이것을하지 않을 것입니다. 이것은 결국 VAO의 전체 목적을 완전히 무효화하기 때문입니다. 그렇다면 왜 VAO를 사용합니까?
Christian Rau 2013 년

2
메모입니다. 지오메트리 데이터를 VAO에 보관하지 않습니다. 그것은 VBO에있을 것입니다. VAO에는 데이터 저장소가 없습니다.
평균 조

20

여기서 또 다른 대답은 glGetAttribLocation이 호출자에게 데이터를 반환한다는 것입니다. 이는 암시 적으로 파이프 라인 플러시가 필요함을 의미합니다. 프로그램을 컴파일 한 직후에 호출하면 본질적으로 비동기 컴파일이 동 기적으로 발생하도록 강제하는 것입니다.



감사합니다. 이것은 매우 중요한 고려 사항입니다.
Jing

1
대부분의 상황에서 glGetUniformLocation어쨌든 전화를해야한다는 것이 제 이해입니다 . 이 특별한 고려 사항이 여전히 관련이 있습니까?
Mike Weir 2016 년

@MikeWeir GL 4.3부터 명시 적으로 균일 한 위치를 설정할 수 있습니다 .
Ruslan

1
@Ruslan 그들은 OpenGL ES를 사용하고 있습니다.
Mike Weir

9

세 번째 옵션 인 layout(location=0) in vec4 position;셰이더 코드는 이제 OpenGL ES 3.0 / GLSL 300 es에서 사용할 수 있습니다. 하지만 버텍스 셰이더 입력 변수에만 해당됩니다.


7
그들은 힌트로 (그렇지 않으면 완벽 3.0 이상 comformant하면서 나는 그것을 얻을로), 인텔 카드 : 역겨운되는,이 기능을 지원하지 않을 수 있습니다
mlvljr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.