Jump to content

Shadow Caching status


Recommended Posts


Additional Contributors: @andrewmac, @LuisAntonRebollo

Target: 3.9

JeffR said:
  • Deferred Shading
  • Shadow Caching


So. those of you that have been following along with the Deferred or PBR branches have likely gotten a bit of a taste of this already, but in the interests of letting folks digest things in a nice testable manner, the first thing out of the gate will be the shadow caching subsystem.


Anyone familiar with pretty much any engine knows that shadows are one of, if not the most hefty hits on the rendering pipelline. Dynamic more so than any other. Stock torque to date uses fully dynamic shadow regeneration per frame for everything unless you explicitly bake them in a third party application via lightmapping tricks, additional materials, et al.


To alleviate this a bit, Andrew and I dug around a bit and dug into regeneration portion of the shadow gen subsystem, augmenting it with a pair of cyclic updaters.

Here's how this works:

Materials gain a new flag: http://i.imgur.com/Qld0ioR.jpg

Lights gain 2 new millisecond entries: http://i.imgur.com/iKZby4B.jpg


Lights start out as now, generating shadows across the board. but no longer update every frame. Instead they wait until either the dynamicRefreshFreq has expired if it's tagged as dynamic, or the static one does if it's static to redraw the relevant portions of the 'shadow scene' for lack of a better term. At time of writing, all materials default to dynamic by request in order to least disturb existing projects, which means folks wanting to take the most advantage of that will need to flip that off for all background materials. (those wishing to automate the process the other way around juts need to flip https://github.com/Azaezel/Torque3D/commit/cff46be3c4eb15bf3f779dfe69589f5716b54cbc#diff-3d0e4d9e155d0616540a32291c591c75R185 and tag players or anything animated to true.


Now the bad news: Turns out there was a lurking bug in https://github.com/Azaezel/Torque3D/commit/48f3ae1e6c873906dcb957c4bc79b4466c4eae99 causing severe issues with spotlights in particular, though given the formation, that was more of a timebomb waiting for someone else to step on it at some point anyway, so looking to fully address that.


At present, that brings the bug down to one report, specifically in debug mode, of

OPENGL: GL_INVALID_OPERATION error generated. Cannot begin query on an active query object.

per light after which queries operate correctly rather than continuous spam from both that one and a secondary error report. (http://i.imgur.com/EdOdT2z.png)


Additional research notes on that matter:


GL_INVALID_OPERATION is generated if glBeginQuery is executed while a query object of the same target is already active.


As this stuff was always intended to be a community project, if folks want, I can flip that over to PR (after cleaning it down to the one documented commit) and let someone clean it up in the development fork, but my first instinct is to hold off on that until this last bit is sorted fully.

Link to comment
Share on other sites

  • 2 months later...
  • 8 months later...
  • 4 weeks later...

Testing this feature out for a while now I noticed issues with it.

By default the static refresh rate is set to 250ms, which is too much, you see shadows popping all the time.

I also first thought I could theoretically set it to 1000ms or several seconds since the shadows of static shapes theoretically never get updated, but I was wrong.

Shadows are also updated when you spawn into the game or when you move your view around very fast.

If you have an update rate of lets say 5 seconds to make it obvious, you will see shadows popping into existance 0-5 seconds after you spawn into the game or 0-5 seconds after you look into a new area.

So I reduced the static refresh rate to 128 ms, then 100 and then 80, which was almost unnoticeable.

It seems to me that everything above 100ms is noticeable by human eye, some people even notice changes below that as well.

So you may want a force instant update when a player joins the game that would solve the popping when spawning, but not the popping of shadows when moving your mouse camera fast.

Trees on the other hand went fine with update rates of around 100, it still looked like the leaves were flattering fast in the wind, this means vegetation probably does not need fully dynamic lighting.

For the dynamic lighting, this could also be updated less often, it does not need to be updated every frame, maybe only every second or third frame.

Good values for lighting would probably be something around 16ms for dynamic shadows and 80ms for static shadows.

Link to comment
Share on other sites

15ms seems to be good for dynamic shadows, since 1000ms is one second and there is max 60fps per second which makes 16.66667 ms so that it updates every frame.

However I found that if you set the dynamic update rate to 16 or 17 sometimes you have frame skippings, but 15 gives a bit of a a puffer so you have almost no visible skips.

Setting all dynamic shadows from updating at 8ms to 15ms also seems to give a good performance boost. Around 13mspf to 12 mspf in my test case.

Dynamic shadows could even be set lower up to 32ms, but this only works for slow moving objects, as soon as you sprint it gets very ugly and often unacceptable flickering.

Link to comment
Share on other sites

  • 2 months later...

I noticed this also gives issues with the polycount metrics display, since the polycount updates so fast that it is almost not visible.

For example I have a scene with 800 000 polygons and 2000 drawcalls and for the fraction of a second it keeps fluctuating between 800 000 and 1 200 000 polycount and 2000 and 4000 drawcalls. I found out this heavy changes come from the shadows being rendered delayed.

This is more a visual flaw, since the metrics display updates so fast it hurts in the eyes and you don't know what number counts.

Maybe this could be changed by changing the update rate of the metrics display to be slower.

Link to comment
Share on other sites

Yeah, we'd been mulling on how to better present the metrics for the 'stages'. The main thing is that during the static update, you have the deferred render, the dynamic shadow render, and static shadow render all in the update, so the poly count rises.

So for better, more readable numbers we'd been discussing having separate entries displayed for that kinda stuff, like:

Deferred(800,000), Dynamic Shadows(200,000), Static Shadows(200,000) or something similar.

If there's a particular way of formatting that sort of thing you think may help, feel free to toss a suggestion.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...