using System ;
using System.Collections.Generic ;
using UnityEngine.Rendering ;
using UnityEngine.Rendering.PostProcessing ;
using UnityEngine.XR ;
public struct LightData
{
public int p ixelLightsCount;
public int additionalP ixelLightsCount;
public int shadow LightIndex;
public bool isSingleLight ;
public int main LightIndex;
public bool hasAdditionalLights ;
public bool shadowsRendered ;
}
private Vector4 [ ] m_LightSpotDirections = new Vector4 [ kMaxVisibleLights ] ;
private Camera m_CurrCamera = null ;
private LightType m_SingleLightType = LightType . Directional ;
private int m_LightIndicesCount = 0 ;
private ComputeBuffer m_LightIndexListBuffer ;
m_Asset = asset ;
BuildShadowSettings ( ) ;
PerFrameBuffer . _GlossyEnvironmentColor = Shader . PropertyToID ( "_GlossyEnvironmentColor" ) ;
PerFrameBuffer . _AttenuationTexture = Shader . PropertyToID ( "_AttenuationTexture" ) ;
PerCameraBuffer . _MainLightPosition = Shader . PropertyToID ( "_MainLightPosition" ) ;
PerCameraBuffer . _MainLightColor = Shader . PropertyToID ( "_MainLightColor" ) ;
PerCameraBuffer . _MainLightAttenuationParams = Shader . PropertyToID ( "_MainLightAttenuationParams" ) ;
PerCameraBuffer . _MainLightSpotDir = Shader . PropertyToID ( "_MainLightSpotDir" ) ;
PerCameraBuffer . _AdditionalLightCount = Shader . PropertyToID ( "_AdditionalLightCount" ) ;
PerCameraBuffer . _AdditionalLightPosition = Shader . PropertyToID ( "_AdditionalLightPosition" ) ;
PerCameraBuffer . _AdditionalLightColor = Shader . PropertyToID ( "_AdditionalLightColor" ) ;
PerCameraBuffer . _AdditionalLightAttenuationParams = Shader . PropertyToID ( "_AdditionalLightAttenuationParams" ) ;
PerCameraBuffer . _AdditionalLightSpotDir = Shader . PropertyToID ( "_AdditionalLightSpotDir" ) ;
m_ShadowMapTexture = Shader . PropertyToID ( "_ShadowMap" ) ;
m_CameraColorTexture = Shader . PropertyToID ( "_CameraRT" ) ;
m_CameraDepthTexture = Shader . PropertyToID ( "_CameraDepthTexture" ) ;
// instead this should be forced when using SRP, since all SRP use linear lighting.
GraphicsSettings . lightsUseLinearIntensity = true ;
SetupPerFrameShaderConstants ( ref context ) ;
// Sort cameras array by camera depth
PostProcessLayer postProcessLayer ;
RenderingConfiguration renderingConfig = SetupRendering ( out postProcessLayer ) ;
bool postProcessEnabled = LightweightUtils . HasFlag ( renderingConfig , RenderingConfiguration . PostProcess ) ;
ScriptableCullingParameters cullingParameters ;
if ( ! CullResults . GetCullingParameters ( m_CurrCamera , stereoEnabled , out cullingParameters ) )
continue ;
// emit scene view UI
#if UNITY_EDITOR
// Emit scene view UI
#endif
// Render Shadow Map
if ( lightData . shadowLightIndex > - 1 )
lightData . shadowsRendered = RenderShadows ( ref m_CullResults ,
ref visibleLights [ lightData . shadowLightIndex ] , lightData . shadowLightIndex , ref context ) ;
ShadowPass ( visibleLights , ref context , ref lightData ) ;
ForwardPass ( visibleLights , ref context , ref lightData , stereoEnabled ) ;
// Setup camera matrices
context . SetupCameraProperties ( m_CurrCamera , stereoEnabled ) ;
context . Submit ( ) ;
}
}
// Setup light and shadow shader constants
SetupShaderLightConstants ( visibleLights , ref lightData , ref m_CullResults , ref context ) ;
if ( lightData . shadowsRendered )
SetupShadowShaderConstants ( ref context , ref visibleLights [ lightData . shadowLightIndex ] ,
lightData . shadowLightIndex , m_ShadowCasterCascadesCount ) ;
SetShaderKeywords ( ref lightData , ref context ) ;
private void ShadowPass ( VisibleLight [ ] visibleLights , ref ScriptableRenderContext context , ref LightData lightData )
{
if ( m_Asset . AreShadowsEnabled ( ) & & lightData . mainLightIndex ! = - 1 )
{
VisibleLight mainLight = visibleLights [ lightData . mainLightIndex ] ;
if ( mainLight . light . shadows ! = LightShadows . None )
lightData . shadowsRendered = RenderShadows ( ref m_CullResults ,
ref mainLight , lightData . mainLightIndex , ref context ) ;
}
}
RendererConfiguration rendererSettings = GetRendererSettings ( ref lightData ) ;
private void ForwardPass ( VisibleLight [ ] visibleLights , ref ScriptableRenderContext context , ref LightData lightData , bool stereoEnabled )
{
PostProcessLayer postProcessLayer ;
RenderingConfiguration renderingConfig = SetupRendering ( out postProcessLayer ) ;
bool postProcessEnabled = LightweightUtils . HasFlag ( renderingConfig , RenderingConfiguration . PostProcess ) ;
CommandBuffer cmd = CommandBufferPool . Get ( "SetupShaderConstants" ) ;
SetupShaderLightConstants ( cmd , visibleLights , ref lightData , ref m_CullResults , ref context ) ;
SetShaderKeywords ( cmd , ref lightData , visibleLights ) ;
context . ExecuteCommandBuffer ( cmd ) ;
CommandBufferPool . Release ( cmd ) ;
BeginForwardRendering ( ref context , renderingConfig ) ;
RenderOpaques ( ref context , rendererSettings ) ;
context . DrawSkybox ( m_CurrCamera ) ;
// Setup camera matrices
context . SetupCameraProperties ( m_CurrCamera , stereoEnabled ) ;
RendererConfiguration rendererSettings = GetRendererSettings ( ref lightData ) ;
if ( postProcessEnabled )
RenderPostProcess ( ref context , postProcessLayer , true ) ;
BeginForwardRendering ( ref context , renderingConfig ) ;
RenderOpaques ( ref context , rendererSettings ) ;
context . DrawSkybox ( m_CurrCamera ) ;
RenderTransparents ( ref context , rendererSettings ) ;
if ( postProcessEnabled )
RenderPostProcess ( ref context , postProcessLayer , true ) ;
if ( postProcessEnabled )
RenderPostProcess ( ref context , postProcessLayer , false ) ;
RenderTransparents ( ref context , rendererSettings ) ;
EndForwardRendering ( ref context , renderingConfig ) ;
if ( postProcessEnabled )
RenderPostProcess ( ref context , postProcessLayer , false ) ;
// Release temporary RT
var discardRT = CommandBufferPool . Get ( ) ;
discardRT . ReleaseTemporaryRT ( m_ShadowMapTexture ) ;
discardRT . ReleaseTemporaryRT ( m_CameraColorTexture ) ;
discardRT . ReleaseTemporaryRT ( m_CameraDepthTexture ) ;
context . ExecuteCommandBuffer ( discardRT ) ;
CommandBufferPool . Release ( discardRT ) ;
EndForwardRendering ( ref context , renderingConfig ) ;
context . Submit ( ) ;
}
// Release temporary RT
var discardRT = CommandBufferPool . Get ( ) ;
discardRT . ReleaseTemporaryRT ( m_ShadowMapTexture ) ;
discardRT . ReleaseTemporaryRT ( m_CameraColorTexture ) ;
discardRT . ReleaseTemporaryRT ( m_CameraDepthTexture ) ;
context . ExecuteCommandBuffer ( discardRT ) ;
CommandBufferPool . Release ( discardRT ) ;
}
private void RenderOpaques ( ref ScriptableRenderContext context , RendererConfiguration settings )
} ;
context . DrawRenderers ( m_CullResults . visibleRenderers , ref transparentSettings , transparentFilterSettings ) ;
}
private void BuildShadowSettings ( )
return renderingConfig ;
}
private void InitializeLightData ( VisibleLight [ ] lights , out LightData lightData )
private void InitializeLightData ( VisibleLight [ ] visibleLights , out LightData lightData )
int lightsCount = lights . Length ;
int maxPerPixelLights = Math . Min ( m_Asset . MaxSupportedPixelLights , kMaxPerObjectLights ) ;
lightData . pixelLightsCount = Math . Min ( lightsCount , maxPerPixelLights ) ;
lightData . vertexLightsCount = ( m_Asset . SupportsVertexLight ) ? Math . Min ( lightsCount - lightData . pixelLightsCount , kMaxPerObjectLights ) : 0 ;
int visibleLightsCount = visibleLights . Length ;
// TODO: Handle Vertex lights in this case
lightData . isSingleLight = lightData . pixelLightsCount < = 1 ;
if ( lightData . isSingleLight )
m_SingleLightType = ( lightData . pixelLightsCount = = 1 ) ? lights [ 0 ] . lightType : LightType . Directional ;
// 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 . mainLightIndex = GetMainLightIndex ( visibleLights ) ;
lightData . additionalPixelLightsCount = maxPixelLights - 1 ;
}
lightData . vertexLightsCount = ( m_Asset . SupportsVertexLight ) ? Math . Min ( visibleLightsCount - maxPixelLights , kMaxPerObjectLights ) : 0 ;
lightData . hasAdditionalLights = ( lightData . additionalPixelLightsCount + lightData . vertexLightsCount ) > 0 ;
}
InitializeMainShadowLightIndex ( lights , out lightData . shadowLightIndex ) ;
// How main light is decided:
// 1) If shadows are enabled and at least a shadow light is present:
// Main light is a shadow light. Directional shadow light has priority over the other supported
// shadow lights types.
// Lightweight pipeline only supports 1 single directional shadow light.
// Any additional pixel lights don't cast shadows.
//
// 2) If shadows are disabled or no shadow light is present then main light is the main brighest directional
// 3) If neither a shadow light or main light is first visible light.
private int GetMainLightIndex ( VisibleLight [ ] lights )
{
bool shadowsEnabled = m_Asset . AreShadowsEnabled ( ) ;
int mainDirectional = - 1 ;
int mainShadowLight = - 1 ;
for ( int i = 0 ; i < lights . Length ; + + i )
{
if ( shadowsEnabled & & LightweightUtils . IsSupportedShadowType ( lights [ i ] . lightType ) & & lights [ i ] . light . shadows ! = LightShadows . None )
{
// Shadow Type priority: Soft > Hard > None
if ( mainShadowLight < 0 | | lights [ i ] . light . shadows > lights [ mainShadowLight ] . light . shadows )
mainShadowLight = i ;
}
if ( lights [ i ] . lightType = = LightType . Directional )
{
if ( mainDirectional < 0 | | lights [ i ] . light . intensity > lights [ mainDirectional ] . light . intensity )
mainDirectional = i ;
}
}
if ( mainShadowLight > = 0 )
{
if ( mainDirectional > 0 & & lights [ mainDirectional ] . light . shadows ! = LightShadows . None )
return mainDirectional ;
else
return mainShadowLight ;
}
if ( mainDirectional > 0 )
return mainDirectional ;
return 0 ;
}
private void InitializeLightConstants ( VisibleLight [ ] lights , int lightIndex , out Vector4 lightPos , out Vector4 lightColor , out Vector4 lightSpotDir ,
}
}
private void SetupShaderLightConstants ( VisibleLight [ ] lights , ref LightData lightData , ref CullResults cullResults , ref ScriptableRenderContext context )
private void SetupPerFrameShaderConstants ( ref ScriptableRenderContext context )
CommandBuffer cmd = CommandBufferPool . Get ( "SetupSingleLightConstants" ) ;
cmd . SetGlobalVector ( "_GlossyEnvironmentColor" , glossyEnvColor ) ;
if ( m_Asset . AttenuationTexture ! = null ) cmd . SetGlobalTexture ( "_AttenuationTexture" , m_Asset . AttenuationTexture ) ;
CommandBuffer cmd = CommandBufferPool . Get ( "SetupPerFrameConstants" ) ;
cmd . SetGlobalVector ( PerFrameBuffer . _GlossyEnvironmentColor , glossyEnvColor ) ;
if ( m_Asset . AttenuationTexture ! = null ) cmd . SetGlobalTexture ( PerFrameBuffer . _AttenuationTexture , m_Asset . AttenuationTexture ) ;
context . ExecuteCommandBuffer ( cmd ) ;
CommandBufferPool . Release ( cmd ) ;
}
if ( lightData . isSingleLight )
SetupShaderSingleLightConstants ( cmd , lights , ( lightData . pixelLightsCount > 0 ) ? 0 : - 1 , ref context ) ;
else
SetupShaderLightListConstants ( cmd , lights , ref lightData , ref context ) ;
private void SetupShaderLightConstants ( CommandBuffer cmd , VisibleLight [ ] lights , ref LightData lightData , ref CullResults cullResults , ref ScriptableRenderContext context )
{
// Main light has an optimized shader path for main light. This will benefit games that only care about a single light.
// Lightweight pipeline also supports only a single shadow light, if available it will be the main light.
if ( lightData . mainLightIndex ! = - 1 )
{
SetupMainLightConstants ( cmd , lights , lightData . mainLightIndex , ref context ) ;
if ( lightData . shadowsRendered )
SetupShadowShaderConstants ( cmd , ref context , ref lights [ lightData . mainLightIndex ] , m_ShadowCasterCascadesCount ) ;
}
context . ExecuteCommandBuffer ( cmd ) ;
CommandBufferPool . Release ( cmd ) ;
if ( lightData . hasAdditionalLights )
SetupAdditionalListConstants ( cmd , lights , ref lightData , ref context ) ;
private void SetupShaderSingleLightConstants ( CommandBuffer cmd , VisibleLight [ ] lights , int lightIndex , ref ScriptableRenderContext context )
private void SetupMainLightConstants ( CommandBuffer cmd , VisibleLight [ ] lights , int lightIndex , ref ScriptableRenderContext context )
cmd . SetGlobalVector ( "_LightPosition" , lightPos ) ;
cmd . SetGlobalColor ( "_LightColor" , lightColor ) ;
cmd . SetGlobalVector ( "_LightSpotDir" , lightSpotDir ) ;
cmd . SetGlobalVector ( "_LightAttenuationParams" , lightAttenuationParams ) ;
cmd . SetGlobalVector ( PerCameraBuffer . _MainLightPosition , lightPos ) ;
cmd . SetGlobalColor ( PerCameraBuffer . _MainLightColor , lightColor ) ;
cmd . SetGlobalVector ( PerCameraBuffer . _MainLightSpotDir , lightSpotDir ) ;
cmd . SetGlobalVector ( PerCameraBuffer . _MainLightAttenuationParams , lightAttenuationParams ) ;
private void SetupShaderLightListConstants ( CommandBuffer cmd , VisibleLight [ ] lights , ref LightData lightData , ref ScriptableRenderContext context )
private void SetupAdditionalListConstants ( CommandBuffer cmd , VisibleLight [ ] lights , ref LightData lightData , ref ScriptableRenderContext context )
int maxLights = Math . Min ( kMaxVisibleLights , lights . Length ) ;
int totalLightCount = lights . Length ;
int maxLights = Math . Min ( kMaxVisibleLights , totalLightCount ) ;
for ( int i = 0 ; i < maxLights ; + + i )
InitializeLightConstants ( lights , i , out m_LightPositions [ i ] , out m_LightColors [ i ] , out m_LightSpotDirections [ i ] , out m_LightAttenuations [ i ] ) ;
// Lightweight pipeline only upload kMaxVisibleLights to shader cbuffer.
// We tell the pipe to disable remaining lights by setting it to -1.
for ( int i = kMaxVisibleLights ; i < lightIndexMap . Length ; + + i )
lightIndexMap [ i ] = - 1 ;
int lightIter = 0 ;
for ( int i = 0 ; i < totalLightCount ; + + i )
{
if ( i = = lightData . mainLightIndex | | lightIter > = maxLights )
{
lightIndexMap [ i ] = - 1 ;
continue ;
}
InitializeLightConstants ( lights , i , out m_LightPositions [ lightIter ] , out m_LightColors [ lightIter ] , out m_LightSpotDirections [ lightIter ] , out m_LightAttenuations [ lightIter ] ) ;
lightIndexMap [ i ] = lightIter ;
lightIter + + ;
}
cmd . SetGlobalVector ( "globalLightCount" , new Vector4 ( lightData . pixelLightsCount , lightData . vertexLightsCount , 0.0f , 0.0f ) ) ;
cmd . SetGlobalVectorArray ( "globalLightPos" , m_LightPositions ) ;
cmd . SetGlobalVectorArray ( "globalLightColor" , m_LightColors ) ;
cmd . SetGlobalVectorArray ( "globalLightAtten" , m_LightAttenuations ) ;
cmd . SetGlobalVectorArray ( "globalLightSpotDir" , m_LightSpotDirections ) ;
cmd . SetGlobalVector ( PerCameraBuffer . _AdditionalLightCount , new Vector4 ( lightData . additionalPixelLightsCount , lightData . vertexLightsCount , 0.0f , 0.0f ) ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightPosition , m_LightPositions ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightColor , m_LightColors ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightAttenuationParams , m_LightAttenuations ) ;
cmd . SetGlobalVectorArray ( PerCameraBuffer . _AdditionalLightSpotDir , m_LightSpotDirections ) ;
}
private void SetupShadowShaderConstants ( CommandBuffer cmd , ref ScriptableRenderContext context , ref VisibleLight shadowLight , int cascadeCount )
{
Vector3 shadowLightDir = Vector3 . Normalize ( shadowLight . localToWorld . GetColumn ( 2 ) ) ;
float bias = shadowLight . light . shadowBias * 0.1f ;
float normalBias = shadowLight . light . shadowNormalBias ;
float shadowResolution = m_ShadowSlices [ 0 ] . shadowResolution ;
const int maxShadowCascades = 4 ;
Matrix4x4 [ ] shadowMatrices = new Matrix4x4 [ maxShadowCascades ] ;
for ( int i = 0 ; i < cascadeCount ; + + i )
shadowMatrices [ i ] = ( cascadeCount > = i ) ? m_ShadowSlices [ i ] . shadowTransform : Matrix4x4 . identity ;
// TODO: shadow resolution per cascade in case cascades endup being supported.
float invShadowResolution = 1.0f / shadowResolution ;
float [ ] pcfKernel =
{
- 0.5f * invShadowResolution , 0.5f * invShadowResolution ,
0.5f * invShadowResolution , 0.5f * invShadowResolution ,
- 0.5f * invShadowResolution , - 0.5f * invShadowResolution ,
0.5f * invShadowResolution , - 0.5f * invShadowResolution
} ;
cmd . SetGlobalMatrixArray ( "_WorldToShadow" , shadowMatrices ) ;
cmd . SetGlobalVectorArray ( "_DirShadowSplitSpheres" , m_DirectionalShadowSplitDistances ) ;
cmd . SetGlobalVector ( "_ShadowLightDirection" , new Vector4 ( - shadowLightDir . x , - shadowLightDir . y , - shadowLightDir . z , 0.0f ) ) ;
cmd . SetGlobalVector ( "_ShadowData" , new Vector4 ( 0.0f , bias , normalBias , 0.0f ) ) ;
cmd . SetGlobalFloatArray ( "_PCFKernel" , pcfKernel ) ;
private void SetShaderKeywords ( ref LightData lightData , ref ScriptableRenderContext context )
private void SetShaderKeywords ( CommandBuffer cmd , ref LightData lightData , VisibleLight [ ] visibleLights )
CommandBuffer cmd = new CommandBuffer ( ) { name = "SetShaderKeywords" } ;
SetShaderKeywords ( cmd , lightData . shadowsRendered , lightData . isSingleLight , lightData . vertexLightsCount > 0 ) ;
context . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
LightweightUtils . SetKeyword ( cmd , "_LIGHTWEIGHT_FORCE_LINEAR" , m_Asset . ForceLinearRendering ) ;
LightweightUtils . SetKeyword ( cmd , "_VERTEX_LIGHTS" , lightData . vertexLightsCount > 0 ) ;
LightweightUtils . SetKeyword ( cmd , "_ATTENUATION_TEXTURE" , m_Asset . AttenuationTexture ! = null ) ;
int mainLightIndex = lightData . mainLightIndex ;
LightweightUtils . SetKeyword ( cmd , "_MAIN_DIRECTIONAL_LIGHT" , mainLightIndex ! = - 1 & & visibleLights [ mainLightIndex ] . lightType = = LightType . Directional ) ;
LightweightUtils . SetKeyword ( cmd , "_MAIN_SPOT_LIGHT" , mainLightIndex ! = - 1 & & visibleLights [ mainLightIndex ] . lightType = = LightType . Spot ) ;
LightweightUtils . SetKeyword ( cmd , "_MAIN_POINT_LIGHT" , mainLightIndex ! = - 1 & & visibleLights [ mainLightIndex ] . lightType = = LightType . Point ) ;
LightweightUtils . SetKeyword ( cmd , "_ADDITIONAL_PIXEL_LIGHTS" , lightData . additionalPixelLightsCount > 0 ) ;
string [ ] shadowKeywords = new string [ ] { "_HARD_SHADOWS" , "_SOFT_SHADOWS" , "_HARD_SHADOWS_CASCADES" , "_SOFT_SHADOWS_CASCADES" } ;
for ( int i = 0 ; i < shadowKeywords . Length ; + + i )
cmd . DisableShaderKeyword ( shadowKeywords [ i ] ) ;
if ( m_Asset . AreShadowsEnabled ( ) & & lightData . shadowsRendered )
{
int keywordIndex = ( int ) m_Asset . ShadowSetting - 1 ;
if ( m_Asset . CascadeCount > 1 )
keywordIndex + = 2 ;
cmd . EnableShaderKeyword ( shadowKeywords [ keywordIndex ] ) ;
}
}
private bool RenderShadows ( ref CullResults cullResults , ref VisibleLight shadowLight , int shadowLightIndex , ref ScriptableRenderContext context )
return resolution ;
}
private void SetupShadowShaderConstants ( ref ScriptableRenderContext context , ref VisibleLight shadowLight , int shadowLightIndex , int cascadeCount )
{
Vector3 shadowLightDir = Vector3 . Normalize ( shadowLight . localToWorld . GetColumn ( 2 ) ) ;
float bias = shadowLight . light . shadowBias * 0.1f ;
float normalBias = shadowLight . light . shadowNormalBias ;
float shadowResolution = m_ShadowSlices [ 0 ] . shadowResolution ;
const int maxShadowCascades = 4 ;
Matrix4x4 [ ] shadowMatrices = new Matrix4x4 [ maxShadowCascades ] ;
for ( int i = 0 ; i < cascadeCount ; + + i )
shadowMatrices [ i ] = ( cascadeCount > = i ) ? m_ShadowSlices [ i ] . shadowTransform : Matrix4x4 . identity ;
// TODO: shadow resolution per cascade in case cascades endup being supported.
float invShadowResolution = 1.0f / shadowResolution ;
float [ ] pcfKernel =
{
- 0.5f * invShadowResolution , 0.5f * invShadowResolution ,
0.5f * invShadowResolution , 0.5f * invShadowResolution ,
- 0.5f * invShadowResolution , - 0.5f * invShadowResolution ,
0.5f * invShadowResolution , - 0.5f * invShadowResolution
} ;
var setupShadow = CommandBufferPool . Get ( "SetupShadowShaderConstants" ) ;
setupShadow . SetGlobalMatrixArray ( "_WorldToShadow" , shadowMatrices ) ;
setupShadow . SetGlobalVectorArray ( "_DirShadowSplitSpheres" , m_DirectionalShadowSplitDistances ) ;
setupShadow . SetGlobalVector ( "_ShadowLightDirection" , new Vector4 ( - shadowLightDir . x , - shadowLightDir . y , - shadowLightDir . z , 0.0f ) ) ;
setupShadow . SetGlobalVector ( "_ShadowData" , new Vector4 ( shadowLightIndex , bias , normalBias , 0.0f ) ) ;
setupShadow . SetGlobalFloatArray ( "_PCFKernel" , pcfKernel ) ;
context . ExecuteCommandBuffer ( setupShadow ) ;
CommandBufferPool . Release ( setupShadow ) ;
}
private void SetShaderKeywords ( CommandBuffer cmd , bool renderShadows , bool singleLight , bool vertexLightSupport )
{
LightweightUtils . SetKeyword ( cmd , "_LIGHTWEIGHT_FORCE_LINEAR" , m_Asset . ForceLinearRendering ) ;
LightweightUtils . SetKeyword ( cmd , "_VERTEX_LIGHTS" , vertexLightSupport ) ;
LightweightUtils . SetKeyword ( cmd , "_ATTENUATION_TEXTURE" , m_Asset . AttenuationTexture ! = null ) ;
if ( ! singleLight )
{
LightweightUtils . SetKeyword ( cmd , "_SINGLE_DIRECTIONAL_LIGHT" , false ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_SPOT_LIGHT" , false ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_POINT_LIGHT" , false ) ;
}
else
{
switch ( m_SingleLightType )
{
case LightType . Directional :
LightweightUtils . SetKeyword ( cmd , "_SINGLE_DIRECTIONAL_LIGHT" , true ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_SPOT_LIGHT" , false ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_POINT_LIGHT" , false ) ;
break ;
case LightType . Spot :
LightweightUtils . SetKeyword ( cmd , "_SINGLE_DIRECTIONAL_LIGHT" , false ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_SPOT_LIGHT" , true ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_POINT_LIGHT" , false ) ;
break ;
case LightType . Point :
LightweightUtils . SetKeyword ( cmd , "_SINGLE_DIRECTIONAL_LIGHT" , false ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_SPOT_LIGHT" , false ) ;
LightweightUtils . SetKeyword ( cmd , "_SINGLE_POINT_LIGHT" , true ) ;
break ;
}
}
string [ ] shadowKeywords = new string [ ] { "_HARD_SHADOWS" , "_SOFT_SHADOWS" , "_HARD_SHADOWS_CASCADES" , "_SOFT_SHADOWS_CASCADES" } ;
for ( int i = 0 ; i < shadowKeywords . Length ; + + i )
cmd . DisableShaderKeyword ( shadowKeywords [ i ] ) ;
if ( renderShadows & & m_Asset . CurrShadowType ! = ShadowType . NO_SHADOW )
{
int keywordIndex = ( int ) m_Asset . CurrShadowType - 1 ;
if ( m_Asset . CascadeCount > 1 )
keywordIndex + = 2 ;
cmd . EnableShaderKeyword ( shadowKeywords [ keywordIndex ] ) ;
}
}
private void InitializeMainShadowLightIndex ( VisibleLight [ ] lights , out int shadowIndex )
{
shadowIndex = - 1 ;
if ( m_Asset . CurrShadowType = = ShadowType . NO_SHADOW )
return ;
float maxIntensity = - 1 ;
for ( int i = 0 ; i < lights . Length ; + + i )
{
Light light = lights [ i ] . light ;
if ( light . shadows ! = LightShadows . None & & IsSupportedShadowType ( light . type ) & & light . intensity > maxIntensity )
{
shadowIndex = i ;
maxIntensity = light . intensity ;
}
}
}
private bool IsSupportedShadowType ( LightType type )
{
return ( type = = LightType . Directional | | type = = LightType . Spot ) ;
}
private void BeginForwardRendering ( ref ScriptableRenderContext context , RenderingConfiguration renderingConfig )
{
RenderTargetIdentifier colorRT = BuiltinRenderTextureType . CameraTarget ;
RendererConfiguration GetRendererSettings ( ref LightData lightData )
{
RendererConfiguration settings = RendererConfiguration . PerObjectReflectionProbes | RendererConfiguration . PerObjectLightmaps | RendererConfiguration . PerObjectLightProbe ;
if ( ! lightData . isSingleLight )
if ( lightData . hasAdditionalLights )
settings | = RendererConfiguration . PerObjectLightIndices8 ;
return settings ;
}