Better way to draw shadows

I messed around with shadows a bit, and noticed, that they always multiplied on top of the final image, either way, if it’s renderer (which draws all geometry for the third time, just to draw shadows) or post-Filter. Here is some limitations of this method:

-Unless shadow is pitch black, you still can see diffuse and specular lighting through it, that’s odd.

-If object both casting and receiving, there is always ugly jagged edge on it, and self shadow get darkened.

-You can’t use other lights with it, like point light. It will not affect shadow.



What I believe is much better way to draw shadows, is to draw them in single pass, while rendering your basic geometry. Mix together Lighting material and postShadowPSSM material.

-Shadow should affect only diffuse and specular from one light source.

-You can lit dark areas with other lights.

-Shadow intensity (and color) can be made with ambient light.

-Self shadow and casted shadow will have same depth and color, and will seamlessly merge to each other.

-That’s must be faster, than draw everything another time.



How I tried to make this:

In order to calculate shadow, material must get certain properties from shadow renderer. Like shadow maps, LightViewProjectionMatri-ces, and other. I wrote class that extends PssmShadowRenderer, but all of this variables are private, so I can’t reach them from my code (right?).



Another approach was to delete default technique in MatDef, and draw this whole material in postShadow technique. However, seems like blend mode for postShadow material is hardcoded in shadow renderer, because changing it in my MatDef did nothing.



I guess, my next step, will be editing sources. I have a good understanding of how 3d rendering pipeline is working, and some experience in shader languages, but I’m not a good coder.



My questions:

Aren’t there anything already done in this direction?

Is there a fine way to get private data from PssmShadowRenderer without editing it’s sources?

What is the best way to do that?

Read this post

http://hub.jmonkeyengine.org/groups/general-2/forum/topic/silly-question-about-shadow-rendering/?topic_page=2&num=15



I can’t elaborate because i’m on my mobile but i’ll answer later

There are many attempts done, none alone really convincing that it is better than the current version.

Just edit the sources, if your version has better results than the current ones it has good chances to get into the core.

@nehon said:
I'm considering trying it for Forward rendering too as it would save a geometry pass. But that would be optional, because the classic way is more likely to be supported on low hardware.

Nice to know. So, you already invent the right way of setting this up?

I meant more the general way of shadows not your specific idea. If you looka t the foum every once ina while there are ideas, tries to improve the current shadow system, some succesfull, some giving good ideas to the current system, ect.



I’m not trying to to exactly your idea :wink:

It’s one of those areas where there is no “right” way. There is the way that works on the most graphics card, there is the way that gives the fastest performance on high end cards, there is the way that looks best, etc.



You can’t get all of those at once so you have to choose.

@zarch said:
You can't get all of those at once so you have to choose.

I meant right way of setting up forward-rendering for shadows.
I want them to look best, and be more physically correct.
I don't want to support oldest possible hardware. (I bet, any hardware, that can't afford forward rendering shadows, runs current implementation impermissibly slow)
So there is no dilemma for me.

@EmpirePhoenix
any interesting links?

Well i would take a looka t the pssmFilter in the current revision.

@bananaft, Shadows in 3D rendering are a full area of study, there are plenty of techniques with their pros and cons, and from what i read (and i did read a lot about it) there is no perfect way to render shadows.



In JME we use the PSSM approach, with a variety of shadow edge filtering that you can choose.

The “traditional” approach is to overlay the shadows on the rendered scene with an additional scene render pass.

Note that usually computing the shadow maps almost always involve a pre geometry pass in light view and there is no way around this.

Of course there are alternatives to shadow mapping but usually the methods are really expensive.



I experimented several things in the thread i linked above :

  • rendering shadows during the lighting pass
  • rendering shadows in a post process



    I noticed that for the lighting pass the bottleneck was to pass the lightviewmatrices and other shadows params to all the scene materials. I made 2 tests : one with a material for each geometries (the worst case) and one with one only material for all the geometries in the scene (the case that’s not gonna happen in real life).

    It gives better performance than the traditional approach but drastically increase the number of uniforms and varyings used in the lighting shader and that will fail on most old hardware.



    The post pass gave results beyond expectations with almost a x2.5 speed increase on some scenes so i decided to put it in core.



    Now if you want to dig that up, I’d be glad. You don’t have to change the pssmRenderer code, you can easily make your own, shadows are not tied to core except for the way to compute what should cast and receive shadows.



    Ultimately what I’d like for JME shadows is to offer several implementations of the state of the art shadows. so users could choose the one that suits their needs. I’m thinking of VSM on the top of my head.



    I’d like that other types of light to be supported (point and spot lights) too.



    Also I really think users should not rely on dynamic shadows for everything. There should be baked shadows for static objects and dynamic only for dynamic objects close to the camera (that’s what’s done in BF3 for example).

    Of course…the shadows system is very game dependent…What we can offer is general approach to shadows, generic enough to suit most needs, but our intention is not to make the perfect shadow system.



    A last word regarding “I want them to look best, and be more physically correct.”. Don’t be too picky or you’ll get disappointed. Aim for the physically “plausible” and it’ll be fine.

    for example “-Unless shadow is pitch black, you still can see diffuse and specular lighting through it, that’s odd.” is very likely to never be noticed in a game…If it is, the player will just move on and forget it.

    Players do know that games are simulations and are ready to handle “non-realism” to a certain degree.

    Of course this last point is just my opinion.
@nehon said:
one only material for all the geometries in the scene (the case that’s not gonna happen in real life).

Minecraft uses one material for all the terrain. If you have a goal to spare materials, you can make good picture with just a few. Besides, case, where every object has it's own material impossible too. You will never get so many modelers to draw all this different assets :)

@nehon said:
Now if you want to dig that up, I’d be glad. You don’t have to change the pssmRenderer code, you can easily make your own,

Copy/paste ? So I really can't extend it?

@nehon said:
There should be baked shadows for static objects and dynamic only for dynamic objects close to the camera

Believe me, baking shadows not all that good. It slows down the process of map creation. You can't just open editor and move some things. Also, there is a big problem - to make static and dynamic look alike. You need to make two absolutely different lighting techniques look as close as possible.

While fully dynamic lighting opens all the possibilities for experiments and improvisation. It's like fresh air after baking.

Also, I want to mess with huge terrains, and dynamic day/night cycle. So, PSSM - exactly what i need.

@nehon said:
(that’s what’s done in BF3 for example)

As I know, BF3 uses stabilized PSSM. They use baked lighting only on very far geometry.

Here, I found presentation about shadows in BF3:
http://www.slideshare.net/repii/02-g-d-c09-shadow-and-decals-frostbite-final3flat
check out stabilization - it's really neat feature too.

@nehon said:
Aim for the physically “plausible” and it’ll be fine.

Yeah, that's better word.
@bananaft said:
Minecraft uses one material for all the terrain. If you have a goal to spare materials, you can make good picture with just a few. Besides, case, where every object has it's own material impossible too. You will never get so many modelers to draw all this different assets :)



You make too many assumptions. Terrain is only one model, you also have monsters, players, intractable stuff, arrows, etc, etc,

HeroDex is a trading card game. Most (some are identical so share materials but not many) of the cards have their own material ... so in this case 90% of the geometries on the scene have a different material.

Actually that's not quite true as the backs all use one material - so lets say 45%.
@nehon said:
@bananaft,
..
I noticed that for the lighting pass the bottleneck was to pass the lightviewmatrices and other shadows params to all the scene materials. I made 2 tests : one with a material for each geometries (the worst case) and one with one only material for all the geometries in the scene (the case that's not gonna happen in real life).

..
..

Also I really think users should not rely on dynamic shadows for everything. There should be baked shadows for static objects and dynamic only for dynamic objects close to the camera (that's what's done in BF3 for example).


Well the first case can very likly happen if you use a deferred rednering model. As far as i remember stalker is one material fits all system. Of course the single amterial is a complexity monster, but every material for deferred rendering is likly to be.

Yes it is simply not possible to use synamic shadows for everything. Imagine a mountain 10km away from you. with the sun behind it. It will cast a shadow oer several hundret of kilometers, and ina real world you would percive them as a dark valley. Doing this with a dxynamic shadowing technique will not work fine. (not to mention the extreme resolution you would need for the shadowmap to result in at least acceptable results.
@nehon said:
I noticed that for the lighting pass the bottleneck was to pass the lightviewmatrices and other shadows params to all the scene materials.


Why don't make them world parameters (global uniforms)? Shouldn't that work faster?

@EmpirePhoenix said:
Imagine a mountain 10km away from you. with the sun behind it. It will cast a shadow oer several hundret of kilometers

That's actually normal situation for PSSM to handle.