• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
danromeo

Optimized deferred lighting....algorithm question

12 posts in this topic

Still SO close to finishing optimized deferred lighting.

 

Using the "standard" deferred algorithm of multiple render targets, etc.  With shadows.  Pretty cool. So in brief I calculate shadows depth, then render the lightmap to a rendertarget, copy the RT to Texture2d, send the Texture2d to the pixel shader for the next lightmap, combine the existing light with the new light, repeat for each light.  

 

I'm trying to clip my draw quads to the lights for optimization.  This means that I can't buffer my light maps to texture2d and send to the light map pixel shader because the light map will only draw within the bounds of the clipped draw quad, thereby clipping out the existing light.  

 

Seems like I need to draw the first clipped light to rendertarget, copy to full screen texture2d buffer, DON'T send the buffer to the pixel shader, draw clipped light 2 to rendertarget without existing light, then send both the new rendertarget and the existing texture2d buffer to a pixel shader which will combine the two in a full screen draw, copy the whole shootin' match to a full screen buffer, repeat for each light.  

 

By my very rough calculations it seems like both algorithms will take about the same amount of time, maybe a small optimization per light but nothing that will add up to any significant performance.  

 

Any opinions on this?  Suggestions for a better algorithm for clipping light draw quads in a deferred renderer for optimization?  

 

THANKS

 

 

0

Share this post


Link to post
Share on other sites

This is a learning process for me, so forgive any misconceptions.  

 

I believe the basic algorithm for deferred lighting is render light pass to RT -> Copy RT to existing light buffer (texture) -> Send existing light buffer to pixel shader -> render next light combining existing light to RT, repeat.  

 

Copy to texture is necessary because in XNA when you reset the render target to RT you wipe out the contents of that RT (unless you're preserving contents, which I don't want to do).  Resetting the rendertarget to RT is necessary because the shadow algorithm requires setting the rendertarget to a depth buffer RT, so the RT constantly switches back and forth.  

 

I'm not making any of this up....culled from the likes of Reimer and Catalin.  

 

I"m not using light geometry for the same reason....subsequent light pass needs to include existing light and drawing only the current light geometry will clip the existing light.  Likewise I don't believe that additive blending is possible because the RT contents are wiped out when setting the rendertarget.  So you copy the RT to texture and send the texture to the pixel shader, again all of this pulled mostly from Reimer samples.  

 

I actually have a pretty quick running engine, with shadows, and am ready to wrap up deferred lighting and move on but I want to optimize as much as possible, mostly so I can call this phase Done DONE and won't have to revisit it later.  After culling and reducing the resolution of the RT's/existing light buffers the only thing left seemed to be clipping the light draw quads to the size of the actual light on screen, therefore only drawing into the screen area affected by the light while still combining with the existing light.  Without losing shadows, limiting the number of light sources, or using a ridiculous amount of memory.....so reusing the RT/buffer texture rather than using one RT per light and then combining.    

 

I'm probably misusing the term "clipping".  I mean resizing my draw textures to clip everything outside of the screen area affected by the light.  

 

As Gavin points out, I'm trying to reduce the total draw size while avoiding full screen draws, yet retaining shadows and combining with existing light, where light geomtery and additive blending don't seem to be an option.  

 

Also as Gavin points out I suspect that I'm doing too much work.....so my basic question is, "Is there an efficient way to do this, or is it not worth the effort?".  

 

Again, I am definitely not an expert.  For example:

 

>  you could use BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource

 

I have no idea what this means.  WIll find out.  

 

Thanks for your replies.  

0

Share this post


Link to post
Share on other sites

I think you'll need to work out how to use additive blending. I can't really help you there, I haven't used XNA for a couple of years, Im using SlimDX and SharpDX these days. But if there is some restriction on using a blend state, then you'll have to get around that restriction. Because blending is definitely the method you need to use. Otherwise, how can you add one light to another ?

 

Edit : BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource  ..... just sets a texture to be used as both a rendertarget and shader resource, so both input and output,

so a texture can be written to and then used in the next pass as a source texture.

Edited by Gavin Williams
2

Share this post


Link to post
Share on other sites

 it sounds much more like an XNA-specific workaround.

This absolutely IS an XNA-specific workaround.  I am using XNA!  

 

I may be misconcieved here....but I am avoiding using preserve contents because I have an eye towards porting to <as yet unnamed> platforms, particularly Windows Phone 8, which I am barely familiar with (or even Windows Phone 9...ie future mobile platforms will undoubtedly have the graphic power eventually.)...DEFINITELY moving to SharpDX & MonoGame asap, and yes I have read that preserve contents is not XBox friendly....so trying to keep my options open for unknown platforms.   Too much for one person to know and by the time I'm ready to port everything may have changed.  BUT without preserve contents RT's in XNA are volatile and the copying mechanism has been used by people who are a lot better at this than I am.  This is the first situation where I haven't been able to get around the preserve contents issue with a creative algorithm....as I said, still learning (yes, I know, learning a dead platform)....which is why I started this post.  The default behavior of DX9 re: preserve contents is not a concern because one of the few things that I do know for sure is that I'll be moving away from DX9 soon, and I am married to C# as being only one person development is SO much faster than C++.  

 

SO....is preserve contents going to be an issue say with Monogame for WP8?  Hope that's not a dumb question, again I've barely explored the platform.        

 

Appreciate your comments, definitely food for thought.  

 

 

 

 

0

Share this post


Link to post
Share on other sites

The point is you shouldn't need to do any copying of data (and thus have no need for "preserve contents"). Lights can be additively blended. The part in your shader where you "combine the existing light with the new light" can be expressed as an alpha-blending function, correct? (Can you post the code?)

 

So just keep the same render target bound and keep drawing your lights into it.

Edited by phil_t
1

Share this post


Link to post
Share on other sites

XNA only clears your render targets when you bind them. If you just bind your target once and you don't re-bind it between lighting passes, it shouldn't be cleared. However you will have to make sure that you use a render target format that supports blending (I believe there's one called HdrBlendable).

0

Share this post


Link to post
Share on other sites

I'm still not sure why. Assuming that you're using a shadow map for each light, you can render all the shadow maps before you do any lighting (this will require a separate shadow map for each light, but... how many lights with shadows do you have?).

0

Share this post


Link to post
Share on other sites

So I'm guessing that you're re-using the same shadow map for each lighting pass, which makes sense. However you should still be able to do this, and preserve the contents of your lighting render target. You just need to create the render target with RenderTargetUsage.PreserveContents.

0

Share this post


Link to post
Share on other sites

I am avoiding using preserve contents because I have an eye towards porting to <as yet unnamed> platforms, particularly Windows Phone 8, which I am barely familiar with (or even Windows Phone 9...ie future mobile platforms will undoubtedly have the graphic power eventually.)...DEFINITELY moving to SharpDX & MonoGame asap, and yes I have read that preserve contents is not XBox friendly....so trying to keep my options open for unknown platforms.

AFAIK, this is only a concern for Xbox360 (I don't know of any other platforms that don't preserve render-target contents when binding).
The main graphics APIs - D3D9/D3D11/OpenGL/GLES/WebGL - all do preserve RT contents when binding.

If you're interested, the reason that the 360 appears not to preserve contents is because you're not actually ever rendering into the render-target that you've created! That sounds strange, so I'll back up...
Most GPUs have a whole heap of RAM built into them, which I'll call VRAM. Everything from RT's to textures to vertex buffers live in VRAM. When you receive an input to your vertex-shader, or perform a texture fetch, it comes from VRAM. Whenever you output a pixel from a pixel-shader, it gets written to VRAM.

The 360 is slightly different: As well as VRAM, it has a separate 10MiB "EDRAM" chip. The only place the pixel-shaders can output their pixels to is this small EDRAM buffer, they cannot write directly to VRAM. After you've finished drawing everything to EDRAM, the GPU can copy it's contents back over to VRAM in one big chunk.

So the internal rendering procedure on 360 is:
1) Create a render-target/texture in VRAM.
2) Bind the render-target.
2.a) Internally, create a new temporary render-target in EDRAM.
2.b) Optionally, copy the contents from VRAM into EDRAM (preserve contents).
3) Render pixels into the temporary render-target.
4) Copy the temporary EDRAM target back over to the real VRAM one.

Whereas on most other platforms it's:
1) Create a render-target/texture in VRAM.
2) Bind the render-target.
3) Render pixels into the render-target.

Given this unconventional design, yes, an optimal rendering pipeline may be different on the 360, because switching render targets is an expensive operation (whereas on other GPUs it may be "free").

If you're targeting the 360, you should definitely take these quirks into account.
If you're targeting another platform, you should find out what quirks it has and design around them.
You cannot optimize for an as-of-yet unknown platform by optimizing for a different, unrelated, platform.

Mobile GPUs will likely operate quite differently to both the 360 and to PC GPUs, so the optimal method for them will be different again :/ Edited by Hodgman
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0