Few serious questions for Ogre-Next, moving Stunt Rally

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Crystal Hammer wrote: Sun Jun 18, 2023 5:58 pm

Okay thank you for help with there. I'll address them later.

I made a video with a faster way to leak v1 meshes GPU RAM.
So, as on video:

  • load a track with pipes e.g. that jungle Jng5-Pipes one
  • go to road detail, set high subdivision counts (steps and multipliers) (but not too high, it overflows 16bit index buffers), and lowest length dimension.
  • press B to rebuild road and F4 to save track (just check on Settings - Settings on bottom, to allow saving originals), so you won't need to do previous step any more.
  • now select a pipe road point in middle (its close 4 segments have a lot of vertices now).
  • shift left right for a couple seconds for me already show GPU RAM increasing (last value bottom right on Fps bar). And it won't go down on track reload or otherwise.

I got something better: taking a look at your code I reproduced the problem in a much smaller sample:

Code: Select all

//-----------------------------------------------------------------------------------
void V2MeshGameState::destroy()
{
    if( !mMesh )
        return;

using namespace Ogre;

SceneManager *sceneManager = mGraphicsSystem->getSceneManager();
sceneManager->destroySceneNode( mSceneNode );
sceneManager->destroyItem( mItem );

MeshManager::getSingleton().remove( mMesh );
mMesh.reset();
v1::MeshManager::getSingleton().remove( mMesh1 );
mMesh1.reset();
}
//-----------------------------------------------------------------------------------
void V2MeshGameState::import()
{
    destroy();

using namespace Ogre;

// clang-format off
const float cubeVertex[4*(3 + 3 + 3 + 2)] = {
     -1, -1, 0, 0, 1, 0, 0, 0 ,//
      1, -1, 0, 0, 1, 0, 1, 0 ,//
      1,  1, 0, 0, 1, 0, 1, 1 ,//
     -1,  1, 0, 0, 1, 0, 0, 1 ,//
};
// clang-format on
const uint16 cubeIndices[6] = {           //
                                0, 1, 2,  //
                                2, 3, 0
};

VertexElement2Vec vertexElements;

vertexElements.push_back( VertexElement2( VET_FLOAT3, VES_POSITION ) );
vertexElements.push_back( VertexElement2( VET_FLOAT3, VES_NORMAL ) );
vertexElements.push_back( VertexElement2( VET_FLOAT2, VES_TEXTURE_COORDINATES ) );

const size_t bytesPerVertex = VaoManager::calculateVertexSize( vertexElements );

const size_t iterations = 5000;

uint8 *vertexData = reinterpret_cast<uint8 *>(  // vertices
    OGRE_MALLOC_SIMD( bytesPerVertex * 4u * iterations, MEMCATEGORY_GEOMETRY ) );
uint16 *indexData = reinterpret_cast<uint16 *>(  // vertices
    OGRE_MALLOC_SIMD( sizeof( uint16 ) * 6u * iterations, MEMCATEGORY_GEOMETRY ) );

for( size_t i = 0u; i < iterations; ++i )
{
    memcpy( vertexData + ( bytesPerVertex * 4u ) * i, cubeVertex, bytesPerVertex * 4u );
    memcpy( indexData + 6u * i, cubeIndices, sizeof( uint16 ) * 6u );
}

SceneManager *sceneManager = mGraphicsSystem->getSceneManager();
VaoManager *vaoManager = sceneManager->getDestinationRenderSystem()->getVaoManager();

VertexBufferPacked *vertexBuffer = vaoManager->createVertexBuffer(
    vertexElements, iterations * 4u, BT_DEFAULT, vertexData, true );
IndexBufferPacked *indexBuffer = vaoManager->createIndexBuffer(
    IndexBufferPacked::IT_16BIT, iterations * 6u, BT_IMMUTABLE, indexData, true );

VertexBufferPackedVec vertexBuffers;
vertexBuffers.push_back( vertexBuffer );

VertexArrayObject *vao =
    vaoManager->createVertexArrayObject( vertexBuffers, indexBuffer, OT_TRIANGLE_LIST );

Ogre::MeshPtr mesh =
    MeshManager::getSingleton().createManual( "v2 Mesh without Tangents", "General" );
SubMesh *subMesh = mesh->createSubMesh();
subMesh->mVao[VpNormal].push_back( vao );
subMesh->mVao[VpShadow].push_back( vao );

Aabb aabox( Vector3::ZERO, Vector3( 2.0f ) );

mesh->_setBounds( aabox, false );  //?
mesh->_setBoundingSphereRadius( ( aabox.getMaximum() - aabox.getMinimum() ).length() / 2.0 );

mMesh1 = v1::MeshManager::getSingleton().create( "V1 TANGENT MESH", "General" );
mMesh1->setVertexBufferPolicy( v1::HardwareBuffer::HBU_STATIC, false );
mMesh1->setIndexBufferPolicy( v1::HardwareBuffer::HBU_STATIC, false );

mMesh1->importV2( mesh.get() );

MeshManager::getSingleton().remove( mesh );  // not needed
mesh.reset();

mMesh1->buildTangentVectors();

mMesh = MeshManager::getSingleton().createManual( "v2 final mesh", "General", 0 );
mMesh->importV1( mMesh1.get(), false, false, false );

mSceneNode =
    sceneManager->getRootSceneNode( SCENE_STATIC )->createChildSceneNode( SCENE_STATIC );
mItem = sceneManager->createItem( "v2 final mesh", "General", SCENE_STATIC );
// it->setVisible( false );
// it->setCastShadows( false );
mItem->setVisibilityFlags( 0x01 );
mSceneNode->attachObject( mItem );
}

It basically does everything you're doing every frame, by calling import() every frame. It should make things much easier to debug for me.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Ok cool. I pushed this and previous fixes to most of these.

But if I do this // if( !renderWindow->isVisible() ) then it sleeps all the time with 1 Fps :) and if I comment out that sleep (or whole block) then I get even worse issue: after like 15 sec or so of being inactive PC hangs and I need to reset it. I think it wasn't RAM.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Crystal Hammer wrote: Sun Jun 18, 2023 7:46 pm

But if I do this // if( !renderWindow->isVisible() ) then it sleeps all the time with 1 Fps :) and if I comment out that sleep (or whole block) then I get even worse issue: after like 15 sec or so of being inactive PC hangs and I need to reset it. I think it wasn't RAM.

I cannot repro that behavior?

Anyway. I've got good news! The leak when editing roads is fixed!

The problem is that you were doing the following:

  1. Create mesh v2 'A'

  2. Convert mesh v2 'A' to mesh v1 'B'

  3. Destroy v2 'A'

  4. Generate tangents on mesh 'B'

  5. Convert mesh v1 'B' to mesh v2 'C'

Because you never called meshA->load() (because you didn't have to), when you destroy it in step 3, OgreNext would see the Mesh was never loaded and thus unloadImpl() was never called... which is still necessary to destroy some misc stuff.

It's possible the bug is yours because I think you still should call meshA->load() since it was manually created; and you made it ready; so you should call this to tell OgreNext the mesh is ready.

However it's also a bug of OgreNext that this could happen at all.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

dark_sylinc wrote: Sun Jun 18, 2023 8:11 pm

I cannot repro that behavior?

Ah my bad, I commented it out in wrong place.

dark_sylinc wrote: Sun Jun 18, 2023 8:11 pm

The leak when editing roads is fixed!

Great, thanks. I added that mesh->load(); too just in case and also since it didn't require rebuilding Ogre etc.

If you had time to look at my other strange issue next (or next week, any time etc) then it's Problem 1 from here.
I'm glad editor doesn't leak now, but this other issue forces me to render all its minimap RTTs each frame, which I usually skipped.

As for mCachedTransformOutOfDate, yes I am setting ndSky each frame to camera position, and thanks, I forgot that light has node too and I'm setting light direction after I update sun every frame too to "silence" atmosphere changing it also (or maybe I commented it out). So I need to call ndSun->_getFullTransformUpdated(); also.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

I looked into your Problem #1 (minimap terrain).

I found the following:

  • When MANUAL_RTT_UPD is not defined, the minimap is one of the last things to render.
  • When MANUAL_RTT_UPD is defined, the minimap is one of the first things to render.

The textures bound look exactly the same in both, that's good.

However what looks different when put side by side is the definition of the PassBuffer:

  • When MANUAL_RTT_UPD is not defined, PassBuffer.lights exists, which means there is at least one directional light enabled. However its values are all zero (direction/position, diffuse, specular). I don't know if this is intentional or not.
  • When MANUAL_RTT_UPD is defined, PassBuffer.lights does not exist at all. which means no directional light exists or they are all disabled (setVisible(false)). My speculation is that this triggers a bug in the shader generation since honestly it was never written to expect having no lights.

Edit: Ahhh, it gets peachy. According to Vulkan, when MANUAL_RTT_UPD is NOT defined, the vales of the light aren't zero. They are uninitialized. Ugh.
Edit 2: OK I'm not sure they're uninitialized. They look like valid values.

Misc

  • You can control whether a workspace renders every frame by toggling CompositorWorkspace::setEnabled.
  • Use CompositorPassSceneDef::mEnableForwardPlus = false (enable_forward_plus in script) to disable Forward+ during the minimap render. It's eating you a lot of performance unnecessarily.
User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Thanks for testing. Well this is very intriguing. I tried a few things, but nothing changed this.
So, workspace->setEnabled(false) doesn't work, I also see it only changes mEnabled.
But whatever I did, it always behaves the way it was set in CompositorManager2::addWorkspace( for bEnabled at start.

  • I tried addWorkspace with true and then after 100 frames (in my App::UpdRnd2Tex()) doing setEnabled(false) and updating manually, it still updates every frame.
  • I tried setEnabled(false) in 1st frame, and updating once in every 100 frames, now I get suddenly white shaded terrain(s).
  • When I setEnabled(false) right after addWorkspace( with true, I get now completely dark view and I still get less Fps.

Should I call something after setEnabled( or is something missing?

I added enable_forward_plus false in script, for pass render_scene in RTTs without lights but I see no change in Fps.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay, it's weekend again and it's been 2 weeks already, it'd be great to progress further and fix stuff.
Here's a list of my current standing issues:

  1. Problem #1 with MANUAL_RTT_UPD is defined (above posts). Maybe not crucial, but it's started already and it drops Fps noticeably in editor.
  2. I got something important, with planar reflections again. I got their code into our scenes so I can have many in right positions but they don't seem to work, i.e. aren't switching to right actor like either I have bugs or their frustum / camera computations are wrong?
    Few quick questions first:
    • Can only one be used? Here: pbs->setPlanarReflections( mPlanarRefl );? What if I wanted completely own reflections (own workspace,texture etc) for each fluid/water areas?
    • Was this tested with many actors? I see lots of code for it. But there is just 1 Pbs and 1 Unlit in demo sample.
    • How do I properly create planar reflection with e.g. up plane, normal 0,1,0 and position 10,20,30 in demo? I'm not sure, anymore, I found some combination that worked but maybe it's bad, why would node need to have any orientation set, if I can create plane mesh with good normal and set node position? But it's not reflecting then.
  3. So if I want to have different uniform Ogre::HlmsPbsDatablock::MaterialSizeInGpu for uploadToConstBuffer in my HlmsPbsDatablock inherited class, will there be a way to change this hardcoded size? Mentioned here.
    The only way now (to change MaterialSizeInGpu) is having whole own HlmsPbsDatablock, own HlmsPbs, and registering it, right?
  4. Is having uniforms cheap? I see there is a lot of stuff in there, now MaterialSizeInGpu is about 270 bytes. Would it matter if I just add all my stuff there too? Say everything I'll ever need (e.g. 120 B), globally for all shaders, not only for those which need it. (E.g. grass deform spheres, tree wind parameters, car paints stuff, etc).
  5. Would water really need own Hlms? There are many differences but for now I'm really more comfortable writing my stuff inside Pbs shaders directly, instead of better approach. Anyway it doesn't seem to be easy to change sampling more textures instead of 1 (for diffuse, normal specular etc) in Pbs, except maybe using detail textures for this IDK.
    I was also thinking of doing that Ocean mod for Terra, but felt the same way. I mean not even having own classes, but doing a bool mbWater inside Terra and changing what's needed depending on that in my already modified Terra code. Does this sound okay? (I got it already modified somewhat with blendmap, seems like less code files just more complicated, and also I'm not a fan of too much O.O.).
User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay, it's been a long while.
I create 3 planar reflections actors in sample. It works okay. I even tried skipping their frames for more Fps in general, seems okay. And also found where to set own Lod Bias for them and shorter camera Far distance.
Problem 2 is done. Only 1 new question:

So if I have e.g. 5 water areas on map I put 5 here, right:
mPlanarReflections->setMaxActiveActors( 5u, ..
But is it possible to use just 1 (PlanarReflections RTT) for all of areas? It sometimes would be okay (we did that in old SR anyway) for better Fps.

I should probably do sky as postprocess I think, since scaling that skydome mesh for every RTT having it's own far distance is trouble now.

And Problem 1. is still an unsolved mystery even after trying. And I think it's rather my bug, but I'm not sure either. Other places in Ogre like even planar reflections render fine if I set them as manual and update later. But my editor RTTs have that dark issue when I do. Maybe order of creating or order in scripts IDK.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

So, pardon my French, is there any freaking chance of getting help (or even replies) here again? It's awesome when you do, but the last time you did was 19 Jun. You wrote here "I can only work on this on weekends, and only partially". Well, doesn't sound to me like it'll be silence for 1.5 months.
I also PMed you ("SR3 issues etc" Sent: 11 Jul). No replies whatsoever. I see that you are recently busy with ParticleFX2 (just because I looked it up, not because you said anything), that's great, cool.

Could you at least comment something honest on this support (or lack of it)?
IDK e.g. like: "don't count on my help anymore", "I'm busy for next month", "I'll continue on 12th or 17th" or "I can't say when I'll have time for this", whatever maybe "Ogre-Next is for experts, and you're a noob" or something :x :? .
Yeah sorry, I wish I knew it will look like this, after I first asked about support (27 Feb, point 1 here). Still it's not like I have an alternative or anything, won't move to Godot (since SR was already in Ogre) and even if it has better support I'd need a year to learn anything else. But I also suspect it's actually bad for any SR3 contributors, I mean who knows Ogre-Next so well or at all.

Maybe you could record some quick tutorial videos (BTW of doing stuff, not even extra)? Not everyone has such vast knowledge and honestly I didn't even know of RenderDoc before. And I surely don't know how to use it, or fix stuff in Ogre-Next (like half of my issues needed it) or debug inside Ogre-Next when I get a callstack from it, to know what really has caused it in my code and how to fix that.


I know I should debug more and I'm doing it now. It's just I still don't know what to do with these freaking issues, some won't even let me start:
Issue 1. When I load a track with trees in game.

Code: Select all

Ogre::Node::_getFullTransform() const (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/include/OgreNode.h:681)
Ogre::MovableObject::_getParentNodeFullTransform() const (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreMovableObject.cpp:292)
Ogre::HlmsPbs::fillBuffersFor(Ogre::HlmsCache const*, Ogre::QueuedRenderable const&, bool, unsigned int, Ogre::CommandBuffer*, bool) (/home/ch/_sr/og3/Ogre/ogre-next/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp:3219)
Ogre::HlmsPbs::fillBuffersForV2(Ogre::HlmsCache const*, Ogre::QueuedRenderable const&, bool, unsigned int, Ogre::CommandBuffer*) (/home/ch/_sr/og3/Ogre/ogre-next/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp:2969)
Ogre::RenderQueue::renderGL3(Ogre::RenderSystem*, bool, bool, Ogre::HlmsCache*, Ogre::RenderQueue::RenderQueueGroup const&, Ogre::IndirectBufferPacked*, unsigned char*, unsigned char*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreRenderQueue.cpp:650)
Ogre::RenderQueue::render(Ogre::RenderSystem*, unsigned char, unsigned char, bool, bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreRenderQueue.cpp:450)
Ogre::SceneManager::_renderPhase02(Ogre::Camera*, Ogre::Camera const*, unsigned char, unsigned char, bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreSceneManager.cpp:1489)
Ogre::Camera::_renderScenePhase02(Ogre::Camera const*, unsigned char, unsigned char, bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreCamera.cpp:386)
Ogre::Viewport::_updateRenderPhase02(Ogre::Camera*, Ogre::Camera const*, unsigned char, unsigned char) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreViewport.cpp:206)
Ogre::CompositorPassScene::execute(Ogre::Camera const*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/Pass/PassScene/OgreCompositorPassScene.cpp:313)
Ogre::CompositorNode::_update(Ogre::Camera const*, Ogre::SceneManager*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorNode.cpp:833)
Ogre::CompositorWorkspace::_update(bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorWorkspace.cpp:836)
Ogre::RenderSystem::compositorWorkspaceUpdate(Ogre::CompositorWorkspace*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreRenderSystem.cpp:1322)
Ogre::CompositorWorkspace::_update(bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorWorkspace.cpp:744)
AppGui::UpdCubeRefl() (/home/ch/_sr/og3/_sr/src/common/AppGui_CubeReflect.cpp:193)
App::update(float) (/home/ch/_sr/og3/_sr/src/game/Game_Update.cpp:238)
BaseSystem::update(float) (/home/ch/_sr/og3/_sr/src/OgreCommon/BaseSystem.cpp:44)
GraphicsSystem::update(float) (/home/ch/_sr/og3/_sr/src/OgreCommon/GraphicsSystem.cpp:472)
MainEntryPoints::mainAppSingleThreaded(int, char const**) (/home/ch/_sr/og3/_sr/src/OgreCommon/System/Desktop/MainLoopSingleThreaded.cpp:145)

We had once issue with sky and was fixed by ndSky->_getFullTransformUpdated(); after any change to its node.
But now I get this crash for freaking trees in game (if I see this right) which for sure aren't moved, and are created the simplest way. I also disabled skyDome creating.

Issue 2. Whenever I add something to 800.PixelShader_piece_ps.any I get a crash at start, either immediately or after deleting shader cache or sometime later saying e.g.:

Code: Select all

20:42:14: Creating PSO with 100000017VertexShader_vs 100000017PixelShader_ps
20:42:14: Shader Compiler:error(high) 71: 0:1077(15): error: cannot access field `globalTime' of structure
20:42:14: Shader Compiler:error(high) 72: 0:1077(15): error: type mismatch
20:42:14: Shader Compiler:error(high) 73: 0:1077(15): error: type mismatch
20:42:14: Shader Compiler:message(high) 74: 0:1172(35): warning: `time' used uninitialized
20:42:14: GLSL compile log: 100000017PixelShader_ps
0:1077(15): error: cannot access field `globalTime' of structure
0:1077(15): error: type mismatch
0:1077(15): error: type mismatch
0:1172(35): warning: `time' used uninitialized
20:42:14: OGRE EXCEPTION(3:RenderingAPIException): Fragment Program 100000017PixelShader_ps failed to compile. See compile log above for details. in GLSLShader::compile at ../../RenderSystems/GL3Plus/src/GLSL/OgreGLSLShader.cpp (line 313)

I setProperty( "water", 1 ); myself in HlmsPbs2::calculateHashForPreCreate( and in shader:

Code: Select all

	@property( water && !hlms_shadowcaster && hlms_lights_directional && !alpha_test)
		float time = passBuf.globalTime.x; // * _h(1.2);

I guess @property( water && !hlms_shadowcaster ) check should be enough?
How do I know what freaking shader permutation / option causes this and how to get rid of these? It's really annoying.

Issue 3. Something new I saw today, no idea, from compositor. I guess it has its own issues maybe now, we didn't get that far to check. And I still didn't add refraction or depth reading etc.

Code: Select all

Ogre::TextureGpu::isDiscardableContent() const (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreTextureGpu.cpp:824)
Ogre::BarrierSolver::resolveTransition(Ogre::FastArray<Ogre::ResourceTransition>&, Ogre::TextureGpu*, Ogre::ResourceLayout::Layout, Ogre::ResourceAccess::ResourceAccess, unsigned char) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreResourceTransition.cpp:163)
Ogre::HlmsPbs::analyzeBarriers(Ogre::BarrierSolver&, Ogre::FastArray<Ogre::ResourceTransition>&, Ogre::Camera*, bool) (/home/ch/_sr/og3/Ogre/ogre-next/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp:1420)
Ogre::CompositorPassScene::analyzeBarriers(bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/Pass/PassScene/OgreCompositorPassScene.cpp:428)
Ogre::CompositorPassScene::execute(Ogre::Camera const*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/Pass/PassScene/OgreCompositorPassScene.cpp:289)
Ogre::CompositorNode::_update(Ogre::Camera const*, Ogre::SceneManager*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorNode.cpp:833)
Ogre::CompositorWorkspace::_update(bool) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorWorkspace.cpp:836)
Ogre::CompositorManager2::_updateImplementation() (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorManager2.cpp:790)
Ogre::RenderSystem::updateCompositorManager(Ogre::CompositorManager2*) (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreRenderSystem.cpp:1311)
Ogre::CompositorManager2::_update() (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/Compositor/OgreCompositorManager2.cpp:712)
Ogre::Root::_updateAllRenderTargets() (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreRoot.cpp:1568)
Ogre::Root::renderOneFrame() (/home/ch/_sr/og3/Ogre/ogre-next/OgreMain/src/OgreRoot.cpp:1102)
GraphicsSystem::update(float) (/home/ch/_sr/og3/_sr/src/OgreCommon/GraphicsSystem.cpp:476)
MainEntryPoints::mainAppSingleThreaded(int, char const**) (/home/ch/_sr/og3/_sr/src/OgreCommon/System/Desktop/MainLoopSingleThreaded.cpp:145)
mainApp(int, char const**) (/home/ch/_sr/og3/_sr/src/common/Main.cpp:235)
main (/home/ch/_sr/og3/_sr/src/OgreCommon/MainEntryPointHelper.h:40)
__libc_start_main (@__libc_start_main:62)
_start (@_start:14)

If you can't help then just please say so, or best say when and what can I (we) count on (expect)?
SR3 beta is not far from ready to be released, but there is plenty of issues I should fix before. Many written here (and I'm guessing forgotten) and many still not touched yet, since I'm waiting for these unsolved and posted before.

And these are just my current blockers before trying to debug anything else, like those serious issues listed in my previous posts.
Still don't know how to properly add time to HLMS shaders, etc, I had many questions here.
And I still think a nice tutorial with few (advanced but) common things around extending HLMS would be best (not links to old forum topics when people did that in 2016 or so).

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Hi,

"I can only work on this on weekends, and only partially"

That means on OgreNext on general. And like any unpaid FOSS project, I'm not obligated to work. This is volunteer work. Some weekends I just want to watch TV and play games all day. Or work in my own projects.

The OgreNext stuff I do during the weeks is thanks to contract work.

I recently took a contract for the weekends, so it is likely I cannot look at it now.

Could you at least comment something honest on this support (or lack of it)?
IDK e.g. like: "don't count on my help anymore", "I'm busy for next month", "I'll continue on 12th or 17th" or "I can't say when I'll have time for this", whatever maybe "Ogre-Next is for experts, and you're a noob" or something :x :? .
Yeah sorry, I wish I knew it will look like this, after I first asked about support (27 Feb, point 1 here). Still it's not like I have an alternative or anything, won't move to Godot (since SR was already in Ogre) and even if it has better support I'd need a year to learn anything else. But I also suspect it's actually bad for any SR3 contributors, I mean who knows Ogre-Next so well or at all.

This is a mix of stuff because you did hit some issues that were purely OgreNext bugs; which is rare.

But on the other hands many of the issues you've had would've been solved by simply running the app in Debug mode. Or googling in the forums as these problems have surfaced in the past before. Or running Valgrind, or ASAN.

I understand that SR3 had A LOT of code and it's not the same as starting from scratch (which would've made a lot of things much easier for you) and you have a lot of components to port. It doesn't help that SR3 seems to do rendering wherever and whenever; it's not very structured. i.e. a structured way to update the game is to prepare all the data first and then fire all rendering related touching as little data as possible.

StuntRally wants to fire up rendering from listeners or start modifying data from arbitrary locations of code or data state and that is troublesome.

But try to focus on the stuff that works, and for the stuff that doesn't; strip to bare bones to analyze the problem in a much more simpler way with fewer things going on.

What you did when you started on the demo was the right way to do things (specially when you're unfamiliar): create a bare bones project; check the individual components you want to use are working; then translate those changes to the bigger project.

For example ForwardClustered takes a big toll on the CPU. Which makes debugging in single threading really hard. Turn it off (or use Forward3D, it makes the GPU take the hit instead). The less features you use, the easier it is to troubleshoot anything.

I can only steer you in the general direction of where to fix stuff, but there's a lot of stuff you have to do on your own. Your thread is 7 pages long by now; and it has a lot that has been asked; it's really hard to keep track of everything.

Issue 1. When I load a track with trees in game.
We had once issue with sky and was fixed by ndSky->_getFullTransformUpdated(); after any change to its node.
But now I get this crash for freaking trees in game (if I see this right) which for sure aren't moved, and are created the simplest way. I also disabled skyDome creating.

The solution is the same: Either you have to call _getFullTransformUpdated() or, since you're modifying the data after the call to SceneManager::updateAllTransform, you should move the update to happen earlier.

If you can't figure out where the modification is coming from, get familiar with gdb memory watchpoints:

Code: Select all

# GDB, get notified whenever a 4 byte address at 0xFFFFAAAA changes
watch ­-location 0xFFFFAAAA
# LLDB, same thing
wa s e ­­ 0xFFFFAAAA

You can help yourself by adding some sort of tag i.e.

Code: Select all

// Tag this object somehow:
renderable->setCustomParameter( 99999, Vector4(0,0,0,0) );

if( renderable->hasCustomParameter( 99999 ) )
   printf( "Reached the tagged renderable\n" );
   
// Do the same with movableObject->setUserAny if you want to watch a MovableObject, though many objects are both a MovableObject and a Renderable at the same time so that's not usually a problem, but can be.

Once you hit the "tagged breakpoint", add the watchpoint to the address in "&movableObject->mCachedAabbOutOfDate" (note that mCachedAabbOutOfDate is 1 byte and watchpoints watch 4 bytes so you'll get a few false positives).

honestly I didn't even know of RenderDoc before

OK for some reason I thought you were familiar with it. Have you seen this recent reply from me? It should guide you on how to troubleshoot rendering problems with it.

I guess @property( water && !hlms_shadowcaster ) check should be enough?
How do I know what freaking shader permutation / option causes this and how to get rid of these? It's really annoying.

I'm not going to sugar coat this one: PBS is a complex shader set; and making changes to it isn't easy.

The only solution is to read what the code is going on and it only gets easier as you get more familiar with the already-written shader code.

Based on the error description and the simplicity of the line, it's complaining that passBuff does not exist.

If we make a "Find in Files" search for passBuff in all *.any and *.glsl files in Samples/Media/Hlms/Pbs we find that it is declared in Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any:

Code: Select all

CONST_BUFFER_STRUCT_BEGIN( PassBuffer, 0 )
{
 // ... stuff ...
}
CONST_BUFFER_STRUCT_END( passBuf );

But this doesn't tell us much. It's declared there but where is it inserted? We must go higher and see in which piece it is.
If we scroll up, we'll end up at the beginning of the file:

Code: Select all

@piece( PassStructDecl )

Aha! Whenever PassStructDecl is inserted, passBuf gets defined. So we look for all instances of @insertpiece( PassStructDecl ):

We learn that for Vertex Shader it is in:

Code: Select all

@piece( DefaultHeaderVS )
	// START UNIFORM DECLARATION
	@insertpiece( PassStructDecl )
@end

And when we look on @insertpiece( DefaultHeaderVS ), it is always declared in VertexShader_vs.glsl
Nice.

But for the Pixel Shader:

Code: Select all

@piece( DefaultHeaderPS )
	// START UNIFORM DECLARATION
	@property( !hlms_shadowcaster || alpha_test )
		@property( !hlms_shadowcaster )
			@insertpiece( PassStructDecl )
		@end

Let's assume @insertpiece( DefaultHeaderPS ) is always inserted (which it is).
That's a lot of checks but if you think about it: only @property( water && !hlms_shadowcaster ) should be necessary.

If we are wrong; what you can do is to introduce syntax errors on the main shader files on purpose. That way you can understand what is getting inserted where and why.
Also remember to look at the property dump, it may provide more info (Hlms::setDebugOutputPath outputProperties should be true) but it makes error lines harder to read (because when the compiler says error on line 123; it does not include the dumped properties at the beginning, you have to remove them).

Issue 3. Something new I saw today, no idea, from compositor. I guess it has its own issues maybe now, we didn't get that far to check. And I still didn't add refraction or depth reading etc.

This happens when OgreNext detects you're trying to read from a texture before drawing anything to it. There are legit cases for this (e.g. HDR needs to know the luminance calculated on the previous frame, motion blur also needs data from previous frames) but it defaults to discard.

See keep_content in Ogre 2.3 notes

On a 2nd thought, it seems to be crashing at if( texture->isDiscardableContent() ) which means texture is either corrupted or nullptr. If that's the case then ASAN / Valgrind is a better tool.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Crystal Hammer wrote: Sat Jul 01, 2023 8:36 am
  1. Problem #1 with MANUAL_RTT_UPD is defined (above posts). Maybe not crucial, but it's started already and it drops Fps noticeably in editor.

I don't know, this is a complex one and it would be much easier if it's broken down to smaller reproducible parts.

Crystal Hammer wrote: Sat Jul 01, 2023 8:36 am
  1. I got something important, with planar reflections again. I got their code into our scenes so I can have many in right positions but they don't seem to work, i.e. aren't switching to right actor like either I have bugs or their frustum / camera computations are wrong?
    Few quick questions first:
    • Can only one be used? Here: pbs->setPlanarReflections( mPlanarRefl );? What if I wanted completely own reflections (own workspace,texture etc) for each fluid/water areas?
    • Was this tested with many actors? I see lots of code for it. But there is just 1 Pbs and 1 Unlit in demo sample.
    • How do I properly create planar reflection with e.g. up plane, normal 0,1,0 and position 10,20,30 in demo? I'm not sure, anymore, I found some combination that worked but maybe it's bad, why would node need to have any orientation set, if I can create plane mesh with good normal and set node position? But it's not reflecting then.

"I don't remember". A client needed Planar Reflections and used this a lot but it's been a while since I've used it.

How do I properly create planar reflection with e.g. up plane, normal 0,1,0 and position 10,20,30 in demo? I'm not sure, anymore, I found some combination that worked but maybe it's bad, why would node need to have any orientation set, if I can create plane mesh with good normal and set node position? But it's not reflecting then.

Because mirrors don't just have a position and normal; they have a right and up vector which are needed for knowing its dimensions and roll.

If you need all 3 axis (forward/normal, up, right) then what you have is a 3x3 Matrix, or in Ogre's preferred representation, a Quaternion. If you need a Position and Quaternion, then what you need is a node.

So if I want to have different uniform Ogre::HlmsPbsDatablock::MaterialSizeInGpu for uploadToConstBuffer in my HlmsPbsDatablock inherited class, will there be a way to change this hardcoded size? Mentioned here.
The only way now (to change MaterialSizeInGpu) is having whole own HlmsPbsDatablock, own HlmsPbs, and registering it, right?

I noticed the other day HlmsUnlit has a way to communicate this (by passing constBufferSize to HlmsUnlit protected constructor) but HlmsPbs does not (note that you'd have to overload uploadToConstBuffer to match the same material size you send to HlmsUnlit/HlmsPbs).

PRs to add the same functionality to HlmsPbs are welcome.

Is having uniforms cheap? I see there is a lot of stuff in there, now MaterialSizeInGpu is about 270 bytes. Would it matter if I just add all my stuff there too? Say everything I'll ever need (e.g. 120 B), globally for all shaders, not only for those which need it. (E.g. grass deform spheres, tree wind parameters, car paints stuff, etc).

They're cheap, but the more you have the less we can batch together (because the max is usually 64kb, so at 270 bytes per material we can draw up to 242 materials together in the same draw call (65536÷270 = 242 after truncation).

However if it's for all shaders, it sounds like it should go in to PassBuffer instead.

  1. Would water really need own Hlms? There are many differences but for now I'm really more comfortable writing my stuff inside Pbs shaders directly, instead of better approach. Anyway it doesn't seem to be easy to change sampling more textures instead of 1 (for diffuse, normal specular etc) in Pbs, except maybe using detail textures for this IDK.
    I was also thinking of doing that Ocean mod for Terra, but felt the same way. I mean not even having own classes, but doing a bool mbWater inside Terra and changing what's needed depending on that in my already modified Terra code. Does this sound okay? (I got it already modified somewhat with blendmap, seems like less code files just more complicated, and also I'm not a fan of too much O.O.).

Personally I prefer doing Water in its own Hlms because I use custom lighting and all that. But if you share code with Pbs then it makes sense to put it inside a derived class from HlmsPbs.

I originally thought Terra should be its own Hlms; and I later regretted it. It is now a derived class of HlmsPbs and shares a lot of code with it. This fixed a lot of problems.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay great, thanks, lots of useful information.
I fixed one bug already. And I started writing SR3 Developing doc, I'm not even sure if I'm right about few things there.

I thought I had a cool way of adding uniforms like globalTime to AtmosphereNprSkyStructDecl. But looks not that great.

  • I can't get which shaders will receive that, that's why I had so many crashes for shaders with this missing. Seems only if atmosky_npr property is set, but IDK how this works.
    Since I only now use fog and those params from AtmosphereNpr (not its rendered sky), I would be likely better of just having that ConstBuffers from it I think. But IDK at all how to achieve that.

  • Is there an easy (or medium, nothing is easy here) way of having some uniforms for all shaders? I mean like time, wind direction etc.
    And I mean really all: Pbs, Terra, Unlit etc. I wanted to also add gamma, brightness and such post process params easily. How else would I e.g. set these params values to all pixel shaders?

  • Can I just use float4 detailOffsetScale[4]; from MaterialStructDecl for any purpose if I'm not having any detail maps?

  • OK, let's say I'll add passing constBufferSize to HlmsPbs protected constructor and uploadToConstBuffer to match the same material size.
    Will I the be able to change this? Or will this value be now for all Pbs materials?

  • Can I create different Datablock classes with different MaterialSizeInGpu in my one custom HlmsPbs?
    If not then this probably means I should have few different Hlms for few cases. E.g. also just for grass and trees, since these only will need wind params. And while grass could only use uniforms, trees actually need own wind params for how much they bend and not too many so more of them could be put in 1 draw call, as you wrote, looks important.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Hi!

Global parameters (i.e. those available for every object) are among the easiest! What's hard to customize are per-object parameters. That's what preparePassHash is for!

I believe you're getting mixed up somewhere.

Crystal Hammer wrote: Sat Aug 19, 2023 8:16 pm
  • I can't get which shaders will receive that, that's why I had so many crashes for shaders with this missing. Seems only if atmosky_npr property is set, but IDK how this works.
    Since I only now use fog and those params from AtmosphereNpr (not its rendered sky), I would be likely better of just having that ConstBuffers from it I think. But IDK at all how to achieve that.

HlmsPbs::preparePassHash reads:

Code: Select all

mAtmosphere = sceneManager->getAtmosphere();

// and then calls
if( !casterPass )
{
    //...
    numPassConstBuffers += mAtmosphere->preparePassHash( this, numPassConstBuffers );
}

Where inside AtmosphereNpr::preparePassHash "atmosky_npr" is set.

Note that sceneManager->getAtmosphere() will always return a valid pointer. If it's unset, then it returns NullAtmosphereComponent whose NullAtmosphereComponent::preparePassHash does nothing.

And obviously, caster passes don't define "atmosky_npr".

  • Is there an easy (or medium, nothing is easy here) way of having some uniforms for all shaders? I mean like time, wind direction etc.
    And I mean really all: Pbs, Terra, Unlit etc. I wanted to also add gamma, brightness and such post process params easily. How else would I e.g. set these params values to all pixel shaders?

Yes!

Code: Select all

class MyListener : public HlmsListener
{
public:
	void preparePassHash( const CompositorShadowNode *shadowNode, bool casterPass,
						  bool dualParaboloid, SceneManager *sceneManager, Hlms *hlms ) override
	{
		if( casterPass )
			return;
		hlms->_setProperty( "my_property", value );
	}

	uint32 getPassBufferSize( const CompositorShadowNode *shadowNode, bool casterPass,
							  bool dualParaboloid, SceneManager *sceneManager ) const override
	{
		if( casterPass )
			return 0u;
		// Request 16 extra bytes for all pass buffers
		return 16;
	}

	float *preparePassBuffer( const CompositorShadowNode *shadowNode, bool casterPass,
							  bool dualParaboloid, SceneManager *sceneManager,
							  float *passBufferPtr ) override
	{
		if( casterPass )
			return passBufferPtr;
		// Write whatever the 16 bytes we requested
		*passBufferPtr++ = windDir.x;
		*passBufferPtr++ = windDir.y;
		*passBufferPtr++ = windDir.z;
		*passBufferPtr++ = 0.0f;
		
		return passBufferPtr;
	}
};

If you need to chain more than listener, you will have to create a listener that can call them all. e.g.

Code: Select all

class MasterListener : public HlmsListener
{
	std::vector<HlmsListener*> m_listeners;

public:
	// Repeat this for every function
	uint32 getPassBufferSize( const CompositorShadowNode *shadowNode, bool casterPass,
							  bool dualParaboloid, SceneManager *sceneManager ) const override
	{
		uint32 retVal = 0u;
		for( const HlmsListener *listener : m_listener )
			retVal += listener->getPassBufferSize( shadowNode, casterPass, dualParaboloid, sceneManager );
		return retVal;
	}
}
  • Can I just use float4 detailOffsetScale[4]; from MaterialStructDecl for any purpose if I'm not having any detail maps?

While this could break in future releases, it'd be very rare. So 90% yes.

  • OK, let's say I'll add passing constBufferSize to HlmsPbs protected constructor and uploadToConstBuffer to match the same material size.
    Will I the be able to change this? Or will this value be now for all Pbs materials?

I'm not sure I get this part.

  • Can I create different Datablock classes with different MaterialSizeInGpu in my one custom HlmsPbs?
    If not then this probably means I should have few different Hlms for few cases. E.g. also just for grass and trees, since these only will need wind params. And while grass could only use uniforms, trees actually need own wind params for how much they bend and not too many so more of them could be put in 1 draw call, as you wrote, looks important.

That probably will be very hard to get right. It could break too easily. I'd advise against that.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay great info.
Wow I think I've gone full circle now :) I actually did once add a global parameter with a HlmsListener to Pbs (which is mHlmsPbsTerraShadows because I use Terra like in that sample).
But now I actually understood why it wasn't working for Terra shaders (only Pbs), because it needs adding own HlmsListener to hlmsTerra too (similar to mHlmsPbsTerraShadows but without receiving terrain shadowmap params). This took me long enough. I didn't test yet.

I think I'll go the route of using for all datablock->getUserValue (has [3][4] so 12 floats) and getDetailMapOffsetScale (has [4][4] so 16 extra floats), that should be enough for everything, even water params.

I started coding Gui Material Editor (WIP screen, both in SR3 game and editor) for Pbs, I think once it could be used to edit all shaders without doing much in .material or .json.
Just a couple of questions:

  • are custom parameters saved in .material.json?
    E.g. I have in .material

    Code: Select all

    hlms WaterReflect pbs
    {
    	fluid yes
    but when I saved it into .json it was gone, lost.
    Please don't tell me it's not supported or something. How would I be able to get those back, when loading from .json to call setProperty?
  • second thing, materials in .json (getRoot()->getHlmsManager()->saveMaterials(HLMS_PBS,) are random, not sorted, do you know a way to quickly sort Pbs materials in json alphabetically? I think best would be to have this as bool param in Ogre already. Otherwise I can't save all materials then look around and edit similar in .json (easily). And saving just one for merging after isn't best. I surely would need to check or edit .json too.

I've been having serious issues with a new critical bug (or possibly the same since long ago that didn't happen so).
Looks cool screens, like a new Anomaly scenery. But joking aside I had enough of it and debugging to fix it is hard. All Pbs have messed up random textures (even Sky), and some blinking.
Obviously any help with this would be awesome.
Update: I found out the cause for this anomaly bug. It is happening because of this

Code: Select all

	mPlanarRefl->update( camera, camera->getAutoAspectRatio()
		? pass->getViewportAspectRatio( 0u ) : camera->getAspectRatio() );

inside void ReflectListener::passEarlyPreExecute( CompositorPass *pass ). I'll check what exactly, maybe my changes.

I'm debugging too. So far, I'm guessing this could be some buffer overrun. It doesn't happen always (like on half of tracks), now also in editor, and loading track again usually fixes it, but not in editor, lol.
I've run valgrind (slowly), and there are many issues, some I wouldn't suspect, from not my code too.
Should I treat them all as real bugs?
Should I disable everything on scene to get a stable running state and then enable back one by one to catch what is causing this? That's one way I think.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Hi!

Crystal Hammer wrote: Sun Aug 27, 2023 12:05 pm

I started coding Gui Material Editor (WIP screen, both in SR3 game and editor) for Pbs, I think once it could be used to edit all shaders without doing much in .material or .json.
Just a couple of questions:

  • are custom parameters saved in .material.json?
    E.g. I have in .material

    Code: Select all

    hlms WaterReflect pbs
    {
    	fluid yes
    but when I saved it into .json it was gone, lost.
    Please don't tell me it's not supported or something. How would I be able to get those back, when loading from .json to call setProperty?

Since we don't know about those custom properties, what you need to do is overload HlmsPbs::_saveJson to insert your own saving function.

The saving class can be based on HlmsJsonPbs, e.g. HlmsJsonMyOwn:

Code: Select all

class HlmsJsonMyOwn : public HlmsJsonPbs
{
public:
    void saveMaterial( const HlmsDatablock *datablock, String &outString )
    {
        outString += ",\n\t\t\t\"fluid\" : ";
        outString += StringConverter::toString( true );
        HlmsJsonPbs::saveMaterial( datablock, outString );
    }
};[

Note that user_values are saved as "user_values" in the Json by HlmsJsonPbs.

- second thing, materials in .json (getRoot()->getHlmsManager()->saveMaterials(HLMS_PBS,) are random, not sorted, do you know a way to quickly sort Pbs materials in json alphabetically? I think best would be to have this as bool param in Ogre already. Otherwise I can't save all materials then look around and edit similar in .json (easily). And saving just one for merging after isn't best. I surely would need to check or edit .json too.

This happens because we iterate through datablockMap in HlmsJson::saveMaterials, which are ordered by address pointer.

This could be fixed if the materials are copied to a temporary container which sorts them by name. And it would probably be a good thing to have.

I'm debugging too. So far, I'm guessing this could be some buffer overrun. It doesn't happen always (like on half of tracks), now also in editor, and loading track again usually fixes it, but not in editor, lol.
I've run valgrind (slowly), and there are many issues, some I wouldn't suspect, from not my code too.
Should I treat them all as real bugs?
Should I disable everything on scene to get a stable running state and then enable back one by one to catch what is causing this? That's one way I think.

Yes!
At the basic level this happens because something is mismatched:

  1. Wrong texture array is bound. In C++ this refers to:

    Code: Select all

    if( datablock->mTexturesDescSet != mLastDescTexture )
    {
        if( datablock->mTexturesDescSet )
        {
            // Rebind textures
            size_t texUnit = mTexUnitSlotStart;
    
            *commandBuffer->addCommand<CbTextures>() = CbTextures(
                (uint16)texUnit, datablock->mCubemapIdxInDescSet, datablock->mTexturesDescSet );
    
            if( !mHasSeparateSamplers )
            {
                *commandBuffer->addCommand<CbSamplers>() =
                    CbSamplers( (uint16)texUnit, datablock->mSamplersDescSet );
            }
            // texUnit += datablock->mTexturesDescSet->mTextures.size();
        }
    
        mLastDescTexture = datablock->mTexturesDescSet;
    }
    Which could be because it wasn't called, or somehow mTexturesDescSet is messed up, mTexUnitSlotStart is incorrect. Maybe the texture slot is incorrectly calculated (usually it's one of the setTextureReg)
  2. ArrayIdx is wrong, e.g. material[perInstance[drawId].materialId].diffuseIdx is wrong (if this is wrong, it's likely it's caused by corruption)
  3. Wrong material pool is bound, e.g. material[worldMaterialIdx[drawId].materialId] will be wrong. In C++ this refers to:

    Code: Select all

    // layout(binding = 1) uniform MaterialBuf {} materialArray
    const ConstBufferPool::BufferPool *newPool = datablock->getAssignedPool();
    *commandBuffer->addCommand<CbShaderBuffer>() =
        CbShaderBuffer( VertexShader, 1, newPool->materialBuffer, 0,
                        (uint32)newPool->materialBuffer->getTotalSizeBytes() );
    *commandBuffer->addCommand<CbShaderBuffer>() =
        CbShaderBuffer( PixelShader, 1, newPool->materialBuffer, 0,
                        (uint32)newPool->materialBuffer->getTotalSizeBytes() );
  4. worldMaterialIdx[drawId].materialId\* is wrong. If this is wrong, it's likely corruption.
  5. drawId is wrong (this happens when HlmsPbs::fillBuffersFor returns the wrong value).
  6. worldMaterialIdx is the wrong buffer. It is rare for this to be the case nowadays, mapNextTexBuffer/rebindTexBuffer takes care of it.

\* Note: worldMaterialIdx[drawId].materialId is just worldMaterialIdx[drawId].x & 0x1FF

Thus basically, we expect everything to be bound correctly but something isn't. For example if in RenderDoc you see that the texture being used is in the same Array being bound and fetched, but in a different slice (RenderDoc lets you scroll through all mipmaps and layers in the texture view), that means diffuseIdx is wrong.

If you see the TextureArray with the right texture is bound, but the shader is fetching it from another one e.g. the right texture lives in textureMaps0 but the shader is fetching from textureMaps1, then it's likely that every slot is off by 1, and mTexUnitSlotStart is incorrect.

Reducing the number of variables/features helps a lot in narrowing the problem.
Cheers.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay thanks for info.

Since we don't know about those custom properties, what you need to do is overload HlmsPbs::_saveJson to insert your own saving function.

So I got just one question, how do I get inside:

Code: Select all

void saveMaterial( const HlmsDatablock *datablock, String &outString )

my custom properties? Should I dynamic_cast to my custom datablock and if it succeeds then read them from it?

I made a PR 413 for material.json saving sorted names, well you saw it.
I made also 2 other, small, earlier: PR 400 and PR 414, in case you missed or something.

Well I fixed that anomaly mixing textures problem by backing out my changes in src/Terra/OgrePlanarReflections.cpp.
Good to know that it happens in C++ and can be debugged.
The issue was happening on maps with no fluids (water etc) because I always create PlanarReflections and I was calling mPlanarRefl->setMaxActiveActors( 0, ). But now I just don't.

I honestly don't know what's up with those.
So to make a workspace manual I just need to:
workspace->setEnabled( false );
and then update it whenever in

I have now 2 new issues with PlanarReflections.
First rather important and really bizarre. IDK what on earth happens here on video 1.
Something seems covering surface when I move camera. Most visible with cull none.
To test this: build sr-editor with this line uncommented in src/common/Reflect.cpp line 220:

Code: Select all

// 1 ? "Water_test" :  // ## test water

Then all fluids will use hlms Water_test pbs from Media/materials/Pbs/water.material.
It is quite basic to show the problem.
With uncommented:

Code: Select all

// cull_mode none  // bad

It is really bad. Tracks I used on video are: Test1-Flat with 1 water, and Test7-FluidsSmall with many fluids.

There is also a second issue, on video 2.
Seems there are errors in camera for doing PlanarReflections when getting close to surface.
I'm certain we didn't have such issues in old SR with old Ogre. So I'd assume it has to be doable to fix this. It's a bit annoying since we drive rather close to these angles near waters so it'd be slightly noticeable. Not a big issue though. But kind of reminds me of screen space reflection's problems, while PlanarReflections shouldn't have them IMO.
These 2 are not happening in Ogre-Next sample, so it's probably something with my setup or code.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Crystal Hammer wrote: Thu Aug 31, 2023 11:36 pm

So I got just one question, how do I get inside:

Code: Select all

void saveMaterial( const HlmsDatablock *datablock, String &outString )

my custom properties? Should I dynamic_cast to my custom datablock and if it succeeds then read them from it?

See that HlmsJsonPbs::saveMaterial performs:

Code: Select all

void HlmsJsonPbs::saveMaterial( const HlmsDatablock *datablock, String &outString )
{
    assert( dynamic_cast<const HlmsPbsDatablock *>( datablock ) );
    const HlmsPbsDatablock *pbsDatablock = static_cast<const HlmsPbsDatablock *>( datablock );

Now my only concern from what you said is that if what you're doing is this:

Code: Select all

HlmsDatablock *HlmsPbs::createDatablockImpl( IdString datablockName,
                                             const HlmsMacroblock *macroblock,
                                             const HlmsBlendblock *blendblock,
                                             const HlmsParamVec &paramVec )
{
    if( some_criteria )
        return OGRE_NEW HlmsMYPbsDatablock( datablockName, this, macroblock, blendblock, paramVec );
    else
        return OGRE_NEW HlmsPbsDatablock( datablockName, this, macroblock, blendblock, paramVec );
}

While it's not technically wrong, it's a code smell. I'd recommend all your datablocks to be of type HlmsMyPbsDatablock.
Whatever is different between the 2 may explain other unrelated bugs.

I honestly don't know what's up with those.
So to make a workspace manual I just need to:
workspace->setEnabled( false );
and then update it whenever in

I have now 2 new issues with PlanarReflections.
First rather important and really bizarre. IDK what on earth happens here on video 1.
Something seems covering surface when I move camera. Most visible with cull none.
To test this: build sr-editor with this line uncommented in src/common/Reflect.cpp line 220:

Code: Select all

// 1 ? "Water_test" :  // ## test water

Then all fluids will use hlms Water_test pbs from Media/materials/Pbs/water.material.
It is quite basic to show the problem.
With uncommented:

Code: Select all

// cull_mode none  // bad

It is really bad. Tracks I used on video are: Test1-Flat with 1 water, and Test7-FluidsSmall with many fluids.

There is also a second issue, on video 2.
Seems there are errors in camera for doing PlanarReflections when getting close to surface.
I'm certain we didn't have such issues in old SR with old Ogre. So I'd assume it has to be doable to fix this. It's a bit annoying since we drive rather close to these angles near waters so it'd be slightly noticeable. Not a big issue though. But kind of reminds me of screen space reflection's problems, while PlanarReflections shouldn't have them IMO.
These 2 are not happening in Ogre-Next sample, so it's probably something with my setup or code.

It doesn't ring a bell, but it looks like some geometry (that is either glitched up or that should not be part of the planar rendering pass) is being included.

I'd suggest outputting the value of the planar reflection texture on screen. For example if you change the planar reflection compositor script to the following:

Code: Select all

compositor_node PlanarReflectionsStandardRenderingNode
{
	in 0 rt_renderwindow
	in 1 planarReflectionTexture

	target rt_renderwindow
	{
		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
			}
			overlays		on
			shadows			PlanarReflectionsShadowNode

			//Used by C++ to identify this pass wants planar reflections
			identifier	25001

			profiling_id "Main Render"
		}
		
		pass render_quad
		{
                        execution_mask 0x01
			material Ogre/Copy/4xFP32
			input 0 planarReflectionTexture
		}
	}
}

workspace PlanarReflectionStandardsWorkspace
{
	connect_output 0 PlanarReflectionsStandardRenderingNode 0
	connect_output 1 PlanarReflectionsStandardRenderingNode 1
}

And then pass the reflection texture to the compositor like this:

Code: Select all

Ogre::CompositorManager2 *compositorManager = mRoot->getCompositorManager2();
Ogre::CompositorChannelVec channels;
channels.push_back(mRenderWindow->getTexture());
channels.push_back(mPlanarReflections->getTexture(0u));
mWorkspace =
    compositorManager->addWorkspace( mSceneManager, mRenderWindow->getTexture(), mCamera,
                                     "PlanarReflectionStandardsWorkspace", true );

(I'll let you sort out how to get mPlanarReflections->getTexture(0u) since in the sample it's not available in PlanarReflectionsGraphicsSystem::setupCompositor).

then you can see what it looks like from the perspective of the planar reflection texture.

If you assign it to a hotkey to toggle between this mode on and off (that's why added an execution_mask) you could see in real time what geometry is getting in the way.

And with the help of RenderDoc you may understand what it belongs to.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay thanks.
So even without all that I see that this is terrain. I see the issue as on video 1 even if I only render terrain with visibility_mask 0x000004 in PlanarReflectNode. So now what, how do I fix this?
I'm gonna add planar reflections to my terrain demo to see if this happens there too. Maybe it's SR3 Terra's unnormalized terrain with all cells visible causing it?
And what are the issues in video 2? It seems to me like PlanarReflection issue with projection or camera? Maybe I got other near value or something else, that is different than in sample.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Crystal Hammer wrote: Sun Sep 03, 2023 1:30 pm

Okay thanks.
So even without all that I see that this is terrain. I see the issue as on video 1 even if I only render terrain with visibility_mask 0x000004 in PlanarReflectNode. So now what, how do I fix this?
I'm gonna add planar reflections to my terrain demo to see if this happens there too. Maybe it's SR3 Terra's unnormalized terrain with all cells visible causing it?

If we're lucky this problem is caused because you need to call terra->update(...) with the actorData->reflectionCamera of the actor being rendered. e.g.

Code: Select all

if( actorData.workspace->getEnabled() )
{
  terra->update( actorData.reflectionCamera );
  actorData.workspace->_update();
  actorData.workspace->setEnabled( false );
}

terra->update( yourRealCamera ); // Restore

You will have to call terra->update( yourRealCamera ); after you're done with each reflection.
If that fixes it, we can then sort out the "proper" way to insert that call there.

Crystal Hammer wrote: Sun Sep 03, 2023 1:30 pm

And what are the issues in video 2? It seems to me like PlanarReflection issue with projection or camera? Maybe I got other near value or something else, that is different than in sample.

At first I thought it may be a problem with the reflection, but on second thought it may simply be an incompatibility in how the sky is rendered during the reflection pass. It's hard to guess more without a capture and without additional geometry (i.e. if I'm right if you put trees in the reflection, the trees will look alright but the sky won't).

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

I added PlanarReflect to my terrain demo (commits).
I replicated 2 of 3 issues there.

To test: build latest, start and press T to create terrain (waits 5 sec for me), and N to create reflect plane.
F1 has more info text. But that's enough to see both issues.
Arrows change parameter (which by default is) water height and below 20 it will create a vertical plane, higher will create flat.

Okay that was it. Updating Terra fixed the 1st issue with terrain pages being random.
So I did

Code: Select all

                if( actorData.workspace->getEnabled() )
                {
                    if (terra)
                    {
                        terra->setCamera( actorData.reflectionCamera );
                        terra->update();
                    }
                    actorData.workspace->_update();
                    actorData.workspace->setEnabled( false );
                }
                

and terra->update(); does

Code: Select all

    void Terra::update()
    {
        update(m_prevLightDir, 0.0f);
    }

And later in PlanarReflectWsListener::passEarlyPreExecute I update terra anyway, for regular scene passes. I need that anyway there right? Since splitscreen viewers can be far away.
Update: no was a bad result. I needed to restore it your way.

The 2nd issue I figured out happens when Plane slices are above 1. So e.g. with 32 or 60 you get that specular madness from wrong normals or something. So the default 1 slices is okay. Obviously I would like it being fixed. Any mesh with water waves would need it.
Update: okay, actually no, it's not fixed, just less visible / odd.

But I still didn't replicate 3rd issue, the camera projection thing going nuts when close. It doesn't happen in terrain demo, but happens in SR3 editor like on video 2. Is really magic.
This happens not just with sky. Everything on plane (terrain, trees etc) get so distorted.
I tried different camera->getNearClipDistance, 0.1 is in SR3.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Okay I fixed the issue 3.
It was happening due to that arbitraryDistortion we added. And just turning the sign from + to - in last line here fixed it:

Code: Select all

	float3 pointInPlane = inPs.pos.xyz - pixelData.normal * distanceToPlanarReflPlane
		- pixelData.normal * float3(3.0, 0.0, 3.0);

So the one last remaining is the issue 2, I made a video with it from terrain-demo.
To test it: just as before run and press T then N.
It very depends on this line 124 from src/TerrainScene_Water.cpp:

Code: Select all

		const int segments = 64;  // 1 !  more bad

But 1 doesn't fix it really. Seems to me like vertex normals are messed or environment map reading maybe or something else entirely IDK. Maybe some shadow since it seems to depend on camera and light dir too?

Anyways what do you think of terrain-demo? Could it be part of Ogre-Next? Or does it need to stay as stand alone demo app. I made it MIT and resources are CC licensed (skies could be replaced). IMO Ogre-Next is missing something like this. I'd say better if it was maintained by team, this way would be easier to spot bugs like the ones we found these with planar reflections or other features we'd add to it.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Sorry for the silence. I've been drowned in work and IRL stuff (nothing to worry about), I haven't gotten yet the time to check out your demo.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Sure, I understand.
Okay I found out that this issue comes from Terra shadowmap reading by Pbs shaders.
If I change in Media/Hlms/Terra/GLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl
the line 37 from:
outVs.terrainShadow = mix( midf_c( terraShadowData.x ), _h( 1.0 ), midf_c( saturate( terraHeightWeight ) ) );
to just:
outVs.terrainShadow = 1.0;
then the issue is gone. Obviously terrain shadow reading too. So it's just a hack not a fix.
I can also do it with @property( water ) for water only in my case.
Anyways I don't have any terrain shadow yet since I moved to unnormalized height floats.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by dark_sylinc »

Ok that is almost certainly the wrong texture at the slot.

Bound at uniform texture2D terrainShadows should be a texture like this one:

When we open it must be an RGB10_A2 texture like this one. The shape may look different for other terrains but they all look similar (i.e. purple and black):

Depending on what you encounter you may see that:

  1. The slot for terrainShadows is wrong, e.g. in vulkan_layout( ogre_t@value(terrainShadows) ) uniform texture2D terrainShadows; The @value(terrainShadows) is wrong. This is calculated in HlmsPbsTerraShadows::propertiesMergedPreGenerationStep.
  2. The slot where we bound the texture in HlmsPbsTerraShadows::hlmsTypeChanged is wrong and is not the same value as calculated in the previous point.
  3. A different texture from another technique ended up calculcating the same slot, and ended up being set on the same slot where the terrain is supposed to go.

Note: Ultimately it is not about "wrong value" but rather poor coordination. There are two or more rendering algorithms that need to coordinate who takes which texture slot and they all must coordinate to stick to that slot and not step on each other's toes.

User avatar
Crystal Hammer
Gnome
Posts: 388
Joined: Sat Jun 23, 2007 5:16 pm
x 99

Re: Few serious questions for Ogre-Next, moving Stunt Rally

Post by Crystal Hammer »

Ok thanks for info. Yeah I can handle this now, but I have plenty of other bugs to fix first.

Important ones first.
I found another issue with my planar reflections water, somehow camera is flipped or wrong when I see water in my preview camera RTT.
Video here. Any idea why this happens? Is this something wrong with my compostor setup in editor or a bug in planar reflections?

How is my PR for sorting in json going, should I do anything?

I'm moving to material.json now and editing it in my Material Editor window on Gui. It's better.
But, if I save some I have this then present in json:

Code: Select all

"reflection" :
{
	"texture" : "DynamicCubemap",
	"sampler" : "Sampler_4"
}

And if I start editor again with this it will crash early on parsing, because DynamicCubemap is created from code much later.
How to deal with this? Instead of removing this manually and adding that in code, based on a parameter stored somewhere.

I'm dealing with water shader and I'm not sure about stuff here in Media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any, is my favorite file for sure.
I'm okay with no shader editor graph, I prefer to write + instead of putting a block for it etc.
But looking e.g. at this water shader or that one, it is really nice and very easy to have those:
ALBEDO, NORMAL, METALLIC, ROUGHNESS, SPECULAR, ALPHA etc output variables for PBS to set up with your own stuff.
Can you list all variables from our 800.PixelShader_piece_ps.any that would do the same thing? In other words, where and what to set for transparency (alpha) per pixel, fresnel (reflection color), specular, etc.

Also BTW, I got problems with my fog and transparency (it gets brighter) IDK why, I think I had this in old SR too, long years ago.
Is my place for applying fog even right, here? Should I multiply or lerp something by transparency (diffuse.w)?

What do you think is better: having many sky dome nodes and setting their position for each view / player, reflection camera etc.
Or adding that pass to compositor and doing sky as postprocess? Which need to split old pass to transparent objects too. I'm not sure, I think there is trouble in both approaches.

Can you tell how much work or in how many places do I need to change TerraShadowMapper for my terrain with unlimited floats (any values, in meters). I can't handle this 10bit and other assumptions. Generally it works now, but only for terrain above 0, below it's all shadowed.

Is there any chance for my old issues? That one with dark RTTs in editor, and terra triplanar normal map causing darker spots etc. And Vulkan not working with MyGui.

Also, I have to say, I bought a new PC recently and wow it all works really fast now (like 3 to 5 times faster). Test tracks load in 1sec, others load fast too, even with my stupid approach of getting terrain height (and 4 times for angle) on 1 CPU thread for each grass or tree put etc.
I don't have that 5 sec. delay for Terra shadowmap compute shaders, and even those lags when loading after (in editor) aren't so long.
I also see really good scaling with better GPU. More vegetation possible, splitcreen is fast too. Every track is 60 Fps with high settings.

What freaks me out still, is those white flashes when a new texture appears (on Gui mostly now).
So, how do I load a texture and ensure it will be there in next frame already? Not after a white flash. It's not proper and quite annoying 8) for eyes too.
I got this code:

Code: Select all

	auto* texMgr = mRoot->getRenderSystem()->getTextureGpuManager();
	TextureGpu *tex = texMgr->createOrRetrieveTexture( filename,
		GpuPageOutStrategy::Discard, CommonTextureTypes::Diffuse, "General" );
	tex->scheduleTransitionTo( GpuResidency::Resident );

I do this at start and right after MinimizeMemory too.
I think it works, not sure. But definitely it doesn't for some Gui preview textures. IDK why.
BTW I don't need to free tex right?

Lastly why is Ogre-Next still not using auto keyword, this shortens code so much. Do you still need old C++ standard supported?

Sorry again for 10 things at once, I can't even. And editing it 10 times right after :) .

Last edited by Crystal Hammer on Mon Oct 09, 2023 6:40 pm, edited 1 time in total.