오거에서 물 효과 작업을 하는데 생각하는데로 나오지 않아서 몇일 삽질을 하다가 알게 된 사실을 여기에 정리한다.
반사 효과를 사용할려면 Render To Target이라고 카메라에 보이는 것 렌더링을 모니터에다가 하는게 아니라 텍스쳐에다가 하고 그 텍스쳐를 엔티티에 붙이면 된다. 반사에 사용되는 쉐이더나 각종 기본 작업은 생략한다.
물 반사층 plane은 아래와 같은 코드로 작성한다.
plane = Ogre::Plane(Ogre::Vector3::UNIT_Y, d); Ogre::MeshManager::getSingleton().createPlane( PlaneName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane , width, height, 1, 1, true, 1, 3, 5, Ogre::Vector3::UNIT_Z);
여기서 주의 해야 할점이 난 처음에 일반 Plane을 만들고 그 엔티티를 노드에 붙인후 노드를 이동하면 그 위치에 맞게 반사가 되는거라 생각했다.
하지만 빌드를 해서 돌려보니 그렇지 않았다.
실제 물 반사판은 이런 원리로 동작한다.
반사판을 깔면 생성시 d값이 반사판으로 부터 -y값으로 카메라를 반전시켜서 그 투영된 이미지를 텍스쳐로 그리는것이였다. 그냥 d의 값에 0값을 넣고 노드의 위치를 이동시키면 그 위치에 맞게 반사가 되는것인줄 알고 있었는데 이 사실을 몰라서 몇일을 삽질했었음.
preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt){ Camera->enableReflection(plane); Camera->enableCustomNearClipPlane(plane); }
실제 이 카메라를 수면판 기준으로 반사위치로 이동시키는 작업은 위 코드에서 작동하고
postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt){ Camera->disableReflection(); Camera->disableCustomNearClipPlane(); }
원상복귀 시키는 작업은 위 코드의 두번째줄(하일라이트부분)에서 한다.
세번째 라인은 중요한 것인데, 이것 때문에 몇일 더 소비하게 된 범인으로 테스트에 사용한 Ogre SDK 1.7.4에 있는Fresel Sample에서는 수면 및 obj들을 별도로 관리하면서 preRenderTargetUpdate, postRenderTargetUpdate 함수내에서 visible(true), visible(fale)를 해가면서 수면 밑의 오브젝트는 반사에 나오지 않게 했었다.
하지만 나무 같이 한 덩어리로 되어 있고 수면아래와 수면위에 걸쳐서 존재하는 오브젝트는 안나오게 하자니 반사가 덜되는거 같아서 이상하고 나오게 하니 수면 위쪽에 살짜꿍 뿌리까지 그려지는 바람에 이것을 어떻게 해야 하나 고민을 했었다.
사장이 유니티 소스에 있는걸 참고하여 직접 구현할려고 하던찰라에 발견하셨다. 이미 오거에서도 함수가 있다는걸 -_-;
아마 샘플은 그 이전부터 있던거라 이런 함수가 나중에 생겨도 쓰지 않았던게 아닐까 싶다.
암튼 저 파란색 글씨 부분을 넣어주면 자연스럽게 수면 아래의 Obj들은 반사가 되지 않고 수면 위의 것들만 반사가 된다.
답글 남기기