Now that I've finished Rage I've gone back to a save game (before entering Capital Prime) and am basically just sandboxing the game. Doing races, driving around killing bandits, and picking up missions I'd missed out on first time through, without having to care about following a main plot line. Of course because a lot of areas are closed off you can't really sandbox it, but it's still fun.
Let's change the subject and talk about dynamic lighting in Quake.
Over a year ago I had done some investigation into the OpenGL side of this, and today I did more work with Direct3D. This involved testing out various different methods of updating dynamic textures and comparing their efficiency.
API differences loom large here. Under OpenGL there is really only one way to update a texture and that involves a glTexSubImage call with a system memory pointer (you can optionally use a PBO but that's useless without glMapBufferRange, and more recent versions do add other ways, but they're not really viable unless you're targetting bleeding-edge modern hardware and/or willing to write multiple paths for doing the same thing - yuck). The differentiating factor lies in the format and type parameters you supply to your glTexSubImage call, and I had determined a factor of 40 performance difference arising from these under certain hardware.
With Direct3D it's just not the same. There's really only one format and type available for use - 32-bit 4-component textures in strict ARGB (or XRGB) layout - but lots of different hints and flags you can supply at creation time and update time that can optimize (or not) the process. Today's testing involved trying out these, as well as trying out some of the alternative methods.
Like OpenGL there is one major way to update a texture - call LockRect to get a pointer to some data, fill in the data, then call UnlockRect to complete the update. Differences also lie in which memory pool the texture is in, whether or not you record dirty regions, do you use a single texture or a pair of textures with UpdateTexture, etc. Much of this is analogous to PBOs in OpenGL (which is one reason why D3D has no PBOs - it doesn't need them) but with added flexibility and clearer usage flags.
The upshot is that I've confirmed the method I'm currently using to update lightmaps in DirectQ (one sysmem texture, one default pool texture, LockRect and record dirty regions on the sysmem texture, then use UpdateTexture) is Just Fine. It's joint fastest (with using a managed pool texture, no dirty regions, then a big AddDirtyRect at the end), and unlikely to be bettered if I continue down a traditional route.
What was interesting is that using a dynamic texture with D3DLOCK_DISCARD is considerably faster if you're updating the entire texture each frame, but considerably slower if you're just updating a subrect. This usage pattern is obviously totally unsuitable for Quake lightmaps.
So, I mentioned "if I continue down a traditional route" above; this could be read as indicating that I have an off-the-wall idea brewing, and in fact I do.
3D textures.
Instead of each lightmap being a separate 2D texture, why not pack them all into a single 3D texture? Each vertex gets an extra lightmap texcoord indicating which slice of the 3D texture is to be used, and we have a single 3D texture containing all lightmaps.
The big advantages of this are that a lot of code gets simpler, I can increase batching efficiency, cut out some intermediate on-CPU steps, and have fewer state changes. I also get to use a function called "AddDirtyBox". Fnarr fnarr.
I don't yet fully know what the tradeoffs are. Obviously a 3D texture requires a little more work in some places, using a power-of-two for depth (if required) incurs some extra memory overhead, and a 3D texture lookup may be less efficient.
It will be interesting to find out.
Tuesday, October 18, 2011
Dynamic Lighting Revisited
Posted by
mhquake
at
7:35 PM
Subscribe to:
Post Comments (Atom)
1 comment:
my personal wishlist for directq:
-cdaudio support (no mci)
-map collusion breaking bug fixed
-software mode like metal material/shiny shader (axe etc)
-fov setting number display
-idgamma settings extended
-true widescreen not stretched/cut (i think its not right)
-no filtering on models option( still gets filtered on certain view angle)
-option to center weapon right/left
thanks for the awesome job done on directq so far! looking forward excited to the next release
Post a Comment