public struct LightData
{
public int additionalPixelLightsCount ;
public int vertexLightsCount ;
public int pixelAdditionalLightsCount ;
public int totalAdditionalLightsCount ;
public bool hasAdditionalLights ;
public bool shadowsRendered ;
}
// Max amount of visible lights. This controls the lights constant buffers in shader but not the max shaded lights.
// Lights are set per-object and the max shaded lights for each object are controlled by the max pixel lights in pipeline asset and kMaxVertexLights.
// Maximum amount of visible lights the shader can process. This controls the constant global light buffer size.
// It must match the MAX_VISIBLE_LIGHTS in LightweightCore.cginc
private static readonly int kMaxPerObjectLights = 8 ;
// Lights are culled per-object. This holds the maximum amount of additional lights that can shade each object.
// The engine fills in the lights indices per-object in unity4_LightIndices0 and unity_4LightIndices1
private static readonly int kMaxPerObjectAdditionalLights = 8 ;
private Vector4 [ ] m_LightPositions = new Vector4 [ kMaxVisibleAdditionalLights ] ;
private Vector4 [ ] m_LightColors = new Vector4 [ kMaxVisibleAdditionalLights ] ;
private Camera m_CurrCamera = null ;
private ComputeBuffer m_LightIndexListBuffer ;
private static readonly int kMaxCascades = 4 ;
private int m_ShadowCasterCascadesCount = kMaxCascades ;
public override void Dispose ( )
{
base . Dispose ( ) ;
if ( m_LightIndexListBuffer ! = null )
{
m_LightIndexListBuffer . Dispose ( ) ;
m_LightIndexListBuffer = null ;
}
}
CullResults m_CullResults ;
// There's no way to map shadow light indices. We need to pass in the original unsorted index.
// If no additional lights then no light sorting is performed and the indices match.
int shadowOriginalIndex = ( lightData . hasAdditionalLights ) ? GetLightUnsortedIndex ( lightData . mainLightIndex ) : lightData . mainLightIndex ;
int shadowOriginalIndex = ( lightData . totalAdditionalLightsCount > 0 ) ? GetLightUnsortedIndex ( lightData . mainLightIndex ) : lightData . mainLightIndex ;
lightData . shadowsRendered = RenderShadows ( ref m_CullResults , ref mainLight ,
shadowOriginalIndex , ref context ) ;
}
int visibleLightsCount = visibleLights . Length ;
m_SortedLightIndexMap . Clear ( ) ;
// kMaxPerObjectLights + 1 main light
int maxSupportedPixelLights = Math . Min ( m_Asset . MaxSupportedPixelLights , kMaxPerObjectLights + 1 ) ;
int maxPixelLights = Math . Min ( maxSupportedPixelLights , visibleLightsCount ) ;
if ( maxPixelLights < = 1 )
{
lightData . mainLightIndex = maxPixelLights - 1 ;
lightData . additionalPixelLightsCount = 0 ;
}
else
lightData . shadowsRendered = false ;
if ( visibleLightsCount < = 1 )
lightData . mainLightIndex = SortLights ( visibleLights ) ;
lightData . additionalPixelLightsCount = maxPixelLights - 1 ;
// If there's exactly one visible light that will be picked as main light.
// Otherwise we disable main light by setting its index to -1.
lightData . mainLightIndex = visibleLightsCount - 1 ;
lightData . pixelAdditionalLightsCount = 0 ;
lightData . totalAdditionalLightsCount = 0 ;
return ;
lightData . vertexLightsCount = ( m_Asset . SupportsVertexLight ) ? Math . Min ( 4 , Math . Min ( visibleLightsCount - maxPixelLights , kMaxPerObjectLights ) ) : 0 ;
lightData . hasAdditionalLights = ( lightData . additionalPixelLightsCount + lightData . vertexLightsCount ) > 0 ;
lightData . shadowsRendered = false ;
// We always support at least one per-pixel light, which is main light. Shade objects up to a limit of per-object
// pixel lights defined in the pipeline settings.
int maxSupportedPixelLights = Math . Min ( m_Asset . MaxAdditionalPixelLights , kMaxPerObjectAdditionalLights ) + 1 ;
int maxPixelLights = Math . Min ( maxSupportedPixelLights , visibleLightsCount ) ;
// If vertex lighting is enabled in the pipeline settings, then we shade the remaining visible lights per-vertex
// up to the maximum amount of per-object lights.
int vertexLights = ( m_Asset . SupportsVertexLight ) ? kMaxPerObjectAdditionalLights - maxPixelLights - 1 : 0 ;
lightData . mainLightIndex = SortLights ( visibleLights ) ;
lightData . pixelAdditionalLightsCount = maxPixelLights - 1 ;
lightData . totalAdditionalLightsCount = lightData . pixelAdditionalLightsCount + vertexLights ;
}
private int SortLights ( VisibleLight [ ] visibleLights )
SetupShadowShaderConstants ( cmd , ref context , ref lights [ lightData . mainLightIndex ] , m_ShadowCasterCascadesCount ) ;
}
if ( lightData . hasAdditionalLights )
if ( lightData . totalAdditionalLightsCount > 0 )
SetupAdditionalListConstants ( cmd , lights , ref lightData , ref context ) ;
}
}
m_CullResults . SetLightIndexMap ( perObjectLightIndexMap ) ;
cmd . SetGlobalVector ( PerCameraBuffer . _AdditionalLightCount , new Vector4 ( lightData . additionalPixelLightsCount , lightData . vertexLightsCount , 0.0f , 0.0f ) ) ;
cmd . SetGlobalVector ( PerCameraBuffer . _AdditionalLightCount , new Vector4 ( lightData . pixelAdditionalLightsCount ,
lightData . totalAdditionalLightsCount , 0.0f , 0.0f ) ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightPosition , m_LightPositions ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightColor , m_LightColors ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightAttenuationParams , m_LightAttenuations ) ;
private void SetShaderKeywords ( CommandBuffer cmd , ref LightData lightData , VisibleLight [ ] visibleLights )
{
int vertexLightsCount = lightData . totalAdditionalLightsCount - lightData . pixelAdditionalLightsCount ;
LightweightUtils . SetKeyword ( cmd , "_VERTEX_LIGHTS" , lightData . vertexLightsCount > 0 ) ;
LightweightUtils . SetKeyword ( cmd , "_ATTENUATION_TEXTURE" , m_Asset . AttenuationTexture ! = null ) ;
LightweightUtils . SetKeyword ( cmd , "_VERTEX_LIGHTS" , vertexLightsCount > 0 ) ;
LightweightUtils . SetKeyword ( cmd , "_ADDITIONAL_PIXEL_ LIGHTS" , lightData . additionalPixe lLightsCount > 0 ) ;
LightweightUtils . SetKeyword ( cmd , "_ADDITIONAL_LIGHTS" , lightData . tot alA dditionalLightsCount > 0 ) ;
string [ ] shadowKeywords = new string [ ] { "_HARD_SHADOWS" , "_SOFT_SHADOWS" , "_HARD_SHADOWS_CASCADES" , "_SOFT_SHADOWS_CASCADES" } ;
for ( int i = 0 ; i < shadowKeywords . Length ; + + i )
RendererConfiguration GetRendererSettings ( ref LightData lightData )
{
RendererConfiguration settings = RendererConfiguration . PerObjectReflectionProbes | RendererConfiguration . PerObjectLightmaps | RendererConfiguration . PerObjectLightProbe ;
if ( lightData . hasAdditionalLights )
if ( lightData . totalAdditionalLightsCount > 0 )
settings | = RendererConfiguration . PerObjectLightIndices8 ;
return settings ;
}