Skip to main content
GameDev.net gamedev.net
🔒 Locked

Interesting Shading Linkage Behavior

Started by KaiRohmer Feb 7, 2014 at 1:31 PM 0 replies 1k views
Original Post
KaiRohmer
KaiRohmer

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.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.