2012-09-29 5 views
1

간소화 된 지연 음영을 구현했습니다 (포인트 라이트의 경계를 계산하지 않음). g 버퍼를 채운 후 계산 조명에 전체 화면 쿼드를 사용합니다. 여러 조명을 처리하는 두 번째 단계에서 혼합 (glBlendFunc (GL_ONE, GL_ONE))을 사용합니다. 올바른 결과를 얻으려면 glClearColor의 rgb 값을 0으로 설정해야합니다. g- 버퍼를 채울 때 glClearColor는 어떤 색이라도 가능합니다 (일부 색은 최종 이미지에서 배경색 만 변경할 수 있음). 이제 최종 이미지에서 배경색을 어떻게 설정해야하는지 궁금합니다. 그것은 잘 작동하지만지연된 음영 및 배경색

if((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0)) 
{ 
    fragColor = vec4(1, 0, 0, 1); // here we can set a background color 
} 
else 
{ 
    fragColor = computeLighting(worldPos, normal, diffM, specM, specMS); 
} 

경우 문이 발생할 수 있습니다 :이 을 수행하는 한 가지 방법은 g-버퍼를 채우는 동안 glClearColor (0, 0, 0)를 사용하고 프래그먼트 쉐이더에서 경우 문을 follwing을 사용하는 것입니다 약간의 성능 저하. 이것이 배경색을 으로 설정하는 유일한 방법입니까?

답변

3

문제가 무엇인지 알 수 있을지 모르지만 여기에는 많은 가정이 있습니다.

이런 식으로 생각 하시나요? :

  • 지우기 원하는 배경색으로 당신으로 G-buffer에 확산 첨부 파일 (! Howevery .. 당신이 그런 법선이 값에 다른 질감을 취소 할 그나마)
  • 당신으로 G-buffer, 아무것도하지 충전 후 지오메트리에 포함 된 도형은 여전히 ​​배경색을 유지해야합니다 (확산 첨부 파일에서)
  • 조각이 정상적으로 정의되지 않은 경우 마지막 단계에서 하드 코딩 된 색상을 수동으로 작성합니다.

난 당신이하고있는 렌더러 가정 다음 당신은 전체 화면 쿼드 첨가제 혼합 렌더링 각 빛

  • 채우기으로 G-buffer (확산, 법선, 여러 첨부 파일이 FBO의 깊이 등)
  • 별도의 FBO (light accumulation buffer)에 연결합니다.
  • 마지막으로 gbuffer의 확산 첨부 파일을 빛 축적 버퍼와 결합하여 화면에 최종 결과를 렌더링합니다.

쉐이더가 이와 같이 배경색을 작성해야하는 이유는 없습니다. 실제로 백그라운드에있는 것을 렌더링하고 항상 0 값으로 gbuffer를 지 웁니다. 마지막 단계에서 확산과 빛을 결합 할 때 문제가 발생할 수 있으므로 스텐실 접근법을 더 자세히 설명하면 더 간단 할 것입니다. 개인적으로 확산 색상의 알파 채널에 머티리얼 인덱스를 저장 한 다음 텍스처의 모든 머티리얼 속성을 업로드합니다.

내 자료에는 두 개의 스칼라가 있습니다 (그리고 더 ...)

  • AmbientWeight
  • 경량

확산 버퍼와 라이트 버퍼 (크게 간소화)를 조합 :

FinalColor = Diffuse * AmbientWeight + Diffuse * Light * LightWeight 

과 배경 물질 0을 사용하는 경우 AmbientWeight = 1 및 LightWeight = 0 인 경우 FinalColor는 항상 확산 버퍼의 원래 값이됩니다.

많은 간단한 이연 렌더러는 단지 최종 결과 이런 식으로 계산 :

FinalColor = Diffuse * Light (조각 빛 버퍼에서 확산 버퍼 * 조각에서) 귀하의 경우에는

을, 물론이 의지는 사라질 당신의 배경 색상의 원인 그 파편들은 절대로 불이 들어오지 않을 것입니다. 당신은 몇 가지 빠른 결과를 위해 AmbientWeight로 확산 버퍼에 알파 채널을 사용할 수 있습니다 (Diffuse * 0은 항상 결과입니다).

FinalColor = Diffuse * Diffuse.a + Diffuse * Light 

는 성능에 관해서 : 이것은 정말 열심히 예측된다

. 쉐이더의 마지막 빛 계산을 건너 뛰는 것은 당신에게 뭔가를 줄 수도 있지만,이 단계에 도달하기 전에 이미 모든으로 G-buffer 읽기 수행 포장을 풀고있다. 셰이더가 반환하는 것과 상관없이 블렌드 작업을 통해 전체 라이트 버퍼에 영향을 미치게되고 라이트 당 전체 버퍼를 읽게됩니다. 일반 버퍼의 모든 구성 요소가 0인지 확인하면 형상이없는 영역에 대해서만 트리거됩니다. 조명 당 전체 화면 쿼드를 사용하는 경우 병목 현상이 많이 발생합니다. 당신의 점 광원이 조각에 도달하고 약간의 도움이 될 다른 작업을 수행하기 전에 폐기 할 수없는 경우 위치 버퍼를 읽고 (또는 깊이 버퍼의 위치를 ​​재구성)에 의해 시작

후 결정합니다. 작은 조명의 경우 조각 당 gbuffer에서 모든 것을 읽지 않게됩니다. 그것은 당신의 gbuffer가 얼마나 뚱뚱한 지, 렌더링하는 것, 조명의 크기가 얼마나 많은지, 렌더링하는 조명의 개수에 달려 있습니다.

동적 분기는 성능을 죽일 수 있지만, 때로는 "차악"이 될 수 있습니다. 가능한 한 많이 피합니다. 추가

:

은 "배경색"나는 개인적으로 스카이 박스 또는 유사한와 배경을 채우기 위해 스텐실 버퍼를 사용하여 제공

. (깊이 테스트 또는 깊이 쓰기없이) 그렇게 만 배경 조각이 영향을받는 역 마스크 배경을 렌더링 할 때, 당신의 확산 버퍼를 작성할 때 스텐실 마스크를 구축 할 수 있습니다. 제 전체 장면이 도형으로 덮여 있다면 조각이 없습니다. 이것은 gbuffer와 동일한 depth 어태치먼트를 사용하는 세 번째 FBO에 최종 결과를 쓰고 있다고 가정합니다. (Depth24 + Stencil8 버퍼)

대신 (혼합)와 쿼드 전체 화면을 사용하여 각각의 광 드로잉, 또한 광 정보를 이용하여 어레이 UBOs 보낼 수있다. 그런 다음 모든 점 광원을 하나의 전체 화면 쿼드로 그립니다. 결국 같은 양의 가벼운 계산을하게되지만 읽기 쓰기 양은 항상 일정합니다. http://www.cse.chalmers.se/~olaolss/main_frame.php?contents=publication&id=tiled_shading (당신은 한 번만으로 G-buffer에서 읽을 만 빛을 통과에 대해 하나 개의 단편을 쓰기)

:

또한 잠재적 다음 단계로 관심을 바둑판 식으로 배열 Deferreed 음영을 찾을 수 있습니다

(UBOs은 여전히 ​​비록 크기 제한이)

종이 : http://www.cse.chalmers.se/~uffe/tiled_shading_preprint.pdf