PSSM multiple splits not working

I have finally managed to get shadows working (it turned out that I have left default far frustrum of 1000.0, which was causing huge shadow pixels).



Now, my frustrum is 1 to 100 and I cannot really make it any more narrow. Setting PSSM splits to 4 are improving shadow quality considerably. Unfortunately, as soon as I move camera out of first split range (16 in this case), shadows are disappearing.



I have done small investigation and it seems that only split 0 has any effect. I can put break in the loop which goes through the splits (so only split 0 is rendered) and there is completely no difference in visual effect.



Edit:

I have managed to get see the effect of further splits. Effect is very strange. I have camera far up - lets say 60 units over ground. No shadows are visible from items on the ground (as they disappear when I move past first split, which is 16 units). I drop some items from that height, they fall down. They start casting shadow immediately - but they cast is as if the receiving plane would be on the closest split to the camera (for example 50 units). When they fall and reach 50 units from ground, shadow on the ground looks like they are directly on the ground (0 units), and shadow size is wrong for that height (way too big, same size as my camera would be very close to ground and objects would be on the ground already). When they breach 50 units, shadows are disappearing.



It is probably very confusing explanation - but there is an easy test. Run TestPssmShadow and observe that far teapots are not casting shadows. Now change the number of splits from 4 to 1 and voila - everything is casting shadow.

It seems that latest update from Sony has taken care about the drivers - when I downloaded mobily hack + latest mobile drivers from ATI, it said I do not need to update the drivers, as I have the latest version…



I will try to investigate what is causing the uniforms warnings.

abies said:
I will try to investigate what is causing the uniforms warnings.

The only ones that matter are the ones for m_ShadowMap, as you can see when you use more splits, there are more m_ShadowMap variables undeclared, which is strange. Since all of them are in the shader.
Perhaps we are hitting some limit in the number of uniforms declared.
You can try to enable full logging (Logger.getLogger("").setLevel(Level.ALL)) and look at the beginning output, it will show your GPU's limits.

Logger.ALL is not showing me any extra things. I have added some printouts and it seems that I might be running out of variables ids ?



g_WorldViewProjectionMatrix 1

g_WorldMatrix 0

m_ShadowMap0 19

m_ShadowMap1 -1

m_ShadowMap2 -1

m_ShadowMap3 -1

m_ShadowMap4 -1

m_ShadowMap5 -1

m_ShadowMap6 -1

m_ShadowMap7 -1

PCF4X4 -1

m_PcfEdg10 -1

m_ShadowIntensity 10

m_DoDither -1

PCF8X8 -1

m_LightViewProjectionMatrix0 2

m_Splits0 11

m_LightViewProjectionMatrix1 3

m_Splits1 12

m_LightViewProjectionMatrix2 4

m_Splits2 13

m_LightViewProjectionMatrix3 5

m_Splits3 14

m_LightViewProjectionMatrix4 6

m_Splits4 15

m_LightViewProjectionMatrix5 7

m_Splits5 16

m_LightViewProjectionMatrix6 8

m_Splits6 17

m_LightViewProjectionMatrix7 9

m_Splits7 18



Seems like there is a limit of 20 values here ? I have downloaded opengl caps viewer and I can see max vertex and max fragment uniforms as 1024…

That’s really odd…

Personally I think we should reduce the maximum number of PSSM splits to 4, there’s no benefit going beyond that. But I am not sure if it will help with your issue

hmmm…can’t reproduce your issue i have shadows everywhere with 4 splits.

Could you post a screenshot of your pssmtest with 4 splits please?



this is what i’ve got :

For me it works as following:



Default (4 splits)





Changing to 1 split







Your case looks correct - both nice shadows and having them far and near… It might be a problem of my driver then ? Shadows used to not work at all for me, then I have updated driver and they started working - but maybe still not fully? Unfortunately, I have Sony VAIO laptop with ATI GPU and I cannot install normal ATI drivers, only ā€˜blessed’ ATI ones, which are not updated frequently…

And here is the movie of my original problem



First two throws are with 4 splits (wrong shadows), next 3 throws are with 1 split (proper, but lower quality shadow). As you can see, with 4 splits, shadows are appearing a lot earlier, too big and then disappear. Place when they appear depend on the camera hight - if I would get close enough to ground, they would be proper all the time (as they fit in first split range).



BTW, you can also observe unrelated problem with last two throws - one die is falling throught the table… I suppose it has something to do with high velocity and low framerate, it is not happening often if I throw dice from reasonable height. Anyway, let’s focus on shadows for now.

abies said:
BTW, you can also observe unrelated problem with last two throws - one die is falling throught the table... I suppose it has something to do with high velocity and low framerate, it is not happening often if I throw dice from reasonable height. Anyway, let's focus on shadows for now.

You might want to consider CCD (continuous collision detection), there's a usage example in the physics tests

CCD is not working for me. It is also not working 100% in example program - one in 30-40 green balls is going through the blocking wall, another 10 or so are getting stuck in the wall instead of rebounding.



In my case fortunately I have only a problem with falling through the table - so I have added simple check if local translation goes below the table too much, if yes, I just teleport dice back up a bit over the table.



But I’m hijacking my own thread, let’s go back to shadows ! :wink:

I made some changes on the PSSM renderer yesterday (not really related but you never know). Could you please retest?

Have you got an error, in the log or a warning or something?

I’m getting



10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform g_WorldViewMatrix is not declared in shader.

10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap1 is not declared in shader.

10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform PCF4X4 is not declared in shader.

10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_PcfEdg10 is not declared in shader.

10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_DoDither is not declared in shader.

10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform PCF8X8 is not declared in shader.

10-Jan-2011 08:47:58 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_VertexColor is not declared in shader.



in TestPssmShadow with 2 splits and



10-Jan-2011 08:49:27 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform g_WorldViewMatrix is not declared in shader.

10-Jan-2011 08:49:27 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform PCF4X4 is not declared in shader.

10-Jan-2011 08:49:27 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_PcfEdg10 is not declared in shader.

10-Jan-2011 08:49:27 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_DoDither is not declared in shader.

10-Jan-2011 08:49:27 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform PCF8X8 is not declared in shader.

10-Jan-2011 08:49:27 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_VertexColor is not declared in shader.



with 1 split.





With 8 splits, it is



10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform g_WorldViewMatrix is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap1 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap2 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap3 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap4 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap5 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap6 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_ShadowMap7 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform PCF4X4 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_PcfEdg10 is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_DoDither is not declared in shader.

10-Jan-2011 08:50:49 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform PCF8X8 is not declared in shader.

10-Jan-2011 08:50:50 com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation

INFO: Uniform m_VertexColor is not declared in shader.

That’s strange the ā€œINFO: Uniform m_ShadowMap1 is not declared in shader.ā€ would explain the problem, it seams the shadow maps are not bind to the shader except the first one (index 0).

But I don’t really understand why

The shadows work fine for me in the PSSM test…



@nehon: maybe its because the driver somehow incorrectly optimizes the shader? Perhaps it detects the distance can never be smaller than the first split?

I think we should do the shadow fetch for all splits, but only use the result from the one appropriate for the distance. I know some older GPUs are not capable of selectively reading certain textures for a given pixel so it won’t matter in that case anyway. We can implement the texture selection for GLSL 1.5 and higher supporting GPUs.

Also hardware shadow mapping might help for older GPUs that aren’t used to the ability of reading depth values from depth textures.



@abies: What is your ATI GPU? Is there a way you can perhaps force-install newer drivers?

Yeah why not, honestly, the benefit versus performance hit of more that 4 splits is questionable.

But…what about that 20 ids max?

No, it is not helping - even with 2 splits, shadowMap1 is not defined (and further half of scene is shadowless).



I have thought it might be a bug where only certain amount of characters are taken into account - I have renamed shadow maps to be distinct on 3 character, still no luck.



I have deleted 5-8 versions of all variables to reduce the amount of uniforms/varyings, still no effect.



Shader is compiling with the shadow maps - if I mistype the name of one of the maps in fragment shader, it complains during compilation. It is just the glGetUniformLocation which is somehow not seeing them.



I have run test in glDEBugger, shader source is correct, number of active uniforms is as expected - only ShadowMap0 is present from all shadows maps (but this is probably because rest could not be bound by jme3).



Interesting thing - if I remove following code

if(shadowPosition < m_Splits0){

shad = getShadow(m_ShadowMap0, projCoord0);

}else

from shader, then m_ShadowMap1 is bound properly, with all the rest of the shaders disappearing. Looks like a kind of strange optimalization of shader compiler to me…

I commited a bunch of fixes and improvements to the PSSM renderer.

I removed the if statements for the splits so now it forces the shader to read from all shadow maps, hopefully this will prevent your driver from over-optimizing it.

Thanks a lot !



pssmRenderer.setFilterMode(PssmShadowRenderer.FilterMode.Bilinear);

pssmRenderer.setCompareMode(CompareMode.Software);



works wonderfully



PCF4/Software gives

WARNING: Common/MatDefs/Shadow/PostShadowPSSM15.frag compile error: Fragment shader failed to compile with the following errors:

ERROR: 0:31: error(#101) Macro redefined KERNEL



Bilinear/Hardware gives

WARNING: Common/MatDefs/Shadow/PostShadowPSSM15.frag compile error: Fragment shader failed to compile with the following errors:

ERROR: 0:87: error(#201) Requires extension support: textureGather (GL_ARB_gpu_shader5)

ERROR: 0:87: error(#160) Cannot convert from ā€˜const float’ to ā€˜highp 4-component vector of float’



PCF4/Hardware gives

ERROR: 0:32: error(#101) Macro redefined KERNEL

ERROR: 0:87: error(#201) Requires extension support: textureGather (GL_ARB_gpu_shader5)

ERROR: 0:87: error(#160) Cannot convert from ā€˜const float’ to ā€˜highp 4-component vector of float’



Anyway, I’m more than happy with Bilinear/Software (quality is more than enough and speed is acceptable), so for me problem is fixed. Once again, thanks a lot !

But I thought you had an old card? Apparently not, since it supports GLSL 1.5 :stuck_out_tongue:

Its strange that it complains about textureGather, since it checks for the proper define for that extension, we might need another check for GL_ARB_gpu_shader5…

Card is quite good, it is ATI Radeon HD 5650. Problem is rather with drivers - I was using Nvidia since I have moved out of Vodoo2 card and always heard horror stories about quality of ATI drivers. I thought it is a thing of the past, so I gave up and bought laptop with ATI…



Anyway, card was promising DirectX11 support. Maybe it does support that, but with opengl things look worse:



GPU Caps viewers says:

OpenGL Core: 3.2 - GLSL: 1.50

but at the same time

GLSL - Shader Model 4.0: YES

GLSL - Shader Model 5.0: NO



It does support GL_EXT_gpu_shader4 cap, but not GL_ARB_gpu_shader5.