Advertisement Jump to content
Sign in to follow this  
KaiRohmer

Interesting Shading Linkage Behavior

This topic is 1809 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,
I encountered an issue I can’t really understand so I’ll try to explain it here to get a reasonable explanation of what’s happing. I modified the tiled deferred rendering code by Andrew Lauritzen (http://software.intel.com/en-us/articles/deferred-rendering-for-current-and-future-rendering-pipelines) to have shadows maps for each light. To be able to turn on and off shadows I’m using shader classes that look this:

interface iBaseVPLShadow
{
    bool IsEnabled();
    float GetVisibility(Texture2DArray shadowBuffer, float3 receiverWorldPos, float4x4 lightViewProjection, uint lightIndex);
};

The lighting is done in a compute shader. Basically like this:

#define TILE_DIM 8
[numthreads(TILE_DIM, TILE_DIM, 1)]
void main( … )
{         
    // Read GBuffer at current Texel
    // Calculate Tile Frustum        
    GroupMemoryBarrierWithGroupSync();           

    for all lights         
    {                  
        // each thread of the block culls one light                 
        // if the light intersects the tile frustum add it to the tiles light list         
    }
    GroupMemoryBarrierWithGroupSync();

    float3 luminance = float3(0,0,0);          
    for all lights in the tiles light list         
    {                 
        // shadow test                 
        float visibility = 1.0; 

        if (SlotVPLShadow.IsEnabled())         
            visibility = SlotVPLShadow.GetVisibility(VPLShadowBuffer, worldPosition, VPLViewProjectionData[tileLightIndex], tileLightIndex);   

        // light amount of the light arriving at the surface
        float3 irradiance = visibility * SlotVPL.GetIrradiance( … )        

        // light amount reflected by the surface (visible to the observer)  
        luminance += irradiance * SlotDiffuseMaterial.BRDF( … )
    }         
    // write luminance to output target
}

As stated by that pseudo code I’m using multiple interface. One class to describe the light source, one for the material brdf, and one for the shadows.  I implemented the iBaseVPLShadow interface to do a common shadow mapping with a Load in the shadow buffer and a comparison in light space depth. And I also implemented the interface for “no shadows” in which case the GetVisibility(…) method simply returns 1.0.

 

Now to the interesting part.

 

You may ask yourself why there is the IsEnabled() method. Actually I really don’t know^^ But if it is not there the execution time for the “no shadow” class is HIGHER than the “shadow mapping” class by factor 1.5. And there are shadow artifacts if don’t unroll the last loop in the latter case.

 

I think both problems might be related to the loop because it’s not clear how often to loop at compile time and number of lights easily goes beyond 100. But nevertheless it totally confuses my understanding on how shader classes work because everything is totally fine (and fast) with the IsEnabled() check to prevent the GetVisibility() call if the shadows are disabled.

 

Sorry for this vague description but I'm not able provide a mini sample because it's in a bigger system with lots of dependencies.

Edited by derKai

Share this post


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

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!