Ogre-Next StereoRendering Issues

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


Lax
Gnoll
Posts: 644
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 59

Re: Ogre-Next StereoRendering Issues

Post by Lax »

Hi @Crystal Hammer,

ah that is good information. I already thought, I'm insane :)
Nice that, we have struggle on similiar topics. Maybe this will help @dark_sylinc in fixing some issues or assist further, what can be done.

I found out, that not only its because of using screen space reflection, but also using post processing compositors at all, because they are using also the Ogre/Copy/4xFP32 shaders.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Gnoll
Posts: 644
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 59

Re: Ogre-Next StereoRendering Issues

Post by Lax »

Hi @dark_sylinc ,

just a ping, so that this important topic will not be forgotten.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

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: Ogre-Next StereoRendering Issues

Post by dark_sylinc »

Lax wrote: Sun Jul 21, 2024 8:22 pm

What I do not understand:

  • There is no Pass Clear! Why?, just scene, shadow nodes, quad

The answer is quite simple: because PassClear never calls setRenderPassDescToCurrent.
You'll have to add a logging to CompositorPassClear::execute.

Lax wrote: Sun Jul 21, 2024 8:22 pm

The viewport sizes, seems to be correct (do not know if also for shadow nodes, as there are created not by code but in a compositor file separately

You have the following two that raise a red flag:

Code: Select all

21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_0 has viewport count: 1 size: 0 0 0.5 1
21:15:16: Pass: NOWA_Final_rtN_Pass_Quad_1 has viewport count: 1 size: 0.5 0 0.5 1

Assuming that these two passes render to the texture: If NOWA_Final_rtN_Pass_Quad_1 uses either clear or dont_care (either at load or store), it's going to overwrite what NOWA_Pbs_Render_Scene_Pass_Scene_0 already wrote, because load/store actions unfortunately ignore viewport bounds.

The same goes for the following two:

Code: Select all

21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_0 has viewport count: 1 size: 0 0 0.5 1
21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_1 has viewport count: 1 size: 0.5 0 0.5 1
Lax wrote: Sun Jul 21, 2024 8:22 pm
  • The mousepointer cannot be moved to the left side

Ummm... I don't know about that. If the cursor can't be moved it may be a bug in your code (i.e. allowed width is half of what it should be) or a rendering issue (the cursor is being overwritten, likely by wrong dont_care/clear usage).

I need that pass, because I'm using screen space reflections:

dont_care will overwrite the depth buffer too (you can specify to only the colour target to have dont_care).
Becareful that if you later still need the depth buffer, then dont_care will overwrite it.

I can't remember the specifics of the SSR pass (since it's quite a complex one) but it might be possible to just not attach a depth buffer into it (i.e. using RTVs or depth_pool 0).

I'm almost sure I have the same issue too now.
E.g. like so, for 3 way split: download/file.php?id=7373
But only since I added refractions, split rendering and started using load/store too.
(mentioned here viewtopic.php?p=556432#p556432)

Yeah it looks like the same issue. But it looks like simply you can't use load/dont care during split screen that way.

Strong Suggestion for everyone: Your use cases are getting complex. Instead of doing split screen directly on the final target, just render every player into its own TextureGpu.
Then use a custom pixel shader that composites all players into the final target and then apply shared UI on top.

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

Re: Ogre-Next StereoRendering Issues

Post by Crystal Hammer »

Ah. Sounds like a lot of work, in my case. Surely for later, I'll mark refractions as not supported in splitscreen, as it works okay the old way for me.
And I got like a ton of questions again. Pity there is no sample.
So if we have 2 viewport vertical split like above, then we need to create 2 textures for render targets? What size, if screen is say 1920x1200, do I create two 960x1200? It's not power of two, is that okay for GPU?
This way needs creating compositor from cpp only am I right?
Will there be any issues putting them into screen together, or will I get issues with blurring or that half or 1 pixel offset etc? That combining shader will have floats for offset,size I assume.

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: Ogre-Next StereoRendering Issues

Post by dark_sylinc »

Crystal Hammer wrote: Tue Sep 10, 2024 7:55 pm

Ah. Sounds like a lot of work, in my case. Surely for later, I'll mark refractions as not supported in splitscreen, as it works okay the old way for me.
And I got like a ton of questions again. Pity there is no sample.

You're not THAT crazy. Originally Refractions was made to reuse the depth buffer in read only mode. This is optimal in terms of performance (less copying around).

But it forces some inflexibilities on compositor setup, as your game shows. Complexities that could be solved if OgreNext showed how to do the same but with a duplicated depth buffer (at the cost of some perf of course).

Crystal Hammer wrote: Tue Sep 10, 2024 7:55 pm

So if we have 2 viewport vertical split like above, then we need to create 2 textures for render targets? What size, if screen is say 1920x1200, do I create two 960x1200? It's not power of two, is that okay for GPU?

1920x1200 isn't power of 2 either :lol:

Some GPUs may waste some VRAM in padding, but that's all.

Ultimately you always end up making sacrifices:

  1. The idea of dont_care and clear as LoadAction are meant to reduce BW but with split screen you need to dont_care/clear regions selectively, which isn't well supported by APIs and GPUs.

    • If you're curious, the reason is that behind the scenes dont_care/clear works in "blocks" (aka tiles) and there is no guarantee your subregion will coincide with the block size. And if it doesn't, the GPU would have to do some overhead.

  2. If you use multiple TextureGpus, you can make efficient use of dont_care/clear BUT you'll need an extra pass to stich everything together, which will result... in extra BW consumption.

So basically whatever you do you end up in an non-optimal path, so at that point why not make it easy for you instead of worrying about perf?

Crystal Hammer wrote: Tue Sep 10, 2024 7:55 pm

This way needs creating compositor from cpp only am I right?

I dunno, creativity is key.
Personally I mix C++ and compositor scripts as much as possible, as to have as little as C++ as possible.

Crystal Hammer wrote: Tue Sep 10, 2024 7:55 pm

Will there be any issues putting them into screen together, or will I get issues with blurring or that half or 1 pixel offset etc? That combining shader will have floats for offset,size I assume.

This was more common with D3D9 where you had to apply a 0.5 / resolution offset; otherwise you ended up sampling in the middle of a pixel, causing blurring. But not so much in D3D11/VK/GL.

However if you're that worried, use OGRE_Load2D instead of OGRE_Sample, which uses integers; and RenderDoc pixel shader debugging to double check.

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

Re: Ogre-Next StereoRendering Issues

Post by Crystal Hammer »

Okay, thanks for clarifications. I understand more now.
I think I will code it all from cpp and drop .compositor then (or leave it for simpler, editor RTTs maybe). I didn't like having constants in .compositor, while I have them anyway i .h file, used by cpp.

Lax
Gnoll
Posts: 644
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 59

Re: Ogre-Next StereoRendering Issues

Post by Lax »

Thanks for taking an eye into the issue.

You have the following two that raise a red flag:

21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_0 has viewport count: 1 size: 0 0 0.5 1
21:15:16: Pass: NOWA_Final_rtN_Pass_Quad_1 has viewport count: 1 size: 0.5 0 0.5 1
Assuming that these two passes render to the texture: If NOWA_Final_rtN_Pass_Quad_1 uses either clear or dont_care (either at load or store), it's going to overwrite what NOWA_Pbs_Render_Scene_Pass_Scene_0 already wrote, because load/store actions unfortunately ignore viewport bounds.

The same goes for the following two:

21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_0 has viewport count: 1 size: 0 0 0.5 1
21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_1 has viewport count: 1 size: 0.5 0 0.5 1

For me that seems correct, as:

    • NOWA_Pbs_Render_Scene_Pass_Scene_0 -> 0 -> first viewport
    • NOWA_Final_rtN_Pass_Quad_1 -> 1 -> second viewport

Same here:

    • NOWA_Pbs_Render_Scene_Pass_Scene_0 -> 0 -> first viewport
    • NOWA_Pbs_Render_Scene_Pass_Scene_1 -> 1 -> second viewport

If I see this log:

Code: Select all

21:15:16: Pass: Shadow Node SCENE 7 has viewport count: 1 size: 0 0 1 0.285714
21:15:16: Pass: Shadow Node SCENE 8 has viewport count: 1 size: 0 0.285714 0.5 0.142857
21:15:16: Pass: Shadow Node SCENE 9 has viewport count: 1 size: 0.5 0.285714 0.5 0.142857
21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_0 has viewport count: 1 size: 0 0 0.5 1
21:15:16: Pass: NOWA_Final_rtN_Pass_Quad_0 has viewport count: 1 size: 0 0 0.5 1
21:15:16: Pass: Shadow Node SCENE 7 has viewport count: 1 size: 0 0 1 0.285714
21:15:16: Pass: Shadow Node SCENE 8 has viewport count: 1 size: 0 0.285714 0.5 0.142857
21:15:16: Pass: Shadow Node SCENE 9 has viewport count: 1 size: 0.5 0.285714 0.5 0.142857
21:15:16: Pass: NOWA_Pbs_Render_Scene_Pass_Scene_1 has viewport count: 1 size: 0.5 0 0.5 1
21:15:16: Pass: NOWA_Final_rtN_Pass_Quad_1 has viewport count: 1 size: 0.5 0 0.5 1
21:15:16: Pass: NOWA_Final_Render_Overlay_Pass_Scene_1 has viewport count: 1 size: 0 0 1 1

First every pass group is rendered for the first viewport "0 0 0.5 1"
Then every pass group is rendered for the second viewport "0.5 0 0.5 1"

Or I'm I totally wrong here?

And why is always the viewport count 1?

This is the log message I added to CompositorPass::setRenderPassDescToCurrent for debug purposes:

Code: Select all

    LogManager::getSingleton().logMessage(
LML_CRITICAL, "Pass: " + mDefinition->mProfilingId + " has viewport count: " +
                  Ogre::StringConverter::toString( numViewports ) +
                  " size: " +
                  Ogre::StringConverter::toString( vpSize[i] ) );

I also again checked, that all passes for splitscreen use this configuration:

Code: Select all

if (false == this->useSplitScreen)
{
				passScene->setAllLoadActions(Ogre::LoadAction::Clear);
				passScene->mStoreActionDepth = Ogre::StoreAction::DontCare;
				passScene->mStoreActionStencil = Ogre::StoreAction::DontCare;
}
else
{
				passScene->setAllLoadActions(Ogre::LoadAction::Load);
				passScene->mStoreActionDepth = Ogre::StoreAction::Store;
				passScene->mStoreActionStencil = Ogre::StoreAction::Store;
}

The same also for passClear and passQuat and still no success.

Could be the splitscreen feature eased for developers by setting automatically those passes to be splittscreen friendly?
That means, if splitscreen is used, do not use "clear" or "dont_care"? This could be added as parameter for splitscreen?

EDIT:
I'm sure its because of this quat pass:

Code: Select all

// Render Quad
{
				auto pass = targetDef->addPass(Ogre::PASS_QUAD);
				Ogre::CompositorPassQuadDef* passQuad = static_cast<Ogre::CompositorPassQuadDef*>(pass);

			if (false == this->useSplitScreen)
			{
				passQuad->setAllLoadActions(Ogre::LoadAction::DontCare);
			}
			passQuad->mMaterialName = "Ogre/Copy/4xFP32";
			passQuad->addQuadTextureSource(0, "rtN");

			passQuad->mProfilingId = "NOWA_Final_rtN_Pass_Quad";

			this->applySplitScreenModifier(pass);
}

If I here manipulate the mExecutionMask, mViewportModifierMask, i get direct effects.

Code: Select all

if (pass->getType() == Ogre::CompositorPassType::PASS_QUAD)
{
	pass->mExecutionMask = 0x01;
	pass->mViewportModifierMask = 0x00;

pass->setAllLoadActions(Ogre::LoadAction::Load);
pass->setAllStoreActions(Ogre::StoreAction::StoreOrResolve);
}

If I set:
pass->mExecutionMask = 0x01;
This is the rendering:
Image

If I set:
pass->mExecutionMask = 0x02;
or
pass->mExecutionMask = 0xFF;
This is the rendering:
Image

Its not possible to merge both, so that on the left side picture 1 is rendered and at the right side picture 2. No matter what I do.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

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: Ogre-Next StereoRendering Issues

Post by dark_sylinc »

The best way to see what's going on is to attempt to merge both, and open it in RenderDoc to see what is overwriting the contents of the other eye.

Lax
Gnoll
Posts: 644
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 59

Re: Ogre-Next StereoRendering Issues

Post by Lax »

Ok I created a Renderdoc capture:

https://www.lukas-kalinowski.com/Homepa ... creen2.rdc

I used the execution_mask, viewport_modifier_mask configuration like it worked for Ogre sky postprocessing:

Code: Select all

void WorkspaceBaseComponent::applySplitScreenModifier(Ogre::CompositorPassDef*& pass, bool isOverlay, bool isSky)
	{
		if (true == this->useSplitScreen)
		{
			pass->mProfilingId += "_" + Ogre::StringConverter::toString(this->cameraComponent->getEyeId());

		if (pass->getType() == Ogre::CompositorPassType::PASS_CLEAR)
		{
			pass->setAllLoadActions(Ogre::LoadAction::Clear);
			pass->setAllStoreActions(Ogre::StoreAction::Store);

			// Gets executed on the first eye
			pass->mExecutionMask = 0x01;
			// Don't be affected by the modifier, apply to the whole screen
			// Will be cleared once for all eyes
			pass->mViewportModifierMask = 0x00;
		}
		else if (pass->getType() == Ogre::CompositorPassType::PASS_SCENE && false == isOverlay)
		{
			// Gets executed in all eyes
			pass->mExecutionMask = 0xFF;
			// Be affected by the modifier, so we render just to a portion of the screen.
			// That means one part is rendered on first eye and the other on the second eye
			pass->mViewportModifierMask = 0xFF;

			pass->setAllLoadActions(Ogre::LoadAction::Clear);
			pass->setAllStoreActions(Ogre::StoreAction::Store);
		}
		else if (pass->getType() == Ogre::CompositorPassType::PASS_QUAD)
		{
			// Gets executed in all eyes
			pass->mExecutionMask = 0xFF;
			// Be affected by the modifier, so we render just to a portion of the screen.
			// That means one part is rendered on first eye and the other on the second eye
			pass->mViewportModifierMask = 0xFF;

			Ogre::CompositorPassQuadDef* passQuad = static_cast<Ogre::CompositorPassQuadDef*>(pass);
			passQuad->mCameraName = this->cameraComponent->getCamera()->getName();

			pass->setAllLoadActions(Ogre::LoadAction::Load);
			pass->setAllStoreActions(Ogre::StoreAction::StoreOrResolve);
		}
		else if (pass->getType() == Ogre::CompositorPassType::PASS_SCENE && true == isOverlay)
		{
			// Gets executed in all eyes
			pass->mExecutionMask = 0xFF;
			// GUI gets executed on the first eye (left side)
			pass->mViewportModifierMask = 0x01;
		}
		else if (pass->getType() == Ogre::CompositorPassType::PASS_CUSTOM)
		{
			// Gets executed in all eyes
			pass->mExecutionMask = 0xFF;
			// GUI gets executed on the first eye (left side)
			pass->mViewportModifierMask = 0x01;
		}
	}
}

The Ogre::CompositorPassType::PASS_QUAD (which is in my case the passQuad->mMaterialName = "Ogre/Copy/4xFP32";) seems to make trouble.

I hope you can solve the situation here. I tried to read the capture in RenderDoc but I'm not able to understand what is going on.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Gnoll
Posts: 644
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 59

Re: Ogre-Next StereoRendering Issues

Post by Lax »

Hi @dark_sylinc,

just a ping for this topic. I provided a renderdoc. I still cannot get it right.
I followed all your instructions.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62