浏览代码

Merge pull request #941 from Unity-Technologies/LW-ScreenSpaceShadows

Lw screen space shadows
/main
GitHub 7 年前
当前提交
ee1e6968
共有 14 个文件被更改,包括 266 次插入182 次删除
  1. 5
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineAsset.cs
  2. 2
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.asset
  3. 1
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.cs
  4. 122
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  5. 30
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl
  6. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Lighting.hlsl
  7. 4
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl
  8. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl
  9. 151
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl
  10. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandard.shader
  11. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardSimpleLighting.shader
  12. 8
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardTerrain.shader
  13. 85
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader
  14. 9
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader.meta

5
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineAsset.cs


#if UNITY_EDITOR
[NonSerialized]
private LightweightPipelineEditorResources m_EditorResourcesAsset;
[MenuItem("Assets/Create/Rendering/Lightweight Pipeline Asset", priority = CoreUtils.assetCreateMenuPriority1)]

public Shader CopyDepthShader
{
get { return resources != null ? resources.CopyDepthShader : null; }
}
public Shader ScreenSpaceShadowShader
{
get { return resources != null ? resources.ScreenSpaceShadowShader : null; }
}
}
}

2
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.asset


m_EditorClassIdentifier:
BlitShader: {fileID: 4800000, guid: c17132b1f77d20942aa75f8429c0f8bc, type: 3}
CopyDepthShader: {fileID: 4800000, guid: d6dae50ee9e1bfa4db75f19f99355220, type: 3}
ScreenSpaceShadowShader: {fileID: 4800000, guid: 0f854b35a0cf61a429bd5dcfea30eddd,
type: 3}

1
ScriptableRenderPipeline/LightweightPipeline/LWRP/Data/LightweightPipelineResources.cs


{
public Shader BlitShader;
public Shader CopyDepthShader;
public Shader ScreenSpaceShadowShader;
}

122
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


// we need use copyColor RT as a work RT.
public static int copyColor;
// Camera depth target. Only used when post processing or soft particles are enabled.
// Camera depth target. Only used when post processing, soft particles, or screen space shadows are enabled.
public static int depth;
// If soft particles are enabled and no depth prepass is performed we need to copy depth.

private static readonly int kMaxVertexLights = 4;
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all punctual lights
// We combine light and shadow classification keywords to reduce the amount of shader variants.
// Lightweight shader library declares defines based on these keywords to avoid having to check them in the shaders
// Core.hlsl defines _MAIN_LIGHT_DIRECTIONAL and _MAIN_LIGHT_SPOT (point lights can't be main light)
// Shadow.hlsl defines _SHADOWS_ENABLED, _SHADOWS_SOFT, _SHADOWS_CASCADE, _SHADOWS_PERSPECTIVE
private static readonly string[] kMainLightKeywords =
{
"_MAIN_LIGHT_DIRECTIONAL_SHADOW",
"_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE",
"_MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT",
"_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT",
"_MAIN_LIGHT_SPOT_SHADOW",
"_MAIN_LIGHT_SPOT_SHADOW_SOFT"
};
private StringBuilder m_MainLightKeywordString = new StringBuilder(43);
private bool m_IsOffscreenCamera;
private Vector4 kDefaultLightPosition = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);

private const int kMaxCascades = 4;
private int m_ShadowCasterCascadesCount;
private int m_ShadowMapRTID;
private int m_ScreenSpaceShadowMapRTID;
private RenderTargetIdentifier m_ScreenSpaceShadowMapRT;
private RenderTargetIdentifier m_ColorRT;
private RenderTargetIdentifier m_CopyColorRT;
private RenderTargetIdentifier m_DepthRT;

private Material m_BlitMaterial;
private Material m_CopyDepthMaterial;
private Material m_ErrorMaterial;
private Material m_ScreenSpaceShadowsMaterial;
private int m_BlitTexID = Shader.PropertyToID("_BlitTex");
private CopyTextureSupport m_CopyTextureSupport;

ShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_ShadowmapSize");
m_ShadowMapRTID = Shader.PropertyToID("_ShadowMap");
m_ScreenSpaceShadowMapRTID = Shader.PropertyToID("_ScreenSpaceShadowMap");
CameraRenderTargetID.color = Shader.PropertyToID("_CameraColorRT");
CameraRenderTargetID.copyColor = Shader.PropertyToID("_CameraCopyColorRT");

m_ShadowMapRT = new RenderTargetIdentifier(m_ShadowMapRTID);
m_ScreenSpaceShadowMapRT = new RenderTargetIdentifier(m_ScreenSpaceShadowMapRTID);
m_ColorRT = new RenderTargetIdentifier(CameraRenderTargetID.color);
m_CopyColorRT = new RenderTargetIdentifier(CameraRenderTargetID.copyColor);

m_BlitQuad = LightweightUtils.CreateQuadMesh(false);
m_BlitMaterial = CoreUtils.CreateEngineMaterial(m_Asset.BlitShader);
m_CopyDepthMaterial = CoreUtils.CreateEngineMaterial(m_Asset.CopyDepthShader);
m_ScreenSpaceShadowsMaterial = CoreUtils.CreateEngineMaterial(m_Asset.ScreenSpaceShadowShader);
m_ErrorMaterial = CoreUtils.CreateEngineMaterial("Hidden/InternalErrorShader");
}

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

context.SetupCameraProperties(m_CurrCamera, stereoEnabled);
if (LightweightUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.DepthPrePass))
{
// Only screen space shadowmap mode is supported.
if (shadows)
ShadowCollectPass(visibleLights, ref context, ref lightData);
}
// Release temporary RT
cmd.ReleaseTemporaryRT(m_ScreenSpaceShadowMapRTID);
cmd.ReleaseTemporaryRT(CameraRenderTargetID.depthCopy);
cmd.ReleaseTemporaryRT(CameraRenderTargetID.depth);
cmd.ReleaseTemporaryRT(CameraRenderTargetID.color);

}
}
private void ShadowPass(List<VisibleLight> visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
private bool ShadowPass(List<VisibleLight> visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
{
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
{

if (!LightweightUtils.IsSupportedShadowType(mainLight.lightType))
{
Debug.LogWarning("Only directional and spot shadows are supported by LightweightPipeline.");
return;
return false;
}
// There's no way to map shadow light indices. We need to pass in the original unsorted index.

{
lightData.shadowMapSampleType = LightShadows.None;
}
return shadowsRendered;
return false;
}
private void ShadowCollectPass(List<VisibleLight> visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
{
CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");
SetupShadowReceiverConstants(cmd, visibleLights[lightData.mainLightIndex]);
SetShadowCollectPassKeywords(cmd, visibleLights[lightData.mainLightIndex], ref lightData);
cmd.GetTemporaryRT(m_ScreenSpaceShadowMapRTID, m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight, 0, FilterMode.Bilinear, RenderTextureFormat.R8);
cmd.Blit(null, m_ScreenSpaceShadowMapRT, m_ScreenSpaceShadowsMaterial);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
private void DepthPass(ref ScriptableRenderContext context)

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

}
}
if (shadows)
{
m_RequireDepthTexture = true;
if (!msaaEnabled)
intermediateTexture = true;
}
if (msaaEnabled)
{
configuration |= FrameRenderingConfiguration.Msaa;

{
// 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.
if (!msaaEnabled)
// Screen space shadows require depth before opaque shading.
if (!msaaEnabled && !shadows)
{
bool supportsDepthCopy = m_CopyTextureSupport != CopyTextureSupport.None && m_Asset.CopyDepthShader.isSupported;
m_DepthRenderBuffer = true;

// 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.
SetupMainLightConstants(cmd, lights, lightData.mainLightIndex);
if (lightData.shadowMapSampleType != LightShadows.None)
SetupShadowReceiverConstants(cmd, lights[lightData.mainLightIndex]);
SetupAdditionalListConstants(cmd, lights, ref lightData);
}

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._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));
}

int mainLightIndex = lightData.mainLightIndex;
for (int i = 0; i < kMainLightKeywords.Length; ++i)
cmd.DisableShaderKeyword(kMainLightKeywords[i]);
if (mainLightIndex != -1 && (lightData.shadowMapSampleType != LightShadows.None))
{
m_MainLightKeywordString.Length = 0;
m_MainLightKeywordString.Append("_MAIN_LIGHT");
LightType mainLightType = visibleLights[mainLightIndex].lightType;
if (mainLightType == LightType.Directional)
{
m_MainLightKeywordString.Append("_DIRECTIONAL_SHADOW");
if (m_Asset.CascadeCount > 1)
m_MainLightKeywordString.Append("_CASCADE");
}
else
{
m_MainLightKeywordString.Append("_SPOT_SHADOW");
}
if (lightData.shadowMapSampleType == LightShadows.Soft)
m_MainLightKeywordString.Append("_SOFT");
string keyword = m_MainLightKeywordString.ToString();
cmd.EnableShaderKeyword(keyword);
}
int mainLightIndex = lightData.mainLightIndex;
CoreUtils.SetKeyword(cmd, "_MAIN_LIGHT_DIRECTIONAL", mainLightIndex == -1 || visibleLights[mainLightIndex].lightType == LightType.Directional);
CoreUtils.SetKeyword(cmd, "_MAIN_LIGHT_SPOT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Spot);
CoreUtils.SetKeyword(cmd, "_SHADOWS_ENABLED", lightData.shadowMapSampleType != LightShadows.None);
bool linearFogModeEnabled = false;
bool exponentialFogModeEnabled = false;
if (RenderSettings.fog)

CoreUtils.SetKeyword(cmd, "FOG_LINEAR", linearFogModeEnabled);
CoreUtils.SetKeyword(cmd, "FOG_EXP2", exponentialFogModeEnabled);
}
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);
}
private bool RenderShadows(ref CullResults cullResults, ref VisibleLight shadowLight, int shadowLightIndex, ref ScriptableRenderContext context)

30
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Core.hlsl


#include "Input.hlsl"
///////////////////////////////////////////////////////////////////////////////
// Light Classification defines //
// //
// In order to reduce shader variations main light keywords were combined //
// here we define main light type keywords. //
// Main light is either a shadow casting light or the brighest directional. //
// Lightweight pipeline doesn't support point light shadows so they can't be //
// classified as main light. //
///////////////////////////////////////////////////////////////////////////////
#if defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT)
#define _MAIN_LIGHT_DIRECTIONAL
#endif
#if defined(_MAIN_LIGHT_SPOT_SHADOW) || defined(_MAIN_LIGHT_SPOT_SHADOW_SOFT)
#define _MAIN_LIGHT_SPOT
#endif
// In case no shadow casting light we classify main light as directional
#if !defined(_MAIN_LIGHT_DIRECTIONAL) && !defined(_MAIN_LIGHT_SPOT)
#define _MAIN_LIGHT_DIRECTIONAL
#endif
#ifdef _NORMALMAP
#define OUTPUT_NORMAL(IN, OUT) OutputTangentToWorld(IN.tangent, IN.normal, OUT.tangent, OUT.binormal, OUT.normal)
#else

{
half3x3 tangentToWorld = half3x3(tangent, binormal, normal);
return normalize(mul(normalTangent, tangentToWorld));
}
// TODO: A similar function should be already available in SRP lib on master. Use that instead
float4 ComputeScreenPos(float4 positionCS)
{
float4 o = positionCS * 0.5f;
o.xy = float2(o.x, o.y * _ProjectionParams.x) + o.w;
o.zw = positionCS.zw;
return o;
}
half ComputeFogFactor(float z)

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


InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
Light mainLight = GetMainLight(inputData.positionWS);
mainLight.attenuation *= RealtimeShadowAttenuation(inputData.positionWS, inputData.shadowCoord);
#ifdef _SHADOWS_ENABLED
mainLight.attenuation *= RealtimeShadowAttenuation(inputData.shadowCoord);
#endif
MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);

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

4
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl


half fogFactor = ComputeFogFactor(o.clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#if defined(_SHADOWS_ENABLED) && !defined(_SHADOWS_CASCADE)
o.shadowCoord = ComputeShadowCoord(o.posWS.xyz);
#ifdef _SHADOWS_ENABLED
o.shadowCoord = ComputeScreenPos(o.clipPos);
#endif
return o;

6
ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassShadow.hlsl


// _ShadowBias.x sign depens on if platform has reversed z buffer
clipPos.z += _ShadowBias.x;
#if defined(UNITY_REVERSED_Z)
clipPos.z = min(clipPos.z, 1.0);
#if UNITY_REVERSED_Z
clipPos.z = min(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
clipPos.z = max(clipPos.z, 0.0);
clipPos.z = max(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
#endif
return clipPos;
}

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


#define MAX_SHADOW_CASCADES 4
///////////////////////////////////////////////////////////////////////////////
// Light Classification shadow defines //
// //
// In order to reduce shader variations main light keywords were combined //
// here we define shadow keywords. //
///////////////////////////////////////////////////////////////////////////////
#if defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT) || defined(_MAIN_LIGHT_SPOT_SHADOW) || defined(_MAIN_LIGHT_SPOT_SHADOW_SOFT)
#define _SHADOWS_ENABLED
#endif
#if defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT) || defined(_MAIN_LIGHT_SPOT_SHADOW_SOFT)
#define _SHADOWS_SOFT
#endif
#if defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE) || defined(_MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT)
#define _SHADOWS_CASCADE
#endif
#if defined(_MAIN_LIGHT_SPOT_SHADOW) || defined(_MAIN_LIGHT_SPOT_SHADOW_SOFT)
#define _SHADOWS_PERSPECTIVE
#endif
TEXTURE2D(_ScreenSpaceShadowMap);
SAMPLER(sampler_ScreenSpaceShadowMap);
TEXTURE2D_SHADOW(_ShadowMap);
SAMPLER_CMP(sampler_ShadowMap);

float4 _ShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
CBUFFER_END
inline half SampleShadowmap(float4 shadowCoord)
#if UNITY_REVERSED_Z
#define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z <= UNITY_RAW_FAR_CLIP_VALUE
#else
#define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z >= UNITY_RAW_FAR_CLIP_VALUE
#endif
#define OUTSIDE_SHADOW_BOUNDS(shadowCoord) shadowCoord.x <= 0 || shadowCoord.x >= 1 || shadowCoord.y <= 0 || shadowCoord.y >= 1 || BEYOND_SHADOW_FAR(shadowCoord)
half GetShadowStrength()
#if defined(_SHADOWS_PERSPECTIVE)
return _ShadowData.x;
}
inline half SampleScreenSpaceShadowMap(float4 shadowCoord)
{
shadowCoord.xy = shadowCoord.xy / shadowCoord.w;
half attenuation = SAMPLE_TEXTURE2D(_ScreenSpaceShadowMap, sampler_ScreenSpaceShadowMap, shadowCoord.xy).x;
// Apply shadow strength
return LerpWhiteTo(attenuation, GetShadowStrength());
}
inline real SampleShadowmap(float4 shadowCoord)
{
#endif
half attenuation;
real attenuation;
#ifdef SHADER_API_MOBILE
// 4-tap hardware comparison
half4 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);
attenuation = dot(attenuation4, 0.25);
#else
real fetchesWeights[9];
real2 fetchesUV[9];
SampleShadow_ComputeSamples_Tent_5x5(_ShadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
#ifdef SHADER_API_MOBILE
// 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);
attenuation = dot(attenuation4, 0.25);
#else
#ifdef _SHADOWS_CASCADE //Assume screen space shadows when cascades enabled
real fetchesWeights[16];
real2 fetchesUV[16];
SampleShadow_ComputeSamples_Tent_7x7(_ShadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[8].xy, shadowCoord.z));
attenuation += fetchesWeights[9] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[9].xy, shadowCoord.z));
attenuation += fetchesWeights[10] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[10].xy, shadowCoord.z));
attenuation += fetchesWeights[11] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[11].xy, shadowCoord.z));
attenuation += fetchesWeights[12] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[12].xy, shadowCoord.z));
attenuation += fetchesWeights[13] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[13].xy, shadowCoord.z));
attenuation += fetchesWeights[14] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[14].xy, shadowCoord.z));
attenuation += fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[15].xy, shadowCoord.z));
#else
real fetchesWeights[9];
real2 fetchesUV[9];
SampleShadow_ComputeSamples_Tent_5x5(_ShadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[8].xy, shadowCoord.z));
#endif
attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[0].xy, shadowCoord.z));
attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[1].xy, shadowCoord.z));
attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[2].xy, shadowCoord.z));
attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[3].xy, shadowCoord.z));
attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[4].xy, shadowCoord.z));
attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[5].xy, shadowCoord.z));
attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[6].xy, shadowCoord.z));
attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[7].xy, shadowCoord.z));
attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, real3(fetchesUV[8].xy, shadowCoord.z));
#endif
#endif
// Apply shadow strength
attenuation = LerpWhiteTo(attenuation, _ShadowData.x);
// TODO: We can set shadowmap sampler to clamptoborder when we don't have a shadow atlas and avoid xy coord bounds check
return (shadowCoord.x <= 0 || shadowCoord.x >= 1 || shadowCoord.y <= 0 || shadowCoord.y >= 1 || shadowCoord.z >= 1) ? 1.0 : attenuation;
return (OUTSIDE_SHADOW_BOUNDS(shadowCoord)) ? 1.0 : attenuation;
}
inline half ComputeCascadeIndex(float3 positionWS)

return mul(_WorldToShadow[0], float4(positionWS, 1.0));
}
half GetShadowStrength()
half RealtimeShadowAttenuation(float4 shadowCoord)
return _ShadowData.x;
}
half RealtimeShadowAttenuation(float3 positionWS)
{
#if !defined(_SHADOWS_ENABLED)
return 1.0;
#endif
float4 shadowCoord = ComputeShadowCoord(positionWS);
return SampleShadowmap(shadowCoord);
}
half RealtimeShadowAttenuation(float3 positionWS, float4 shadowCoord)
{
#if !defined(_SHADOWS_ENABLED)
return 1.0;
#endif
#ifdef _SHADOWS_CASCADE
shadowCoord = ComputeShadowCoord(positionWS);
#endif
return SampleShadowmap(shadowCoord);
return SampleScreenSpaceShadowMap(shadowCoord);
}
#endif

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


// -------------------------------------
// Lightweight Pipeline keywords
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all puctual lights
// Lightweight combines light classification and shadows keywords to reduce shader variants.
// Lightweight shader library declares defines based on these keywords to avoid having to check them in the shaders
// Core.hlsl defines _MAIN_LIGHT_DIRECTIONAL and _MAIN_LIGHT_SPOT (point lights can't be main light)
// Shadow.hlsl defines _SHADOWS_ENABLED, _SHADOWS_SOFT, _SHADOWS_CASCADE, _SHADOWS_PERSPECTIVE
#pragma multi_compile _ _MAIN_LIGHT_DIRECTIONAL_SHADOW _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE _MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT _MAIN_LIGHT_SPOT_SHADOW _MAIN_LIGHT_SPOT_SHADOW_SOFT
#pragma multi_compile _MAIN_LIGHT_DIRECTIONAL _MAIN_LIGHT_SPOT
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS

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


// -------------------------------------
// Lightweight Pipeline keywords
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all puctual lights
// Lightweight combines light classification and shadows keywords to reduce shader variants.
// Lightweight shader library declares defines based on these keywords to avoid having to check them in the shaders
// Core.hlsl defines _MAIN_LIGHT_DIRECTIONAL and _MAIN_LIGHT_SPOT (point lights can't be main light)
// Shadow.hlsl defines _SHADOWS_ENABLED, _SHADOWS_SOFT, _SHADOWS_CASCADE, _SHADOWS_PERSPECTIVE
#pragma multi_compile _ _MAIN_LIGHT_DIRECTIONAL_SHADOW _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE _MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT _MAIN_LIGHT_SPOT_SHADOW _MAIN_LIGHT_SPOT_SHADOW_SOFT
#pragma multi_compile _MAIN_LIGHT_DIRECTIONAL _MAIN_LIGHT_SPOT
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS

8
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightStandardTerrain.shader


// -------------------------------------
// Lightweight Pipeline keywords
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all puctual lights
// Lightweight combines light classification and shadows keywords to reduce shader variants.
// Lightweight shader library declares defines based on these keywords to avoid having to check them in the shaders
// Core.hlsl defines _MAIN_LIGHT_DIRECTIONAL and _MAIN_LIGHT_SPOT (point lights can't be main light)
// Shadow.hlsl defines _SHADOWS_ENABLED, _SHADOWS_SOFT, _SHADOWS_CASCADE, _SHADOWS_PERSPECTIVE
#pragma multi_compile _ _MAIN_LIGHT_DIRECTIONAL_SHADOW _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE _MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT _MAIN_LIGHT_SPOT_SHADOW _MAIN_LIGHT_SPOT_SHADOW_SOFT
#pragma multi_compile _MAIN_LIGHT_DIRECTIONAL _MAIN_LIGHT_SPOT
#pragma multi_compile _ _SHADOWS_ENABLED
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _VERTEX_LIGHTS

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


Shader "Hidden/LightweightPipeline/ScreenSpaceShadows"
{
SubShader
{
Tags{ "RenderPipeline" = "LightweightPipeline" }
HLSLINCLUDE
//Keep compiler quiet about Shadows.hlsl.
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "CoreRP/ShaderLibrary/EntityLighting.hlsl"
#include "CoreRP/ShaderLibrary/ImageBasedLighting.hlsl"
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/Shadows.hlsl"
TEXTURE2D(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
struct VertexInput
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Interpolators
{
half4 pos : SV_POSITION;
half4 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
Interpolators Vertex(VertexInput i)
{
Interpolators o;
UNITY_SETUP_INSTANCE_ID(i);
UNITY_TRANSFER_INSTANCE_ID(i, o);
o.pos = TransformObjectToHClip(i.vertex.xyz);
float4 projPos = o.pos * 0.5;
projPos.xy = projPos.xy + projPos.w;
o.texcoord.xy = i.texcoord;
o.texcoord.zw = projPos.xy;
return o;
}
half Fragment(Interpolators i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
float deviceDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.texcoord.xy);
#if UNITY_REVERSED_Z
deviceDepth = 1 - deviceDepth;
#endif
deviceDepth = 2 * deviceDepth - 1; //NOTE: Currently must massage depth before computing CS position.
float3 vpos = ComputeViewSpacePosition(i.texcoord.zw, deviceDepth, unity_CameraInvProjection);
float3 wpos = mul(unity_CameraToWorld, float4(vpos, 1)).xyz;
//Fetch shadow coordinates for cascade.
float4 coords = ComputeShadowCoord(wpos);
return SampleShadowmap(coords);
}
ENDHLSL
Pass
{
ZTest Always ZWrite Off
HLSLPROGRAM
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _SHADOWS_CASCADE
#pragma vertex Vertex
#pragma fragment Fragment
ENDHLSL
}
}
}

9
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader.meta


fileFormatVersion: 2
guid: 0f854b35a0cf61a429bd5dcfea30eddd
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存