프로그래밍 2016.10.23 18:07

 

volume fog - 파헤치기 - 기본 원리를 살펴보자

 

 

볼륨포그를 구현하려고 보니, 자료를 구하기가 너무 힘들었다

웬만한 것들은 이것저것 뒤져보면, 자료들이 좀 나오는데,

이것은 잘 나오지 않더란 말이지...

 

구현할때, DirectX9 쉐이더 프로그래밍 책을 참고하였다

(이 책은 참 도움이 된다 ㅎㅎ)

기본 개념을 잡는데는 도움이 된다.

하지만, 책이 오래전 출판된 것이라, 실제 구현소스 등은 지금과는 맞지 않는 부분이 많았다

 

그래서 혹시 찾는 사람들이 있지 않을까하여, 구현에 도움이 될만할

것들을 포스팅 해둔다

 

관심있으신 분들은 직접 구현해 보시라

이미 렌더타겟을 여러장 사용하고 있다면, 기본 구현은 큰 어려움은 없을 것이다

다만,,, 자잘한 작업은 드럽게 많으니, 각오는 해두시고! 크하하하

 

그런데, 구현중에 이것저것 테스트 해본바로는, 볼륨포그 자체는 좀 구닥다리 같다는 생각도 든다, 실제 게임에 사용할때는 볼륨포그 대신에, 안개 메쉬라든가, 이펙트 등으로 더 멋있게 만들수도 있을테니까, 

어쨋든 그리 사용도가 높지는 않을것 같다

 

 

 

 

볼륨포그는 모델을 깊이 버퍼에 렌더링함으로써, 

공간에 볼륨을 만들어 내는 렌더링 기법중의 하나이다

->이때 모델 자체를 실제화면에 렌더링하지는 않는다

->단지 볼륨깊이버퍼에 깊이값만을 기록해두는 것이다

(별도의 볼륨깊이버퍼 렌더타겟 텍스쳐 가 필요하다 )

->깊이버퍼 그림자를 그릴때와 같다

 

공간에 어떠한 볼륨값을 만들어 낸다는 의미로써는,

꼭 포그 역활이 아닌, 이를 이용한 다양한 렌더링 기법을 만들어 볼수도 있을듯 하다

 

어쨋든,

모델의 월드z 값을 깊이버퍼에 기록하고,

이 기록된 z값을 fog 연산을 이용하여, 화면컬러에 블렌딩 시켜주는 것이

볼륨포그의 핵심이다

카메라 시점에 가까울수록 z 값은 작고, 멀수록 z값이 커지니

이 z값을 볼륨값으로 이용하는 것이다

 

볼륨버퍼 렌더타겟 텍스쳐는 월드z값을 기록할수 있을정도로 큰,

D3DFMT_R32F 포맷을 이용한다

텍스쳐 생성에 관해서는 일반적인 것이니, 따로 설명하지 않겠다

 

 

posted by 비케이제이

댓글을 달아 주세요

  1.  Addr  Edit/Del  Reply 초짜

    그냥 그림자 할때 방식의 깊이 렌더 타겟과 모델의 월드 Z좌표만 있으면 되나요?

    2018.01.02 21:12 신고
  2.  Addr  Edit/Del  Reply Favicon of http://bkjcr.tistory.com BlogIcon 비케이제이

    음? 물론 그것만으로는 안됩니다, ㅎㅎ, 자잘한 작업이 무척많은 기법입니다,
    제 블러그의 프로그래밍 항목에서 volume fog 관련된 다른 글들도 읽어보시면, 좀더 디테일하게 파악하실수 있습니다

    2018.01.02 22:25 신고
    •  Addr  Edit/Del 초짜

      게임스타 게임스타 님의 볼륨 포그 글을 더 보고 기본적으로 큐브를 가지고 ccw와 cw가 된 두 가지 렌더타겟을 ccw - cw 해 줘서 이제 디퍼드 마지막에 모든 장면을 합쳐주는 작업에서 어떻게 합성해야 할지 감이 안 오네요

      2018.01.02 23:54 신고
  3.  Addr  Edit/Del  Reply 게임스타

    최종적으로 씬을 합성할때,볼륨텍스쳐를 가져와서, 포그연산으로 최종컬러와 합성시켜 주면 됩니다, 저의 경우에는 대략 ( 최종컬러 = lerp( 원컬러, 포그컬러, 증폭수치 ) 요런식으로 적용시켜 주었습니다만, 씬과 합성시켜 줄때는 여러가지 포그 연산으로 적용해 볼수 있으리라 생각됩니다,

    이해를 돕고자, 쉐이더 코드를 첨부합니다,

    저의 경우는 여러개의 볼륨포그를 사용할수 있도록 구성해 두었기에,
    Samp_Tex_VolumeDepth[i] 식으로 가져옵니다,
    포그색상값은 따로 변수를 만들어 넘겨주었구요,

    float fvd = tex2D( Samp_Tex_VolumeDepth[i], _uv ).r;
    if( fvd > 0 )
    {
    fVolumeDepth += (fvd * _vRTVolumeDepth3[i].x);
    Vcolor += (_vVolumeColor[i] * fvd) * _vVolumeColor[i].a;
    }


    // 값을 크게 변화, 5 -> 25, 0.2 -> 0.04
    //진한 부분은 더욱 진하게, 옅은 부분은 더욱 옅게 해주어야, 포그 느낌이 난다
    float fV = sqrt( fVolumeDepth );
    if( fV > 1 )
    fV = 1;

    vRet = lerp( vRet.rgb, Vcolor.rgb, fV );




    2018.01.03 15:13 신고
  4.  Addr  Edit/Del  Reply Favicon of http://bkjcr.tistory.com BlogIcon 비케이제이

    저의 경우에는 디퍼드가 아니라, 포워드 렌더링이지만, 기본개념은 같다고 생각됩니다,
    좀더 디테일하게 설명드리자면( 이해를 돕고자) , 디퓨즈+노말 등의 모든 연산이 결합된 풀씬을 하나의 텍스쳐로 저장해두고, 이 텍스쳐로 다시 포스트이펙트 처리 등을 추가해서 최종씬을 만들어 냈습니다,
    (풀씬 텍스쳐 + 포스트 이펙트 -> 최종화면)
    위의 코드는 풀씬텍스쳐를 포스트이펙트 처리와 결합할때 삽입된 코드입니다,

    2018.01.03 15:21 신고
    •  Addr  Edit/Del 초짜

      정말 게임스타 게임스타님 말대로 손이 많이 가는 기능이네요. 위 글 처럼 안개가 네모나면서 모서리가 옅은 거 까진 됐는데 이제 안에 들어갔을 때가 문제가 되네요. 나머지 게임스타 게임스타님 글 보고 해결하겠습니다. 친절하게 답해주셔서 감사합니다!

      2018.01.03 23:28 신고
  5.  Addr  Edit/Del  Reply Favicon of http://bkjcr.tistory.com BlogIcon 비케이제이

    오옷! 정말 이것저것 손이 많이 갑니다, ㅎㅎ, 벌써 출력하셨나요, (빠르시네요, 물어보신게 어제같은데;;; ), 사실 볼륨포그는 별로 인기가 없는 기법이라 생각하고 있었는데, 관심을 가지고, 직접 구현하시다니, 조금 감동했습니다 ^^, 화이팅 입니다!!

    2018.01.04 00:23 신고