浏览代码

Split directional and local light shadow maps.

/main
Felipe Lira 6 年前
当前提交
7597374d
共有 7 个文件被更改,包括 335 次插入212 次删除
  1. 16
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightConstantBuffer.cs
  2. 380
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  3. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl
  4. 138
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl
  5. 3
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader
  6. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandard.shader
  7. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardSimpleLighting.shader

16
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightConstantBuffer.cs


{
public static int _MainLightPosition;
public static int _MainLightColor;
public static int _MainLightDistanceAttenuation;
public static int _MainLightSpotDir;
public static int _MainLightSpotAttenuation;
public static int _MainLightCookie;
public static int _WorldToLight;

public static int _AdditionalLightSpotAttenuation;
}
public static class ShadowConstantBuffer
public static class DirectionalShadowConstantBuffer
{
public static int _WorldToShadow;
public static int _ShadowData;

public static int _ShadowOffset2;
public static int _ShadowOffset3;
public static int _ShadowmapSize;
}
public static class LocalShadowConstantBuffer
{
public static int _LocalWorldToShadow;
public static int _LocalShadowData;
public static int _LocalShadowOffset0;
public static int _LocalShadowOffset1;
public static int _LocalShadowOffset2;
public static int _LocalShadowOffset3;
public static int _LocalShadowmapSize;
}
}

380
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


[Serializable]
public class ShadowSettings
{
public bool enabled;
public bool screenSpace;
public int shadowAtlasWidth;
public int shadowAtlasHeight;
public bool enabled;
public bool screenSpace;
public int shadowAtlasWidth;
public int shadowAtlasHeight;
public float maxShadowDistance;
public int directionalLightCascadeCount;
public Vector3 directionalLightCascades;
public float directionalLightNearPlaneOffset;
public float maxShadowDistance;
public int directionalLightCascadeCount;
public Vector3 directionalLightCascades;
public float directionalLightNearPlaneOffset;
public RenderTextureFormat shadowmapTextureFormat;
public RenderTextureFormat screenspaceShadowmapTextureFormat;

public struct ShadowSliceData
{
public Matrix4x4 shadowTransform;
public int atlasX;
public int atlasY;
public int shadowResolution;
public Matrix4x4 shadowTransform;
public int atlasX;
public int atlasY;
public int shadowResolution;
}
public struct LightData

public int mainLightIndex;
public LightShadows shadowMapSampleType;
}
public enum MixedLightingSetup

// Lights are culled per-object. This holds the maximum amount of lights that can be shaded per-object.
// The engine fills in the lights indices per-object in unity4_LightIndices0 and unity_4LightIndices1
private static readonly int kMaxPerObjectLights = 8;
private static readonly int kMaxPerObjectLights = 4;
private static readonly int kMaxVertexLights = 4;

private const int kMaxCascades = 4;
private int m_ShadowCasterCascadesCount;
private int m_ShadowMapRTID;
private int m_DirectionalShadowmapRTID;
private int m_AdditionalShadowmapRTID;
private Matrix4x4[] m_LocalLightShadowMatrices = new Matrix4x4[4];
private RenderTexture m_ShadowMapRT;
private RenderTexture m_DirectionalShadowmapRT;
private RenderTexture m_AdditionalShadowmapRT;
private RenderTargetIdentifier m_ScreenSpaceShadowMapRT;
private RenderTargetIdentifier m_ColorRT;
private RenderTargetIdentifier m_CopyColorRT;

private Vector4 m_DirectionalShadowSplitRadii;
private ShadowSettings m_ShadowSettings = ShadowSettings.Default;
private ShadowSliceData[] m_ShadowSlices = new ShadowSliceData[kMaxCascades];
private ShadowSliceData[] m_ShadowCascadeSlices = new ShadowSliceData[kMaxCascades];
private ShadowSliceData[] m_AddtionalShadowSlices = new ShadowSliceData[kMaxPerObjectLights];
private LightShadows m_ShadowSampling;
private LightShadows m_LocalLightShadowSampling;
private int m_LocalLightShadowResolution = 512;
private int m_LocalLightShadowIndex;
// Pipeline pass names
private static readonly ShaderPassName m_DepthPrepass = new ShaderPassName("DepthOnly");

// Lights are culled per-camera. Therefore we need to reset light buffers on each camera render
PerCameraBuffer._MainLightPosition = Shader.PropertyToID("_MainLightPosition");
PerCameraBuffer._MainLightColor = Shader.PropertyToID("_MainLightColor");
PerCameraBuffer._MainLightDistanceAttenuation = Shader.PropertyToID("_MainLightDistanceAttenuation");
PerCameraBuffer._MainLightSpotDir = Shader.PropertyToID("_MainLightSpotDir");
PerCameraBuffer._MainLightSpotAttenuation = Shader.PropertyToID("_MainLightSpotAttenuation");
PerCameraBuffer._MainLightCookie = Shader.PropertyToID("_MainLightCookie");
PerCameraBuffer._WorldToLight = Shader.PropertyToID("_WorldToLight");
PerCameraBuffer._AdditionalLightCount = Shader.PropertyToID("_AdditionalLightCount");

PerCameraBuffer._AdditionalLightSpotDir = Shader.PropertyToID("_AdditionalLightSpotDir");
PerCameraBuffer._AdditionalLightSpotAttenuation = Shader.PropertyToID("_AdditionalLightSpotAttenuation");
ShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_WorldToShadow");
ShadowConstantBuffer._ShadowData = Shader.PropertyToID("_ShadowData");
ShadowConstantBuffer._DirShadowSplitSpheres = Shader.PropertyToID("_DirShadowSplitSpheres");
ShadowConstantBuffer._DirShadowSplitSphereRadii = Shader.PropertyToID("_DirShadowSplitSphereRadii");
ShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_ShadowOffset0");
ShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_ShadowOffset1");
ShadowConstantBuffer._ShadowOffset2 = Shader.PropertyToID("_ShadowOffset2");
ShadowConstantBuffer._ShadowOffset3 = Shader.PropertyToID("_ShadowOffset3");
ShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_ShadowmapSize");
DirectionalShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_WorldToShadow");
DirectionalShadowConstantBuffer._ShadowData = Shader.PropertyToID("_ShadowData");
DirectionalShadowConstantBuffer._DirShadowSplitSpheres = Shader.PropertyToID("_DirShadowSplitSpheres");
DirectionalShadowConstantBuffer._DirShadowSplitSphereRadii = Shader.PropertyToID("_DirShadowSplitSphereRadii");
DirectionalShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_ShadowOffset0");
DirectionalShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_ShadowOffset1");
DirectionalShadowConstantBuffer._ShadowOffset2 = Shader.PropertyToID("_ShadowOffset2");
DirectionalShadowConstantBuffer._ShadowOffset3 = Shader.PropertyToID("_ShadowOffset3");
DirectionalShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_ShadowmapSize");
LocalShadowConstantBuffer._LocalWorldToShadow = Shader.PropertyToID("_LocalWorldToShadowAtlas");
LocalShadowConstantBuffer._LocalShadowData = Shader.PropertyToID("_LocalShadowData");
LocalShadowConstantBuffer._LocalShadowOffset0 = Shader.PropertyToID("_LocalShadowOffset0");
LocalShadowConstantBuffer._LocalShadowOffset1 = Shader.PropertyToID("_LocalShadowOffset1");
LocalShadowConstantBuffer._LocalShadowOffset2 = Shader.PropertyToID("_LocalShadowOffset2");
LocalShadowConstantBuffer._LocalShadowOffset3 = Shader.PropertyToID("_LocalShadowOffset3");
LocalShadowConstantBuffer._LocalShadowmapSize = Shader.PropertyToID("_LocalShadowmapSize");
m_ShadowMapRTID = Shader.PropertyToID("_ShadowMap");
m_DirectionalShadowmapRTID = Shader.PropertyToID("_ShadowMap");
m_AdditionalShadowmapRTID = Shader.PropertyToID("_LocalShadowMapAtlas");
m_ScreenSpaceShadowMapRTID = Shader.PropertyToID("_ScreenSpaceShadowMap");
CameraRenderTargetID.color = Shader.PropertyToID("_CameraColorRT");

LightData lightData;
InitializeLightData(visibleLights, out lightData);
bool shadows = ShadowPass(visibleLights, ref context, ref lightData);
bool screenspaceShadows = ShadowPass(visibleLights, ref context, ref lightData);
SetupFrameRenderingConfiguration(out frameRenderingConfiguration, shadows, stereoEnabled, sceneViewCamera);
SetupFrameRenderingConfiguration(out frameRenderingConfiguration, screenspaceShadows, stereoEnabled, sceneViewCamera);
SetupIntermediateResources(frameRenderingConfiguration, ref context);
// SetupCameraProperties does the following:

if (LightweightUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.DepthPrePass))
DepthPass(ref context, frameRenderingConfiguration);
if (shadows && m_ShadowSettings.screenSpace)
if (screenspaceShadows)
ShadowCollectPass(visibleLights, ref context, ref lightData, frameRenderingConfiguration);
ForwardPass(visibleLights, frameRenderingConfiguration, ref context, ref lightData, stereoEnabled);

if (sceneViewCamera)
CopyTexture(cmd, CameraRenderTargetID.depth, BuiltinRenderTextureType.CameraTarget, m_CopyDepthMaterial, true);
#endif
if (m_ShadowMapRT)
{
cmd.ReleaseTemporaryRT(m_ShadowMapRTID);
m_ShadowMapRT = null;
}
cmd.ReleaseTemporaryRT(m_ScreenSpaceShadowMapRTID);
cmd.ReleaseTemporaryRT(CameraRenderTargetID.depthCopy);

CommandBufferPool.Release(cmd);
context.Submit();
if (m_DirectionalShadowmapRT)
{
RenderTexture.ReleaseTemporary(m_DirectionalShadowmapRT);
m_DirectionalShadowmapRT = null;
}
if (m_AdditionalShadowmapRT)
{
RenderTexture.ReleaseTemporary(m_AdditionalShadowmapRT);
m_AdditionalShadowmapRT = null;
}
m_ShadowMapRT = null;
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
{
VisibleLight mainLight = visibleLights[lightData.mainLightIndex];
m_DirectionalShadowmapRT = null;
m_AdditionalShadowmapRT = null;
m_LocalLightShadowIndex = -1;
m_ShadowSampling = LightShadows.None;
m_LocalLightShadowSampling = LightShadows.None;
if (mainLight.light.shadows != LightShadows.None)
bool directionalShadowmapRendered = false;
if (m_Asset.AreShadowsEnabled())
{
if (lightData.mainLightIndex != -1)
if (!LightweightUtils.IsSupportedShadowType(mainLight.lightType))
{
Debug.LogWarning("Only directional and spot shadows are supported by LightweightPipeline.");
return false;
}
// 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.totalAdditionalLightsCount > 0) ? GetLightUnsortedIndex(lightData.mainLightIndex) : lightData.mainLightIndex;
bool shadowsRendered = RenderShadows(ref m_CullResults, ref mainLight, shadowOriginalIndex, ref context);
if (shadowsRendered)
{
lightData.shadowMapSampleType = (m_Asset.ShadowSetting != ShadowType.SOFT_SHADOWS) ? LightShadows.Hard : mainLight.light.shadows;
VisibleLight mainLight = visibleLights[lightData.mainLightIndex];
// In order to avoid shader variants explosion we only do hard shadows when sampling shadowmap in the lit pass.
// GLES2 platform is forced to hard single cascade shadows.
if (!m_ShadowSettings.screenSpace)
lightData.shadowMapSampleType = LightShadows.Hard;
}
else
if (mainLight.lightType == LightType.Directional && mainLight.light.shadows != LightShadows.None)
lightData.shadowMapSampleType = LightShadows.None;
// 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.totalAdditionalLightsCount > 0) ? GetLightUnsortedIndex(lightData.mainLightIndex) : lightData.mainLightIndex;
directionalShadowmapRendered = RenderDirectionalCascadeShadowmap(ref mainLight, shadowOriginalIndex, ref context);
return shadowsRendered;
}
return false;
RenderAdditionalShadowmapAtlas(visibleLights, ref context);
}
return directionalShadowmapRendered && m_ShadowSettings.screenSpace;
}
private void ShadowCollectPass(List<VisibleLight> visibleLights, ref ScriptableRenderContext context, ref LightData lightData, FrameRenderingConfiguration frameRenderingConfiguration)

}
}
private void SetupFrameRenderingConfiguration(out FrameRenderingConfiguration configuration, bool shadows, bool stereoEnabled, bool sceneViewCamera)
private void SetupFrameRenderingConfiguration(out FrameRenderingConfiguration configuration, bool screenspaceShadows, bool stereoEnabled, bool sceneViewCamera)
{
configuration = (stereoEnabled) ? FrameRenderingConfiguration.Stereo : FrameRenderingConfiguration.None;
if (stereoEnabled && XRSettings.eyeTextureDesc.dimension == TextureDimension.Tex2DArray)

if (sceneViewCamera)
m_RequireDepthTexture = true;
if (shadows)
if (screenspaceShadows)
{
m_RequireDepthTexture = m_ShadowSettings.screenSpace;

// If msaa is enabled we don't use a depth renderbuffer as we might not have support to Texture2DMS to resolve depth.
// Instead we use a depth prepass and whenever depth is needed we use the 1 sample depth from prepass.
// Screen space shadows require depth before opaque shading.
if (!msaaEnabled && !shadows)
if (!msaaEnabled && !screenspaceShadows)
{
bool supportsDepthCopy = m_CopyTextureSupport != CopyTextureSupport.None && m_Asset.CopyDepthShader.isSupported;
m_DepthRenderBuffer = true;

{
int visibleLightsCount = Math.Min(visibleLights.Count, m_Asset.MaxPixelLights);
m_SortedLightIndexMap.Clear();
lightData.shadowMapSampleType = LightShadows.None;
if (visibleLightsCount <= 1)
lightData.mainLightIndex = GetMainLight(visibleLights);

{
cmd.SetGlobalVector(PerCameraBuffer._AdditionalLightCount, Vector4.zero);
// Clear to default all light cosntant data
// Clear to default all light constant data
for (int i = 0; i < kMaxVisibleLights; ++i)
InitializeLightConstants(lights, -1, out m_LightPositions[additionalLightIndex],
out m_LightColors[additionalLightIndex],

cmd.SetGlobalVector("_LightDirection", new Vector4(lightDirection.x, lightDirection.y, lightDirection.z, 0.0f));
}
private void SetupShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight, ref ScriptableRenderContext context)
private void SetupDirectionalShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight, ref ScriptableRenderContext context)
m_ShadowMatrices[i] = (cascadeCount >= i) ? m_ShadowSlices[i].shadowTransform : Matrix4x4.identity;
m_ShadowMatrices[i] = (cascadeCount >= i) ? m_ShadowCascadeSlices[i].shadowTransform : Matrix4x4.identity;
// We setup and additional a no-op WorldToShadow matrix in the last index
// because the ComputeCascadeIndex function in Shadows.hlsl can return an index

float invShadowResolution = 1.0f / m_Asset.ShadowAtlasResolution;
float invHalfShadowResolution = 0.5f * invShadowResolution;
cmd.SetGlobalTexture(m_DirectionalShadowmapRTID, m_DirectionalShadowmapRT);
cmd.SetGlobalMatrixArray(DirectionalShadowConstantBuffer._WorldToShadow, m_ShadowMatrices);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowData, new Vector4(light.shadowStrength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVectorArray(DirectionalShadowConstantBuffer._DirShadowSplitSpheres, m_DirectionalShadowSplitDistances);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._DirShadowSplitSphereRadii, m_DirectionalShadowSplitRadii);
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset0, new Vector4(-invHalfShadowResolution, -invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset1, new Vector4(invHalfShadowResolution, -invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset2, new Vector4(-invHalfShadowResolution, invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowOffset3, new Vector4(invHalfShadowResolution, invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(DirectionalShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowResolution, invShadowResolution, m_Asset.ShadowAtlasResolution, m_Asset.ShadowAtlasResolution));
context.ExecuteCommandBuffer(cmd);
cmd.SetGlobalTexture(m_ShadowMapRTID, m_ShadowMapRT);
cmd.SetGlobalMatrixArray(ShadowConstantBuffer._WorldToShadow, m_ShadowMatrices);
cmd.SetGlobalVector(ShadowConstantBuffer._ShadowData, new Vector4(light.shadowStrength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVectorArray(ShadowConstantBuffer._DirShadowSplitSpheres, m_DirectionalShadowSplitDistances);
cmd.SetGlobalVector(ShadowConstantBuffer._DirShadowSplitSphereRadii, m_DirectionalShadowSplitRadii);
cmd.SetGlobalVector(ShadowConstantBuffer._ShadowOffset0, new Vector4(-invHalfShadowResolution, -invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(ShadowConstantBuffer._ShadowOffset1, new Vector4(invHalfShadowResolution, -invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(ShadowConstantBuffer._ShadowOffset2, new Vector4(-invHalfShadowResolution, invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(ShadowConstantBuffer._ShadowOffset3, new Vector4(invHalfShadowResolution, invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(ShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowResolution, invShadowResolution, m_Asset.ShadowAtlasResolution, m_Asset.ShadowAtlasResolution));
}
private void SetupLocalLightsShadowReceiverConstants(CommandBuffer cmd, List<VisibleLight> visibleLights, ref ScriptableRenderContext context)
{
VisibleLight shadowLight = visibleLights[m_LocalLightShadowIndex];
m_LocalLightShadowMatrices[0] = m_AddtionalShadowSlices[0].shadowTransform;
m_LocalLightShadowMatrices[1] = Matrix4x4.identity;
m_LocalLightShadowMatrices[2] = Matrix4x4.identity;
m_LocalLightShadowMatrices[3] = Matrix4x4.identity;
float invShadowResolution = 1.0f / m_LocalLightShadowResolution;
float invHalfShadowResolution = 0.5f * invShadowResolution;
cmd.SetGlobalTexture(m_AdditionalShadowmapRTID, m_AdditionalShadowmapRT);
cmd.SetGlobalMatrixArray(LocalShadowConstantBuffer._LocalWorldToShadow, m_LocalLightShadowMatrices);
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowData, new Vector4(shadowLight.light.shadowStrength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset0, new Vector4(-invHalfShadowResolution, -invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset1, new Vector4(invHalfShadowResolution, -invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset2, new Vector4(-invHalfShadowResolution, invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowOffset3, new Vector4(invHalfShadowResolution, invHalfShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector(LocalShadowConstantBuffer._LocalShadowmapSize, new Vector4(invShadowResolution, invShadowResolution, m_LocalLightShadowResolution, m_LocalLightShadowResolution));
cmd.Clear();
}
private void SetShaderKeywords(CommandBuffer cmd, ref LightData lightData, List<VisibleLight> visibleLights)

int mainLightIndex = lightData.mainLightIndex;
//TIM: Not used in shader for V1 to reduce keywords
CoreUtils.SetKeyword(cmd, "_MAIN_LIGHT_DIRECTIONAL", mainLightIndex == -1 || visibleLights[mainLightIndex].lightType == LightType.Directional);
//TIM: Not used in shader for V1 to reduce keywords
CoreUtils.SetKeyword(cmd, "_MAIN_LIGHT_SPOT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Spot);
//TIM: Not used in shader for V1 to reduce keywords
CoreUtils.SetKeyword(cmd, "_SHADOWS_ENABLED", lightData.shadowMapSampleType != LightShadows.None);
CoreUtils.SetKeyword(cmd, "_SHADOWS_ENABLED", m_ShadowSampling != LightShadows.None);
CoreUtils.SetKeyword(cmd, "_LOCAL_SHADOWS_ENABLED", m_LocalLightShadowSampling != LightShadows.None);
//TIM: Not used in shader for V1 to reduce keywords
CoreUtils.SetKeyword(cmd, "_MAIN_LIGHT_COOKIE", mainLightIndex != -1 && LightweightUtils.IsSupportedCookieType(visibleLights[mainLightIndex].lightType) && visibleLights[mainLightIndex].light.cookie != null);

private void SetShadowCollectPassKeywords(CommandBuffer cmd, VisibleLight shadowLight, ref LightData lightData)
{
bool cascadeShadows = shadowLight.lightType == LightType.Directional && m_Asset.CascadeCount > 1;
CoreUtils.SetKeyword(cmd, "_SHADOWS_SOFT", lightData.shadowMapSampleType == LightShadows.Soft);
CoreUtils.SetKeyword(cmd, "_SHADOWS_CASCADE", cascadeShadows);
CoreUtils.SetKeyword(cmd, "_SHADOWS_SOFT", m_ShadowSampling == LightShadows.Soft);
CoreUtils.SetKeyword(cmd, "_SHADOWS_CASCADE", m_Asset.CascadeCount > 1);
private bool RenderShadows(ref CullResults cullResults, ref VisibleLight shadowLight, int shadowLightIndex, ref ScriptableRenderContext context)
private bool RenderDirectionalCascadeShadowmap(ref VisibleLight shadowLight, int shadowLightIndex, ref ScriptableRenderContext context)
CommandBuffer cmd = CommandBufferPool.Get("Prepare Directional Shadowmap");
if (shadowLight.lightType == LightType.Spot)
m_ShadowCasterCascadesCount = 1;
float shadowNearPlane = m_Asset.ShadowNearOffset;
if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
if (!m_CullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
float shadowNearPlane = m_Asset.ShadowNearOffset;
var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);
bool success = false;
var settings = new DrawShadowsSettings(m_CullResults, shadowLightIndex);
var cmd = CommandBufferPool.Get("Prepare Shadowmap");
m_ShadowMapRT = RenderTexture.GetTemporary(shadowmapDescriptor);
m_ShadowMapRT.filterMode = FilterMode.Bilinear;
m_ShadowMapRT.wrapMode = TextureWrapMode.Clamp;
m_DirectionalShadowmapRT = RenderTexture.GetTemporary(shadowmapDescriptor);
m_DirectionalShadowmapRT.filterMode = FilterMode.Bilinear;
m_DirectionalShadowmapRT.wrapMode = TextureWrapMode.Clamp;
CoreUtils.SetRenderTarget(cmd, m_ShadowMapRT, ClearFlag.Depth, CoreUtils.ConvertSRGBToActiveColorSpace(m_CurrCamera.backgroundColor));
CoreUtils.SetRenderTarget(cmd, m_DirectionalShadowmapRT, ClearFlag.Depth, CoreUtils.ConvertSRGBToActiveColorSpace(m_CurrCamera.backgroundColor));
if (shadowLight.lightType == LightType.Spot)
bool success = false;
for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
success = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out view, out proj,
success = m_CullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
cascadeIndex, m_ShadowCasterCascadesCount, m_ShadowSettings.directionalLightCascades, shadowResolution, shadowNearPlane, out view, out proj,
if (success)
{
SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
SetupShadowSliceTransform(0, shadowResolution, proj, view);
RenderShadowSlice(cmd, ref context, 0, proj, view, settings);
}
}
else if (shadowLight.lightType == LightType.Directional)
{
for (int cascadeIdx = 0; cascadeIdx < m_ShadowCasterCascadesCount; ++cascadeIdx)
{
success = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
cascadeIdx, m_ShadowCasterCascadesCount, m_ShadowSettings.directionalLightCascades, shadowResolution, shadowNearPlane, out view, out proj,
out settings.splitData);
float cullingSphereRadius = settings.splitData.cullingSphere.w;
m_DirectionalShadowSplitDistances[cascadeIndex] = settings.splitData.cullingSphere;
m_DirectionalShadowSplitRadii[cascadeIndex] = cullingSphereRadius * cullingSphereRadius;
float cullingSphereRadius = settings.splitData.cullingSphere.w;
m_DirectionalShadowSplitDistances[cascadeIdx] = settings.splitData.cullingSphere;
m_DirectionalShadowSplitRadii[cascadeIdx] = cullingSphereRadius * cullingSphereRadius;
if (!success)
break;
if (!success)
break;
int atlasX = (cascadeIndex % 2) * shadowResolution;
int atlasY = (cascadeIndex / 2) * shadowResolution;
float atlasWidth = (float)m_ShadowSettings.shadowAtlasWidth;
float atlasHeight = (float)m_ShadowSettings.shadowAtlasHeight;
Rect shadowSliceRect = new Rect((float)atlasX, (float)atlasY, atlasWidth, atlasHeight);
SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view);
RenderShadowSlice(cmd, ref context, cascadeIdx, proj, view, settings);
}
}
else
{
Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
SetupShadowSliceTransform(ref shadowSliceRect, shadowResolution, proj, view, out m_ShadowCascadeSlices[cascadeIndex]);
RenderShadowSlice(cmd, ref context, ref m_ShadowCascadeSlices[cascadeIndex], proj, view, settings);
SetupShadowReceiverConstants(cmd, shadowLight, ref context);
{
m_ShadowSampling = (m_Asset.ShadowSetting != ShadowType.SOFT_SHADOWS) ? LightShadows.Hard : shadowLight.light.shadows;
// In order to avoid shader variants explosion we only do hard shadows when sampling shadowmap in the lit pass.
// GLES2 platform is forced to hard single cascade shadows.
if (!m_ShadowSettings.screenSpace)
m_ShadowSampling = LightShadows.Hard;
SetupDirectionalShadowReceiverConstants(cmd, shadowLight, ref context);
}
context.ExecuteCommandBuffer(cmd);
private void SetupShadowSliceTransform(int cascadeIndex, int shadowResolution, Matrix4x4 proj, Matrix4x4 view)
private bool RenderAdditionalShadowmapAtlas(List<VisibleLight> visibleLights, ref ScriptableRenderContext context)
if (cascadeIndex >= kMaxCascades)
CommandBuffer cmd = CommandBufferPool.Get("Prepare Local Lights Shadowmap");
Matrix4x4 view, proj;
Bounds bounds;
bool success = false;
int shadowResolution = m_LocalLightShadowResolution;
int shadowSampling = 0;
RenderTextureDescriptor shadowmapDescriptor = new RenderTextureDescriptor(shadowResolution, shadowResolution, m_ShadowSettings.shadowmapTextureFormat, kShadowBufferBits);
shadowmapDescriptor.shadowSamplingMode = ShadowSamplingMode.CompareDepths;
m_AdditionalShadowmapRT = RenderTexture.GetTemporary(shadowmapDescriptor);
m_AdditionalShadowmapRT.filterMode = FilterMode.Bilinear;
m_AdditionalShadowmapRT.wrapMode = TextureWrapMode.Clamp;
// LightweightPipeline.SetRenderTarget is meant to be used with camera targets, not shadowmaps
CoreUtils.SetRenderTarget(cmd, m_AdditionalShadowmapRT, ClearFlag.Depth, CoreUtils.ConvertSRGBToActiveColorSpace(m_CurrCamera.backgroundColor));
for (int i = 0; i < visibleLights.Count; ++i)
Debug.LogError(String.Format("{0} is an invalid cascade index. Maximum of {1} cascades", cascadeIndex, kMaxCascades));
return;
VisibleLight shadowLight = visibleLights[i];
if (shadowLight.lightType != LightType.Spot)
continue;
int shadowLightIndex = GetLightUnsortedIndex(i);
if (!m_CullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
continue;
var settings = new DrawShadowsSettings(m_CullResults, shadowLightIndex);
success = m_CullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out view, out proj, out settings.splitData);
if (success)
{
Rect shadowSliceRect = new Rect(0.0f, 0.0f, shadowResolution, shadowResolution);
SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
SetupShadowSliceTransform(ref shadowSliceRect, shadowResolution, proj, view, out m_AddtionalShadowSlices[0]);
RenderShadowSlice(cmd, ref context, ref m_AddtionalShadowSlices[0], proj, view, settings);
m_LocalLightShadowIndex = i;
shadowSampling = Math.Max(shadowSampling, (int)shadowLight.light.shadows);
break;
}
int atlasX = (cascadeIndex % 2) * shadowResolution;
int atlasY = (cascadeIndex / 2) * shadowResolution;
float atlasWidth = (float)m_ShadowSettings.shadowAtlasWidth;
float atlasHeight = (float)m_ShadowSettings.shadowAtlasHeight;
if (success)
SetupLocalLightsShadowReceiverConstants(cmd, visibleLights, ref context);
m_LocalLightShadowSampling = (LightShadows)Math.Min(shadowSampling, (int)m_Asset.ShadowSetting);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
return success;
}
// Currently CullResults ComputeDirectionalShadowMatricesAndCullingPrimitives doesn't
private void SetupShadowSliceTransform(ref Rect shadowSliceRect, int shadowResolution, Matrix4x4 proj, Matrix4x4 view, out ShadowSliceData shadowSliceData)
{
// Currently CullResults ComputeDirectionalShadowMatricesAndCullingPrimitives doesn't
// apply z reversal to projection matrix. We need to do it manually here.
if (SystemInfo.usesReversedZBuffer)
{

worldToShadow = textureScaleAndBias * worldToShadow;
var cascadeAtlas = Matrix4x4.identity;
cascadeAtlas.m00 = (float)shadowResolution / atlasWidth;
cascadeAtlas.m11 = (float)shadowResolution / atlasHeight;
cascadeAtlas.m03 = (float)atlasX / atlasWidth;
cascadeAtlas.m13 = (float)atlasY / atlasHeight;
cascadeAtlas.m00 = (float)shadowResolution / shadowSliceRect.width;
cascadeAtlas.m11 = (float)shadowResolution / shadowSliceRect.height;
cascadeAtlas.m03 = shadowSliceRect.x / shadowSliceRect.width;
cascadeAtlas.m13 = shadowSliceRect.y / shadowSliceRect.height;
m_ShadowSlices[cascadeIndex].atlasX = atlasX;
m_ShadowSlices[cascadeIndex].atlasY = atlasY;
m_ShadowSlices[cascadeIndex].shadowResolution = shadowResolution;
m_ShadowSlices[cascadeIndex].shadowTransform = worldToShadow;
shadowSliceData.atlasX = (int)shadowSliceRect.x;
shadowSliceData.atlasY = (int)shadowSliceRect.y;
shadowSliceData.shadowResolution = shadowResolution;
shadowSliceData.shadowTransform = worldToShadow;
private void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, int cascadeIndex,
private void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, ref ShadowSliceData shadowSliceData,
cmd.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY,
m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution));
cmd.EnableScissorRect(new Rect(m_ShadowSlices[cascadeIndex].atlasX + 4, m_ShadowSlices[cascadeIndex].atlasY + 4,
m_ShadowSlices[cascadeIndex].shadowResolution - 8, m_ShadowSlices[cascadeIndex].shadowResolution - 8));
cmd.SetViewport(new Rect(shadowSliceData.atlasX, shadowSliceData.atlasY, shadowSliceData.shadowResolution, shadowSliceData.shadowResolution));
cmd.EnableScissorRect(new Rect(shadowSliceData.atlasX + 4, shadowSliceData.atlasY + 4, shadowSliceData.shadowResolution - 8, shadowSliceData.shadowResolution - 8));
cmd.SetViewProjectionMatrices(view, proj);
context.ExecuteCommandBuffer(cmd);

8
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl


// 1) Gives good estimate of illumination as if light would've been shadowed during the bake.
// We only subtract the main direction light. This is accounted in the contribution term below.
half shadowStrength = GetShadowStrength();
half shadowStrength = _ShadowData.x;
half contributionTerm = saturate(dot(mainLight.direction, normalWS)) * (1.0 - _MainLightPosition.w);
half3 lambert = mainLight.color * contributionTerm;
half3 estimatedLightContributionMaskedByInverseOfShadow = lambert * (1.0 - mainLight.attenuation);

InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
Light mainLight = GetMainLight();
mainLight.attenuation = RealtimeShadowAttenuation(inputData.shadowCoord, 0.0);
mainLight.attenuation = MainLightRealtimeShadowAttenuation(inputData.shadowCoord);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);

for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetLight(i, inputData.positionWS);
light.attenuation *= LocalLightRealtimeShadowAttenuation(inputData.shadowCoord, inputData.positionWS);
color += LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS);
}
#endif

half4 LightweightFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half shininess, half3 emission, half alpha)
{
Light mainLight = GetMainLight();
mainLight.attenuation = RealtimeShadowAttenuation(inputData.shadowCoord, 0.0);
mainLight.attenuation = MainLightRealtimeShadowAttenuation(inputData.shadowCoord);
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 attenuatedLightColor = mainLight.color * mainLight.attenuation;

for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetLight(i, inputData.positionWS);
light.attenuation *= LocalLightRealtimeShadowAttenuation(inputData.shadowCoord, inputData.positionWS);
half3 attenuatedLightColor = light.color * light.attenuation;
diffuseColor += LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
specularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, specularGloss, shininess);

138
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl


TEXTURE2D_SHADOW(_ShadowMap);
SAMPLER_CMP(sampler_ShadowMap);
CBUFFER_START(_ShadowBuffer)
TEXTURE2D_SHADOW(_LocalShadowMapAtlas);
SAMPLER_CMP(sampler_LocalShadowMapAtlas);
CBUFFER_START(_DirectionalShadowBuffer)
// Last cascade is initialized with a no-op matrix. It always transforms
// shadow coord to half(0, 0, NEAR_PLANE). We use this trick to avoid
// branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES

float4 _ShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
CBUFFER_END
CBUFFER_START(_LocalShadowBuffer)
float4x4 _LocalWorldToShadowAtlas[4];
half4 _LocalShadowOffset0;
half4 _LocalShadowOffset1;
half4 _LocalShadowOffset2;
half4 _LocalShadowOffset3;
half4 _LocalShadowData; // (x: shadowStrength)
float4 _LocalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
CBUFFER_END
#if UNITY_REVERSED_Z
#define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z <= UNITY_RAW_FAR_CLIP_VALUE
#else

half GetShadowStrength()
struct ShadowSamplingData
{
half shadowStrength;
half4 shadowOffset0;
half4 shadowOffset1;
half4 shadowOffset2;
half4 shadowOffset3;
half4 shadowmapSize;
};
ShadowSamplingData GetMainLightShadowSamplingData()
{
ShadowSamplingData shadowSamplingData;
shadowSamplingData.shadowStrength = _ShadowData.x;
shadowSamplingData.shadowOffset0 = _ShadowOffset0;
shadowSamplingData.shadowOffset1 = _ShadowOffset1;
shadowSamplingData.shadowOffset2 = _ShadowOffset2;
shadowSamplingData.shadowOffset3 = _ShadowOffset3;
shadowSamplingData.shadowmapSize = _ShadowmapSize;
return shadowSamplingData;
}
ShadowSamplingData GetLocalLightShadowSamplingData()
return _ShadowData.x;
ShadowSamplingData shadowSamplingData;
shadowSamplingData.shadowStrength = _LocalShadowData.x;
shadowSamplingData.shadowOffset0 = _LocalShadowOffset0;
shadowSamplingData.shadowOffset1 = _LocalShadowOffset1;
shadowSamplingData.shadowOffset2 = _LocalShadowOffset2;
shadowSamplingData.shadowOffset3 = _LocalShadowOffset3;
shadowSamplingData.shadowmapSize = _LocalShadowmapSize;
return shadowSamplingData;
}
inline half SampleScreenSpaceShadowMap(float4 shadowCoord)

return attenuation;
}
inline real SampleShadowmap(float4 shadowCoord, float isPerspectiveProjection = 1.0)
inline real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), ShadowSamplingData samplingData, float isMainLight = 0.0)
if (isPerspectiveProjection == 0.0)
if (isMainLight == 0.0)
shadowCoord.xyz /= shadowCoord.w;
real attenuation;

// 4-tap hardware comparison
real4 attenuation4;
attenuation4.x = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset0.xyz);
attenuation4.y = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset1.xyz);
attenuation4.z = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset2.xyz);
attenuation4.w = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset3.xyz);
attenuation4.x = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset0.xyz);
attenuation4.y = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset1.xyz);
attenuation4.z = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset2.xyz);
attenuation4.w = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset3.xyz);
SampleShadow_ComputeSamples_Tent_7x7(_ShadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
SampleShadow_ComputeSamples_Tent_7x7(samplingData.shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation += fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[9].xy, shadowCoord.z));
attenuation += fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[10].xy, shadowCoord.z));
attenuation += fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[11].xy, shadowCoord.z));
attenuation += fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[12].xy, shadowCoord.z));
attenuation += fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[13].xy, shadowCoord.z));
attenuation += fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[14].xy, shadowCoord.z));
attenuation += fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[15].xy, shadowCoord.z));
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation += fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[9].xy, shadowCoord.z));
attenuation += fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[10].xy, shadowCoord.z));
attenuation += fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[11].xy, shadowCoord.z));
attenuation += fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[12].xy, shadowCoord.z));
attenuation += fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[13].xy, shadowCoord.z));
attenuation += fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[14].xy, shadowCoord.z));
attenuation += fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[15].xy, shadowCoord.z));
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
attenuation = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz);
attenuation = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz);
attenuation = LerpWhiteTo(attenuation, GetShadowStrength());
attenuation = LerpWhiteTo(attenuation, samplingData.shadowStrength);
#endif
// Shadow coords that fall out of the light frustum volume must always return attenuation 1.0

return ComputeScreenPos(clipPos);
}
half RealtimeShadowAttenuation(float4 shadowCoord, float isPerspectiveProjection = 1.0)
half MainLightRealtimeShadowAttenuation(float4 shadowCoord)
#ifndef _SHADOWS_ENABLED
return 1.0h;
#endif
#if defined(NO_SHADOWS)
#if defined(NO_SHADOWS) || !defined(_SHADOWS_ENABLED)
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
return SampleShadowmap(shadowCoord, TEXTURE2D_PARAM(_ShadowMap, sampler_ShadowMap), shadowSamplingData, 1.0);
#endif
return SampleShadowmap(shadowCoord, isPerspectiveProjection);
}
half LocalLightRealtimeShadowAttenuation(int lightIndex, float3 positionWS)
{
#if defined(NO_SHADOWS) || !defined(_LOCAL_SHADOWS_ENABLED)
return 1.0h;
#else
float4 shadowCoord = mul(_LocalWorldToShadowAtlas[lightIndex], float4(positionWS, 1.0));
ShadowSamplingData shadowSamplingData = GetLocalLightShadowSamplingData();
return SampleShadowmap(shadowCoord, TEXTURE2D_PARAM(_LocalShadowMapAtlas, sampler_LocalShadowMapAtlas), shadowSamplingData, 0.0);
#endif
}

3
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader


float4 coords = TransformWorldToShadowCoord(wpos);
// Screenspace shadowmap is only used for directional lights which use orthogonal projection.
return SampleShadowmap(coords, 0.0);
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
return SampleShadowmap(coords, TEXTURE2D_PARAM(_ShadowMap, sampler_ShadowMap), shadowSamplingData, 1.0);
}
ENDHLSL

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandard.shader


#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardSimpleLighting.shader


#pragma multi_compile _ _VERTEX_LIGHTS
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile _ _LOCAL_SHADOWS_ENABLED
// -------------------------------------
// Unity defined keywords

正在加载...
取消
保存