浏览代码

Fix shadowmap on low end devices. Forces hard shadow/ single cascade on GLES2 platform.

/main
Felipe Lira 7 年前
当前提交
225e061d
共有 4 个文件被更改,包括 40 次插入20 次删除
  1. 34
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  2. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/LightweightPassLit.hlsl
  3. 14
      ScriptableRenderPipeline/LightweightPipeline/LWRP/ShaderLibrary/Shadows.hlsl
  4. 6
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader

34
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


public class ShadowSettings
{
public bool enabled;
public bool screenSpace;
public int shadowAtlasWidth;
public int shadowAtlasHeight;

{
defaultShadowSettings = new ShadowSettings();
defaultShadowSettings.enabled = true;
defaultShadowSettings.screenSpace = true;
defaultShadowSettings.shadowAtlasHeight = defaultShadowSettings.shadowAtlasWidth = 4096;
defaultShadowSettings.directionalLightCascadeCount = 1;
defaultShadowSettings.directionalLightCascades = new Vector3(0.05F, 0.2F, 0.3F);

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, frameRenderingConfiguration);
}
if (shadows && m_ShadowSettings.screenSpace)
ShadowCollectPass(visibleLights, ref context, ref lightData, frameRenderingConfiguration);
if (!shadows)
{

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;
lightData.shadowMapSampleType = (m_Asset.ShadowSetting != ShadowType.SOFT_SHADOWS) ? LightShadows.Hard : mainLight.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)
lightData.shadowMapSampleType = LightShadows.Hard;
}
else
{

{
CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");
SetupShadowReceiverConstants(cmd, visibleLights[lightData.mainLightIndex]);
// TODO: Support RenderScale for the SSSM target. Should probably move allocation elsewhere, or at
// least propogate RenderTextureDescriptor generation

private void BuildShadowSettings()
{
m_ShadowSettings = ShadowSettings.Default;
m_ShadowSettings.directionalLightCascadeCount = m_Asset.CascadeCount;
m_ShadowSettings.screenSpace = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2;
m_ShadowSettings.directionalLightCascadeCount = (m_ShadowSettings.screenSpace) ? m_Asset.CascadeCount : 1;
m_ShadowSettings.shadowAtlasWidth = m_Asset.ShadowAtlasResolution;
m_ShadowSettings.shadowAtlasHeight = m_Asset.ShadowAtlasResolution;

if (shadows)
{
m_RequireDepthTexture = true;
m_RequireDepthTexture = m_ShadowSettings.screenSpace;
if (!msaaEnabled)
intermediateTexture = true;

cmd.SetGlobalVector("_LightDirection", new Vector4(lightDirection.x, lightDirection.y, lightDirection.z, 0.0f));
}
private void SetupShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight)
private void SetupShadowReceiverConstants(CommandBuffer cmd, VisibleLight shadowLight, ref ScriptableRenderContext context)
{
Light light = shadowLight.light;

float invShadowResolution = 1.0f / m_Asset.ShadowAtlasResolution;
float invHalfShadowResolution = 0.5f * invShadowResolution;
cmd.Clear();
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._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));
context.ExecuteCommandBuffer(cmd);
}
private void SetShaderKeywords(CommandBuffer cmd, ref LightData lightData, List<VisibleLight> visibleLights)

CoreUtils.SetKeyword(cmd, "_MIXED_LIGHTING_SUBTRACTIVE", m_MixedLightingSetup == MixedLightingSetup.Subtractive);
CoreUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", vertexLightsCount > 0);
CoreUtils.SetKeyword(cmd, "SOFTPARTICLES_ON", m_RequireDepthTexture && m_Asset.RequireSoftParticles);
bool linearFogModeEnabled = false;
bool exponentialFogModeEnabled = false;
if (RenderSettings.fog)

{
Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
}
if (success)
SetupShadowReceiverConstants(cmd, shadowLight, ref context);
CommandBufferPool.Release(cmd);
return success;

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


float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct LightweightVertexOutput

half3 vertexLight = VertexLighting(o.posWSShininess.xyz, o.normal.xyz);
half fogFactor = ComputeFogFactor(o.clipPos.z);
o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
#if SHADOWS_SCREEN
#else
o.shadowCoord = TransformWorldToShadowCoord(o.posWSShininess.xyz);
#endif
return o;
}

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


#define MAX_SHADOW_CASCADES 4
#ifdef SHADER_API_GLES
#define SHADOWS_SCREEN 0
#else
#define SHADOWS_SCREEN 1
#endif
SCREENSPACE_TEXTURE(_ScreenSpaceShadowMap);
SAMPLER(sampler_ScreenSpaceShadowMap);

return 4 - dot(weights, half4(4, 3, 2, 1));
}
float4 ComputeScreenSpaceShadowCoords(float3 positionWS)
float4 TransformWorldToShadowCoord(float3 positionWS)
#ifdef _SHADOWS_CASCADE
#ifdef _SHADOWS_CASCADE
half cascadeIndex = ComputeCascadeIndex(positionWS);
return mul(_WorldToShadow[cascadeIndex], float4(positionWS, 1.0));
#else

half RealtimeShadowAttenuation(float4 shadowCoord)
{
#if SHADOWS_SCREEN
#endif
return SampleShadowmap(shadowCoord);
}
#endif

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


#if UNITY_REVERSED_Z
deviceDepth = 1 - deviceDepth;
#endif
deviceDepth = 2 * deviceDepth - 1; //NOTE: Currently must massage depth before computing CS position.
deviceDepth = 2 * deviceDepth - 1; //NOTE: Currently must massage depth before computing CS position.
float4 coords = ComputeScreenSpaceShadowCoords(wpos);
float4 coords = TransformWorldToShadowCoord(wpos);
return SampleShadowmap(coords);
}

正在加载...
取消
保存