浏览代码

Controls the amount of local lights shaded in a pass based on the support for StructuredBuffer

/main
Felipe Lira 6 年前
当前提交
4fe2fdda
共有 2 个文件被更改,包括 42 次插入37 次删除
  1. 42
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  2. 37
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs

42
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


// Maximum amount of visible lights the shader can process. This controls the constant global light buffer size.
// It must match the MAX_VISIBLE_LIGHTS in LightweightInput.cginc
private static readonly int kMaxVisibleLights = 16;
private static readonly int kMaxVisibleLocalLights = 16;
// 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 kMaxLocalPixelLightPerPass = 4;
// Lights are culled per-object. In platforms that don't use StructuredBuffer
// the engine will set 4 light indices in the following constant unity_4LightIndices0
// Additionally the engine set unity_4LightIndices1 but LWRP doesn't use that.
private static readonly int kMaxNonIndexedLocalLights = 4;
private static readonly int kMaxVertexLights = 4;
private const int kDepthStencilBufferBits = 32;

private Vector4 kDefaultLightSpotDirection = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
private Vector4 kDefaultLightSpotAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
private Vector4[] m_LightPositions = new Vector4[kMaxVisibleLights];
private Vector4[] m_LightColors = new Vector4[kMaxVisibleLights];
private Vector4[] m_LightDistanceAttenuations = new Vector4[kMaxVisibleLights];
private Vector4[] m_LightSpotDirections = new Vector4[kMaxVisibleLights];
private Vector4[] m_LightSpotAttenuations = new Vector4[kMaxVisibleLights];
private Vector4[] m_LightPositions = new Vector4[kMaxVisibleLocalLights];
private Vector4[] m_LightColors = new Vector4[kMaxVisibleLocalLights];
private Vector4[] m_LightDistanceAttenuations = new Vector4[kMaxVisibleLocalLights];
private Vector4[] m_LightSpotDirections = new Vector4[kMaxVisibleLocalLights];
private Vector4[] m_LightSpotAttenuations = new Vector4[kMaxVisibleLocalLights];
private Camera m_CurrCamera;

private MixedLightingSetup m_MixedLightingSetup;
private ComputeBuffer m_LightIndicesBuffer;
private List<int> m_LocalLightIndices = new List<int>(kMaxLocalPixelLightPerPass);
private List<int> m_LocalLightIndices;
private int m_MaxLocalLightsShadedPerPass;
private bool m_UseComputeBuffer;
// Pipeline pass names

m_Asset = asset;
SetRenderingFeatures();
m_ShadowPass = new LightweightShadowPass(m_Asset);
PerFrameBuffer._GlossyEnvironmentColor = Shader.PropertyToID("_GlossyEnvironmentColor");
PerFrameBuffer._SubtractiveShadowColor = Shader.PropertyToID("_SubtractiveShadowColor");

m_UseComputeBuffer = true;
m_LightIndicesBuffer = null;
m_MaxLocalLightsShadedPerPass = m_UseComputeBuffer ? kMaxVisibleLocalLights : kMaxNonIndexedLocalLights;
m_LocalLightIndices = new List<int>(m_MaxLocalLightsShadedPerPass);
m_ShadowPass = new LightweightShadowPass(m_Asset, m_MaxLocalLightsShadedPerPass);
// Let engine know we have MSAA on for cases where we support MSAA backbuffer
if (QualitySettings.antiAliasing != m_Asset.MSAASampleCount)

private void InitializeLightData(List<VisibleLight> visibleLights, out LightData lightData)
{
m_LocalLightIndices.Clear();
for (int i = 0; i < visibleLights.Count && i < kMaxLocalPixelLightPerPass; ++i)
for (int i = 0; i < visibleLights.Count && i < m_MaxLocalLightsShadedPerPass; ++i)
for (int i = 0; i < kMaxVisibleLights; ++i)
for (int i = 0; i < kMaxVisibleLocalLights; ++i)
InitializeLightConstants(visibleLights, -1, out m_LightPositions[i],
out m_LightColors[i],
out m_LightDistanceAttenuations[i],

// If we have a main light we don't shade it in the per-object light loop. We also remove it from the per-object cull list
int mainLightPresent = (lightData.mainLightIndex >= 0) ? 1 : 0;
int additionalPixelLightsCount = visibleLightsCount - mainLightPresent;
int vertexLightCount = (m_Asset.SupportsVertexLight) ? Math.Min(visibleLights.Count, kMaxPerObjectLights) - additionalPixelLightsCount - mainLightPresent : 0;
int vertexLightCount = (m_Asset.SupportsVertexLight) ? Math.Min(visibleLights.Count, m_MaxLocalLightsShadedPerPass) - additionalPixelLightsCount - mainLightPresent : 0;
vertexLightCount = Math.Min(vertexLightCount, kMaxVertexLights);
lightData.pixelAdditionalLightsCount = additionalPixelLightsCount;

m_MixedLightingSetup = MixedLightingSetup.None;
}
// How main light is decided:
// If shadows enabled, main light is always a shadow casting light. Directional has priority over local lights.
// Otherwise directional lights have priority based on cookie support and intensity
// Main Light is always a directional light
private int GetMainLight(List<VisibleLight> visibleLights)
{
int totalVisibleLights = visibleLights.Count;

int[] perObjectLightIndexMap = m_CullResults.GetLightIndexMap();
int directionalLightCount = 0;
int localLightsCount = 0;
for (int i = 0; i < lights.Count && localLightsCount < kMaxVisibleLights; ++i)
for (int i = 0; i < lights.Count && localLightsCount < kMaxVisibleLocalLights; ++i)
{
VisibleLight light = lights[i];
if (light.lightType == LightType.Directional)

37
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowPass.cs


public float RenderingDistance { get { return m_ShadowSettings.maxShadowDistance; } }
// TODO: move to a global settings file
private static readonly int kMaxPerObjectLights = 8;
private static readonly int kMaxLocalPixelLightPerPass = 4;
private const int kMaxCascades = 4;
private int m_ShadowCasterCascadesCount;

private LightShadows m_DirectionalShadowmapQuality;
private LightShadows m_LocalShadowmapQuality;
private Matrix4x4[] m_DirectionalShadowMatrices = new Matrix4x4[kMaxCascades + 1];
private Matrix4x4[] m_LocalShadowMatrices = new Matrix4x4[kMaxLocalPixelLightPerPass];
private Vector4[] m_CascadeSplitDistances = new Vector4[kMaxCascades];
private Matrix4x4[] m_DirectionalShadowMatrices;
private ShadowSliceData[] m_CascadeSlices;
private Vector4[] m_CascadeSplitDistances;
private ShadowSliceData[] m_CascadeSlices = new ShadowSliceData[kMaxCascades];
private ShadowSliceData[] m_LocalLightSlices = new ShadowSliceData[kMaxPerObjectLights];
private float[] m_LocalShadowStrength = new float[kMaxLocalPixelLightPerPass];
public LightweightShadowPass(LightweightPipelineAsset pipelineAsset)
private Matrix4x4[] m_LocalShadowMatrices;
private ShadowSliceData[] m_LocalLightSlices;
private float[] m_LocalShadowStrength;
public LightweightShadowPass(LightweightPipelineAsset pipelineAsset, int maxLocalLightsCount)
m_DirectionalShadowMatrices = new Matrix4x4[kMaxCascades + 1];
m_CascadeSlices = new ShadowSliceData[kMaxCascades];
m_CascadeSplitDistances = new Vector4[kMaxCascades];
m_LocalShadowMatrices = new Matrix4x4[maxLocalLightsCount];
m_LocalLightSlices = new ShadowSliceData[maxLocalLightsCount];
m_LocalShadowStrength = new float[maxLocalLightsCount];
DirectionalShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_WorldToShadow");
DirectionalShadowConstantBuffer._ShadowData = Shader.PropertyToID("_ShadowData");

{
List<int> localLightIndices = lightData.localLightIndices;
List<VisibleLight> visibleLights = lightData.visibleLights;
int localLightsCount = Math.Min(localLightIndices.Count, kMaxLocalPixelLightPerPass);
int localLightsCount = localLightIndices.Count;
for (int i = 0; i < localLightsCount; ++i)
{
VisibleLight shadowLight = visibleLights[localLightIndices[i]];

{
// This way of computing the shadow slice only work for spots and with most 4 shadow casting lights per pass
// Change this when point lights are supported.
Debug.Assert(kMaxLocalPixelLightPerPass == 4 && shadowLight.lightType == LightType.Spot);
Debug.Assert(localLightsCount <= 4 && shadowLight.lightType == LightType.Spot);
// TODO: We need to pass bias and scale list to shader to be able to support multiple
// shadow casting local lights.

private void SetupLocalLightsShadowReceiverConstants(CommandBuffer cmd, ref ScriptableRenderContext context)
{
for (int i = 0; i < kMaxLocalPixelLightPerPass; ++i)
for (int i = 0; i < m_LocalLightSlices.Length; ++i)
m_LocalShadowMatrices[i] = m_LocalLightSlices[i].shadowTransform;
float invShadowAtlasWidth = 1.0f / m_ShadowSettings.localShadowAtlasWidth;

正在加载...
取消
保存