Jump to content
  • Advertisement
Sign in to follow this  
Swartz27

Switching From Deferred Shading To Deferred Lighting

This topic is 853 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

Hi,

Unfortunately I haven't had much luck searching for information on this.

 

Basically I'm looking to take the source code to a game, take their deferred shading renderer, and switch it over to deferred lighting, or better yet, Tiled Index Deferred Lighting.

 

I'm very new to all this (still working through DirectX11 tutorials) but I've learned a lot in that time.

 

There are many reasons for wanting to switch the method of rendering, with the main one being adding a more complex  BRDF system to the game.

 

Any help or useful links on this subject would be very much appreciated.

Edited by Swartz27

Share this post


Link to post
Share on other sites
Advertisement

Well it highly depends on the source code that you've got, and how cleanly they've written their renderer.

 

A deferred shading renderer has two main steps:

1) Draw opaque objects to a gbuffer

2) Draw lights to lighting buffer

 

Your first step would be understanding enough of their source code to locate these functions and prepare to change them to:

1) Draw opaque objects to "thin gbuffer" -- change number of gbuffer textures and their formats, change this shader that writes to them.

2) Draw lights to intermediate lighting buffer -- change light shaders to read the new "thin gbuffer" format.

3) Draw opaque objects to lighting buffer -- using a new shader that uses the results in the intermediate lighting buffer.

Share this post


Link to post
Share on other sites

Thanks :)

 

I just want to make sure I understand this 100%

Step 1: Create thin gbuffer: by "thin" I suppose you mean either less things in the gbuffer, a lower DXGI format, or both?
The current Gbuffer consists of Position, Normal, Diffuse Light, Specular Light, and Material type. 

 

Step 2: Create intermediate lighting buffer, so include all lights here, and then have it read the necessary info from the thin Gbuffer?

 

Step 3: Draw opaque objects to light buffer: straightforward

As for how neat the code is, even though I'm a beginner I can tell that this game engine is pretty much held together by duct-tape. The renderer is a huge mess as well, but I know how to navigate around it.

Share this post


Link to post
Share on other sites
Step 1: Create thin gbuffer: by "thin" I suppose you mean either less things in the gbuffer, a lower DXGI format, or both? The current Gbuffer consists of Position, Normal, Diffuse Light, Specular Light, and Material type.

It's not "Diffuse light" and "Specular light", but material properties of a pixel.

On this stage you are writing to GBuffer properties for each pixel.

These MATERIAL properties will be used with Light-related data on step 2.

 

 

Step 2: Create intermediate lighting buffer, so include all lights there, and then have it read the necessary info from the thin Gbuffer?

 

I've done it via packed structured buffer. Each type of light (direct, ambient, point, and spot) will be written to this kind of structure:

struct LightData
{
    uint   type;          //All lights
    float3 color;         //All lights

    float3 dirToLightVS;  //Directional, Spot
    float  innerAngleCos; //Spot

    float3 posVS;         //Point, Spot
    float  outerAngleCos; //Spot
}; //48 bytes 

StructuredBuffer<LightData> Lights;

 

The buffer will contain n elements (== light count + 1-last stub "LIGHT_NO" to break a loop).

The shader unpacks the data, calculate amount of light from each light source, and sum it with different light:

for (each pixel/sample)
{
    for (uint i = 0; i < 102400; ++i) // i - index of Light in LightBuffer
    {
        if (lights[i].type == LIGHT_NO)
            break; //No more lights

        DiffSpec curr = (DiffSpec)0;

        switch (lights[i].type)
        {
        //Sorted by occurrence
        case LIGHT_POINT:
            curr = CalcPoint(Lights[i], ...);
            break;

        case LIGHT_SPOT:
            curr = CalcSpot(Lights[i], ...);
            break;

        case LIGHT_DIRECTIONAL:
            curr = CalcDirectional(Lights[i], ...);
            break;

        case LIGHT_AMBIENT:
            curr = CalcAmbient(Lights[i], ...);
            break;

        case LIGHT_SHADOW_PRIM:
            curr = CalcDirectional(Lights[i], ...);
            break;
        } 
        totalLight += curr;
     } 
Edited by Happy SDE

Share this post


Link to post
Share on other sites

 

Step 1: Create thin gbuffer: by "thin" I suppose you mean either less things in the gbuffer, a lower DXGI format, or both? The current Gbuffer consists of Position, Normal, Diffuse Light, Specular Light, and Material type.

It's not "Diffuse light" and "Specular light", but material properties of a pixel.

On this stage you are writing to GBuffer properties for each pixel.

These MATERIAL properties will be used with Light-related data on step 2.

 

 

Step 2: Create intermediate lighting buffer, so include all lights there, and then have it read the necessary info from the thin Gbuffer?

 

I've done it via packed structured buffer. Each type of light (direct, ambient, point, and spot) will be written to this kind of structure:

struct LightData
{
    uint   type;          //All lights
    float3 color;         //All lights

    float3 dirToLightVS;  //Directional, Spot
    float  innerAngleCos; //Spot

    float3 posVS;         //Point, Spot
    float  outerAngleCos; //Spot
}; //48 bytes 

StructuredBuffer<LightData> Lights;

The buffer will contain n elements (== light count + 1-last stub "LIGHT_NO" to break a loop).

The shader unpacks the data, calculate amount of light from each light source, and sum it with different light:

for (each pixel/sample)
{
    for (uint i = 0; i < 102400; ++i) // i - index of Light in LightBuffer
    {
        if (lights[i].type == LIGHT_NO)
            break; //No more lights

        DiffSpec curr = (DiffSpec)0;

        switch (lights[i].type)
        {
        //Sorted by occurrence
        case LIGHT_POINT:
            curr = CalcPoint(Lights[i], ...);
            break;

        case LIGHT_SPOT:
            curr = CalcSpot(Lights[i], ...);
            break;

        case LIGHT_DIRECTIONAL:
            curr = CalcDirectional(Lights[i], ...);
            break;

        case LIGHT_AMBIENT:
            curr = CalcAmbient(Lights[i], ...);
            break;

        case LIGHT_SHADOW_PRIM:
            curr = CalcDirectional(Lights[i], ...);
            break;
        } 
        totalLight += curr;
     } 

You're awesome (same with Hodgman) :)  This is very helpful, thank you so much!

Share this post


Link to post
Share on other sites
My small share;
Maybe it's a bit in the details, but I think terms are a bit mixed together, deferred lightning and deferred shading I believe are not interchangable.

I believe for lighting you can go for:
- forward lighting (1 pass)
- deferred rendering/ lighting (using a gbuffer etc)

Then there's shading, for example:
- blinn phong "N dot L" stuff
- physical based shading/ rendering (different Material properties, roughness, albedo etc)

In practice I believe some parts of PBR are only possible combined with deferred lighting.

I believe tile based rendering is also a form processing the lights in your scene.

Share this post


Link to post
Share on other sites

Hi, yes I likely butchered the terms.

 

Basically, what I am looking for, is to be able to assign a special shader to a given material that I have, like you said, PBR.

 

I'll just go ahead and say that the project I'm working on is with Xray Engine 1.6 (note: I have "unofficial" permission to be using their source code, I am not doing anything illegal/immoral, GSC just won't come right out and say it's ok due to 3rd party code it contains [which is being removed]). To clarify, I did contact GSC about it.

 

The whole renderer, and well, the whole engine, is a total mess. 

 

So I guess I have a question for a moderator rather than creating a brand new topic: would it be ok if I make a topic where I ask someone that has experience to look through the rendering code, and let me know of what needs to be fixed and improved for it's DX11 renderer? I don't expect anyone to do any work for me, I just would like some hints in the right direction.

Edited by Swartz27

Share this post


Link to post
Share on other sites

My small share;
Maybe it's a bit in the details, but I think terms are a bit mixed together, deferred lightning and deferred shading I believe are not interchangable.

Deferred shading is the common gbuffer technique that everyone uses.
Deferred lighting is another name for light-pre-pass, where you only store normals and roughness in the gbuffer and do a second geometry pass after lighting to combine the lighting buffer with the rest of the material properties... Which is actually a terrible fit for PBR.

I assumed the OP knew these terms and had a good reason to do this switch...

Swartz, what's the final end result that you want from these engine mods? What's the high level goal?

Share this post


Link to post
Share on other sites

I assumed the OP knew these terms and had a good reason to do this switch... But it seems I assumed wrong

 

I don't care if you're a moderator: you're a dick. 

Share this post


Link to post
Share on other sites
Hey, no offence intended. I was self deprecating for simply answering your original question and failing to ask why you would need to switch to LPP.
You said above that you want PBR, which isn't compatible with LPP, so the first advice that I gave you is not helpful.

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!