how to do multiple terras
-
- Goblin
- Posts: 272
- Joined: Thu Jun 10, 2004 4:19 am
- x 26
how to do multiple terras
So, is it possible to have multiple terras at once? Like, page them in and out and stitch them together? How would I go about this? I'm sort of clueless.
-
- OGRE Team Member
- Posts: 5446
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1348
Re: how to do multiple terras
I can't remember if it was supported. I ported Terra to another engine and we're using multiple Terras there. IIRC these changes to support multiple Terras were sync'ed with Ogre.
If everything is alright (i.e. planets align), simply creating another Ogre::Terra pointer should do (and setting a different offset, of course). You need to call Terra::update() on both to determine visibility of the chunks to draw, and recalculate shadows if light direction changes.
Each Terra can have its own material datablock.
If everything is alright (i.e. planets align), simply creating another Ogre::Terra pointer should do (and setting a different offset, of course). You need to call Terra::update() on both to determine visibility of the chunks to draw, and recalculate shadows if light direction changes.
Each Terra can have its own material datablock.
-
- Goblin
- Posts: 272
- Joined: Thu Jun 10, 2004 4:19 am
- x 26
Re: how to do multiple terras
Well the problem seems to come from the shadow mapper, each terra has its own shadow mapper and yet that shadow mapper is bound specifically to a compositor channel [2]. Wouldn't i need to somehow swap these maps on the compositor channel?
-
- Goblin
- Posts: 272
- Joined: Thu Jun 10, 2004 4:19 am
- x 26
Re: how to do multiple terras
Code: Select all
if (terra){
//Terra is initialized
const Ogre::ShadowMapper* shadowMapper = terra->getShadowMapper();
shadowMapper->fillUavDataForCompositorChannel(&externalChannels[1], initialLayouts,
initialUavAccess);
}else{
//The texture is not available. Create a dummy dud.
Ogre::TextureGpuManager* textureManager = root->getRenderSystem()->getTextureGpuManager();
Ogre::TextureGpu* nullTex = textureManager->createOrRetrieveTexture("DummyNull",
Ogre::GpuPageOutStrategy::Discard,
Ogre::TextureFlags::ManualTexture,
Ogre::TextureTypes::Type2D);
nullTex->setResolution(1u, 1u);
nullTex->setPixelFormat(Ogre::PFG_R10G10B10A2_UNORM);
nullTex->scheduleTransitionTo(Ogre::GpuResidency::Resident);
externalChannels[1] = nullTex;
}
getSceneManager()->setForwardClustered(true, 4, 4, 24, 20, 5, 20, 0, 1200);
mWorkspace = compositorManager->addWorkspace(sceneManager, externalChannels, camera,
"Tutorial_TerrainWorkspace", true, -1,
(Ogre::UavBufferPackedVec*)0, &initialLayouts,
&initialUavAccess);
-
- OGRE Team Member
- Posts: 5446
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1348
Re: how to do multiple terras
This issue is split in 2 parts:
Part 1:
The compositor workspace is something you're in control of. The shadow mapper is bound to channel[2] but this is not a hard limit, and this is to expose the texture to Ogre, so that the proper memory barriers are set in place (otherwise rendering may start before the compute shader is done writing to the shadow map)
The modified script would look like this (I'm skipping the shadow node since that stays the same):
And C++ code:
2.3 Answer:
Exposing the texture to the compositor has been removed since it was user hostile and even if you knew what you were doing, it was very error prone and certain rendering algorithms could simply not be implemented. Although this may result in slightly higher CPU overhead (profiling reveals it's negligible), our sanity demanded it.
So you don't need to do anything in 2.3.
Part 2:
Part 1 answers and solves your question, but you're still left with the fact that HlmsPbsTerraShadows only accepts one terrain shadow map at at a time.
There are two possible solutions:
1. Modify HlmsPbsTerraShadows (and its shader code) to support multiple Terras. That means commandBuffer->addCommand<CbTexture>() needs to either be called per renderable rather than in HlmsPbsTerraShadows::hlmsTypeChanged; or you set all textures at once.
This also means HlmsPbsTerraShadows::getPassBufferSize needs to be called for N terras.
And the shader code needs to index the texture and offsets to use per terrain idx.
It's possible but it's a bit more than just 2 lines of code changes.
2. Keep things as is, and assume there is only ever one Terra active, and actively switch HlmsPbsTerraShadows::mTerra based on the position of the camera. This means however, there may be a sudden "pop" when crossing the seams between the terrains because there's suddenly an entire quadrant of Items being affected by terrain shadows while another quadrant loses those shadows.
If there's few or no items at the boundaries, this issue won't be noticed at all.
Note that terrain-shadows-on-terrain will still work as normal. It's just terrain-shadows-on-items what's affected.
Part 1:
2.2 Answer:Well the problem seems to come from the shadow mapper, each terra has its own shadow mapper and yet that shadow mapper is bound specifically to a compositor channel [2]. Wouldn't i need to somehow swap these maps on the compositor channel?
The compositor workspace is something you're in control of. The shadow mapper is bound to channel[2] but this is not a hard limit, and this is to expose the texture to Ogre, so that the proper memory barriers are set in place (otherwise rendering may start before the compute shader is done writing to the shadow map)
The modified script would look like this (I'm skipping the shadow node since that stays the same):
Code: Select all
compositor_node Tutorial_TerrainRenderingNode
{
in 0 rt_renderwindow
in 1 TerraShadowTexture1
in 2 TerraShadowTexture2
target rt_renderwindow
{
pass clear
{
colour_value 0.2 0.4 0.6 1
}
pass render_scene
{
load
{
all clear
clear_colour 0.2 0.4 0.6 1
}
store
{
colour store_or_resolve
depth dont_care
stencil dont_care
}
expose TerraShadowTexture1
expose TerraShadowTexture2
overlays on
shadows Tutorial_TerrainShadowNode
}
}
}
workspace Tutorial_TerrainWorkspace
{
connect_external 0 Tutorial_TerrainRenderingNode 0
connect_external 1 Tutorial_TerrainRenderingNode 1
connect_external 2 Tutorial_TerrainRenderingNode 2
}
Code: Select all
CompositorChannelVec externalChannels( 2 );
//Render window
externalChannels[0] = renderWindow->getTexture();
//Terra's Shadow texture
ResourceLayoutMap initialLayouts;
ResourceAccessMap initialUavAccess;
//Terra is initialized
ShadowMapper const *shadowMapper = mTerra0->getShadowMapper();
shadowMapper->fillUavDataForCompositorChannel( &externalChannels[1], initialLayouts,
initialUavAccess );
shadowMapper = mTerra1->getShadowMapper();
mTerra->getShadowMapper();
shadowMapper->fillUavDataForCompositorChannel( &externalChannels[2], initialLayouts,
initialUavAccess );
return compositorManager->addWorkspace( sceneManager, externalChannels, camera,
"Tutorial_TerrainWorkspace", true, -1,
(UavBufferPackedVec*)0, &initialLayouts,
&initialUavAccess );
Exposing the texture to the compositor has been removed since it was user hostile and even if you knew what you were doing, it was very error prone and certain rendering algorithms could simply not be implemented. Although this may result in slightly higher CPU overhead (profiling reveals it's negligible), our sanity demanded it.
So you don't need to do anything in 2.3.
Part 2:
Part 1 answers and solves your question, but you're still left with the fact that HlmsPbsTerraShadows only accepts one terrain shadow map at at a time.
There are two possible solutions:
1. Modify HlmsPbsTerraShadows (and its shader code) to support multiple Terras. That means commandBuffer->addCommand<CbTexture>() needs to either be called per renderable rather than in HlmsPbsTerraShadows::hlmsTypeChanged; or you set all textures at once.
This also means HlmsPbsTerraShadows::getPassBufferSize needs to be called for N terras.
And the shader code needs to index the texture and offsets to use per terrain idx.
It's possible but it's a bit more than just 2 lines of code changes.
2. Keep things as is, and assume there is only ever one Terra active, and actively switch HlmsPbsTerraShadows::mTerra based on the position of the camera. This means however, there may be a sudden "pop" when crossing the seams between the terrains because there's suddenly an entire quadrant of Items being affected by terrain shadows while another quadrant loses those shadows.
If there's few or no items at the boundaries, this issue won't be noticed at all.
Note that terrain-shadows-on-terrain will still work as normal. It's just terrain-shadows-on-items what's affected.