여러 셰이더 사용


53

나는 현재 OpenGL 쉐이더를 연구하고 있지만 무언가를 알아낼 수 없습니다 : 예를 들어 툰 쉐이더를 사용하여 렌더링 된 주전자와 같은 장면에서 매우 반사되는 표면을 사용하여 다른 쉐이더를 적용하는 방법 이 비디오와 같은 노이즈 기능

http://www.youtube.com/watch?v=1ogg4ZfdBqU

다른 하나는 장면에 블룸 쉐이더를 적용한 후 모션 블러 셰이더를 적용하는 것입니다. 버텍스 쉐이더 하나와 프래그먼트 쉐이더 하나만 가질 수있을 때 이러한 효과를 얻는 방법은 무엇입니까? 하나 이상의 셰이더 프로그램을 사용하는 것과 같은 트릭이 있습니까?


Re Nathan과 David의 좋은 대답입니다. 이것이 렌더 패스 또는 셰이더 패스 라는 용어를 보는 이유입니다 . 최종 이미지 / 프레임을 구성하는 데 필요한 여러 패스가 있습니다. GPU 처리가 병렬화되어 속도가 빨라지는 이유 중 하나는 프레임 당 여러 패스가 필요하기 때문입니다. Quake II 또는 Half Life 소프트웨어 렌더러로 돌아가서 전체 3D 그래픽 경험에 얼마나 많은 러브 셰이더 패스가 추가되는지를 상기하십시오.
엔지니어

답변:


59

간단한 대답은 각 드로우 콜 사이에서 변경하는 것입니다. 셰이더 설정, 주전자 그리기, 다른 셰이더 설정, 다른 주전자 그리기.

블러, 글로우 등과 같은 하나의 오브젝트에만 여러 셰이더를 적용해야하는 복잡한 작업에 적합합니다. 기본적으로 텍스처에 렌더링 된 모든 것이 있습니다. 그런 다음 다른 셰이더를 사용하는 동안 해당 텍스처가 적용된 전체 화면에 쿼드를 렌더링합니다.

예를 들어 글로우 효과를 렌더링하려면 먼저 일반 비 광택 장면을 렌더링 한 다음 텍스처에서 빛을 내기 위해 채색하려는 색상의 실루엣 만 렌더링 한 다음 블러 셰이더로 전환하고 비 광택 장면에 텍스처가 적용된 쿼드.

디퍼 드 셰이딩 ( Deferred shading) 이라는 또 다른 기술이있어 장면을 조명없이 렌더링하고 나중에 화면 공간에 적용 할 수 있습니다. 핵심 목표는 픽셀 당 조명 비용을 줄이는 것입니다.

일반적으로 화면에 표시되는 컬러 버퍼를 렌더링합니다. 디퍼 드 셰이딩을 사용하면 하나의 쉐이더 패스에 컬러 버퍼와 노멀 및 깊이 버퍼를 렌더링합니다 (노멀 및 높이 매핑과 같이 텍스처에 노말 벡터와 깊이를 저장할 수 있음).

즉, 모든 픽셀에 대해 가장 투명하지 않은 지오메트리 (눈에서 깊이 또는 거리)의 가장 가까운 부분의 위치와 색상을 알 수 있습니다. 이 때문에 렌더링하는 모든 객체의 보이는 각 픽셀 대신 화면의 각 픽셀에 조명을 적용 할 수 있습니다. 장면이 앞뒤 순서로 완벽하게 렌더링되지 않으면 일부 오브젝트가 다른 오브젝트 위에 그려집니다.

그림자의 경우 실제로는 빛의 관점에서 깊이 버퍼 만 렌더링 한 다음 해당 깊이 정보를 사용하여 빛이 비추는 곳을 해결하십시오. 이를 쉐도우 매핑 (Shadow Mapping)이라고합니다 (기하 도형의 실루엣을 만들고 돌출시키는 섀도우 볼륨이라는 또 다른 방법이 있지만 여전히 쉐이더를 사용하게됩니다).

최신 OpenGL (3.0+) 에서는 Renderbuffers Objects가 첨부 된 Framebuffer Object 를 사용합니다 . 렌더 버퍼는 텍스처처럼 취급 될 수 있기 때문입니다. 1 개의 셰이더 렌더를 여러 개의 다른 렌더 버퍼로 렌더링하는 것과 같은 작업을 수행 할 수 있습니다 (따라서 텍스처를 렌더 할 필요가없고 노멀을 선택한 다음 글로우 구성 요소).하지만 기본 연습은 여전히 ​​동일합니다.

또한 오버 헤드를 줄이기 위해 가능한 한 많은 쉐이더 스위치 수를 최소화하는 것이 바람직합니다. 따라서 일부 엔진은 동일한 재질로 모든 것을 그룹화하여 한 번에 모두 그릴 수 있습니다.


16

하나의 셰이더를 바인딩하고 해당 셰이더를 사용하여 모든 객체를 렌더링 한 다음 다음 셰이더를 바인딩하고 해당 셰이더를 사용하여 객체를 렌더링하는 등의 작업 만하면됩니다.

원하는만큼 셰이더 객체 (메모리에로드되고 컴파일 된 셰이더)를 가질 수 있습니다. 한 번에 하나만 바인딩 (활성화) 할 수 있습니다.


5
구현 측면에서 모든 프레임에서 glUseProgram (1) 및 glUseProgram (2)을 사용하여 쉐이더를 변경합니까? 성능이 얼마나 비싼가요?
ibrabeicker

4
비용이 들지 않습니다 (최근 GPU보다 최신 GPU에서는 저렴하지만). 그렇기 때문에 대부분의 사람들은 물체를 재료별로 정렬하여 같은 재료를 가진 모든 물체를 함께 렌더링합니다. 그러나 프레임 당 수십에서 수백 번까지 프로그램을 변경할 수는있을 것입니다.
Nathan Reed

9

한 장면에서 둘 이상의 쉐이더를 사용하는 것은 매우 간단합니다. 셰이더를 변경하고 값을 설정 한 다음 오브젝트를 렌더링합니다.

그러나 전환 셰이더는 비용이 많이들 수 있으므로 셰이더 전환은 최소한으로 유지해야합니다. 원하는 모든 효과를 얻는 동안이 영향을 줄이는 몇 가지 방법이 있습니다.

첫 번째 방법은 일반적으로 가장 바람직한 방법으로 모든 셰이더 기술에 대한 기능을 하나의 셰이더에 추가하고 동일한 셰이더로 각 객체를 다른 방식으로 렌더링하도록 설정 한 조건을 사용하는 것입니다. OpenGL 및 GLSL 셰이더에 대해서는 잘 모르지만 HLSL 셰이더 및 DirectX를 사용하면 "기술"로 그룹화 할 수 있으며 셰이더를 변경하는 대신 기술을 설정할 수 있습니다. 이를 통해 실제로 동일한 파일에 여러 개의 서로 다른 픽셀 및 버텍스 쉐이더를 가질 수 있습니다.

성능 영향을 줄이는 두 번째 방법은 셰이더를 설정하고 해당 셰이더를 사용하는 모든 객체를 렌더링 한 다음 반복하는 것입니다. 즉, 렌더링을 일괄 처리합니다.

동일한 오브젝트에 두 가지 다른 효과를 적용하려면 (예 : 툰 쉐이더를 적용한 다음 일부 조명 적용) 두 가지 방식으로 수행 할 수 있습니다. 첫 번째는 동일한 함수에서 여러 효과를 적용하는 셰이더를 작성하는 것입니다. 두 번째 방법은 각 셰이더로 모델을 한 번 렌더링하고 다른 혼합 옵션을 설정하여 결과를 혼합하는 것입니다. 그러나 이것은 훨씬 더 많은 작업이며 모든 상황에서 달성 할 수는 없습니다. 따라서 가장 좋은 방법은 모든 효과를 하나의 셰이더로 결합하는 것입니다.


7

내가 발견 한 또 다른 방법은 glsl 서브 루틴이라는 것을 통해하는 것입니다. 각 유형의 쉐이더는 하나의 함수에 정의되어 있으며 OpenGL 응용 프로그램에서는 현재 서브 루틴을 정의하고 버퍼의 정점을 그리며 서브 루틴을 변경하고 다른 버퍼를 렌더링


4
DX11 급 하드웨어 인 GL 4.x 가능 하드웨어가 필요합니다.
Nicol Bolas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.