[2.1] [GL] Point light shadow target rendered on screen [SOLVED] Topic is solved

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


Post Reply
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

[2.1] [GL] Point light shadow target rendered on screen [SOLVED]

Post by SolarPortal »

Hi, I am experiencing some strange shadow bugs when it comes to Ogre3d v2.1 using the latest commit 239cafd
I will try to be as clear as possible as its a tough one to describe :)

1) Point light casting a shadow: If you place a point light in the scene and use a tmpCubemap size of 512x512 and using a compositor workspace where the textures are generated and then copied onto the render window, it will show a strange overlay that is the same colour as the background(clear pass). I have managed to replicate it in the basic PbsMaterials sample through a simple few tweaks and test setups. Here's a picture of the problem for reference:

Image

It only happens with point lights casting shadows, anyway to replicate the error, change the following:
In the "PbsMaterialsGameState.cpp" around where the lights are created, change it to this:

Code: Select all

        Ogre::Light *light = sceneManager->createLight();
        Ogre::SceneNode *lightNode = rootNode->createChildSceneNode();
        lightNode->attachObject( light );
        light->setPowerScale( 1.0f );
        light->setType( Ogre::Light::LT_DIRECTIONAL );
        light->setDirection( Ogre::Vector3( -1, -1, -1 ).normalisedCopy() );
		light->setCastShadows(false);
        mLightNodes[0] = lightNode;

        sceneManager->setAmbientLight( Ogre::ColourValue( 0.3f, 0.5f, 0.7f ) * 0.1f * 0.75f,
                                       Ogre::ColourValue( 0.6f, 0.45f, 0.3f ) * 0.065f * 0.75f,
                                       -light->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f );

        light = sceneManager->createLight();
        lightNode = rootNode->createChildSceneNode();
        lightNode->attachObject( light );
        light->setDiffuseColour( 0.8f, 0.4f, 0.2f ); //Warm
        light->setSpecularColour( 0.8f, 0.4f, 0.2f );
        light->setPowerScale( Ogre::Math::PI );
        light->setType( Ogre::Light::LT_POINT );
		light->setCastShadows(true);
        lightNode->setPosition( -0, 0.3f, 0 );
       // light->setDirection( Ogre::Vector3( 1, -1, -1 ).normalisedCopy() );
        light->setAttenuationBasedOnRadius( 10.0f, 0.01f );

        mLightNodes[1] = lightNode;

        /*light = sceneManager->createLight();
        lightNode = rootNode->createChildSceneNode();
        lightNode->attachObject( light );
        light->setDiffuseColour( 0.2f, 0.4f, 0.8f ); //Cold
        light->setSpecularColour( 0.2f, 0.4f, 0.8f );
        light->setPowerScale( Ogre::Math::PI );
        light->setType( Ogre::Light::LT_SPOTLIGHT );
        lightNode->setPosition( 10.0f, 10.0f, -10.0f );
        light->setDirection( Ogre::Vector3( -1, -1, 1 ).normalisedCopy() );
        light->setAttenuationBasedOnRadius( 10.0f, 0.01f );

        mLightNodes[2] = lightNode;
*/
Now head to the "PbsMaterials.compositor" and change the file accordiingly(its pretty much the basic with the extra tests):

Code: Select all

// TEST 01 --- Render the scene and shadows directly inside the RenderWindow target.
compositor_node PbsMaterialsRenderingNode
{
	in 0 rt_renderwindow

	target rt_renderwindow
	{
		pass clear
		{
			colour_value 0.2 0.4 0.6 1
		}

		pass render_scene
		{
			overlays	on
			shadows		PbsMaterialsShadowNode
		}
	}
}

// TEST 02 --- Render the scene into a generated render target and then copy the texture into the render window.
// 			   Which uses a start & end compositing node.
compositor_node PbsMaterials_Gen_And_Window
{
	in 0 rt_renderwindow
	texture rt0 target_width target_height PF_FLOAT16_RGBA

	// Render to the generated texture
	target rt0
	{	
		pass clear
		{
			colour_value 0.2 0.4 0.6 1
		}
	
		pass render_scene
		{
			shadows				PbsMaterialsShadowNode
			overlays			off
		}
	}
	
	// Now copy the texture contents into the render window target.
	target rt_renderwindow
	{		
		pass clear
		{
			colour_value	1 0 0 1
			buffers			colour
			discard_only	true
		}
		
		pass render_quad
	    {
			material Ogre/Copy/4xFP32
	    	input 0 rt0
		}
	
		pass render_scene
		{
			overlays	on
			rq_first	254
			rq_last		255
		}
	}
}

// TEST 03 --- Render the scene into a generated render target and then copy the texture into the render window.
// 			   Which uses a start & end compositing node.
compositor_node PbsMaterials_StartingNode
{
	texture rt0 target_width target_height PF_FLOAT16_RGBA

	target rt0
	{	
		pass clear
		{
			colour_value 0.2 0.4 0.6 1
		}
	
		pass render_scene
		{
			shadows				PbsMaterialsShadowNode
			overlays			off
		}
	}
	
	out 0 rt0
}

compositor_node PbsMaterials_RenderFinal
{
	in 0 rt_output
	in 1 rt1
	
	target rt_output
	{		
		pass clear
		{
			colour_value	1 0 0 1
			buffers			colour
			discard_only	true
		}
		
		pass render_quad
	    {
			material Ogre/Copy/4xFP32
	    	input 0 rt1
		}
	
		pass render_scene
		{
			overlays	on
			rq_first	254
			rq_last		255
		}
	}
}


abstract target cubemap_target_shadow
{
	pass clear { colour_value 1 1 1 1 }
	pass render_scene
	{
		camera_cubemap_reorient true
	}
}

compositor_node_shadow PbsMaterialsShadowNode
{
	technique pssm

	texture atlas 2048 7168 PF_D32_FLOAT no_fsaa
	texture tmpCubemap 512 512 PF_FLOAT32_R cubemap no_fsaa

	num_splits		3
	pssm_lambda		0.95
	shadow_map 0 atlas uv 0.0 0.000000000000000 1.0 0.285714285714286 light 0 split 0
	shadow_map 1 atlas uv 0.0 0.285714285714286 0.5 0.142857142857143 light 0 split 1
	shadow_map 2 atlas uv 0.5 0.285714285714286 0.5 0.142857142857143 light 0 split 2

	technique focused
	shadow_map 3 atlas uv 0.0 0.428571428571429 1.0 0.285714285714286 light 1
	shadow_map 4 atlas uv 0.0 0.714285714285714 1.0 0.285714285714286 light 2

	target atlas
	{
		pass clear
		{
			colour_value 1 1 1 1
		}
	}

	shadow_map_target_type directional
	{
		shadow_map 0 1 2
		{
			pass render_scene
			{
			}
		}
	}

	shadow_map_target_type directional spot
	{
		shadow_map 3 4
		{
			pass render_scene
			{
			}
		}
	}

	shadow_map_target_type point
	{
		shadow_map_repeat 3 4
		{
			target tmpCubemap +X : cubemap_target_shadow {}
			target tmpCubemap -X : cubemap_target_shadow {}
			target tmpCubemap +Y : cubemap_target_shadow {}
			target tmpCubemap -Y : cubemap_target_shadow {}
			target tmpCubemap +Z : cubemap_target_shadow {}
			target tmpCubemap -Z : cubemap_target_shadow {}

			shadow_map
			{
				pass render_quad
				{
					material Ogre/DPSM/CubeToDpsm
					input 0 tmpCubemap
				}
			}
		}
	}
}

workspace PbsMaterialsWorkspace
{
	// Test 01
	//connect_output PbsMaterialsRenderingNode 0
	
	// Test 02
	connect_output PbsMaterials_Gen_And_Window 0
	
	// Test 03
	//connect PbsMaterials_StartingNode 0 PbsMaterials_RenderFinal 1
	//connect_output PbsMaterials_RenderFinal 0
}

Description of whats changed:
* The main change which i have found to cause this is changing the scale of the "tmpCubemap" texture from 1024x1024 to 512x512 and not rendering directly into the main renderwindow rendertarget.
* Also; In the workspace is 3 different tests, they all use the same shadow node with the same cubemap settings, however:
- Test 01: This works as expected but renders the scene directly into the main output target.
- Test 02: This shows the error of the render target from the point light, This is a single compositor node, but first the scene is rendered into a texture, then the texture is copied to the main render window.
- Test 03: This shows the error. This uses one compositor node to generate the texture followed by another to copy the texture to the main render window. This is a more real world case example as this is used for sending to other post FX nodes.


I believe it has something to do with the:

Code: Select all

	    pass render_quad
	    {
	    	    material Ogre/Copy/4xFP32
	    	    input 0 rt0
	    }
but i cant quite work it out.

The other strange thing is that it only breaks at certain size resolutions, e.g. changing the window size can make this appear or disappear. I found it happened every time for me with this ogre.cfg:

Code: Select all

[OpenGL 3+ Rendering Subsystem]
Colour Depth=32
Display Frequency=N/A
FSAA=0
Full Screen=No
RTT Preferred Mode=FBO
VSync=No
VSync Interval=1
Video Mode=1366 x 768
sRGB Gamma Conversion=Yes
From what i have tried, it seems related to openGL only.

---------------------------------------------------------------------------------------------------------------------------------------------------------
2) Since the last merge of the commit: https://bitbucket.org/sinbad/ogre/commi ... d5?at=v2-1 using PSSM. When looking towards the directional light and looking up slightly, it was producing a black shadow at the bottom of the window. Increasing the settings from the commit to above 1.0 got rid of the artefact again.

There was another one, but i think these 2 are enough for now, but mainly the first bug as its giving me problems with different quality shadows in fullscreen mode for our end games and when not in fullscreen mode for the editor..

Thanks for your time and if you need any more information, then please ask and i shall provide. Hope this helps :)

p.s. you probably want my specs too:
CPU: Intel core i7 3770
GPU: Nvidia GTX 750ti
Ram: Corsair DDR3 16gb
Drivers are mostly up to date for all :)
Last edited by SolarPortal on Mon Nov 06, 2017 8:58 pm, edited 1 time in total.
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.1] [GL] Point light shadow target rendered on screen

Post by al2950 »

I am just running out of the office, but at a quick look the cubemap shadow map does not use a depth texture and so might be sharing the rendertarget depth pool.

What happens if you explicitly set a depth pool for that texture?
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Re: [2.1] [GL] Point light shadow target rendered on screen

Post by SolarPortal »

Thanks for the reply. Did as you suggested and it did work once i changed the depth_pool to 0 or 2, but when set to 1, the same thing happens again.
Q) Do depth_pools have to be increased for every texture or can multiple textures share the same pool?
Q) do depth_pools have to increase 1 at a time e.g. depth_pool 0, 1, 2, 3, 4, etc...
Q) This question sort of fits with the previous question, Can you use any arbitrary number for the depth pool, e.g. specify 15?
Q) What is the max number of depth_pools?

I will try this fix into our engine and see if it works there too :)

Thanks for your time :)

Edit: Setting the depth pool to the tmpCubemap did nothing, but setting it to the rendertexture:

Code: Select all

texture rt0 target_width target_height PF_FLOAT16_RGBA depth_pool 0
did work on the ogre demo :)

will let you know how it goes with the engine.

Edit 2: On preliminary testing in our engine, "depth_pool 2" works whereas "depth_pool 0" seemed to invert the render order....
Note: Our workspace goes from render scene -> SSAO -> HDR -> Final composition
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.1] [GL] Point light shadow target rendered on screen

Post by al2950 »

The way depth pools are shared always confuses me a little, so I just play it safe and assume they might be shared.

Now a depth pool of ID 0, actually disables the depth pool, and so thats why when you use 0, you get odd problems with render order. When you dont specify a depth pool ogre uses this logic

Code: Select all

                    if( depthBufferId == DepthBuffer::POOL_INVALID )
                    {
                        if( PixelUtil::isDepth( format ) )
                            depthBufferId = DepthBuffer::POOL_NON_SHAREABLE;
                        else if( format == PF_NULL )
                            depthBufferId = DepthBuffer::POOL_NO_DEPTH;
                        else
                            depthBufferId = DepthBuffer::POOL_DEFAULT;
                    }
Which is why when you use a depth texture you have no problems. Also when rendering to a render window the ogre manual says this;
RenderWindows can**not** share their depth buffers due to API limitations on some RenderSystems.
So ignoring the above edge case, if you dont specify a depth pool it will used depth pool 1. If you use the same depth pool for your scene and shadows, different artifacts will happen depending on how you use your clear passes.

SO have your shadow textures on a different depth pool to your scene (unless they are depth only), ALSO set your full screen QUAD pass textures to depth pool 0, as this will disable the depth texture and improve performance.

Does that all make sense!?
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.1] [GL] Point light shadow target rendered on screen

Post by al2950 »

Thought I should actually try and answer your questions as well
SolarPortal wrote: Mon Nov 06, 2017 6:34 pm Q1) Do depth_pools have to be increased for every texture or can multiple textures share the same pool?
Q2) do depth_pools have to increase 1 at a time e.g. depth_pool 0, 1, 2, 3, 4, etc...
Q3) This question sort of fits with the previous question, Can you use any arbitrary number for the depth pool, e.g. specify 15?
Q4) What is the max number of depth_pools?
1 - it depends on the behaviour you want! but no they dont have to increase for every texture and multiple textures can share the same pool. BUT there are some rules, like they have to be the same resolution and some other things I cant remember!
2 - no, they can be any number
3- yes
4 - not sure, but the depth_pool enum states the following

Code: Select all

        enum PoolId
        {
            POOL_NO_DEPTH       = 0,
            POOL_MANUAL_USAGE   = 0,
            POOL_DEFAULT        = 1,
            POOL_NON_SHAREABLE  = 65534,
            POOL_INVALID        = 65535
        };
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Re: [2.1] [GL] Point light shadow target rendered on screen

Post by SolarPortal »

Thanks for the answers, that clears up a lot and makes a lot of sense :)
RenderWindows can**not** share their depth buffers due to API limitations on some RenderSystems.
That was the bit of information that i was lacking the most :P Penny has dropped..

Thank you for your responses and the help :)
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
Post Reply