셰이더 유니폼을 업데이트하는 가장 좋은 방법은 무엇입니까?


10

셰이더의 행렬을 최신 상태로 유지하는 데 가장 많이 사용되는 방법은 무엇이며 그 이유는 무엇입니까?

예를 들어, 현재 ShaderGLSL 쉐이더 프로그램 및 유니폼에 핸들을 저장 하는 클래스가 있습니다. 카메라를 움직일 때마다 새 뷰 매트릭스를 쉐이더에 전달해야합니다. 그러면 모든 다른 월드 오브젝트는 모델 매트릭스를 쉐이더에 전달해야합니다.

이 쉐이더 오브젝트에 액세스하지 않고는 아무것도 할 수 없으므로 심각하게 제한됩니다.

ShaderManager모든 활성 셰이더를 보유 하는 단일 클래스를 만드는 것을 생각했습니다 . 그런 다음 어디에서나 액세스 할 수 있으며 월드 오브젝트는 셰이더가 어떤 활성인지 알 필요가 ShaderManager없으며 원하는 매트릭스 를 알려줘야 하지만 이것이 최선의 방법인지 확실하지 않으며 아마도 몇 가지 문제가있을 것입니다. 이 접근 방식을 통해 발생합니다.


렌더링 할 때 데이터를 셰이더에 전달하지 않겠습니까?
Nick Caplinger 2016 년

그게 내가 의도 한 것이지만 어떻게? 하나의 객체가 셰이더를 생성하는 경우 월드 객체는 해당 셰이더의 존재에 대해 어떻게 알고 필요한 매트릭스를 전달해야합니까?
Lerp

답변:


11

사용하여 균일 한 버퍼 (즉 일정한 버퍼 D3D의 용어에서 참조).

모든 셰이더가 이러한 각 버퍼의 레이아웃과 바인딩 포인트에 동의하는 한 업데이트는 산들 바람이됩니다. 모델은 쉐이더에 대해 전혀 알 필요가 없습니다. 상수 버퍼에서 모델 뷰 행렬 만 업데이트하면 렌더링 파이프 라인에서 자동으로 사용합니다.

최소한 두 가지 버퍼가 있어야한다고 주장합니다. 첫 번째는 투영 행렬, 카메라 행렬, 연결된 카메라 투영 행렬, 뷰포트 정보, 절두체 세부 정보 및 행렬 역수를 저장해야합니다. 이 버퍼는 장면 당 한 번만 업데이트하면됩니다.

그런 다음 각 모델에 모델 뷰 행렬, 일반 행렬, 역수 및 재료 특성을 저장하는 다른 버퍼를 제공하십시오. 이것은 각 모델에 대해 한 번 업데이트되며 다른 업데이트 단계에서 수행 할 수 있습니다 (해당하는 경우). 여러 객체간에 재료를 공유 할 수있는 경우 재료 정보를 세 번째 재료 별 버퍼로 이동할 수 있습니다.

포워드 셰이딩 설정에서는 모든 라이트를 다른 버퍼에 넣는 것이 의미가 있으며, 디퍼 드 셰이딩의 경우 라이트 패스에 대한 라이트 별 버퍼를 사용하는 것이 좋습니다. 지오메트리 패스).

균일 한 버퍼를 사용하려면 (3.1 또는 확장, 일부는 오래되었지만 아직 서비스중인 랩톱을 제외하고는 오늘날 충분히 일반적) GL을 적당히 최신 버전의 GL이 필요하며 최신 버전이 필요합니다. 쉐이더 코드 내부에서 특정 바인딩 위치에 균일 한 버퍼를 바인딩 할 수 있음 (4.2; 여전히 드물지만 더 나아지고 있음) 그렇지 않으면 CPU 측 코드에서 더 많은 작업을 수행하여 설정해야합니다 (CPU 코드가 올바른 바인딩을 알아야 함) 어쨌든 그것은 심각한 문제보다 API 냄새가 더 큽니다). OpenGL | ES는 불행히도 가장 인기있는 모바일 플랫폼에서 여전히 지원되지 않는 3.0까지 균일 한 버퍼를 추가하지 않았습니다.

버퍼가 옵션이 아닌 경우 활성 셰이더의 인덱스 위치를 저장하기위한 전역 위치가 필요합니다. 당신은 사용할 수 있습니다 glGetUniformLocation(같은 잘 알려진 이름에 대한 인덱스 찾기 위해 쉐이더를로드 한 후 ModelViewMatrix다음이 인덱스를 저장하거나 등). 렌더는 래퍼 함수에 MODEL_VIEW전달 된 것과 같은 열거 형 값을 매핑 SetUniform하여 바운드 셰이더를보고 인덱스를 찾은 다음 glUniform올바르게 호출 할 수 있습니다. 모든 유니폼을 멋지게 정리하면 개별 유니폼을 개별적으로 설정 해야하는 것 이외의 버퍼에서 클라이언트 코드 사용이 크게 변경되지는 않습니다.

GLSL 인터페이스 블록균일 버퍼 객체를 참조하십시오 .


나는 그들이 내장 된 방법이라는 것을 알았습니다. 감사!
Lerp

4

가장 간단한 방법은 셰이더간에 균일 한 이름을 표준화하고 그리기 직전에 모든 데이터를 보내는 것입니다. 오버 헤드는 제정신이 아니지만 나중에 덜 업데이트 된 유니폼을 보내지 않도록 나중에 최적화 할 수 있습니다.

게임에서이 작업을 수행하는 방법은 추상 Material클래스 가 있다는 것 입니다. 머티리얼은 게임과 쉐이더 사이의 다리 역할을합니다. 각각 Material에는 Shader텍스처를 포함하여 설정할 수있는 다양한 속성이 있습니다. 객체를 그릴 때가 Material바인딩됩니다. 이 Bind메서드에는 GraphicsState현재의 모든 그래픽 상태 행렬, 라이트 등이 포함 된 매개 변수가 있습니다.이 Bind메서드는에서 필요한 모든 것을 사용하여 셰이더와 텍스처를 바인딩하고 모든 유니폼을 설정합니다 GraphicsState.

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