Page 1 of 3

Properly support PSSM/CSM

Posted: Sat May 31, 2008 5:50 am
by lf3thn4d
Right up to now, Ogre has the most number of shadow technique I know of in any 3d engine. However, the current shadow methods does not really do well when it comes to PSSM/CSM shadows.

To do PSSM/CSM shadows one has to use dummy lights now. What does it take to make ogre support multiple shadowmap per light? I suppose this would fit quite well with point light shadowing as well.

I would like to volunteer to make this happen. Just hoping to get some input before I dive into it. (desperately need it for my game. :-P)

Posted: Sat May 31, 2008 9:12 pm
by sinbad
Yeah the main reason this hasn't been tackled is that currently there is considerable assumption that 1 light == 1 shadow texture. This will need to be broken which implies a new level of indirection in the mapping between lights and shadow textures (and vice versa). I'd love to see it done but frankly, I haven't had time / inclination to tackle it because it affects a number of different parts of the code.

If you want to have a go, I'd welcome that and I'll give as many tips as I can find time for :)

Posted: Sun Jun 01, 2008 6:04 am
by lf3thn4d
cool. Ok, from what I've been thinking about, one way is to add settings to the light object to define how many texture iteration that light needs. Light::setShadowTextureCount()

At anyrate, it seems like SceneManager::Listener::shadowTextureReceiverPreViewProj needs to be tweaked with an additional iteration parameter. That means breaking compatibility.

Does that sound too generic?

Posted: Mon Jun 02, 2008 9:43 am
by sinbad
lf3thn4d wrote:cool. Ok, from what I've been thinking about, one way is to add settings to the light object to define how many texture iteration that light needs. Light::setShadowTextureCount()

At anyrate, it seems like SceneManager::Listener::shadowTextureReceiverPreViewProj needs to be tweaked with an additional iteration parameter. That means breaking compatibility.

Does that sound too generic?
Hmm, I actually prefer for Light to be ignorant of this, because the number of textures is surely a facet of the shadowing technique and not the light itself? Ie it would be better to be able to change the shadow basis on the SceneManager and for that to just apply to the appropriate lights (PSSM is mostly a directional light technique as I understand it) without having to go and find them in the scene, and remember to alter new ones. Perhaps a 'use n shadow textures for x light type' option? I'm just musing here, not necessarily saying this is the most feasible option.

There are many things that will need to change API yes; also the ShadowCameraSetup class too no doubt. Obviously try to change as little as possible but I'm expecting some breakage to support this. We'll be talking 1.8 now anyway.

Posted: Tue Jun 03, 2008 6:06 am
by lf3thn4d
Hmm.. that actually works better :) no need to set settings per light. You're right that PSSM is mostly a directional light techinique. It's not needed for anything else.

void SceneManager::setShadowTexturePerLight(size_t count, Light::LightTypes type)

It does makes me wonder what category PSSM falls under. Shadow partitioning? Definitely a level above ShadowCameraSetup.

[edit]
Ok, I've looked more into what needs to be changed. Here's an outline.

1. Add lightType/ShadowCount list to scene manager.
2. Modify SceneManager::prepareShadowTextures to render multiple shadow per light.
3. Add shadow iteration per light parameter to SceneManager::Listener
4. Add shadow iteration per light parameter to ShadowCameraSetup class
5. Modify shadow_scene_depth_range auto param to allow specification of shadow iteration in a light.

Right now, the problem I see is number 5. The auto param currently only allows one custom parameter. Now, we need two (light num, shadow num).

Another way to work around this is to make shadow_scene_depth_range return an array. Then we have a shadow_scene_depth_range_count to return the number of shadow texture that light have.

Or else, we could maybe make shadow_scene_depth_range's param to be the shadow texture index instead of the light index. But this doesn't sound good.

Any suggestion? :)
[/edit]

Posted: Thu Jun 12, 2008 8:16 pm
by lf3thn4d
Ok, I've took the liberty to attempt adding multiple shadow map per light
support in ogre. This is to allow custom shadow mapping like PSSM or Cubic
shadow map(point light).

Along the way, I found the long problematic issue I had with directional
lights on Focussed and LiSPSM camera setup. They didn't seem to follow the
render backface flag. After some hacking, I managed to solve the issue
which is included in this patch. I'm not entirely sure if my solution makes
sense or if it's correct. But it does get the job done. I basically flip
the Z frustum of the Focussed camera for directional light. As for LiSPSM,
I flipped the Z frustum when building the unit cube frustum. This solution
seemed to produce correct result for the shadow demo as well. Previously,
LiSPSM mode is rendering the front face instead of the back face.

Anyways, here's a list of what has been modified:
- Added multiple shadow map per light support to scene manager.
- Modified ShadowCameraSetup and SceneManager::Listener to have shadow map
iteration param.
- Fixed up render pass codes to set texture projector param with the right
shadow texture unit index. (it was using shadow texture index which is
wrong. Should be index base on the shadows in that pass.)
- Changed AutoParam of shadow_scene_depth_range to be per shadow texture
unit instead of light.
- "Fixed" Focussed camera setup for directional light.
- "Fixed" LiSPSM frustum setup.
- Fixed Focussed and LiSPSM to get shadow camera bound info directly
instead of using the light.

Note:
I did not modify build in shadow pass as multiple shadow map there does not
make sense.
Also I believe getShadowCasterBoundsInfo() should be removed as it doesn't
make sense anymore in multiple shadow map system. Besides, I've removed all
dependency to this function on this patch.

P.S. Sorry for such a huge patch with so many changes.


http://sourceforge.net/tracker/index.ph ... tid=302997

Here's a screen shot of my PSSM working with these changes:
Image
3 1024x1024 shadow map. PSSM+LiSPSM+PCF.
<Shameless plug>Btw, this is an inhouse level editor shot i did for aftershock. I haven't revealed this part to the showcase yet. Maybe soon when I feel ready. :-P</Shameless plug>

Posted: Fri Jun 13, 2008 12:39 am
by eugen
Very nice indeed!
What version of ogre is this patch applying to?

Posted: Fri Jun 13, 2008 5:27 am
by lf3thn4d
I'm using SVN version of ogre. I guess you can call it shoggoth. But like sinbad said, if it goes in, it would be talking about 1.8 (Cthugha).

Posted: Fri Jun 13, 2008 9:31 pm
by sinbad
Excellent, thanks for the patch. I'm having a crazy month so might not get to look at it immediately but you can guarantee I'll revisit it as soon as I can.

Posted: Sat Jun 14, 2008 8:20 am
by Injector
Looking really good, indeed! I would love to get some detailed information on how to put these new features to use (ie how exactly to set up the materials/shaders/parameters for PSSM) - an example would be awesome :) .

Posted: Sat Jun 14, 2008 6:21 pm
by lf3thn4d
sinbad: Sure thing :) Take your time. I expect to see more changes needed to be done. My solution might not be very correct or I might have missed some things. Would be good if there are more people proof reading it.

Posted: Sat Jun 14, 2008 7:50 pm
by Praetor
I may be able to take a look at it soon. Since this will be going into head (1.7) and not Shoggoth I suppose there isn't a huge rush. Keep us posted on any other changes. I think this is an important feature to put in.

Posted: Sat Jun 14, 2008 8:10 pm
by lf3thn4d
Cool! :) Thanks :)

Just a few stuffs while trying to get PSSM working:
- Since there isn't anyway to provide custom gpu auto param that applies to the whole scene, PSSM split distance has to be either hardcoded or apply the param for every renderable. Second option allows dynamic split distance but is not really optimized.
- I found that LiSPSM works very well with PSSM. However one would need to tweak the optimal adjust factor for each split section.
- Shadow texture resolution of 1024 is the minimum res that looks good. Anything lower looks a little crap. But i guess it could still be used for low end cards.

<edit>
Just did more testing. Turns out that scene depth range given for far distance is way smaller than it should be. Right now, my hack is to use PF_FLOAT32_R to work around the problem.

Another problem I noticed was bad frustum culling for cave type rooms. It seems the frustum culling code was designed for convex type meshes instead of inverted cave meshes.

Image
</edit>

Posted: Wed Jun 18, 2008 1:31 am
by Praetor
Hey, I'm just grazing over your patch and was wondering, in the interests of saving time do you have a small piece of code which demonstrates the new features of the patch? I can check to make sure all the old stuff isn't broken but I don't have time right now to try to code up a demo for myself. Would happen to have something on hand to help me look into this?

Posted: Wed Jun 18, 2008 2:24 am
by lf3thn4d
Hey, at the moment, I've only tested these changes with my own game engine.

The way I did it was to subclass the LiSPSM camera setup class. From there I cache the camera that is being used and generate a cached split distant array.

For each light iteration, I then force set the camera's clipping planes before and after the original LiSPSM code.

I also force set the optimal adjust factor for each split to some value that gives best result.

Lastly for the shader part of things, I made a specialized renderable listener to inject split points to the custom params.

It's rather hackish. For one, i'm const casting all over due to the method I overwrote(getCameraSetup()) had to be a const method. Secondly, I had to hack the camera projection distant to get the right shadow segment for each split.

There may be a better way, but right now, this is the fastest way I could get PSSM up and running.

I can try and hack up a demo.

Posted: Mon Jul 28, 2008 9:10 pm
by lf3thn4d
*Bump*

As promised, I found time to build a PSSM demo. Of course for anybody who want to build this would need to use a patched version of ogre.

At any rate, this will give you guys a head up on how to get PSSM working in Ogre :)

http://www.sendspace.com/file/jomw2w

Screen shot:
Image

Posted: Mon Jul 28, 2008 9:28 pm
by lilljohan
lf3thn4d wrote:*Bump*

As promised, I found time to build a PSSM demo. Of course for anybody who want to build this would need to use a patched version of ogre.

At any rate, this will give you guys a head up on how to get PSSM working in Ogre :)

http://www.sendspace.com/file/jomw2w

Screen shot:
Image
Nice, was just trying to implement PSSM myself, but my second and third shadowmap was screwed up. Maybe this can help me figure out what i was doing wrong =)

Posted: Mon Jul 28, 2008 10:36 pm
by serkanergun
Thanks for the demo. It looks great. Will be looking at the code very soon

Posted: Tue Jul 29, 2008 10:51 am
by sinbad
Thanks for that. I'd hoped to get time to chew over some more patches this weekend but that went out the window unfortunately. I want to get to this patch asap.

Posted: Tue Jul 29, 2008 2:42 pm
by Vectrex
very nice and fast. I assume the white hairline at geometry edges is a hard problem to kill?

Posted: Tue Jul 29, 2008 2:52 pm
by nullsquared
Vectrex wrote:very nice and fast. I assume the white hairline at geometry edges is a hard problem to kill?
Looks like you'd need to do setShadowCasterRenderBackFaces(false).

Posted: Wed Jul 30, 2008 3:45 pm
by ahmedismaiel
first ,nice work
i just tried applying the batch on the latest svn version but i'm getting a bit different results than the compile demo you supplied

Image

the first and third shadow textures are used correctly,but the second texture usage doesn't exist although the overlay seem to have correct data

do u think i missed anything through the merge?

let me know if there is something i should try

Posted: Thu Jul 31, 2008 12:38 am
by lf3thn4d
Hey guys, thanks for the feedback :)

sinbad: Though I'd love to see this patch get in soon, but yeah, I understand. I'll patiently wait. :)

Vectrex: Yes this is hard to fix. However I think it would be less obvious if you stick meshes bellow ground level (intersect meshes) Still, it's no real fix. But if you play games like Assassin Creed, you'll find that they also have this problem.

nullsquared: that would cause a whole lot of other problem. Shadow biasing is a horrible solution that is a nightmare to tweak. Unless you use VSM that is. But VSM doesn't work very well for directional lights since shadow casting range is really far most of the time.

ahmedismaiel: That is rather odd. I'm not exactly sure what is wrong but most likely it's a shader issue. I hit it once in a while. It seemed sometimes linearizing the depth range gives weird issues.

Posted: Wed Aug 13, 2008 10:04 am
by lf3thn4d
*Bump*

http://www.sendspace.com/file/oitxnh

I've updated the demo with better shader code. I threw away linearized depth as it wasn't working as it should(Maybe scene manager problem). At any rate, this one just use post projection depth. Papers tend to go against this, but this method seemed to do it pretty well. In fact I would say it's a lot better. :?

Posted: Wed Aug 13, 2008 2:24 pm
by Praetor
I'm sorry sinbad and I both have hit busy patches the last few weeks. Looks like a lot of good work, and an important improvement for 1.8. One of us will definitely get to this.