浏览代码

Merge pull request #316 from Unity-Technologies/Update-shadow-API-to-use-Lits-VisibleLight--to-reduce-GC-pressure

Update shadow API - Use List<VisibleLight> instead of VisibleLight[]
/RenderPassXR_Sandbox
GitHub 7 年前
当前提交
5c55ff09
共有 4 个文件被更改,包括 35 次插入35 次删除
  1. 36
      Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  2. 26
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs
  3. 4
      Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs
  4. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs

36
Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs


using UnityEngine.Rendering;
using System;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering
{

Object.DestroyImmediate(m_DebugMaterial);
}
override public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, VisibleLight[] lights )
override public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)
{
for( uint i = 0, cnt = sr.facecount; i < cnt; ++i )
{

return Reserve( frameId, ref shadowData, sr, m_TmpWidths, m_TmpHeights, ref entries, ref payload, lights );
}
override public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, VisibleLight[] lights )
override public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)
{
if( m_FrameId.frameCount != frameId.frameCount )
m_ActiveEntriesCount = 0;

bit <<= 1;
}
WritePerLightPayload( ref lights[sr.index], sr, ref sd, ref payload, ref originalPayloadCount );
WritePerLightPayload(lights, sr, ref sd, ref payload, ref originalPayloadCount );
return true;
}

}
// Writes additional per light data into the payload vector. Make sure to call base.WritePerLightPayload first.
virtual protected void WritePerLightPayload( ref VisibleLight light, ShadowRequest sr, ref ShadowData sd, ref ShadowPayloadVector payload, ref uint payloadOffset )
virtual protected void WritePerLightPayload(List<VisibleLight> lights, ShadowRequest sr, ref ShadowData sd, ref ShadowPayloadVector payload, ref uint payloadOffset )
{
ShadowPayload sp = new ShadowPayload();
if( sr.shadowType == GPUShadowType.Directional )

ShadowUtils.Unpack( sr.shadowAlgorithm, out algo, out vari, out prec );
if( algo == ShadowAlgorithm.PCF )
{
AdditionalShadowData asd = light.light.GetComponent<AdditionalShadowData>();
AdditionalShadowData asd = lights[sr.index].light.GetComponent<AdditionalShadowData>();
if( !asd )
return;

cb.ClearRenderTarget( true, !IsNativeDepth(), m_ClearColor );
}
override public void Update( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights )
override public void Update( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, List<VisibleLight> lights)
{
var profilingSample = new HDPipeline.Utilities.ProfilingSample(string.Format("Shadowmap{0}",m_TexSlot), renderContext);

profilingSample.Dispose();
}
virtual protected void PostUpdate( FrameId frameId, CommandBuffer cb, uint rendertargetSlice, VisibleLight[] lights )
virtual protected void PostUpdate( FrameId frameId, CommandBuffer cb, uint rendertargetSlice, List<VisibleLight> lights)
{
if( !IsNativeDepth() )
cb.ReleaseTemporaryRT( m_TempDepthId );

}
// Writes additional per light data into the payload vector. Make sure to call base.WritePerLightPayload first.
override protected void WritePerLightPayload( ref VisibleLight light, ShadowRequest sr, ref ShadowData sd, ref ShadowPayloadVector payload, ref uint payloadOffset )
override protected void WritePerLightPayload(List<VisibleLight> lights, ShadowRequest sr, ref ShadowData sd, ref ShadowPayloadVector payload, ref uint payloadOffset )
base.WritePerLightPayload( ref light, sr, ref sd, ref payload, ref payloadOffset );
base.WritePerLightPayload(lights, sr, ref sd, ref payload, ref payloadOffset );
AdditionalShadowData asd = light.light.GetComponent<AdditionalShadowData>();
AdditionalShadowData asd = lights[sr.index].light.GetComponent<AdditionalShadowData>();
if( !asd )
return;

cb.ClearRenderTarget( true, true, m_ClearColor );
}
protected override void PostUpdate( FrameId frameId, CommandBuffer cb, uint rendertargetSlice, VisibleLight[] lights )
protected override void PostUpdate( FrameId frameId, CommandBuffer cb, uint rendertargetSlice, List<VisibleLight> lights)
{
cb.name = "VSM conversion";
if ( rendertargetSlice == uint.MaxValue )

cullingParams.shadowDistance = Mathf.Min( m_ShadowSettings.maxShadowDistance, cullingParams.shadowDistance );
}
public override void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices )
public override void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices )
{
shadowDataIndices = null;

}
}
protected override void PrioritizeShadowCasters( Camera camera, VisibleLight[] lights, uint shadowRequestsCount, int[] shadowRequests )
protected override void PrioritizeShadowCasters( Camera camera, List<VisibleLight> lights, uint shadowRequestsCount, int[] shadowRequests )
{
// this function simply looks at the projected area on the screen, ignoring all light types and shapes
m_TmpSortKeys.Reset( shadowRequestsCount );

m_TmpSortKeys.ExtractTo( shadowRequests, 0, out shadowRequestsCount, delegate(long key) { return (int) (key & 0xffffffff); } );
}
protected override void PruneShadowCasters( Camera camera, VisibleLight[] lights, ref VectorArray<int> shadowRequests, ref ShadowRequestVector requestsGranted, out uint totalRequestCount )
protected override void PruneShadowCasters( Camera camera, List<VisibleLight> lights, ref VectorArray<int> shadowRequests, ref ShadowRequestVector requestsGranted, out uint totalRequestCount )
{
Debug.Assert( shadowRequests.Count() > 0 );
// at this point the array is sorted in order of some importance determined by the prioritize function

if( add )
{
sreq.instanceId = vl.light.GetInstanceID();
sreq.index = (uint) requestIdx;
sreq.index = requestIdx;
sreq.facemask = (uint) (1 << facecount) - 1;
sreq.shadowType = shadowType;

m_TmpSortKeys.ExtractTo( ref shadowRequests, (long idx) => { return (int) idx; } );
}
protected override void AllocateShadows( FrameId frameId, VisibleLight[] lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload )
protected override void AllocateShadows( FrameId frameId, List<VisibleLight> lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload )
{
ShadowData sd = new ShadowData();
shadowDatas.Reserve( totalGranted );

}
}
public override void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights )
public override void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, List<VisibleLight> lights)
{
using (new HDPipeline.Utilities.ProfilingSample("Render Shadows Exp", renderContext))
{

26
Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs


set { m_ShadowTypeAndAlgorithm = (m_ShadowTypeAndAlgorithm & ~(ShadowConstants.Masks.k_GPUShadowAlgorithm)) | (int)value; }
}
// index into the visible lights array
public uint index
public int index // use "int" and not "uint" as it is use to index inside List<>
get { return m_MaskIndex & k_MaxIndex; }
set { m_MaskIndex = value & k_MaxIndex; }
get { return (int)(m_MaskIndex & k_MaxIndex); }
set { m_MaskIndex = (uint)value & k_MaxIndex; }
}
// mask of which faces are requested:
// - for spotlights the value is always 1

public ShadowSupport QueryShadowSupport() { return m_ShadowSupport; }
public uint GetMaxPayload() { return m_MaxPayloadCount; }
public void Assign( CullResults cullResults ) { m_CullResults = cullResults; } // TODO: Remove when m_CullResults is removed again
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights );
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights );
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, List<VisibleLight> lights);
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, List<VisibleLight> lights);
abstract public void Update( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights );
abstract public void Update( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, List<VisibleLight> lights);
abstract public void ReserveSlots( ShadowContextStorage sc );
abstract public void Fill( ShadowContextStorage cs );
abstract public void CreateShadowmap();

// shadowPayloads contains implementation specific data that is accessed from the shader by indexing into an Buffer<int> using ShadowData.ShadowmapData.payloadOffset.
// This is the equivalent of a void pointer in the shader and there needs to be loader code that knows how to interpret the data.
// If there are no valid shadow casters all output arrays will be null, otherwise they will contain valid data that can be passed to shaders.
void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights );
void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, List<VisibleLight> lights);
// Debug function to display a shadow at the screen coordinate
void DisplayShadow(ScriptableRenderContext renderContext, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
void DisplayShadowMap(ScriptableRenderContext renderContext, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);

abstract public class ShadowManagerBase : ShadowRegistry, IShadowManager
{
public abstract void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
public abstract void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights );
public abstract void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
public abstract void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, List<VisibleLight> lights);
public abstract void DisplayShadow(ScriptableRenderContext renderContext, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void DisplayShadowMap(ScriptableRenderContext renderContext, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void SyncData();

protected abstract void PrioritizeShadowCasters( Camera camera, VisibleLight[] lights, uint shadowRequestsCount, int[] shadowRequests );
protected abstract void PrioritizeShadowCasters( Camera camera, List<VisibleLight> lights, uint shadowRequestsCount, int[] shadowRequests );
protected abstract void PruneShadowCasters( Camera camera, VisibleLight[] lights, ref VectorArray<int> shadowRequests, ref VectorArray<ShadowmapBase.ShadowRequest> requestsGranted, out uint totalRequestCount );
protected abstract void PruneShadowCasters( Camera camera, List<VisibleLight> lights, ref VectorArray<int> shadowRequests, ref VectorArray<ShadowmapBase.ShadowRequest> requestsGranted, out uint totalRequestCount );
protected abstract void AllocateShadows( FrameId frameId, VisibleLight[] lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
protected abstract void AllocateShadows( FrameId frameId, List<VisibleLight> lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
public abstract uint GetShadowMapCount();
public abstract uint GetShadowMapSliceCount(uint shadowMapIndex);

4
Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs


uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights.ToArray(),
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
// update the visibleLights with the shadow information

BuildPerTileLightLists(camera, loop, numLights, projscr, invProjscr);
m_ShadowMgr.RenderShadows( m_FrameId, loop, cullResults, cullResults.visibleLights.ToArray() );
m_ShadowMgr.RenderShadows( m_FrameId, loop, cullResults, cullResults.visibleLights );
m_ShadowMgr.SyncData();
m_ShadowMgr.BindResources( loop );

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


//TODO: Do not call ToArray here to avoid GC, refactor API
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, cullResults.visibleLights.ToArray(),
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, cullResults.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
// update the visibleLights with the shadow information

public void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults)
{
// kick off the shadow jobs here
m_ShadowMgr.RenderShadows(m_FrameId, renderContext, cullResults, cullResults.visibleLights.ToArray());
m_ShadowMgr.RenderShadows(m_FrameId, renderContext, cullResults, cullResults.visibleLights);
}
private void SetupDebugDisplayMode(bool debugDisplayEnable)

正在加载...
取消
保存