If you want to access lighting information directly you can use this.
Lights can be easily accessed using this class, this already implies going over the surface of what's being drawn.
struct Light
{
// The color is an RGB value in the linear sRGB color space.
float3 Color;
// The normalized light vector, in world space (direction from the
// current fragment's position to the light).
float3 Direction;
// The position of the light in world space. This value is the same as
// Direction for directional lights.
float3 Position;
// Attenuation of the light based on the distance from the current
// fragment to the light in world space. This value between 0.0 and 1.0
// is computed differently for each type of light (it's always 1.0 for
// directional lights).
float Attenuation;
// Visibility factor computed from shadow maps or other occlusion data
// specific to the light being evaluated. This value is between 0.0 and
// 1.0.
float Visibility;
// Gets the light structure given the screen-space and world position and
// the light index.
static Light From( float4 vPositionSs, float3 vPositionWs, uint nLightIndex );
// Number of lights in the current fragment.
static uint Count( float2 vPositionSs );
};
for( int i=0; i < Light::Count(); i++ )
{
Light l = Light::From( ScreenPosition, WorldPosition, i );
...
}
This iterates both Dynamic and Static lights, this does all you need and returns with all optimizations from Frustum Tiled Lighting
This is the raw, internal information of lights that comes from the scene in the CPU, listed here for reference.
class BinnedLight
{
uint4 Params; // x = num sequential frusta, y = cookie texture index, z = flags, w = light type
float4 Color; // w - Linear radius
float4 FalloffParams; // x - Linear falloff, y - quadratic falloff, z - radius squared for culling, w - truncation
float4 SpotLightInnerOuterConeCosines; // x - inner cone, y - outer cone, z - reciprocal between inner and outer angle, w - Tangent of outer angle
float4 Shape; // xy - size, zw - unused
float4x4 LightToWorld;
// Shadow
float4 ShadowBounds [ MAX_SHADOW_FRUSTA_PER_LIGHT ];
float4 ShadowVigniette[ MAX_SHADOW_FRUSTA_PER_LIGHT ];
float4x4 WorldToShadow[ MAX_SHADOW_FRUSTA_PER_LIGHT ];
float4 ProjectedShadowDepthToLinearDepth; // Assume all frusta have the same depth range
float4x4 WorldToLightCookie; // Could just be world to light now, we are bindless! Still could use it for stuff like cloud layers if we keep separate though
// ---------------------------------
uint NumShadowFrusta() { return Params.x; }
float3 GetPosition() { return LightToWorld[3].xyz; }
float3 GetDirection() { return LightToWorld[0].xyz; }
float3 GetDirectionUp() { return LightToWorld[1].xyz; }
float3 GetColor() { return Color.xyz; }
float GetLinearFalloff() { return FalloffParams.x; }
float GetQuadraticFalloff() { return FalloffParams.y; }
float GetRadiusSquared() { return FalloffParams.z; }
float GetRadius() { return Color.w; }
float2 GetShapeSize() { return Shape.xy; }
uint GetType() { return Params.z; }
bool IsSpotLight() { return ( SpotLightInnerOuterConeCosines.x != 0.0f ); }
// ---------------------------------
bool IsVisible() { return ( Params.z & LightFlags::Visible ) != 0; }
bool IsDiffuseEnabled() { return ( Params.z & LightFlags::DiffuseEnabled ) != 0; }
bool IsSpecularEnabled() { return ( Params.z & LightFlags::SpecularEnabled ) != 0; }
bool IsTransmissiveEnabled() { return ( Params.z & LightFlags::TransmissiveEnabled ) != 0; }
bool HasDynamicShadows() { return ( Params.z & LightFlags::ShadowEnabled ) != 0; }
bool HasLightCookie() { return ( Params.z & LightFlags::LightCookieEnabled ) != 0; }
bool HasFrustumFeathering() { return ( Params.z & LightFlags::FrustumFeathering ) != 0; }
Texture2D GetLightCookieTexture() { return g_bindless_Texture2D[ Params.y ]; }
};
StructuredBuffer<BinnedLight> BinnedLightBuffer < Attribute( "BinnedLightBuffer" ); > ;
BinnedLight DynamicLightConstantByIndex( int index )
{
return BinnedLightBuffer[ index ];
}
BinnedLight BakedIndexedLightConstantByIndex( int index )
{
return BinnedLightBuffer[ BakedLightIndexMapping[index].x ];
}