//#define SHADOWS_OLD
using UnityEngine.Rendering ;
using UnityEngine.Rendering ;
#if !SHADOWS_OLD
using ShadowExp ;
class ShadowSetup : IDisposable
{
// shadow related stuff
public ShadowSetup ( ShadowSettings shadowSettings , out IShadowManager shadowManager )
{
s_ShadowDataBuffer = new ComputeBuffer ( k_MaxShadowDataSlots , System . Runtime . InteropServices . Marshal . SizeOf ( typeof ( ShadowExp . Shadow Data ) ) ) ;
s_ShadowPayloadBuffer = new ComputeBuffer ( k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData , System . Runtime . InteropServices . Marshal . SizeOf ( typeof ( ShadowExp . Shadow Payload ) ) ) ;
s_ShadowDataBuffer = new ComputeBuffer ( k_MaxShadowDataSlots , System . Runtime . InteropServices . Marshal . SizeOf ( typeof ( ShadowData ) ) ) ;
s_ShadowPayloadBuffer = new ComputeBuffer ( k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData , System . Runtime . InteropServices . Marshal . SizeOf ( typeof ( ShadowPayload ) ) ) ;
ShadowAtlas . AtlasInit atlasInit ;
atlasInit . baseInit . width = ( uint ) shadowSettings . shadowAtlasWidth ;
atlasInit . baseInit . height = ( uint ) shadowSettings . shadowAtlasHeight ;
var varianceInit3 = varianceInit ;
varianceInit3 . baseInit . shadowmapFormat = ShadowVariance . GetFormat ( true , false , true ) ;
m_Shadowmaps = new ShadowmapBase [ ] { new ShadowExp . Shadow Variance ( ref varianceInit ) , new ShadowExp . ShadowVariance ( ref varianceInit2 ) , new ShadowExp . Shadow Variance ( ref varianceInit3 ) , new ShadowExp . ShadowAtlas ( ref atlasInit ) } ;
m_Shadowmaps = new ShadowmapBase [ ] { new ShadowVariance ( ref varianceInit ) , new ShadowVariance ( ref varianceInit2 ) , new ShadowVariance ( ref varianceInit3 ) , new ShadowAtlas ( ref atlasInit ) } ;
ShadowExp . Shadow Data [ ] sds ;
ShadowData [ ] sds ;
sc . GetShadowDatas ( out sds , out offset , out count ) ;
Debug . Assert ( offset = = 0 ) ;
s_ShadowDataBuffer . SetData ( sds ) ; // unfortunately we can't pass an offset or count to this function
scInit . dataSyncer = syncer ;
scInit . resourceBinder = binder ;
m_ShadowMgr = new ShadowExp . Shadow Manager ( shadowSettings , ref scInit , m_Shadowmaps ) ;
m_ShadowMgr = new ShadowManager ( shadowSettings , ref scInit , m_Shadowmaps ) ;
// set global overrides - these need to match the override specified in ShadowDispatch.hlsl
bool useGlobalOverrides = true ;
m_ShadowMgr . SetGlobalShadowOverride ( GPUShadowType . Point , ShadowAlgorithm . PCF , ShadowVariant . V4 , ShadowPrecision . High , useGlobalOverrides ) ;
s_ShadowPayloadBuffer . Release ( ) ;
}
}
#endif
namespace TilePass
{
Material m_SingleDeferredMaterialSRT = null ;
Material m_SingleDeferredMaterialMRT = null ;
#if !SHADOWS_OLD
FrameId m_FrameId ;
FrameId m_FrameId = new FrameId ( ) ;
ShadowSetup m_ShadowSetup ; // doesn't actually have to reside here, it would be enough to pass the IShadowManager in from the outside
IShadowManager m_ShadowMgr ;
List < int > m_ShadowRequests = new List < int > ( ) ;
m_ShadowMgr = null ;
}
}
#endif
int GetNumTileFtplX ( Camera camera )
UnityEditor . SceneView . onSceneGUIDelegate + = OnSceneGUI ;
#endif
#if !SHADOWS_OLD
#endif
#if !SHADOWS_OLD
#endif
#if UNITY_EDITOR
UnityEditor . SceneView . onSceneGUIDelegate - = OnSceneGUI ;
#endif
{
return new Vector3 ( light . finalColor . r , light . finalColor . g , light . finalColor . b ) ;
}
#if SHADOWS_OLD
// Return number of added shadow
public int GetShadows ( VisibleLight light , int lightIndex , ref ShadowOutput shadowOutput , ShadowSettings shadowSettings )
{
for ( int sliceIndex = 0 ; sliceIndex < shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) ; + + sliceIndex )
{
ShadowData shadowData = new ShadowData ( ) ;
int shadowSliceIndex = shadowOutput . GetShadowSliceIndex ( lightIndex , sliceIndex ) ;
shadowData . worldToShadow = shadowOutput . shadowSlices [ shadowSliceIndex ] . shadowTransform . transpose ; // Transpose for hlsl reading ?
shadowData . bias = light . light . shadowBias ;
shadowData . invResolution = new Vector4 ( 1.0f / shadowSettings . shadowAtlasWidth , 1.0f / shadowSettings . shadowAtlasHeight , 0.0f , 0.0f ) ;
m_lightList . shadows . Add ( shadowData ) ;
}
return shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) ;
}
#endif
#if SHADOWS_OLD
public bool GetDirectionalLightData ( ShadowSettings shadowSettings , GPULightType gpuLightType , VisibleLight light , AdditionalLightData additionalData , int lightIndex , ref ShadowOutput shadowOutput , ref int directionalShadowcount )
#else
#endif
{
var directionalLightData = new DirectionalLightData ( ) ;
directionalLightData . tileCookie = ( light . light . cookie . wrapMode = = TextureWrapMode . Repeat ) ;
directionalLightData . cookieIndex = m_CookieTexArray . FetchSlice ( light . light . cookie ) ;
}
#if SHADOWS_OLD
bool hasDirectionalShadows = light . light . shadows ! = LightShadows . None & & shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) ! = 0 ;
bool hasDirectionalNotReachMaxLimit = directionalShadowcount = = 0 ; // Only one cascade shadow allowed
// If we have not found a directional shadow casting light yet, we register the last directional anyway as "sun".
if ( directionalShadowcount = = 0 )
{
m_CurrentSunLight = light . light ;
}
if ( hasDirectionalShadows & & hasDirectionalNotReachMaxLimit ) // Note < MaxShadows should be check at shadowOutput creation
{
// Always choose the directional shadow casting light if it exists.
m_CurrentSunLight = light . light ;
directionalLightData . shadowIndex = m_lightList . shadows . Count ;
directionalShadowcount + = GetShadows ( light , lightIndex , ref shadowOutput , shadowSettings ) ;
// Fill split information for shaders
for ( int s = 0 ; s < k_MaxCascadeCount ; + + s )
{
m_lightList . directionalShadowSplitSphereSqr [ s ] = shadowOutput . directionalShadowSplitSphereSqr [ s ] ;
}
}
#else
// fix up shadow information
int shadowIdx ;
if ( m_ShadowIndices . TryGetValue ( lightIndex , out shadowIdx ) )
}
m_CurrentSunLight = m_CurrentSunLight = = null ? light . light : m_CurrentSunLight ;
#endif
m_lightList . directionalLights . Add ( directionalLightData ) ;
return true ;
return 1.0f - Mathf . Clamp01 ( ( distanceToCamera - distanceFadeNear ) / ( fadeDistance - distanceFadeNear ) ) ;
}
#if SHADOWS_OLD
public bool GetLightData ( ShadowSettings shadowSettings , Camera camera , GPULightType gpuLightType , VisibleLight light , AdditionalLightData additionalData , int lightIndex , ref ShadowOutput shadowOutput , ref int shadowCount )
#else
#endif
{
var lightData = new LightData ( ) ;
float shadowDistanceFade = ComputeLinearDistanceFade ( distanceToCamera , additionalData . shadowFadeDistance ) ;
lightData . shadowDimmer = additionalData . shadowDimmer * shadowDistanceFade ;
#if SHADOWS_OLD
// Setup shadow data arrays
// In case lightData.shadowDimmer == 0.0 we need to avoid rendering the shadow map... see how it can be done with the culling (and more specifically, how can we do that BEFORE sending for shadows)
bool hasShadows = lightData . shadowDimmer > 0.0f & & distanceToCamera < shadowSettings . maxShadowDistance & & light . light . shadows ! = LightShadows . None & & shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) ! = 0 ;
bool hasNotReachMaxLimit = shadowCount + ( lightData . lightType = = GPULightType . Point ? 6 : 1 ) < = k_MaxShadowOnScreen ;
// TODO: Read the comment about shadow limit/management at the beginning of this loop
if ( hasShadows & & hasNotReachMaxLimit )
{
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
lightData . shadowIndex = m_lightList . shadows . Count ;
shadowCount + = GetShadows ( light , lightIndex , ref shadowOutput , shadowSettings ) ;
}
#else
// fix up shadow information
int shadowIdx ;
if ( m_ShadowIndices . TryGetValue ( lightIndex , out shadowIdx ) )
#endif
if ( additionalData . archetype ! = LightArchetype . Punctual )
{
lightData . twoSided = additionalData . isDoubleSided ;
m_lightList . bounds . Add ( bound ) ;
m_lightList . lightVolumes . Add ( lightVolumeData ) ;
}
#if SHADOWS_OLD
public override void PrepareLightsForGPU ( ShadowSettings shadowSettings , CullResults cullResults , Camera camera , ref ShadowOutput shadowOutput )
#else
public override int GetCurrentShadowCount ( )
{
return m_ShadowRequests . Count ;
}
public override void PrepareLightsForGPU ( ShadowSettings shadowSettings , CullResults cullResults , Camera camera )
#endif
#if !SHADOWS_OLD
// 0. deal with shadows
{
m_FrameId . frameCount + + ;
uint shadowRequestCount = ( uint ) m_ShadowRequests . Count ;
int [ ] shadowRequests = m_ShadowRequests . ToArray ( ) ;
int [ ] shadowDataIndices ;
uint originalRequestCount = shadowRequestCount ;
m_ShadowMgr . ProcessShadowRequests ( m_FrameId , cullResults , camera , cullResults . visibleLights ,
ref shadowRequestCount , shadowRequests , out shadowDataIndices ) ;
m_ShadowIndices . Add ( shadowRequests [ i ] , shadowDataIndices [ i ] ) ;
}
}
#endif
float oldSpecularGlobalDimmer = m_PassSettings . specularGlobalDimmer ;
// Change some parameters in case of "special" rendering (can be preview, reflection, etc.
if ( camera . cameraType = = CameraType . Reflection )
GPULightType gpuLightType = GPULightType . Point ;
LightVolumeType lightVolumeType = LightVolumeType . Count ;
// Note: LightType.Area is offline only, use for baking, no need to test it
if ( additionalData . archetype = = LightArchetype . Punctual )
{
switch ( light . lightType )
// Note: LightType.Area is offline only, use for baking, no need to test it
if ( additionalData . archetype = = LightArchetype . Punctual )
case LightType . Point :
if ( punctualLightcount > = k_MaxPunctualLightsOnScreen )
continue ;
lightCategory = LightCategory . Punctual ;
gpuLightType = GPULightType . Point ;
lightVolumeType = LightVolumeType . Sphere ;
break ;
switch ( light . lightType )
{
case LightType . Point :
if ( punctualLightcount > = k_MaxPunctualLightsOnScreen )
continue ;
lightCategory = LightCategory . Punctual ;
gpuLightType = GPULightType . Point ;
lightVolumeType = LightVolumeType . Sphere ;
break ;
case LightType . Spot :
if ( punctualLightcount > = k_MaxPunctualLightsOnScreen )
continue ;
lightCategory = LightCategory . Punctual ;
gpuLightType = GPULightType . Spot ;
lightVolumeType = LightVolumeType . Cone ;
break ;
case LightType . Spot :
if ( punctualLightcount > = k_MaxPunctualLightsOnScreen )
continue ;
lightCategory = LightCategory . Punctual ;
gpuLightType = GPULightType . Spot ;
lightVolumeType = LightVolumeType . Cone ;
break ;
case LightType . Directional :
if ( directionalLightcount > = k_MaxDirectionalLightsOnScreen )
continue ;
lightCategory = LightCategory . Punctual ;
gpuLightType = GPULightType . Directional ;
// No need to add volume, always visible
lightVolumeType = LightVolumeType . Count ; // Count is none
break ;
case LightType . Directional :
if ( directionalLightcount > = k_MaxDirectionalLightsOnScreen )
continue ;
lightCategory = LightCategory . Punctual ;
gpuLightType = GPULightType . Directional ;
// No need to add volume, always visible
lightVolumeType = LightVolumeType . Count ; // Count is none
break ;
default :
Debug . Assert ( false , "TODO: encountered an unknown LightType." ) ;
break ;
default :
Debug . Assert ( false , "TODO: encountered an unknown LightType." ) ;
break ;
}
}
else
{
switch ( additionalData . archetype )
else
case LightArchetype . Area :
if ( areaLightCount > = k_MaxAreaLightsOnScreen ) { continue ; }
lightCategory = LightCategory . Area ;
gpuLightType = ( additionalData . lightWidth > 0 ) ? GPULightType . Rectangle : GPULightType . Line ;
lightVolumeType = LightVolumeType . Box ;
break ;
case LightArchetype . Projector :
if ( projectorLightCount > = k_MaxProjectorLightsOnScreen ) { continue ; }
lightCategory = LightCategory . Projector ;
switch ( light . lightType )
{
case LightType . Directional :
gpuLightType = GPULightType . ProjectorOrtho ;
lightVolumeType = LightVolumeType . Box ;
break ;
case LightType . Spot :
gpuLightType = GPULightType . ProjectorPyramid ;
lightVolumeType = LightVolumeType . Cone ;
break ;
default :
Debug . Assert ( false , "Projectors can only be Spot or Directional lights." ) ;
break ;
}
break ;
default :
Debug . Assert ( false , "TODO: encountered an unknown LightArchetype." ) ;
break ;
switch ( additionalData . archetype )
{
case LightArchetype . Area :
if ( areaLightCount > = k_MaxAreaLightsOnScreen ) { continue ; }
lightCategory = LightCategory . Area ;
gpuLightType = ( additionalData . lightWidth > 0 ) ? GPULightType . Rectangle : GPULightType . Line ;
lightVolumeType = LightVolumeType . Box ;
break ;
case LightArchetype . Projector :
if ( projectorLightCount > = k_MaxProjectorLightsOnScreen ) { continue ; }
lightCategory = LightCategory . Projector ;
switch ( light . lightType )
{
case LightType . Directional :
gpuLightType = GPULightType . ProjectorOrtho ;
lightVolumeType = LightVolumeType . Box ;
break ;
case LightType . Spot :
gpuLightType = GPULightType . ProjectorPyramid ;
lightVolumeType = LightVolumeType . Cone ;
break ;
default :
Debug . Assert ( false , "Projectors can only be Spot or Directional lights." ) ;
break ;
}
break ;
default :
Debug . Assert ( false , "TODO: encountered an unknown LightArchetype." ) ;
break ;
}
}
#if SHADOWS_OLD
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 6 bit (0x3F) lightVolume, 16 bit index
sortKeys [ sortCount + + ] = ( uint ) lightCategory < < 2 7 | ( uint ) gpuLightType < < 2 2 | ( uint ) lightVolumeType < < 1 6 | ( uint ) lightIndex ;
#else
uint shadow = m_ShadowIndices . ContainsKey ( lightIndex ) ? 1 u : 0 ;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys [ sortCount + + ] = ( uint ) lightCategory < < 2 7 | ( uint ) gpuLightType < < 2 2 | ( uint ) lightVolumeType < < 1 7 | shadow < < 1 6 | ( uint ) lightIndex ;
#endif
uint shadow = m_ShadowIndices . ContainsKey ( lightIndex ) ? 1 u : 0 ;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys [ sortCount + + ] = ( uint ) lightCategory < < 2 7 | ( uint ) gpuLightType < < 2 2 | ( uint ) lightVolumeType < < 1 7 | shadow < < 1 6 | ( uint ) lightIndex ;
}
Array . Sort ( sortKeys ) ;
// will be use...)
// The lightLoop is in charge, not the shadow pass.
// For now we will still apply the maximum of shadow here but we don't apply the sorting by priority + slot allocation yet
#if SHADOWS_OLD
int directionalShadowcount = 0 ;
int shadowCount = 0 ;
#endif
m_CurrentSunLight = null ;
// 2. Go thought all lights, convert them to GPU format.
uint sortKey = sortKeys [ sortIndex ] ;
LightCategory lightCategory = ( LightCategory ) ( ( sortKey > > 2 7 ) & 0 x1F ) ;
GPULightType gpuLightType = ( GPULightType ) ( ( sortKey > > 2 2 ) & 0 x1F ) ;
#if SHADOWS_OLD
LightVolumeType lightVolumeType = ( LightVolumeType ) ( ( sortKey > > 1 6 ) & 0 x3F ) ;
#else
#endif
int lightIndex = ( int ) ( sortKey & 0 xFFFF ) ;
var light = cullResults . visibleLights [ lightIndex ] ;
if ( gpuLightType = = GPULightType . Directional )
{
#if SHADOWS_OLD
if ( GetDirectionalLightData ( shadowSettings , gpuLightType , light , additionalData , lightIndex , ref shadowOutput , ref directionalShadowcount ) )
#else
#endif
#if SHADOWS_OLD
if ( GetLightData ( shadowSettings , camera , gpuLightType , light , additionalData , lightIndex , ref shadowOutput , ref shadowCount ) )
#else
// Punctual, area, projector lights - the rendering side.
#endif
// Punctual, area, projector lights - the rendering side.
{
switch ( lightCategory )
{
private void BindGlobalParams ( CommandBuffer cmd , ComputeShader computeShader , int kernelIndex , Camera camera , ScriptableRenderContext loop )
{
#if !SHADOWS_OLD
#endif
SetGlobalBuffer ( "g_vLightListGlobal" , ! usingFptl ? s_PerVoxelLightLists : s_LightList ) ; // opaques list (unless MSAA possibly)
SetGlobalTexture ( "_CookieTextures" , m_CookieTexArray . GetTexCache ( ) ) ;
{
var cmd = new CommandBuffer { name = "Push Global Parameters" } ;
#if !SHADOWS_OLD
#endif
SetGlobalPropertyRedirect ( computeShader , kernelIndex , cmd ) ;
BindGlobalParams ( cmd , computeShader , kernelIndex , camera , loop ) ;
SetGlobalPropertyRedirect ( null , 0 , null ) ;
public override void RenderShadows ( ScriptableRenderContext renderContext , CullResults cullResults )
{
#if !SHADOWS_OLD
#endif
}
private void SetupRenderingForDebug ( LightingDebugSettings lightDebugSettings )