HDR
여기에서는 HDR의 간략한 개념과 PostEffect를 구현하는 방법에 대해서 이야기합니다.
HDR의 구현에 대해서는 자세하게 적지 않습니다.
HDR
Hight Dinamic Range....
빛의 밝기를 R8G8B8A8로 표현하려고 하다보면.. 8비트 컬러값으로 부족하다.
밝기의 단계가..256단계라니... 쉣!
그래서 DX9로 넘어오면서 R16G16B16A16 이라는 엄청난 포맷을 내놓았다고...
이제는 16비트 컬러값으로 밝기를 표현할 수 있으니.. 실로 엄청난 발전이라 할 수 있겠다.
HDR은 위와 같은 발전된 파일 포맷을 이용하여, 빛을 좀 더 풍부하게.. 그리고 좀 더 현실적으로 표현하는 방법이라고 정의 하는것이 맞을 것 같다.
HDR의 구현은 간단하다.
화면 전체의 평균 밝기를 계산하고
밝은 부분은 따로 때내서( 이때, 평균 밝기를 사용 ).... 가우시안 블러를 먹인 후, 원본 이미지와 더해주면 된다.
( 역시, 말은 쉽다 ㅎㅎ )
In Gamebryo
알아야 하는 것들..
- Shader 사용 방법
- Mesh에 Shader 적용하는 방법
- NiScreenFillingRenderViewImpl 의 소개
- Shader의 변수 설정 : float, texture
- Render Target의 관리
Shader 사용 방법
간단하다... NiSample을 사용한 Shader 등록은 정말 간단하다.
혹시, NiSample을 이용하지 않았다면.. ShaderLib 샘플에서 제시한 방법을 사용하도록 한다.
bool HDRSample::RegisterShaderParsers() |
Mesh에 Shader 적용하는 방법
Gamebryo 2.5에서는 Shader가 Material로 통합되어있다. 정확하게 몇 버전 부터 그래왔는 지는 잘 모르겠다.
다음은 우리가 .fx 파일에 정의해둔 Material을 받아오는 방법이다. NiMaterial* pDownScale4x4Material = NiSingleShaderMaterial::Create("HDRRenderStep_DownScale4x4");
다음은 RenderObject( 일반적으로 NiMesh )에 Material을 적용하는 방법이다. kRenderObject.ApplyAndSetActiveMaterial(pDownScale4x4Material); |
NiScreenFillingRenderViewImpl
몇 일전에 Shader를 Post Effect를 적용하기 위해서...
2DRenderView를 만드들고 RenderView을 가득채울 수 있는 NiMeshScreenElements를 만든적이 있다.
아~!!!! 삽질이여...
NiScreenFillingRenderViewImpl 는 PostEffect에서 딱 사용하기 좋은
내가 위에서 했던 삽질을 한방에 해결해주는 RenderView이다. |
Shader의 변수 설정 : float, texture
변수 설정
NiShaderFactory::UpdateGlobalShaderConstant( "gfBrightPassThreshold", sizeof(float), &f);
float, matrix, color, float array... 등을 넘기는 함수는 형태가 동일하다 ^^;
텍스쳐 설정 if (pkShaderMap0) NIASSERT(pkPSVSShaderMap0);
그냥 TexturingProperty에 SetShaderMap이라는 함수를 호출해 주기만 하면.. Shader로 Texture가 넘어가도록 되어있다.
SetShaderMap 함수의 첫 번째 인자가 Shader에 정의해둔 Shader Index와 일치해야한다.
다음은 HDRRenderStep.fx 의 내용중 일부이다.
|
Render Target 관리
Render Step의 Render Target 설정
m_spFrame->GetRenderStepByName(m_kMainRenderStepName)-> m_spHDREffect->SetOutputRenderTargetGroup(
// MainRenderStep의 출력을 HDREffect의 입력으로 넣어주고.. // HDREffectStep 의 출력은 DefaultRenderTargetGroup 로 맞춰준다.
GetInputRenderTargetGroup은 원래는 제공하지 않는 함수다.. 멤버 변수로 화면 크기와 같은 Texture와 그의 RenderTargetGroup을 만들어 놓은 것이다.
|
각 HDR 단계도 위와 같이 RenderTarget을 공유하도록 한다.
타겟으로 사용될 하나의 Texture를 만들고, 여기서 RenderTarget을 만들어 내낸다.
m_spTex = NiRenderedTexture::Create(uiWidth, uiHeight, m_pkD3DRenderer, kPrefs ); spRenderTG = NiRenderTargetGroup::Create( kBuffer.m_spTex->GetBuffer(), m_pkD3DRenderer, true, true) );
m_spTex를 누군가의 입력으로 사용하는 방법은 간단하다...
spMesh 에 Base Texture 혹은 Shader Texture로 설정해주기만하면 된다. ( Shader 변수 설정을 보면 된다 )
샘플에서는 HDR 각 단계가 RenderClick을 상속 받아서 만들어졌다.
아직도 RenderClick으로 구분하는 것과... RenderView에 RenderObject를 차례대로 넣어주는 것의 차이를 정확하게는 이해할 수 없지만.. 뭔가 어렴풋하게는 좋은것 같다.
|
위에서 한 번 언급한적 있지만.. RenderTargetGroup은 DefaultRenderTargetGroup 이외에는 존재하지 않는다.
우리가 사용할 RenderTargetGroup을 만들어서 RenderStep과 RenderClick 사이에 입력과 출력으로 잘 끼워넣어야한다.
[출처] [Sample] HDR |작성자 프라이드
'Gamebryo > Shader' 카테고리의 다른 글
알파 텍스쳐 블렌딩 공식 (0) | 2011.07.22 |
---|---|
[펌] Soft Particle (Depth bias blend) (0) | 2011.06.15 |
쉐이더 (0) | 2011.04.04 |
겜브리오 쉐이더 제작시 주의사항 (0) | 2011.04.04 |
Using Fx Shader In GameBryo (0) | 2011.03.17 |