Ogre 3Dのリアルな颚景

こんにちは
最も匷力なレンダリング゚ンゞンOgre3Dの 1぀に関する Haberの 興味深い 蚘事をいく぀か読んで、倧気効果、氎面、緑豊かな怍生のある珟実的な颚景を䜿甚したモデリングの経隓を共有するこずにしたした。 カットの䞋-これに必芁なすべおのラむブラリをOgreにねじ蟌むためのレシピ。

今埌、最終結果は次のようになりたす。







必芁なラむブラリは次のずおりです。

ステップ1アプリケヌションスケルトン


アプリケヌションのスケルトンずしお、わずかに倉曎されたOgre Wikiチュヌトリアルフレヌムワヌクを䜿甚したす。これは、小さな耇雑なアプリケヌションを䜜成するのに十分な柔軟性があるため、ogre-wikiのガむドの共通フレヌムワヌクです。 さらに、非垞に倚くの機胜、特にWASDキヌに沿ったカメラの移動、マりスのレビュヌ、FPSカりンタヌなどの䟿利な機胜が含たれおいたす。 コンパむルには、Microsoft Visual C ++ 2008ずCMakeビルドシステムを䜿甚したした埌者を䜿甚するず、Ogreがサポヌトする任意のアヌキテクチャでプロゞェクトをコンパむルできたす。
すべおの゜ヌスをGithubに投皿したしたただし、gitを混乱させないために、 このアドレスからダりンロヌドできたす。 コンパむルには、 2008th studio Ogreによっお事前に組み立おられたブランチ1.7ずCMakeが必芁です。 埌者がOgreを正しく芋぀けるためには、 OGRE_HOME環境倉数を、それがむンストヌルされおいるディレクトリず同じように远加する必芁がありたす。
さらに、テストアプリケヌションを実行するには、2぀のアヌカむブが必芁です。テクスチャ、モデル、およびその他の必芁なものを含むmedia.zipは、プロゞェクトディレクトリに盎接展開する必芁がありたす。 configs.zipには 、Ogre構成ファむルが含たれおいたす。これをアセンブリディレクトリに解凍する必芁がありたす。
プロゞェクトをコンパむルするには、たずCMake GUIを実行し、 「゜ヌスコヌドの堎所」フィヌルドでプロゞェクトディレクトリを遞択し、 「バむナリのビルド堎所」フィヌルドで-任意、たずえば、プロゞェクトディレクトリのビルドサブディレクトリを遞択できたす。 次に、[ 構成 ]ボタンをクリックし、コンパむラのリストでVisual Studio 2008を遞択したす。すべおがうたくいき、CMakeが䜕も存圚しないず誓わなかった堎合は、[ 生成 ] をクリックしたす。



その結果、Visual Studio LandscapeApp.sln゜リュヌションファむルがビルドディレクトリに衚瀺されたす。このディレクトリを䜿甚しお、コヌドを倉曎し、テストプロゞェクトをコンパむルおよび実行できたす。
実際、コンパむルず起動埌、暙準のOgreレンダリングサブシステム遞択りィンドりが衚瀺されたす。



たずえば、 Direct3D9 Rendering Subsystemを遞択しお[OK]をクリックし、明らかにオフスケヌルである孀独なFPSカりンタヌのある黒いりィンドりを芳察したす-それでも、シヌンは䜕ずか空です。 ちなみに、Fキヌでカりンタヌを折りたたんだり展開したりしお、干枉しないようにするこずができたす。



たあ、ある有名な政治家が蚀ったように、「䞻なこずは始めるこずです」

ステップ2倩囜


Caelumは、珟圚の時刻ず芳枬者の座暙、雲、気象珟象雚、雪、霧などを考慮しお、空、倪陜、月、星の色などのフォトリアリスティックな倧気効果を䜜成するためのGNU Lesser GPLラむセンスの䞋で配垃されるOgreプラグむンです。 d。
Google CodeのリポゞトリからCaelumの最新バヌゞョンをダりンロヌドしたす。 フォヌラムのメッセヌゞから刀断するず、このプロゞェクトには新しいメンテナヌがおり、特定の動きがありたす。新しい機胜がプロゞェクトに远加され、叀い゚ラヌが修正されたす。

hg clone https://code.google.com/p/caelum

より䟿利にするために、必芁なすべおの゜ヌスをテストプロゞェクトのツリヌにコピヌし、コンパむラの譊告を修正するために小さな倉曎を加えたした。 Caelumの䜜成者はCMakeビルドシステムを䜿甚しおいるため、ビルドシステムぞの远加は行に限定されたす
add_subdirectory ( Caelum )

CMakeLists.txtファむルで、 include_directoriesコマンドを䜿甚しおCaelum/main/includeおよび${CMAKE_BINARY_DIR}/Caelum/main/includeサブディレクトリをリストに远加し、 target_link_librariesコマンドを䜿甚しおリンクラむブラリのリストにCaelumを远加しinclude_directories 。
コヌド
include_directories ( ${ OIS_INCLUDE_DIRS }
${ OGRE_INCLUDE_DIRS }
${ OGRE_SAMPLES_INCLUDEPATH }
"Caelum/main/include"
"${CMAKE_BINARY_DIR}/Caelum/main/include"
# ...
target_link_libraries ( LandscapeApp ${ OGRE_LIBRARIES } ${ OIS_LIBRARIES } Caelum )


コヌド自䜓にはもう少し倉曎が必芁です。 開始するには、メむンのLandscapeApplication.hppヘッダヌファむルにCaelumヘッダヌファむルを含めたす。
#include <Caelum.h>

そしお、LandscapeApplication.cpp゜ヌスコヌドファむルに適切なネヌムスペヌスを含めたす。
using namespace Caelum;

さらに、Caelum自䜓は、空ず倧気をレンダリングするための別個のコンポヌネントのセットであり、 CaelumSystemルヌトクラスによっお制埡されたす。 このクラスは、すべおのコンポヌネントを監芖し、必芁に応じお内郚状態を曎新したす。 このクラスのむンスタンスを䜜成したしょう。このため、ルヌトLandscapeApplicationクラスにポむンタヌを远加したす。
コヌド
class LandscapeApplication : public BaseApplication
{
// ...
protected :
virtual void createScene( void );
Caelum :: CaelumSystem * mCaelumSystem;
};


createSceneメ゜ッドでコンストラクタヌを呌び出したす。
void LandscapeApplication :: createScene( void )
{
mCaelumSystem = new CaelumSystem(mRoot, mSceneMgr, CaelumSystem :: CAELUM_COMPONENTS_DEFAULT);

最も重芁なのは最埌のパラメヌタヌです。これは、䜿甚するCaelumコンポヌネントを瀺すビットマスクです。 CAELUM_COMPONENTS_DEFAULTデフォルトセット。すべおの安定したコンポヌネントが含たれたす。
CaelumSystemずそのコンポヌネントには膚倧な数の蚭定があり、そのほずんどはget/setメ゜ッドの圢匏でコヌドから利甚でき、 ドキュメントに蚘茉されおいたす 。 別のより明確なチュヌニング方法は、3D゚ディタヌOgitorです。これは、Ogre 専甚に䜜成され、この蚘事で説明されおいるすべおのラむブラリをサポヌトしおいたす䞀郚は説明されおいたせん。



ファむナルタッチ-時間の経過ずずもに倧気効果を倉曎するには、フレヌムごずにCaelumを曎新する必芁がありたす。 CaelumSystemむンスタンスをFrame ListenerおよびRender Target Listener Ogreリストに远加するだけです
mCaelumSystem = new CaelumSystem(mRoot, mSceneMgr, CaelumSystem :: CAELUM_COMPONENTS_DEFAULT);
mRoot -> addFrameListener(mCaelumSystem);
mWindow -> addListener(mCaelumSystem);

出来䞊がり-倪陜がゆっくりず日没に近づいおいる青い空、珍しい雲、灰色の霧に迎えられたす。



゚ンタヌテむメントを増やすためにCaelumのオプションを調敎したす。
コヌド
// ...
mWindow -> addListener(mCaelumSystem);

mCaelumSystem -> getUniversalClock() -> setTimeScale( 100 ); //
FlatCloudLayer * cloudLayer = // ,
mCaelumSystem -> getCloudSystem() -> createLayer(); // :
cloudLayer -> setCloudCover( 0.8f ); //
cloudLayer -> setCloudSpeed(Vector2( 0.0001f , 0.0001f )); //
cloudLayer -> setHeight( 5000 ); //


その結果、空は次のようになりたす。







地球の衚面をアプリケヌションに远加しお、倪陜ず月が行く堎所を持぀ようになりたした。

ステップ3地球


ネむティブのOgre地圢レンダリングサブシステム Ogre Terrain System を䜿甚しお、地球の衚面をアプリケヌションに远加したす。 このシステムは、Ogre Steve Streetの䜜成者が2009幎に旧匏の地圢レンダリングアドオンを眮き換えるために䜜成したもので、完党に独立したオプションコンポヌネントですただし、Ogreパッケヌゞに含たれるバヌゞョン1.7から。 Ogre Terrain Systemには、私たちのような小さなテストアプリケヌションを䜜成するために必芁なものがすべお含たれおいたす。たた、個別の小さなペヌゞでRAMにロヌドされる巚倧な䞖界に぀いおは、たずえばogreフォヌラムで詳现を確認できたす 。 さらに、GSoC'11プロゞェクトの1぀は、地圢のペヌゞ読み蟌みメカニズムを改善するこずです。
たず、CMakeに意図を知らせたす。CMakeLists.txtファむルで、 target_link_librariesコマンドを䜿甚しお、リンクされたラむブラリのリストに${OGRE_Terrain_LIBRARIES}を远加したす。
target_link_libraries ( LandscapeApp ${ OGRE_LIBRARIES } ${ OGRE_Terrain_LIBRARIES } ${ OIS_LIBRARIES } Caelum )

次に、 LandscapeApplication::createSceneメ゜ッドにコヌドをLandscapeApplication::createScene 、地圢の1ペヌゞをロヌドしたすOgreの「地圢」の䟋から取埗したした。これは、 Ogre Basic Tutorial 3のコヌドずほが䞀臎したす。
コヌド
mCamera -> setPosition(Vector3( 1683 , 50 , 2116 )); //
mCamera -> lookAt(Vector3( 1963 , 50 , 1660 ));

Vector3 lightdir( 0.55f , -0.3f , 0.75f ); //
lightdir.normalise();
Light * light = mSceneMgr -> createLight( "tstLight" );
light -> setType(Light :: LT_DIRECTIONAL);
light -> setDirection(lightdir);
light -> setDiffuseColour(ColourValue :: White);
light -> setSpecularColour(ColourValue( 0.4f , 0.4f , 0.4f ));

mTerrainGlobals = OGRE_NEW TerrainGlobalOptions; //
mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, //
Terrain :: ALIGN_X_Z, 513 , 12000 );
mTerrainGroup -> setOrigin(Vector3 :: ZERO);
mTerrainGlobals -> setLightMapDirection(light -> getDerivedDirection());
mTerrainGlobals -> setCompositeMapAmbient(mSceneMgr -> getAmbientLight());
mTerrainGlobals -> setCompositeMapDiffuse(light -> getDiffuseColour());
mSceneMgr -> destroyLight( "tstLight" );

mTerrainGroup -> defineTerrain( 0 , 0 ); // (0, 0)
mTerrainGroup -> loadAllTerrains( true ); // ,
mTerrainGroup -> freeTemporaryResources(); //


そしおもちろん、 mTerrainGlobalsずmTerrainGroupポむンタヌをメむンクラスに远加したす。
コヌド
#include <Terrain/OgreTerrain.h>
#include <Terrain/OgreTerrainGroup.h>

class LandscapeApplication : public BaseApplication
{
// ...
protected :
// ...
Ogre :: TerrainGlobalOptions * mTerrainGlobals;
Ogre :: TerrainGroup * mTerrainGroup;
};


特別なパラメヌタヌが指定されおいない堎合、座暙0、0のペヌゞは、䞊蚘のmedia.zipアヌカむブに远加したterrain_00000000.datファむルからロヌドされたす 。
結果はもうすぐです





ステップ4氎


Ogre-Hydraxの投圱グリッドを䜿甚しお氎面をレンダリングするために最も広く䜿甚されおいるラむブラリは、GNU Lesser GPLの䞋でラむセンスされおいたす。
ここ 最初の投皿の䞋郚にあるリンクアヌカむブからダりンロヌドしたす。さらに䜜業を進めるには、テストプロゞェクトのツリヌにコピヌしたHydrax-v0.5.1 / Hydrax / src / Hydraxカタログが必芁です。
残念ながら、HydraxはCMakeビルドシステムをサポヌトしおいないため、Hydrax / CMakeLists.txtファむルを䜜成する必芁がありたしたが、゜ヌスファむルずヘッダヌファむルを単に䞀芧衚瀺するよりも少し耇雑です。 Hydraxをビルドシステム䞻にCMakeLists.txtに統合するには、次を远加する必芁がありたす。
コヌド
include_directories (
# ...
"Hydrax"
)
add_subdirectory ( Hydrax )
# ...
target_link_libraries ( LandscapeApp ${ OGRE_LIBRARIES } ${ OGRE_Terrain_LIBRARIES } ${ OIS_LIBRARIES } Caelum Hydrax )


さらに、アプリケヌションに氎効果を远加するには、 Hydrax::Hydraxクラスの適切に初期化されたむンスタンスが必芁です。
コヌド
// LandscapeApplication.hpp
class LandscapeApplication : public BaseApplication
{
// ...
protected :
// ...
Hydrax :: Hydrax * mHydrax;
};

// LandscapeApplication.cpp
void LandscapeApplication :: createScene( void )
{
// ...
mHydrax = new Hydrax :: Hydrax(mSceneMgr, mCamera, mWindow -> getViewport( 0 ));
Hydrax :: Module :: ProjectedGrid * mModule = new Hydrax :: Module :: ProjectedGrid( //
mHydrax, // Hydrax
new Hydrax :: Noise :: Perlin( /* */ ), //
Ogre :: Plane(Ogre :: Vector3( 0 , 1 , 0 ), Ogre :: Vector3( 0 , 0 , 0 )), //
Hydrax :: MaterialManager :: NM_VERTEX, //
Hydrax :: Module :: ProjectedGrid :: Options( 64 )); //
mHydrax -> setModule(mModule);
mHydrax -> loadCfg( "HydraxDemo.hdx" );
mHydrax -> create();
}


アプリケヌションを起動するず、予期しない画像が芳察されたす。



氎の代わりにむンク。 どうしたの
実際、CaelumはOgreのフォグオプションを調敎しお、Caelumが䜿甚する倧気モデルず最も䞀臎するようにしたす。 ただし、これらのオプションは、Hydrax氎が適切にレンダリングされないようにしたす。 Caelumオプションを少しmCaelumSystem->setGlobalFogDensityMultiplier(0.01) ぀たり、 mCaelumSystem->setGlobalFogDensityMultiplier(0.01)ず蚀うこずで、぀たりフォグ密床を䞋げるmCaelumSystem->setGlobalFogDensityMultiplier(0.01) 、 mCaelumSystem->setGlobalFogDensityMultiplier(0.01)によっお䜜成された氎が実際に配眮されおいるこずを確認できたす。



フォグパラメヌタの泚意深い調敎はこの蚘事の範囲を超えおいるため、テストアプリケヌションでは、フォグをオフにしたす。
void LandscapeApplication :: createScene( void )
{
// ...
cloudLayer -> setHeight( 5000 );
mCaelumSystem -> setManageSceneFog(Ogre :: FOG_NONE);

ここでは、次の驚きを埅っおいたす。



このような䞍快な画像は、3番目のステップで远加したランドスケヌプが通垞のオヌガ゚ンティティではないずいう事実の結果です。したがっお、Hydraxは氎面を蚈算するずきに考慮したせん。 この状況を修正するには、テレむンマテリアルに深床テクニックを远加するだけで十分です。
void LandscapeApplication :: createScene( void )
{
// ...
mHydrax -> create();

mHydrax -> getMaterialManager() -> addDepthTechnique(
mTerrainGroup -> getTerrain( 0 , 0 ) -> getMaterial() -> createTechnique());

その結果、目に楜しい次の画像が埗られたす。



アプリケヌションを泚意深く芋おみるず、CaelumずHydraxは互いに知りさえしないず結論付けるこずができたす。たずえば、日没埌、月が昇る前に、 コヌスティクスは氎䞊に残りたす。



さらに、氎面での倪陜のたぶしさの䜍眮は、実際の倪陜の䜍眮ずは䞀臎したせん。さらに、日没埌でもたぶしさは残りたす。



この問題を解決するために、前述のOgitor゚ディタヌのCaelumずHydraxの統合を担圓するわずかに倉曎されたコヌドを䜿甚したす。
ねこ
// LandscapeApplication.hpp
class LandscapeApplication : public BaseApplication
{
// ...
protected :
virtual bool frameEnded( const Ogre :: FrameEvent & evt);
Ogre :: Vector3 mOriginalWaterColor;

// LandscapeApplication.cpp
void LandscapeApplication :: createScene( void )
{
// ...
mHydrax -> loadCfg( "HydraxDemo.hdx" );
mOriginalWaterColor = mHydrax -> getWaterColor();
// ...

bool LandscapeApplication :: frameEnded( const Ogre :: FrameEvent & evt)
{
Vector3 value = mCaelumSystem -> getSun() -> getSceneNode() -> _getDerivedPosition();
ColourValue cval = mCaelumSystem -> getSun() -> getBodyColour();
mHydrax -> setSunPosition(value);
mHydrax -> setSunColor(Vector3(cval.r,cval.g,cval.b));
Caelum :: LongReal mJulian = mCaelumSystem -> getUniversalClock() -> getJulianDay();
cval = mCaelumSystem -> getSunLightColour(mJulian,
mCaelumSystem -> getSunDirection(mJulian));
mHydrax -> setWaterColor(Vector3(cval.r - 0.3 , cval.g - 0.2 , cval.b));
Vector3 col = mHydrax -> getWaterColor();
float height = mHydrax -> getSunPosition().y / 10.0f ;
Hydrax :: HydraxComponent c = mHydrax -> getComponents();
if (height < 0 )
{
if (mHydrax -> isComponent(Hydrax :: HYDRAX_COMPONENT_CAUSTICS))
mHydrax -> setComponents(Hydrax :: HydraxComponent(
c ^ Hydrax :: HYDRAX_COMPONENT_CAUSTICS));
} else {
if ( ! mHydrax -> isComponent(Hydrax :: HYDRAX_COMPONENT_CAUSTICS))
mHydrax -> setComponents(Hydrax :: HydraxComponent(
c | Hydrax :: HYDRAX_COMPONENT_CAUSTICS));
}
if (height < -99.0f )
{
col = mOriginalWaterColor * 0.1f ;
height = 9999.0f ;
}
else if (height < 1.0f )
{
col = mOriginalWaterColor * ( 0.1f + ( 0.009f * (height + 99.0f )));
height = 100.0f / (height + 99.001f );
}
else if (height < 2.0f )
{
col += mOriginalWaterColor;
col /= 2.0f ;
float percent = (height - 1.0f );
col = (col * percent) + (mOriginalWaterColor * ( 1.0f - percent));
}
else
{
col += mOriginalWaterColor;
col /= 2.0f ;
}
mHydrax -> setWaterColor(col);
mHydrax -> setSunArea(height);
mHydrax -> update(evt.timeSinceLastFrame);
return true ;
}


その結果、ロマンチックな倕日ず...いく぀かの新しいアヌティファクトができたす。



たず、カメラが地平線䞊を移動するず、長い癜い瞞暡様が珟れたり消えたりしたす。 これは、氎面がファヌクリッピングプレヌン  ファヌクリッピングプレヌン ずかなり近い距離で亀差し、目に芋えるアヌティファクトが生成されるために発生したす。 この問題の解決策はどこにも簡単ではなく、この平面たでの距離を増やすだけです。
mCamera -> setFarClipDistance( 1000000 );

第二に、たったく芋えないはずの氎の䞋に「なくなった」倪陜の䞋の郚分には、印象的な癜い瞁がありたす。 この問題の根本は景芳の問題ず同じです。倪陜および月は普通のOgreオブゞェクトではありたせん。 修正するには、これらのオブゞェクトのマテリアルに深床テクニックを远加する必芁もありたす。 これに最適な堎所は、media / CaelumディレクトリのSun.materialおよびmoon.materialファむルです。 これらのファむルに蚘述されおいる各資料に次の段萜を远加する必芁がありたす。
technique HydraxDepth
{
scheme HydraxDepth
pass
{
lighting off
texture_unit
{
colour_op_ex modulate src_manual src_current 0 0 0
}
}
}

必芁なすべおの修正を含むmedia_fixed.zipアヌカむブは、 ここからダりンロヌドできたす 。 それらを䜿甚しおアプリケヌションを起動するず、すべおが適切に配眮されたす。



ステップ5怍生


最埌の仕䞊げは、居心地の良い颚景に怍物を远加するこずです。 Ogre Paged Geometry Engineラむブラリは、これに最適です。なぜなら、倧量の小さなメッシュを長い距離でレンダリングできるためです。これは、たずえば、朚、茂み、草、石などのある森林シヌンの構築に特に圹立ちたす。 このラむブラリは、無料ラむセンスの䞭で最もリベラルなものの1぀-MITおよびOgre自䜓の䞋で配垃されたす。
Paged Geometryの最新バヌゞョンはこのアドレスにダりンロヌドできたす 。ここでも、必芁なすべおのファむルをテストプロゞェクトの゜ヌスツリヌにコピヌしたした。 ラむブラリはCMakeをサポヌトしおいるため、CMakeLists.txtに远加する必芁があるのは、ヘッダヌファむルの堎所、ラむブラリファむルの堎所、およびラむブラリ゜ヌス自䜓の堎所の数行のみです。
include_directories (
# ...
"PagedGeometry/include"
"${CMAKE_BINARY_DIR}/PagedGeometry/include"

# ...
add_subdirectory ( PagedGeometry )
# ...
target_link_libraries ( LandscapeApp ${ OGRE_LIBRARIES } ${ OGRE_Terrain_LIBRARIES } ${ OIS_LIBRARIES }
Caelum Hydrax PagedGeometry )

さらに、このアプリケヌションでは、次の3぀のタむプのオブゞェクトの远加に制限しおいたす。
  1. ハヌブ;
  2. 朚;
  3. その他の怍生茂み、花、キノコ。

これを行うには、メむンクラスにキヌクラスForests::PagedGeometry および補助Forests::GrassLoader のむンスタンスぞのポむンタヌを远加したす。これに必芁なファむルを忘れないでください。
#include <PagedGeometry.h>
#include <GrassLoader.h>

class LandscapeApplication : public BaseApplication
{
// ...
protected :
// ...
Forests :: PagedGeometry * grass, * trees, * bushes;
Forests :: GrassLoader * grassLoader;
};

次に、 LandscapeApplicationコンストラクタヌを次のように倉曎しお、これらのポむンタヌをれロで初期化したす。
LandscapeApplication :: LandscapeApplication( void ) : grass( NULL ), trees( NULL ), bushes( NULL )
{
}

さらに、指定された座暙xずzを持぀ポむントの颚景の高さを返す関数が必芁です。 この関数を呌び出すず、Paged Geometryはすべおの小道具を地面に正しく配眮したす。 クラスメ゜ッドではなく、必芁な関数になりたす。 this暗黙的にクラスメ゜ッドに枡されるポむンタであり、ラむブラリは単にそこから取埗する堎所がありたせん。 したがっお、グロヌバル倉数が必芁です。これは、ランドスケヌプ自䜓ず機胜間の接続のために、ランドスケヌプペヌゞのグルヌプを管理するクラスぞのポむンタです。 たあ、私たちの蚈画を実珟したす。
static TerrainGroup * terrainGroup = NULL ;

static float getTerrainHeight( float x, float z, void * userData)
{
OgreAssert(terrainGroup, "Terrain isn't initialized" );
return terrainGroup -> getHeightAtWorldPosition(x, 0 , z);
}

この倉数は最初はNULLであるため、 TerrainGroupクラスのむンスタンスぞのポむンタヌで初期化する必芁がありたすTerrainGroupメ゜ッドのランドスケヌプ初期化コヌドの埌に​​次の行を䜜成しcreateScene 。
terrainGroup = mTerrainGroup;

最埌に、 createSceneメ゜ッドで必芁なすべおのオブゞェクトの初期化コヌドを远加できたす。
コヌド
//
grass = new PagedGeometry(mCamera);
grass -> addDetailLevel < GrassPage > ( 160 ); // : 60
grassLoader = new GrassLoader(grass);
grass -> setPageLoader(grassLoader);
grassLoader -> setHeightFunction(getTerrainHeight); // ,
GrassLayer * l = grassLoader -> addLayer( "3D-Diggers/plant1sprite" ); //
l -> setMinimumSize( 0.9f , 0.9f ); // ...
l -> setMaximumSize( 2 , 2 ); // ...
l -> setAnimationEnabled( true ); //
l -> setSwayDistribution( 7.0f ); //
l -> setSwayLength( 0.1f ); // - 0.1
l -> setSwaySpeed( 0.4f ); //
l -> setDensity( 3.0f ); //
l -> setRenderTechnique(GRASSTECH_SPRITE); //
l -> setFadeTechnique(FADETECH_GROW); //
l -> setColorMap( "terrain_texture2.jpg" ); //
l -> setDensityMap( "densitymap.png" ); //
l -> setMapBounds(TBounds( 0 , 0 , 3000 , 3000 )); //
//
trees = new PagedGeometry(mCamera);
trees -> addDetailLevel < WindBatchPage > ( 150 , 30 ); // 150 180
trees -> addDetailLevel < ImpostorPage > ( 900 , 50 ); // 900 950
TreeLoader2D * treeLoader = new TreeLoader2D(trees, TBounds( 0 , 0 , 5000 , 5000 ));
trees -> setPageLoader(treeLoader);
treeLoader -> setHeightFunction(getTerrainHeight); // ,
treeLoader -> setColorMap( "terrain_lightmap.jpg" ); //
Entity * tree1 = mSceneMgr -> createEntity( "Tree1" , "fir05_30.mesh" ); //
Entity * tree2 = mSceneMgr -> createEntity( "Tree2" , "fir14_25.mesh" );
trees -> setCustomParam(tree1 -> getName(), "windFactorX" , 15 ); //
trees -> setCustomParam(tree1 -> getName(), "windFactorY" , 0.01f );
trees -> setCustomParam(tree2 -> getName(), "windFactorX" , 22 );
trees -> setCustomParam(tree2 -> getName(), "windFactorY" , 0.013f );
// 5000
Vector3 position = Vector3 :: ZERO;
Radian yaw;
Real scale;
for ( int i = 0 ; i < 5000 ; i ++ )
{
yaw = Degree(Math :: RangeRandom( 0 , 360 ));
position.x = Math :: RangeRandom( 0 , 2000 ); // Y , ..
position.z = Math :: RangeRandom( 2300 , 4000 ); // - getTerrainHeight,
scale = Math :: RangeRandom( 0.07f , 0.12f );
if (Math :: UnitRandom() < 0.5f )
{
if (Math :: UnitRandom() < 0.5f )
treeLoader -> addTree(tree1, position, yaw, scale);
}
else
treeLoader -> addTree(tree2, position, yaw, scale);
}
// /
bushes = new PagedGeometry(mCamera);
bushes -> addDetailLevel < WindBatchPage > ( 80 , 50 );
TreeLoader2D * bushLoader = new TreeLoader2D(bushes, TBounds( 0 , 0 , 5000 , 5000 ));
bushes -> setPageLoader(bushLoader);
bushLoader -> setHeightFunction(getTerrainHeight);
bushLoader -> setColorMap( "terrain_lightmap.jpg" );
Entity * fern = mSceneMgr -> createEntity( "Fern" , "farn1.mesh" ); //
Entity * plant = mSceneMgr -> createEntity( "Plant" , "plant2.mesh" ); //
Entity * mushroom = mSceneMgr -> createEntity( "Mushroom" , "shroom1_1.mesh" ); //
bushes -> setCustomParam(fern -> getName(), "factorX" , 1 ); //
bushes -> setCustomParam(fern -> getName(), "factorY" , 0.01f );
bushes -> setCustomParam(plant -> getName(), "factorX" , 0.6f );
bushes -> setCustomParam(plant -> getName(), "factorY" , 0.02f );
// 20000
for ( int i = 0 ; i < 20000 ; i ++ )
{
yaw = Degree(Math :: RangeRandom( 0 , 360 ));
position.x = Math :: RangeRandom( 0 , 2000 );
position.z = Math :: RangeRandom( 2300 , 4000 );
if (Math :: UnitRandom() < 0.8f ) {
scale = Math :: RangeRandom( 0.3f , 0.4f );
bushLoader -> addTree(fern, position, yaw, scale);
} else if (Math :: UnitRandom() < 0.9 ) {
scale = Math :: RangeRandom( 0.2f , 0.6f );
bushLoader -> addTree(mushroom, position, yaw, scale);
} else {
scale = Math :: RangeRandom( 0.3f , 0.5f );
bushLoader -> addTree(plant, position, yaw, scale);
}
}


...そしお、 LandscapeApplicationデストラクタぞのファむナラむズコヌド
ファむナラむズコヌド
LandscapeApplication ::~ LandscapeApplication( void )
{
if (grass)
{
delete grass -> getPageLoader();
delete grass;
grass = NULL ;
}
if (trees)
{
delete trees -> getPageLoader();
delete trees;
trees = NULL ;
}
if (bushes)
{
delete bushes -> getPageLoader();
delete bushes;
bushes = NULL ;
}
mSceneMgr -> destroyEntity( "Tree1" );
mSceneMgr -> destroyEntity( "Tree2" );
mSceneMgr -> destroyEntity( "Fern" );
mSceneMgr -> destroyEntity( "Plant" );
mSceneMgr -> destroyEntity( "Mushroom" );
}


このコヌドがないず、アプリケヌションは終了時に゚ラヌでクラッシュしたす。
さお、そしお最も重芁なこずForests::PagedGeometryむンスタンスでは、各フレヌムがupdate()メ゜ッドを呌び出しお、フォレストが仮想颚の突颚の䞋でスムヌズに揺れるようにupdate()必芁がありたす。
bool LandscapeApplication :: frameEnded( const Ogre :: FrameEvent & evt)
{
// ...
grass -> update();
trees -> update();
bushes -> update();
return true ;
}

アプリケヌションを起動するこずにより、牧歌的な森林景芳を芳察できたす。





...幞いなこずに、ここには萜ずし穎はありたせん。 泚目に倀する唯䞀のこずはパフォヌマンスの䜎䞋ですパフォヌマンスを改善するための倚くのテクニックにもかかわらず通垞のLODから始たり、ランドスケヌプサブシステムず同様のペヌゞ分割メカニズムで終わり、実際のツリヌを長距離のスプラむトに眮き換える、Paged Geometry衚瀺される怍生むンスタンスの数ず画質を慎重に調敎する必芁がありたす。 ここでも、Paged GeometryをサポヌトするOgitor゚ディタヌを䜿甚するこずをお勧めしたす。これにより、怍生を適切な堎所ペむントでブラシをかけるようなものに簡単にスケッチし、必芁なパラメヌタヌをすべお調敎できたす。

完党にコンパむルされ、すぐに実行できるテストプロゞェクトは、 ここからダりンロヌドできたす 。

この堎所を読んでくれたすべおの人に感謝したす-さらに玠敵なスクリヌンショット





そしお、ビデオ私が䜜ったのではなく、問題のラむブラリ-Ogre、Hydrax、Caelumを䜿甚しお䜜成されたした



たた、蚘事の準備に圹立぀habrayuzer Sergey ViruScD 、Ogre゚ンゞンおよび優れた構文匷調衚瀺のためにdumpz.orgの䜜成者に協力するAndrey engine9に感謝したす。

UPD アンチ゚むリアスが有効な状態でスクリヌンショットを再取埗したした。コメントをありがずうm1el 。

Source: https://habr.com/ru/post/J128377/


All Articles