Jump to content
  • Advertisement
Sign in to follow this  
d h k

[D3D9] Deferred Rendering: Blending light shader output together

This topic is 2477 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on my first Deferred Renderer and I'm a little stuck at the moment. I have a G-Buffer all filled up with data correctly and I have two light shader working correctly - both of them working on the entire screen, meaning they are used with a fullscreen quad both. The first is a super-simple ambient light shader. It really just reads the diffuse (or albedo) color from the G-Buffer and multiplies that with a float3 lightcolor. This is what that looks like:

defrend_ambient.png

The second is a directional light shader. It's a little more complicated, it reads the diffuse color and the view-space normal from the G-Buffer and renders directional light from those values:

defrend_directional.png

Now I want to combine (blend) these two fullscreen quads. My first question: do I need a composite rendertarget and another fullscreen quad? I don't see why I shouldn't be able to mix it all right on the backbuffer.

The only way of blending this that I managed to find (unfortunately almost all Deferred Rendering papers or tutorials go into great detail only when talking about the G-Buffer and Light Shader steps, not the Final Composite) was to add a DWORD color to my fullscreen quad vertex definition, give the vertices a 0.5f alpha value when building the fullscreen quad's vertex buffer and then setting the following render and sampler states:


window->GetDevice ( )->SetRenderState ( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
window->GetDevice ( )->SetRenderState ( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
window->GetDevice ( )->SetRenderState ( D3DRS_BLENDOP, D3DBLENDOP_ADD );
window->GetDevice ( )->SetTextureStageState ( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
window->GetDevice ( )->SetRenderState ( D3DRS_ALPHABLENDENABLE, true );


While that code blends my interface elements (the crosshair for example) just fine, it flat out doesn't work with my fullscreen quads. The quad (ambient or directional) I render last is always the only one showing up fully opaque on my backbuffer. In addition, I wonder if this is the right way to go about this at all, if I have, say, 4 directional lights combined, I would have to use an alpha value of 0.25f for every quad and so on. Isn't there a way to multiply the color values more elegantly?

As always, any help is greatly appreciated. I have a feeling I got stuck right at the easiest part of the idea... :P

Share this post


Link to post
Share on other sites
Advertisement
Combine images by reading both as textures to a shader and write the output with full opacity. Then you can sample dynamic volume light after rendering the whole scene's colors, positions, normals...

Share this post


Link to post
Share on other sites
So I render the ambient fullscreen-quad to its own ambient render target, the directional quad to its own directional target, then write a shader that reads in both render targets as textures, combines them and outputs a mix of the values onto another fullscreen-quad on the backbuffer? I can see that working but it doesn't sound very elegant at all, what with adding a new render target for every light and so on. Did I understand you correctly? Is that really the way it's usually done?

Share this post


Link to post
Share on other sites

So I render the ambient fullscreen-quad to its own ambient render target, the directional quad to its own directional target, then write a shader that reads in both render targets as textures, combines them and outputs a mix of the values onto another fullscreen-quad on the backbuffer? I can see that working but it doesn't sound very elegant at all, what with adding a new render target for every light and so on. Did I understand you correctly? Is that really the way it's usually done?


No, you should just be able to additively blend them into the same rendertarget. Use [font=Consolas, Courier, monospace][size=2]D3DBLEND_ONE for both your destination and source blend states.[/font]

Share this post


Link to post
Share on other sites
That works very nicely! So it looks like I can just mix all the light shader output together directly on the backbuffer too!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!