浏览代码

Improved shadow ALU and CB usage.

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

12
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


private const int kDepthStencilBufferBits = 32;
private Vector4[] m_DirectionalShadowSplitDistances = new Vector4[kMaxCascades];
private Vector4 m_DirectionalShadowSplitRadii;
private ShadowSettings m_ShadowSettings = ShadowSettings.Default;
private ShadowSliceData[] m_ShadowSlices = new ShadowSliceData[kMaxCascades];

private void SetupShadowReceiverConstants(CommandBuffer cmd, ref VisibleLight shadowLight, int cascadeCount)
{
Light light = shadowLight.light;
float strength = 1.0f - light.shadowStrength;
float shadowResolution = m_ShadowSlices[0].shadowResolution;
const int maxShadowCascades = 4;

float invShadowResolution = 0.5f / shadowResolution;
cmd.SetGlobalMatrixArray("_WorldToShadow", shadowMatrices);
cmd.SetGlobalVector("_ShadowData", new Vector4(light.shadowStrength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVector("_ShadowData", new Vector4(strength, 0.0f, 0.0f, 0.0f));
cmd.SetGlobalVector("_DirShadowSplitSphereRadii", m_DirectionalShadowSplitRadii);
cmd.SetGlobalVector("_ShadowOffset0", new Vector4(-invShadowResolution, -invShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector("_ShadowOffset1", new Vector4(invShadowResolution, -invShadowResolution, 0.0f, 0.0f));
cmd.SetGlobalVector("_ShadowOffset2", new Vector4(-invShadowResolution, invShadowResolution, 0.0f, 0.0f));

var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);
bool success = false;
var cmd = CommandBufferPool.Get("Render Shadowmap");
var cmd = CommandBufferPool.Get("Prepare Shadowmap");
SetRenderTarget(cmd, m_ShadowMapRT, ClearFlag.All);
SetRenderTarget(cmd, m_ShadowMapRT, ClearFlag.Depth);
if (shadowLight.lightType == LightType.Spot)
{

cascadeIdx, m_ShadowCasterCascadesCount, m_ShadowSettings.directionalLightCascades, shadowResolution, shadowNearPlane, out view, out proj,
out settings.splitData);
float cullingSphereRadius = settings.splitData.cullingSphere.w;
m_DirectionalShadowSplitDistances[cascadeIdx].w *= settings.splitData.cullingSphere.w;
m_DirectionalShadowSplitRadii[cascadeIdx] = cullingSphereRadius * cullingSphereRadius;
if (!success)
break;

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


CBUFFER_START(_ShadowBuffer)
float4x4 _WorldToShadow[MAX_SHADOW_CASCADES];
float4 _DirShadowSplitSpheres[MAX_SHADOW_CASCADES];
float4 _DirShadowSplitSphereRadii;
half4 _ShadowData; // (x: 1.0 - shadowStrength)
half4 _ShadowData; // (x: shadowStrength)
CBUFFER_END
inline half SampleShadowmap(float4 shadowCoord)

#ifdef _SHADOWS_SOFT
// 4-tap hardware comparison
half4 attenuation;
attenuation.x = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset0.xyz);
attenuation.y = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset1.xyz);
attenuation.z = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset2.xyz);
attenuation.w = SAMPLE_TEXTURE2D_SHADOW(_ShadowMap, sampler_ShadowMap, shadowCoord.xyz + _ShadowOffset3.xyz);
lerp(attenuation, 1.0, _ShadowData.xxxx);
return dot(attenuation, 0.25);
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);
half attenuation = dot(attenuation4, 0.25);
return lerp(attenuation, 1.0, _ShadowData.x);
// Apply shadow strength
return LerpWhiteTo(attenuation, _ShadowData.x);
// TODO: profile if there's a performance improvement if we avoid indexing here
float3 fromCenter0 = wpos.xyz - _DirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - _DirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - _DirShadowSplitSpheres[2].xyz;

float4 vDirShadowSplitSphereSqRadii;
vDirShadowSplitSphereSqRadii.x = _DirShadowSplitSpheres[0].w;
vDirShadowSplitSphereSqRadii.y = _DirShadowSplitSpheres[1].w;
vDirShadowSplitSphereSqRadii.z = _DirShadowSplitSpheres[2].w;
vDirShadowSplitSphereSqRadii.w = _DirShadowSplitSpheres[3].w;
half4 weights = half4(distances2 < vDirShadowSplitSphereSqRadii);
half4 weights = half4(distances2 < _DirShadowSplitSphereRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return 4 - dot(weights, half4(4, 3, 2, 1));
}

// 2) Allows user to define overall ambient of the scene and control situation when realtime shadow becomes too dark.
half3 realtimeShadow = max(subtractedLightmap, _SubtractiveShadowColor.xyz);
realtimeShadow = lerp(realtimeShadow, lightmap, shadowStrength);
realtimeShadow = lerp(lightmap, realtimeShadow, shadowStrength);
// 3) Pick darkest color
return min(lightmap, realtimeShadow);

正在加载...
取消
保存