이제 어느 정도 렌더러 모습도 갖춰가기 시작해서 좀 있어보이게 하기 위해 셰이더쪽으로 이것저것 시도 해보고 있습니다. 범프맵도 적용해봤고, 그 다음 무엇을 해보까 하다가 오즈라엘님의 블로그를 보다 SSAO를 보고 와~ 나도 해보자 해서 이것저것 시도 해보려고 했는데, 그냥은 안되겠더군요. 그래서 그냥 으악~ 하고...

차근 차근 시작하자 해서 일단 지연 렌더링 ( Deferred Rendering, Deferred Shading )부터 구현해보자 해서 시작해봤습니다. 그러기 위해서 일단 MRT ( Multiple RenderTargets ) 를 구현!!

LPDIRECT3DSURFACE9 m_surfPos, m_surfNorm, m_surfDiff; // 서페이스
LPDIRECT3DTEXTURE9 m_texPos, m_texNorm, m_texDiff; // 텍스쳐

// MRT 갯수 체크
assert( m_D3DCaps.NumSimultaneousRTs > 3 );

// 텍스쳐 생성
m_pD3DDevice->CreateTexture( 1024, 768, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F,
							D3DPOOL_DEFAULT, &m_texDiff, NULL );
m_pD3DDevice->CreateTexture( 1024, 768, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F,
							D3DPOOL_DEFAULT, &m_texNorm, NULL );
m_pD3DDevice->CreateTexture( 1024, 768, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F,
							D3DPOOL_DEFAULT, &m_texPos, NULL );

// 텍스쳐 - 서페이스 연결
m_texDiff->GetSurfaceLevel( 0, &m_surfDiff );
m_texNorm->GetSurfaceLevel( 0, &m_surfNorm );
m_texPos->GetSurfaceLevel( 0, &m_surfPos );

// 셰이더에 텍스쳐 등록

// MRT 지정
m_pD3DDevice->SetRenderTarget( 0, m_surfDiff );
m_pD3DDevice->SetRenderTarget( 1, m_surfNorm );
m_pD3DDevice->SetRenderTarget( 2, m_surfPos );

// 지연 렌더링 ㄱㄱㅆ~

// 렌더링 후 기존 백버퍼로 복구
m_pD3DDevice->SetRenderTarget( 0, m_surfBackBuffer );
m_pD3DDevice->SetRenderTarget( 1, NULL );
m_pD3DDevice->SetRenderTarget( 2, NULL );

대략 위와 같은 분위기로 구현. 어쨋든 출력까지는 성공 했습니다.



다만, 기존 렌더러에 억지로 끼어넣는 바람에 화면이 겹치(?)는 현상이 좀 발생하고 있습니다. 이것은 차근 차근 수정해나가야 할 듯 합니다. 수정이 완료되면, 다음엔 Pre-Lighting 도 도전!!!!

  1. BlogIcon ohyecloudy 2010.08.20 21:57 신고

    rt0에 텍스쳐 색상이 나와야 하는데, 그냥 하얀색으로만 나오네요.
    말씀하신대로 기존 렌더러에 끼워 넣는 과정에서 생긴 문제 같습니다.

    rt2 색상을 보니 view space에서 좌표값을 렌더링한 것 같은데, 맞나요?
    screen space 좌표와 depth 그리고 invProj 매트릭스만 있음 view space에서의 좌표를 알 수 있는데,
    x, y값을 렌더링하는 것은 낭비입니다. 정밀도를 생각하면 depth만 쓰는 게 좋습니다.
    참고로 gdc 발표자료를 보니 스타 2 실내 장면은 8 bit에 뎁스를 저장했습니다. 그 정도로 좁은 씬이면 가능하죠.

    • BlogIcon 친절한티스 2010.08.21 00:58 신고

      우와... 좋은 정보 감사합니다. 계속 이런저런 삽질을 해가면서 조금씩 익혀 나가고 있습니다 ^-^;

  2. BlogIcon 핫소스 2010.08.21 04:59

    와........ 감탄사만 나옵니다... ㅎㄷㄷ;
    엔진프로그래머 역시 대단한듯..
    반할것같습니다!!<퍽
    ㅎㅎ 나날이 엔진이 멋져지네요 ㅎ

  3. BlogIcon 구차니 2010.08.21 19:39 신고

    으아 전 언제 이런경지에 이르려나요 ㅠ.ㅠ

  4. BlogIcon ozlael 2010.08.23 11:26

    테스트라 사용 하신 건지 모르겠지만 MRT의 포맷을 ARGB16F(64bit)로 사용하시면 급격한 성능 하락을 불러오시게 됩니다 >ㅈ< 노말은 킬존에서 사용한 것 처럼 R16FG16F로 x,y컴포넌트만 저장하는 방식으로 사용하셔요
    어서 어서 지연 랜더의 세계로 넘어오세요 동지~!

  5. BlogIcon 구차니 2010.08.25 23:26 신고

    음.. 그런데 지연 (Defer) 라는게 어떤걸 의미하는거죠? -ㅁ-

    • BlogIcon 친절한티스 2010.08.26 08:56 신고

      일반적인 렌더는 그냥 그린걸 바로 백버퍼에 그려내잖아요. 그리고 모든 오브젝트를 그리면 화면에 출력. 식인데... 위 방식은 MRT라고 해서 3개의 다른 서페이스에 각각의 정보를 먼저 그려내요.

      노말, 뎁스, 디퓨즈 식으로요. 그 다음 이 정보를 토대로 광원을 입히고 최종 결과물을 출력 하는거죠. 바로 오브젝트를 하나하나 그려내는게 아니라 정보를 취합하고 나서 그리기 때문에 지연( Defeered )라는 말을 쓰는것 같아요.

      일단 위의 장점은 다수의 광원을 처리할 때 비약적으로 속도가 빨라진다는거죠. 기존에는 광원을 입힐때 오브젝트 하나당 광원 처리를 해줘야 해서 최악의 경우 오브젝트 갯수 * 광원 갯수 처리가 되는데 지연 렌더링을 이용하면 오브젝트 갯수 + 광원 갯수 처리가 되죠.

    • BlogIcon 구차니 2010.08.26 09:03 신고

      +와 * 차이라니 엄청 난 차이네요.
      음.. 대신 메모리를 많이 먹을려나요? ㅋ

    • BlogIcon 친절한티스 2010.08.26 09:59 신고

      대신 제약도 만만치 않아요. MRT 미지원 하드웨어에서는 약간 꼼수를 써야 하고 또 지오메트리 정보를 셰이더에 텍스쳐로 넘기기 때문에 추가 텍스쳐 사용에도 제약이 생기고요.

      그래도 최근에 이것저것 많이 개량된 방식이 나오고 있어서 이거 완료하면 계속 공부해야죠~

  6. BlogIcon 오즈라엘 2010.08.27 15:23

    특히 라데온 1xxx 시리즈요~~ ㅠㅡ 개같아요 ㅋ

  7. BlogIcon 오즈라엘 2010.08.30 02:50

    답변 드린것 중 빠진게 있네요. z/w로 저장 하는 법 말고 z/far로 리니어 하게 저장해서 쓸 수 있는 방법도 있어요. http://ozlael.egloos.com/3226675

  8. 아해누리 2013.02.03 01:33

    안녕하세요~, 지연 렌더링을 공부중인 학생입니다 ^^.
    티스님 글을 통해서 좋은 배움 얻어 가고 있습니다!.
    다만, 어디에도 뚜렷하게 여쭤볼 곳이 없어서 질문 올려봅니다.
    MRT의 경우는 안티 알리아싱이 안되는 단점이 있는데요.
    위 포스트의 사진을 보면.. 딱히 계단 현상이 보이지 않아보이는데, 이미 안티알리아싱을 후처리 하신건가요~?

    • BlogIcon 친절한티스 2013.02.04 02:19 신고

      아뇨. 위 동영상에서는 따로 AA를 적용하지 않았습니다.
      요즘은 FXAA 같은 좋은 후처리 AA 방법이 있으니 이를 이용하면 되지요.

    • 아해누리 2013.02.06 05:48

      아하. 그렇군요! 답변 감사드립니다^^

+ Recent posts