Shader와 C++에서 RenderState를 혼용할 때 주의사항
Shader의 Pass 안에 설정해 놓은 RenderState는 Effect의 Pass에 의해 적용된다.
C++에서도 RenderState를 설정할 수 있으므로, 두 곳에서 RenderState를 작성할 때에는 주의해야 할 것이 있을 수 있다.

그런데, 주의 할 것은 셰이더 이펙트를 사용한다고 선언할 때, Flag를 주는데,
    Effect->Begin( &m_nNumPass, flags );
    /// 패스 그리기
    Effect->End();
일반적으로는 Begin()하기 전에 랜더스테이트를 기억해 두었다가, End()가 호출되면 랜더스테이트를 복구한다.
(Flag 설정에 따라 다르지만...)

예를 들어,

    | SolidEntities
    {
        ///C++에서는 랜더스테이트를 설정 하지 않음
        effect->Begin();      // 셰이더 안에서 AlphaTestEnable = true;
        /// 삼각형 그리기!!!
        effect->End();
    }
    | TransparentEntities

    {
        SetRenderState( ALHPABLENDENABLE, TRUE );
        effect->Begin();      // 셰이더 안에는 AlphaBlendEnable = false;로 설정
        /// 사각형 그리기!!!
        effect->End();
    }
이렇게 되면, 결과는 어떻게 될까?
1번째 프렘임의 마지막 랜더링 할 때, effect->End()가 호출된 후에, AlphaBlendEnable = true 로 복구가 되면서, 2번째 프레임의 SolidEntity들을 그릴 때에도 AlphaBlendEnable = true가 계속 적용되어서, 결국 원하지 않게, 전체 화면에 AlphaBlend가 적용된다.

결론으로는, 왠만하면, 섞어서 쓰지 말고, 한 쪽을 선택해서 사용하시라!!!

당연한 이야기이지만, 가끔은 이런 사소한 것 때문에 고생한다.. ㅎㅎ

by cagetu | 2009/11/05 22:38 | 개발 노트 | 트랙백 | 덧글(5)
트랙백 주소 : http://cagetu.egloos.com/tb/5114857
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 친절한티스 at 2009/11/06 13:40
ㅎㅎ 다른 방법으로는 StateBlock을 이용해 기본 RenderState를 정의해놓고 매 프레임 시작시에 적용해주는 방법도 있어요.
이렇게하면 렌더링중에 변경된 RenderState를 모두 복구 할수 있죠.
Commented by cagetu at 2009/11/06 20:49
예... 랜더스테이트를 왠만하면, C++에서가 아니라, 외부에서 설정을 할 수 있도록 하려고 하는데, 정리 중에 한번 꼬이니까 의외로 까다로와요.
셰이더에 몰빵하는 것도 괜찮을 것 같아요.. ^^

감사 감사!!
Commented by kjmgo at 2009/11/17 22:19
저의 경우에는 Multi Pass ( HLSL내에 패스를 여러개 두는 경우 )에서 각 Pass마다 설정이 다른 경우가 좀 문제가 되더군요.
문제라기 보다는 DX Debug Level을 높이면 엄청난 주의 메시지가....
Commented by cagetu at 2009/11/18 10:12
랜더스테이트 설정에 대한 정책은 항상 고민이 많군요. ㅎㅎ
Commented by kjmgo at 2009/11/18 12:35
다른 쉐이더들은 문제가 없었는데 Hair Shader의 경우 2 Pass로 해야 깔끔하게 빠져서 ( 다른데선 4 pass까지 쓰더라구요 )
HLSL 내에서 지원해보려고 하니 저런 문제가 생기더라구요.
아직도 완벽히 해결은 못했고 고민중입니다.

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >