기초 튜토리얼 3-3 (마지막)
Ogre3D 삽질란/Basic Tutorial 3 2008/11/14 13:25안개
안개 소개
오우거에서의 안개는 사용하는데 어렵지 않습니다. 안개를 프로그램에 적용시키는데에는 한가지 절차만 알면 됩니다. TerrainSceneManager 를 쓸때 setFog 함수는 setWorldGeometry 함수 전에 호출되어야 합니다. (다른 SceneManager 에서는 상관없습니다.) 어느게 먼저 호출되느냐에따라 다른 vertex 프로그램이 안개와 지형을 만드는데 선택됩니다. (오우거 1.0.0 에서는 잘못된 호출 순서로 인한 급격한 안개량 증가로 아무것도 안보이게 만드는 큰 버그거리였습니다; 오우거 1.0.1. 에서 고쳐졌습니다.)
시작하기전에 createScene 함수에서 setWorldGeometry 부분만 제외하고 다 지우세요.
안개를 설정함에 있어서 가장 중요한 것은 빈 공간에 안개 Entity 를 흔히들 상상하는것 처럼 만들지 않는다는 점 입니다. 그 대신에 안개는 단지 현재 바라보고 있는 객체에 적용되는 필터일 뿐입니다. 이것은 흥미로운 점을 내포합니다. 아무것도 없는 공간을 쳐다볼 때(그 어떤 객체도 보고 있지 않을때), 안개는 보이지 않습니다. 사실은 뷰포트의 배경색만 보이는 것 입니다. 그래서 안개가 제대로 보이게 하기 위해서는 배경색을 안개와 동일하게 맞춰줘야 합니다.
2가지 종류의 기본 안개타입이 있습니다 : linear 와 exponential 방식입니다. Linear 안개는 선형적으로 안개가 짙어지고 exponential 안개는 급격하게 짙어집니다 (매 거리마다 바로 전에 짙어진 만큼보다 더 짙어 집니다). 설명하는 것 보다 보여주는게 이해가 쉬울것입니다. 다음 예제를 봅시다.
안개 종류
가장 이해하기 쉬운 linear 방식 안개를 먼저 보도록 합시다. 첫번째로 해야 할 일은 setWorldGeometry 호출 이후에 뷰포트의 배경색을 설정해야 합니다. createViewport 함수를 재정의 하여 구현할 수 있지만 (지난번 튜토리얼에서 했던 것 처럼) 가끔씩은 매번 뷰포트를 다시 생성하지 않고도 설정할 수 있어야 합니다. 이렇게 하면 됩니다 :
ColourValue fadeColour(0.9, 0.9, 0.9);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);
getNumViewports 멤버함수를 사용하여 뷰포트 갯수를 절정할 수 있고 1개 이상의 뷰포트를 다룰때 그 함수를 통해서 하나하나 선택할 수 있지만 그런경우는 잘 없습니다(그리고 여기서는 1개의 뷰포트만 씁니다). 뷰포트는 한번에 획득될 수 있습니다. 배경색을 설정한 지금 안개를 만들 수 있습니다. 이 코드는 setWorldGeometry 이전에 호출되어야 함을 명심하세요 :
mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 50, 500);
첫번째 setFog 매개변수는 안개 종류(이 경우는 linear)입니다. 두번째 매개변수는 안개에 쓰일 색상(이 경우는 매우 옅은 회색 또는 C# 의 "WhiteSmoke")입니다. 세번째 매개변수는 linear 안개방식에서는 쓰이지 않습니다. 네번째와 다섯번째 매개변수는 안개가 두터워질 범주를 설정합니다. 이 경우는 안개가 50에서 시작하여 500에서 끝납니다. 이 말은 카메라로부터 0과 50사이에는 안개가 없으며 50부터 500까지는 선형적으로 두꺼워 집니다. 500 이상 떨어진 경우 안개때문에 아무것도 보이지 않습니다. 컴파일 하고 실행시켜보세요.
다른 타입은 exponential 안개입니다. 안개의 시작과 끝 경계를 설정하는것 대신에 안개의 농도를 설정합니다(4, 5번째 매개변수는 안씁니다). 아까 setFog 함수내용을 이 내용으로 바꾸세요 :
mSceneMgr->setFog(FOG_EXP, fadeColour, 0.005);
컴파일 후 실행시켜 보세요. DirectX Renderer 를 사용하신다면 안개때문에 아무것도 안보일 수 있습니다. 이때는 setFog 함수를 setWorldGeometry 다음에 호출하시면 해결됩니다. OpenGL Renderer는 이 설명드렸던 것 처럼 동작합니다. 이건 안개가 생성되는것 마다 다르게 보입니다. 좀더 세밀한 exponential 안개함수도 있습니다(앞서 소개드린 함수보다 더 진하게 생성됩니다). FOG_EXP2를 쓸때 좀 더 진한 안개가 연출됩니다. 예전의 setFog 코드를 이 코드로 바꿔보세요 :
mSceneMgr->setFog(FOG_EXP2, fadeColour, 0.003);
다시 컴파일하고 실행시켜 보세요. 오우거에서 제공하는 세가지 안개들은 손쉽게 교체가 가능합니다. 당신의 어플리케이션에서 세가지 안개함수들을 시험해 보시고 뭐가 가장 나아 보이는지 확인하세요.
안개와 하늘
SkyBox와 SkyDome을 안개와 같이 출력할때 재미있는 문제점들에 봉착할 수 있습니다. SkyDome과 SkyBox가 큐브형태이기 때문에 안개가 나타날때 원형표면에 대해 문제가 발생합니다. createScene 함수 내용을 삭제하세요. 만약 그럴싸하게 SkyDome과 안개 매개변수를 선택한다면 문제점을 바로 확인할 수 있습니다.
ColourValue fadeColour(0.9, 0.9, 0.9);
mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 50, 515);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);
mSceneMgr->setWorldGeometry("terrain.cfg");
mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8, 500);
컴파일하고 실행시켜보세요. 만약 카메라를 움직이면 바라보고 있는 SkyDome의 한 부분이 안개에 의해 잘려나간 것을 볼 수 있을것 입니다(중앙이 아닌 측면의 blue 색상으로 나타납니다) :
우리가 원하던 결과값이 아닙니다. 다른 방법은 SkyPlane 을 대신 사용하는 것 입니다. createScene 함수내용을 다음으로 바꿔주세요 :
ColourValue fadeColour(0.9, 0.9, 0.9);
mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 0, 130);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);
Plane plane;
plane.d = 100;
plane.normal = Vector3::NEGATIVE_UNIT_Y;
mSceneMgr->setWorldGeometry("terrain.cfg");
mSceneMgr->setSkyPlane(true, plane, "Examples/CloudySky", 500, 20, true, 0.5, 150, 150);
제대로 보이는군요. 위로 보면 정상적인 하늘이 보입니다(안개가 제대로 표시된다면 실제세계와 비슷한 화면입니다). 곡률을 적용해도 괜찮습니다. 이 방법은 수평선을 바라볼때 문제되는 SkyPlane의 단점을 잘 해결해 줍니다.
하늘의 일부분에만 안개를 적용하는 방법도 있습니다. 그러나 그렇게 하기 위해서는 하늘 텍스쳐를 위해 재질 스크립트 수정을 필요로 합니다.
이런 내용은 이 튜토리얼의 범주를 벗어납니다. 추후 특정재질을 위해 안개를 비활성화 시키시려면 여기 (http://www.ogre3d.org/docs/manual/manual_16.html#SEC64)를 참조하세요.
안개를 어둠처럼 사용하기
안개를 설정하고 항상 하늘을 사용하지 않아도 됩니다. 왜냐하면 안개가 너무 짙으면 어쨋든 하늘은 안보이기 때문입니다. 지금까지 설명한 안개의 설명에 의하면 한정된 경우 멋진 그래픽트릭을 쓸 수 있게끔 해줍니다. 안개를 밝은 색상 대신에 매우 어두운 색상으로 만들면 어떻게 되는지 봅시다 (지금 작성한 코드의 SkyPlane은 카메라와 겨우 10단위거리 밖에 떨어져 있지 않습니다.) :
ColourValue fadeColour(0.1, 0.1, 0.1);
mWindow->getViewport(0)->setBackgroundColour(fadeColour);
mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 10, 150);
mSceneMgr->setWorldGeometry("terrain.cfg");
Plane plane;
plane.d = 10;
plane.normal = Vector3::NEGATIVE_UNIT_Y;
mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane", 100, 45, true, 0.5, 150, 150);
컴파일하고 실행시켜 보세요. 이게 그 결과입니다 :
나쁘진 않군요. 물론 가능하다면 적절한 조명으로도 이런 효과를 낼 수 있습니다. 그러나 이 방법은 안개의 유연한 기능을 보여주고 오우거엔진으로 할 수 있는 재미있는 기능이기도 합니다. 검은 안개는 FPS 게임에서 "시력약화" 나 "암흑" 과 같은 마법 효과를 낼 수 있는 흥미로운 기법이 될 수도 있습니다.