2009년 06월 26일
[3D][DirectX] 물에 잠기는 알파오브젝트
드디어 한학기가 끝났습니다.
시험이다 과제때문에 한동안 포스팅이 없었네요. (정기방문보다 검색방문이 많겠지만 ;;;)
기말고사는 저번주에 끝났지만, 늦게 내는 텀이 남아서 방학(!)이 한주 더 걸렸네요.
이제 남은건 성적공개뿐이군요....
알파오브젝트는 일반적인 오브젝트를 그린 후,
알파 오브젝트끼리 카메라에서의 거리로 먼곳부터 그려줘야 합니다.
문제는 지형에 커다란 사각형으로 물을 씌울때 발생합니다.
물도 알파오브젝트인데, 다른 작은 알파오브젝트와 비교해 언제 그려줘야 할까요?
빌보드로 알파값을 가진 나무입니다.
나무를 먼저 그려주고, 물을 그려준 상태입니다.
보시다시피 빌보드의 투명부분에 물이 그려지지 않았습니다.
나무의 Z버퍼가 물보다 앞에 있기때문에 그려지지 않는것이죠.
이번엔 반대로 물을 그려주고, 나무를 그려줬습니다.
얼핏보면 제대로 그져진듯 하지만, 물에 잠긴 나무밑둥이 그려지지 않습니다.
아까와 반대로 물의 Z버퍼가 잠긴 나무앞에 있기 때문에 그려질 수 없는것이죠.
만약 물이 투명하지 않는 거라면 이정도로도 충분할 겁니다.
하지만 투명히 비추는 물에 잠긴 오브젝트를 원한다면 불충분하죠.
해결법은 나무를 2번 그리고, Z버퍼쓰기 상태를 이용하는 겁니다.
먼저 나무를 그려줍니다.
중요 포인트는 Z버퍼쓰기를 꺼주는 겁니다.
SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
이렇게하면 출력은 되지만, Z버퍼에는 반영이 되지 않죠.
다시 Z버퍼쓰기를 활성화한 후, 물을 그려줍니다.
물 위쪽에 그려진 나무가 물과 알파블렌딩되서 흐려진것을 알 수 있습니다.
당연히 물에 잠긴 밑둥은 물과 블렌딩된 상태입니다.
마지막으로 나무를 다시 그려줍니다.
물을 그릴때 Z버퍼가 변하여, 밑둥이 다시 그려지지 않고,
잠긴 효과 그대로 유지되는것을 알 수 있습니다.
물 위 가지부분은 물보다 카메라에 가까우므로, 덮어 써지는것을 알 수 있습니다.
정리하면 다음과 같습니다.
이걸 생각해내기 전에는 요상하게 작성해봤었죠.
Z버퍼쓰기를 끄고, 물을 그리고, Z버퍼쓰기 키고 오브젝트를 그리고 알파블렌딩을
D3DBLENDOP_MIN로 지정한뒤 물을 다시 출력했었습니다.
이렇게하면 오브젝트의 알파부분과 물과 약간의 색차가 존재합니다.
그래도 멀리서 보면, 어느정도 그럴듯 했었죠;;;;
원래 과제에 덤으로 넣은 물효과인데, 그냥 초안대로 작성해서 빨리 내버렸습니다.
근데 제출한 다음날에 이방법이 떠올랐다죠 orz...
다행히 기말 실기시험에서 이 소스를 사용해서, 기말고사는 수정된 버전으로 제출~
시험이다 과제때문에 한동안 포스팅이 없었네요. (정기방문보다 검색방문이 많겠지만 ;;;)
기말고사는 저번주에 끝났지만, 늦게 내는 텀이 남아서 방학(!)이 한주 더 걸렸네요.
이제 남은건 성적공개뿐이군요....
알파오브젝트는 일반적인 오브젝트를 그린 후,
알파 오브젝트끼리 카메라에서의 거리로 먼곳부터 그려줘야 합니다.
문제는 지형에 커다란 사각형으로 물을 씌울때 발생합니다.
물도 알파오브젝트인데, 다른 작은 알파오브젝트와 비교해 언제 그려줘야 할까요?

나무를 먼저 그려주고, 물을 그려준 상태입니다.
보시다시피 빌보드의 투명부분에 물이 그려지지 않았습니다.
나무의 Z버퍼가 물보다 앞에 있기때문에 그려지지 않는것이죠.

얼핏보면 제대로 그져진듯 하지만, 물에 잠긴 나무밑둥이 그려지지 않습니다.
아까와 반대로 물의 Z버퍼가 잠긴 나무앞에 있기 때문에 그려질 수 없는것이죠.
만약 물이 투명하지 않는 거라면 이정도로도 충분할 겁니다.
하지만 투명히 비추는 물에 잠긴 오브젝트를 원한다면 불충분하죠.
해결법은 나무를 2번 그리고, Z버퍼쓰기 상태를 이용하는 겁니다.

중요 포인트는 Z버퍼쓰기를 꺼주는 겁니다.
SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
이렇게하면 출력은 되지만, Z버퍼에는 반영이 되지 않죠.

물 위쪽에 그려진 나무가 물과 알파블렌딩되서 흐려진것을 알 수 있습니다.
당연히 물에 잠긴 밑둥은 물과 블렌딩된 상태입니다.

물을 그릴때 Z버퍼가 변하여, 밑둥이 다시 그려지지 않고,
잠긴 효과 그대로 유지되는것을 알 수 있습니다.
물 위 가지부분은 물보다 카메라에 가까우므로, 덮어 써지는것을 알 수 있습니다.
정리하면 다음과 같습니다.
- Z버퍼쓰기를 끄고 알파 오브젝트를 그린다. (Z버퍼 사용[D3DRS_ZENABLE])이 아님.)
- Z버퍼쓰기를 다시 키고 물을 그린다.
- 알파 오브젝트를 다시 그린다.
이걸 생각해내기 전에는 요상하게 작성해봤었죠.
Z버퍼쓰기를 끄고, 물을 그리고, Z버퍼쓰기 키고 오브젝트를 그리고 알파블렌딩을
D3DBLENDOP_MIN로 지정한뒤 물을 다시 출력했었습니다.
이렇게하면 오브젝트의 알파부분과 물과 약간의 색차가 존재합니다.
그래도 멀리서 보면, 어느정도 그럴듯 했었죠;;;;
원래 과제에 덤으로 넣은 물효과인데, 그냥 초안대로 작성해서 빨리 내버렸습니다.
근데 제출한 다음날에 이방법이 떠올랐다죠 orz...
다행히 기말 실기시험에서 이 소스를 사용해서, 기말고사는 수정된 버전으로 제출~
# by | 2009/06/26 23:51 | Programming | 트랙백 | 덧글(0)




☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]