浏览代码

Removed cascade index branching by setting an extra no-op cascade matrix.

/feature-ReflectionProbeFit
Felipe Lira 7 年前
当前提交
0424ce0c
共有 2 个文件被更改,包括 37 次插入20 次删除
  1. 30
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  2. 27
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightShaderLibrary/Shadows.hlsl

30
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


defaultShadowSettings.shadowAtlasHeight = defaultShadowSettings.shadowAtlasWidth = 4096;
defaultShadowSettings.directionalLightCascadeCount = 1;
defaultShadowSettings.directionalLightCascades = new Vector3(0.05F, 0.2F, 0.3F);
defaultShadowSettings.directionalLightCascadeCount = 4;
defaultShadowSettings.directionalLightNearPlaneOffset = 5;
defaultShadowSettings.maxShadowDistance = 1000.0F;
defaultShadowSettings.renderTextureFormat = RenderTextureFormat.Shadowmap;

private Camera m_CurrCamera;
private static readonly int kMaxCascades = 4;
private int m_ShadowCasterCascadesCount = kMaxCascades;
private const int kMaxCascades = 4;
private int m_ShadowCasterCascadesCount;
private int m_ShadowMapRTID;
private RenderTargetIdentifier m_CurrCameraColorRT;
private RenderTargetIdentifier m_ShadowMapRT;

m_PostProcessRenderContext = new PostProcessRenderContext();
m_CopyTextureSupport = SystemInfo.copyTextureSupport;
for (int i = 0; i < kMaxCascades; ++i)
m_DirectionalShadowSplitDistances[i] = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
m_DirectionalShadowSplitRadii = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
// Let engine know we have MSAA on for cases where we support MSAA backbuffer
if (QualitySettings.antiAliasing != m_Asset.MSAASampleCount)

// 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, ref lights[lightData.mainLightIndex], m_ShadowCasterCascadesCount);
SetupShadowReceiverConstants(cmd, ref lights[lightData.mainLightIndex]);
if (lightData.totalAdditionalLightsCount > 0)
SetupAdditionalListConstants(cmd, lights, ref lightData);

cmd.SetGlobalVector("_ShadowBias", new Vector4(bias, normalBias, 0.0f, 0.0f));
}
private void SetupShadowReceiverConstants(CommandBuffer cmd, ref VisibleLight shadowLight, int cascadeCount)
private void SetupShadowReceiverConstants(CommandBuffer cmd, ref VisibleLight shadowLight)
const int maxShadowCascades = 4;
Matrix4x4[] shadowMatrices = new Matrix4x4[maxShadowCascades];
for (int i = 0; i < cascadeCount; ++i)
int cascadeCount = m_ShadowCasterCascadesCount;
Matrix4x4[] shadowMatrices = new Matrix4x4[kMaxCascades + 1];
for (int i = 0; i < kMaxCascades; ++i)
// We setup and additional a no-op WorldToShadow matrix in the last index
// because the ComputeCascadeIndex function in Shadows.hlsl can return an index
// out of bounds. (position not inside any cascade) and we want to avoid branching
Matrix4x4 noOpShadowMatrix = Matrix4x4.zero;
noOpShadowMatrix.m33 = (SystemInfo.usesReversedZBuffer) ? 1.0f : 0.0f;
shadowMatrices[kMaxCascades] = noOpShadowMatrix;
float invShadowResolution = 0.5f / shadowResolution;
cmd.SetGlobalMatrixArray("_WorldToShadow", shadowMatrices);
cmd.SetGlobalVector("_ShadowData", new Vector4(light.shadowStrength, 0.0f, 0.0f, 0.0f));

int vertexLightsCount = lightData.totalAdditionalLightsCount - lightData.pixelAdditionalLightsCount;
int mainLightIndex = lightData.mainLightIndex;
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all puctual lights
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all punctual lights
// Lightweight shader library declares defines based on these keywords to make avoid having to check them in the shaders
// 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
string[] mainLightKeywords =

27
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightShaderLibrary/Shadows.hlsl


SAMPLER_CMP(sampler_ShadowMap);
CBUFFER_START(_ShadowBuffer)
float4x4 _WorldToShadow[MAX_SHADOW_CASCADES];
// 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
float4x4 _WorldToShadow[MAX_SHADOW_CASCADES + 1];
float4 _DirShadowSplitSpheres[MAX_SHADOW_CASCADES];
float4 _DirShadowSplitSphereRadii;
half4 _ShadowOffset0;

half4 weights = half4(distances2 < _DirShadowSplitSphereRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
inline half RealtimeShadowAttenuation(float3 posWorld)
inline float4 ComputeShadowCoord(float3 positionWS, half cascadeIndex = 0)
#if !defined(_SHADOWS_ENABLED)
return 1.0;
#ifdef _SHADOWS_CASCADE
return mul(_WorldToShadow[cascadeIndex], float4(positionWS, 1.0));
int cascadeIndex = 0;
#ifdef _SHADOWS_CASCADE
cascadeIndex = ComputeCascadeIndex(posWorld);
if (cascadeIndex >= MAX_SHADOW_CASCADES)
return 1.0;
return mul(_WorldToShadow[0], float4(positionWS, 1.0));
}
inline half RealtimeShadowAttenuation(float3 positionWS)
{
#if !defined(_SHADOWS_ENABLED)
return 1.0;
float4 shadowCoord = mul(_WorldToShadow[cascadeIndex], float4(posWorld, 1.0));
half cascadeIndex = ComputeCascadeIndex(positionWS);
float4 shadowCoord = ComputeShadowCoord(positionWS, cascadeIndex);
return SampleShadowmap(shadowCoord);
}

正在加载...
取消
保存