You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
681 lines
43 KiB
681 lines
43 KiB
using System;
|
|
using System.ComponentModel;
|
|
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using Unity.Jobs;
|
|
using Unity.Mathematics;
|
|
using Unity.Profiling;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
[BurstCompile] [NoAlias]
|
|
internal unsafe struct HDShadowRequestUpdateJob : IJob
|
|
{
|
|
public HDShadowManagerDataForShadowRequestUpateJob shadowManager;
|
|
|
|
[Unity.Collections.ReadOnly] public NativeBitArray shadowRequestValidityArray;
|
|
[Unity.Collections.ReadOnly] public NativeArray<uint> sortKeys;
|
|
[Unity.Collections.ReadOnly] public NativeArray<int> visibleLightEntityDataIndices;
|
|
[Unity.Collections.ReadOnly] public NativeArray<HDProcessedVisibleLight> processedEntities;
|
|
[Unity.Collections.ReadOnly] public NativeArray<VisibleLight> visibleLights;
|
|
[Unity.Collections.ReadOnly] public NativeList<int> requestIndicesStorage;
|
|
[Unity.Collections.ReadOnly] public NativeArray<HDAdditionalLightDataUpdateInfo> additionalLightDataUpdateInfos;
|
|
[Unity.Collections.ReadOnly] public NativeArray<ShadowIndicesAndVisibleLightData> visibleLightsAndIndicesBuffer;
|
|
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> cachedPointVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> cachedSpotVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> cachedAreaRectangleVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> cachedDirectionalVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> dynamicPointVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> dynamicSpotVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> dynamicAreaRectangleVisibleLightsAndIndices;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<ShadowIndicesAndVisibleLightData> dynamicDirectionalVisibleLightsAndIndices;
|
|
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> dynamicPointHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> cachedPointHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> dynamicSpotHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> cachedSpotHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> dynamicAreaRectangleHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> cachedAreaRectangleHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> dynamicDirectionalHDSplits;
|
|
[Unity.Collections.ReadOnly] public UnsafeList<HDShadowCullingSplit> cachedDirectionalHDSplits;
|
|
|
|
public NativeList<HDShadowRequest> requestStorage;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> cachedPointUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> cachedSpotUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> cachedAreaRectangleUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> cachedDirectionalUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> dynamicPointUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> dynamicSpotUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> dynamicAreaRectangleUpdateInfos;
|
|
public NativeList<ShadowRequestIntermediateUpdateData> dynamicDirectionalUpdateInfos;
|
|
public NativeList<float4> frustumPlanesStorage;
|
|
public NativeList<Vector3> cachedViewPositionsStorage;
|
|
|
|
public NativeArray<int> shadowIndices;
|
|
|
|
#if UNITY_EDITOR
|
|
[WriteOnly] public NativeArray<int> shadowRequestCounts;
|
|
#endif
|
|
|
|
[Unity.Collections.ReadOnly] public int lightCounts;
|
|
[Unity.Collections.ReadOnly] public int shadowSettingsCascadeShadowSplitCount;
|
|
|
|
[Unity.Collections.ReadOnly] public Vector3 worldSpaceCameraPos;
|
|
[Unity.Collections.ReadOnly] public int shaderConfigCameraRelativeRendering;
|
|
[Unity.Collections.ReadOnly] public int shadowRequestCount;
|
|
[Unity.Collections.ReadOnly] public HDShadowFilteringQuality punctualShadowFilteringQuality;
|
|
[Unity.Collections.ReadOnly] public HDShadowFilteringQuality directionalShadowFilteringQuality;
|
|
[Unity.Collections.ReadOnly] public bool usesReversedZBuffer;
|
|
|
|
public ProfilerMarker cachedDirectionalRequestsMarker;
|
|
public ProfilerMarker dynamicDirectionalRequestsMarker;
|
|
public ProfilerMarker dynamicPointRequestsMarker;
|
|
public ProfilerMarker dynamicSpotRequestsMarker;
|
|
public ProfilerMarker dynamicAreaRectangleRequestsMarker;
|
|
public ProfilerMarker cachedPointRequestsMarker;
|
|
public ProfilerMarker cachedSpotRequestsMarker;
|
|
public ProfilerMarker cachedAreaRectangleRequestsMarker;
|
|
|
|
public void Execute()
|
|
{
|
|
// Write the first relevant shadow index to the shadowIndices buffer, one of this job's outputs.
|
|
// The value may get overwritten later in the job with -1 if the request does not have atlas placement,
|
|
// but we don't know which shadows do or don't have atlas placement yet.
|
|
// We may want to extract this and the overwriting to a different set of loops in future iterations.
|
|
|
|
for (int sortKeyIndex = 0; sortKeyIndex < lightCounts; sortKeyIndex++)
|
|
{
|
|
int shadowRequestCount = 0;
|
|
int firstShadowRequestIndex = -1;
|
|
|
|
if (shadowRequestValidityArray.IsSet(sortKeyIndex))
|
|
{
|
|
uint sortKey = sortKeys[sortKeyIndex];
|
|
int lightIndex = (int)(sortKey & 0xFFFF);
|
|
|
|
ShadowIndicesAndVisibleLightData visibleLightsAndIndices = visibleLightsAndIndicesBuffer[lightIndex];
|
|
HDShadowRequestSetHandle shadowRequestSetHandle = visibleLightsAndIndices.shadowRequestSetHandle;
|
|
|
|
for (int index = 0; index < visibleLightsAndIndices.splitCount; index++)
|
|
{
|
|
if (!visibleLightsAndIndices.isSplitValidMask[(uint)index])
|
|
continue;
|
|
|
|
HDShadowRequestHandle shadowRequestIndexLocation = shadowRequestSetHandle[index];
|
|
int shadowRequestIndex = requestIndicesStorage[shadowRequestIndexLocation.storageIndexForRequestIndex];
|
|
shadowManager.shadowRequests[shadowRequestIndex] = shadowRequestIndexLocation;
|
|
|
|
// Store the first shadow request id to return it
|
|
if (firstShadowRequestIndex == -1)
|
|
firstShadowRequestIndex = shadowRequestIndex;
|
|
}
|
|
|
|
shadowRequestCount = visibleLightsAndIndices.splitCount;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
shadowRequestCounts[sortKeyIndex] = shadowRequestCount;
|
|
#endif
|
|
shadowIndices[sortKeyIndex] = firstShadowRequestIndex;
|
|
}
|
|
|
|
// Perform two loops for each combination of light type and atlas associativity.
|
|
// In the first loop, we get all the atlas-related work out of the way.
|
|
// In the second, we do the heavier ALU work for shadow requests with matrix math etc.
|
|
// Note: some of the work for directional lights is still managed, and so we do it after this job completes.
|
|
|
|
using (cachedDirectionalRequestsMarker.Auto())
|
|
{
|
|
for (int i = 0; i < cachedDirectionalVisibleLightsAndIndices.Length; i++)
|
|
{
|
|
ref ShadowIndicesAndVisibleLightData shadowIndicesAndVisibleLightData = ref cachedDirectionalVisibleLightsAndIndices.ElementAt(i);
|
|
HDShadowRequestSetHandle shadowRequestSetHandle = shadowIndicesAndVisibleLightData.shadowRequestSetHandle;
|
|
ShadowMapUpdateType cachedDirectionalUpdateType = shadowIndicesAndVisibleLightData.shadowUpdateType;
|
|
BitArray8 needCacheUpdateMask = shadowIndicesAndVisibleLightData.needCacheUpdateMask;
|
|
int lightIdxForCachedShadows = shadowIndicesAndVisibleLightData.additionalLightUpdateInfo.lightIdxForCachedShadows;
|
|
bool shadowHasAtlasPlacement = lightIdxForCachedShadows != -1;
|
|
|
|
if (!shadowHasAtlasPlacement)
|
|
shadowIndices[shadowIndicesAndVisibleLightData.sortKeyIndex] = -1;
|
|
|
|
for (int index = 0; index < shadowIndicesAndVisibleLightData.splitCount; index++)
|
|
{
|
|
bool needToUpdateCachedContent = needCacheUpdateMask[(uint)index];
|
|
HDShadowRequestHandle indexHandle = shadowRequestSetHandle[index];
|
|
int shadowRequestIndex = requestIndicesStorage[indexHandle.storageIndexForRequestIndex];
|
|
ref HDShadowResolutionRequest resolutionRequest = ref shadowManager.shadowResolutionRequestStorage.ElementAt(shadowRequestIndex);
|
|
|
|
ref var shadowRequest = ref requestStorage.ElementAt(indexHandle.storageIndexForShadowRequest);
|
|
shadowRequest.isInCachedAtlas = cachedDirectionalUpdateType == ShadowMapUpdateType.Cached;
|
|
shadowRequest.isMixedCached = cachedDirectionalUpdateType == ShadowMapUpdateType.Mixed;
|
|
shadowRequest.shouldUseCachedShadowData = !needToUpdateCachedContent;
|
|
shadowRequest.shadowMapType = ShadowMapType.CascadedDirectional;
|
|
shadowRequest.dynamicAtlasViewport = resolutionRequest.dynamicAtlasViewport;
|
|
shadowRequest.cachedAtlasViewport = resolutionRequest.cachedAtlasViewport;
|
|
|
|
int updateDataListIndex = cachedDirectionalUpdateInfos.Length;
|
|
cachedDirectionalUpdateInfos.Length = updateDataListIndex + 1;
|
|
ref ShadowRequestIntermediateUpdateData updateInfo = ref cachedDirectionalUpdateInfos.ElementAt(updateDataListIndex);
|
|
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_HasCachedComponent] = true;
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent] = needToUpdateCachedContent;
|
|
updateInfo.shadowRequestHandle = shadowRequestSetHandle[index];
|
|
updateInfo.additionalLightDataIndex = shadowIndicesAndVisibleLightData.dataIndex;
|
|
updateInfo.updateType = cachedDirectionalUpdateType;
|
|
updateInfo.viewportSize = resolutionRequest.resolution;
|
|
updateInfo.lightIndex = shadowIndicesAndVisibleLightData.lightIndex;
|
|
|
|
if (shadowRequestIndex < shadowRequestCount)
|
|
{
|
|
if (cachedDirectionalUpdateType == ShadowMapUpdateType.Mixed && shadowManager.cachedShadowManager.directionalHasCachedAtlas)
|
|
{
|
|
shadowManager.cachedShadowManager.directionalLightAtlas.shadowRequests.Add(shadowRequestSetHandle[index]);
|
|
shadowManager.cascadeShadowAtlas.mixedRequestsPendingBlits.Add(shadowRequestSetHandle[index]);
|
|
}
|
|
|
|
shadowManager.cascadeShadowAtlas.shadowRequests.Add(shadowRequestSetHandle[index]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
using (dynamicDirectionalRequestsMarker.Auto())
|
|
{
|
|
for (int i = 0; i < dynamicDirectionalVisibleLightsAndIndices.Length; i++)
|
|
{
|
|
ref ShadowIndicesAndVisibleLightData shadowIndicesAndVisibleLightData = ref dynamicDirectionalVisibleLightsAndIndices.ElementAt(i);
|
|
HDShadowRequestSetHandle shadowRequestSetHandle = shadowIndicesAndVisibleLightData.shadowRequestSetHandle;
|
|
|
|
for (int index = 0; index < shadowIndicesAndVisibleLightData.splitCount; index++)
|
|
{
|
|
HDShadowRequestHandle indexHandle = shadowRequestSetHandle[index];
|
|
int shadowRequestIndex = requestIndicesStorage[indexHandle.storageIndexForRequestIndex];
|
|
ref HDShadowResolutionRequest resolutionRequest = ref shadowManager.shadowResolutionRequestStorage.ElementAt(shadowRequestIndex);
|
|
|
|
ref var shadowRequest = ref requestStorage.ElementAt(indexHandle.storageIndexForShadowRequest);
|
|
shadowRequest.isInCachedAtlas = false;
|
|
shadowRequest.isMixedCached = false;
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.shadowMapType = ShadowMapType.CascadedDirectional;
|
|
shadowRequest.dynamicAtlasViewport = resolutionRequest.dynamicAtlasViewport;
|
|
shadowRequest.cachedAtlasViewport = resolutionRequest.cachedAtlasViewport;
|
|
|
|
int updateDataListIndex = dynamicDirectionalUpdateInfos.Length;
|
|
dynamicDirectionalUpdateInfos.Length = updateDataListIndex + 1;
|
|
ref ShadowRequestIntermediateUpdateData updateInfo = ref dynamicDirectionalUpdateInfos.ElementAt(updateDataListIndex);
|
|
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_HasCachedComponent] = false;
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent] = false;
|
|
updateInfo.shadowRequestHandle = shadowRequestSetHandle[index];
|
|
updateInfo.additionalLightDataIndex = shadowIndicesAndVisibleLightData.dataIndex;
|
|
updateInfo.updateType = ShadowMapUpdateType.Dynamic;
|
|
updateInfo.viewportSize = resolutionRequest.resolution;
|
|
updateInfo.lightIndex = shadowIndicesAndVisibleLightData.lightIndex;
|
|
|
|
if (shadowRequestIndex < shadowRequestCount)
|
|
shadowManager.cascadeShadowAtlas.shadowRequests.Add(shadowRequestSetHandle[index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update cached area rectangle:
|
|
using (cachedAreaRectangleRequestsMarker.Auto())
|
|
{
|
|
UpdateNonDirectionalCachedRequests(LightType.Rectangle,
|
|
shadowManager.cachedShadowManager.areaShadowAtlas,
|
|
shadowManager.areaShadowAtlas,
|
|
cachedAreaRectangleVisibleLightsAndIndices, cachedAreaRectangleUpdateInfos,
|
|
shadowIndices, shadowRequestCount);
|
|
UpdateCachedAreaShadowRequestsAndResolutionRequests(cachedAreaRectangleUpdateInfos);
|
|
}
|
|
|
|
// Update cached point:
|
|
using (cachedPointRequestsMarker.Auto())
|
|
{
|
|
UpdateNonDirectionalCachedRequests(LightType.Point,
|
|
shadowManager.cachedShadowManager.punctualShadowAtlas,
|
|
shadowManager.atlas,
|
|
cachedPointVisibleLightsAndIndices, cachedPointUpdateInfos,
|
|
shadowIndices, shadowRequestCount);
|
|
UpdateCachedPointShadowRequestsAndResolutionRequests();
|
|
}
|
|
|
|
// Update cached spot:
|
|
using (cachedSpotRequestsMarker.Auto())
|
|
{
|
|
UpdateNonDirectionalCachedRequests(LightType.Spot,
|
|
shadowManager.cachedShadowManager.punctualShadowAtlas,
|
|
shadowManager.atlas,
|
|
cachedSpotVisibleLightsAndIndices, cachedSpotUpdateInfos,
|
|
shadowIndices, shadowRequestCount);
|
|
UpdateCachedSpotShadowRequestsAndResolutionRequests();
|
|
}
|
|
|
|
// Update dynamic area rectangle:
|
|
using (dynamicAreaRectangleRequestsMarker.Auto())
|
|
{
|
|
UpdateNonDirectionalDynamicRequests(LightType.Rectangle,
|
|
shadowManager.cachedShadowManager.areaShadowAtlas,
|
|
shadowManager.areaShadowAtlas,
|
|
dynamicAreaRectangleVisibleLightsAndIndices, dynamicAreaRectangleUpdateInfos,
|
|
shadowRequestCount);
|
|
UpdateDynamicAreaShadowRequestsAndResolutionRequests(dynamicAreaRectangleUpdateInfos);
|
|
}
|
|
|
|
// Update dynamic point:
|
|
using (dynamicPointRequestsMarker.Auto())
|
|
{
|
|
UpdateNonDirectionalDynamicRequests(LightType.Point,
|
|
shadowManager.cachedShadowManager.punctualShadowAtlas,
|
|
shadowManager.atlas,
|
|
dynamicPointVisibleLightsAndIndices, dynamicPointUpdateInfos,
|
|
shadowRequestCount);
|
|
UpdateDynamicPointShadowRequestsAndResolutionRequests();
|
|
}
|
|
|
|
|
|
// Update dynamic point:
|
|
using (dynamicSpotRequestsMarker.Auto())
|
|
{
|
|
UpdateNonDirectionalDynamicRequests(LightType.Spot,
|
|
shadowManager.cachedShadowManager.punctualShadowAtlas,
|
|
shadowManager.atlas,
|
|
dynamicSpotVisibleLightsAndIndices, dynamicSpotUpdateInfos,
|
|
shadowRequestCount);
|
|
UpdateDynamicSpotShadowRequestsAndResolutionRequests();
|
|
}
|
|
}
|
|
|
|
public void UpdateCachedPointShadowRequestsAndResolutionRequests()
|
|
{
|
|
int pointCount = cachedPointUpdateInfos.Length;
|
|
|
|
for (int i = 0; i < pointCount; i++)
|
|
{
|
|
ref ShadowRequestIntermediateUpdateData pointUpdateInfo = ref cachedPointUpdateInfos.ElementAt(i);
|
|
ref HDShadowCullingSplit newShadowCullingSplit = ref cachedPointHDSplits.ElementAt(i);
|
|
bool needToUpdateCachedContent = pointUpdateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent];
|
|
bool hasCachedComponent = pointUpdateInfo.states[ShadowRequestIntermediateUpdateData.k_HasCachedComponent];
|
|
HDShadowRequestHandle shadowRequestHandle = pointUpdateInfo.shadowRequestHandle;
|
|
ref HDShadowRequest shadowRequest = ref requestStorage.ElementAt(shadowRequestHandle.storageIndexForRequestIndex);
|
|
int additionalLightDataIndex = pointUpdateInfo.additionalLightDataIndex;
|
|
int lightIndex = pointUpdateInfo.lightIndex;
|
|
Vector2 viewportSize = pointUpdateInfo.viewportSize;
|
|
ShadowMapUpdateType updateType = pointUpdateInfo.updateType;
|
|
bool isSampledFromCache = (updateType == ShadowMapUpdateType.Cached);
|
|
bool needToUpdateDynamicContent = !isSampledFromCache;
|
|
HDAdditionalLightDataUpdateInfo updateInfo = additionalLightDataUpdateInfos[additionalLightDataIndex];
|
|
bool hasUpdatedRequestData = false;
|
|
|
|
if (needToUpdateCachedContent)
|
|
{
|
|
cachedViewPositionsStorage[shadowRequestHandle.storageIndexForCachedViewPosition] = worldSpaceCameraPos;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetPointRequestSettings(ref shadowRequest, shadowRequestHandle, in pointUpdateInfo.visibleLight,
|
|
worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
|
|
hasUpdatedRequestData = true;
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.shouldRenderCachedComponent = true;
|
|
}
|
|
else if (hasCachedComponent)
|
|
{
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = worldSpaceCameraPos - cachedViewPositionsStorage[shadowRequestHandle.storageIndexForCachedViewPosition];
|
|
shadowRequest.shouldUseCachedShadowData = true;
|
|
shadowRequest.shouldRenderCachedComponent = false;
|
|
}
|
|
|
|
if (needToUpdateDynamicContent && !hasUpdatedRequestData)
|
|
{
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetPointRequestSettings(ref shadowRequest, shadowRequestHandle, in pointUpdateInfo.visibleLight,
|
|
worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateDynamicPointShadowRequestsAndResolutionRequests()
|
|
{
|
|
int pointCount = dynamicPointUpdateInfos.Length;
|
|
|
|
for (int i = 0; i < pointCount; i++)
|
|
{
|
|
ref ShadowRequestIntermediateUpdateData pointUpdateInfo = ref dynamicPointUpdateInfos.ElementAt(i);
|
|
ref HDShadowCullingSplit newShadowCullingSplit = ref dynamicPointHDSplits.ElementAt(i);
|
|
HDShadowRequestHandle shadowRequestHandle = pointUpdateInfo.shadowRequestHandle;
|
|
ref HDShadowRequest shadowRequest = ref requestStorage.ElementAt(shadowRequestHandle.storageIndexForRequestIndex);
|
|
int additionalLightDataIndex = pointUpdateInfo.additionalLightDataIndex;
|
|
int lightIndex = pointUpdateInfo.lightIndex;
|
|
Vector2 viewportSize = pointUpdateInfo.viewportSize;
|
|
HDAdditionalLightDataUpdateInfo updateInfo = additionalLightDataUpdateInfos[additionalLightDataIndex];
|
|
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetPointRequestSettings(ref shadowRequest, shadowRequestHandle, in pointUpdateInfo.visibleLight,
|
|
worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This method has a duplicate of the same name in HDGpuLightsBuilder.LightLoop.cs
|
|
/// This was duplicated to support the expensive managed callback per spot light, without sacrificing performance in the Burst compiled job.
|
|
/// Any changes made here should be duplicated in the other function and vice versa.
|
|
/// </summary>
|
|
public void UpdateCachedSpotShadowRequestsAndResolutionRequests()
|
|
{
|
|
int spotCount = cachedSpotUpdateInfos.Length;
|
|
|
|
for (int i = 0; i < spotCount; i++)
|
|
{
|
|
ref ShadowRequestIntermediateUpdateData spotUpdateInfo = ref cachedSpotUpdateInfos.ElementAt(i);
|
|
ref HDShadowCullingSplit newShadowCullingSplit = ref cachedSpotHDSplits.ElementAt(i);
|
|
bool needToUpdateCachedContent = spotUpdateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent];
|
|
HDShadowRequestHandle shadowRequestHandle = spotUpdateInfo.shadowRequestHandle;
|
|
ref HDShadowRequest shadowRequest = ref requestStorage.ElementAt(shadowRequestHandle.storageIndexForRequestIndex);
|
|
int additionalLightDataIndex = spotUpdateInfo.additionalLightDataIndex;
|
|
int lightIndex = spotUpdateInfo.lightIndex;
|
|
Vector2 viewportSize = spotUpdateInfo.viewportSize;
|
|
ShadowMapUpdateType updateType = spotUpdateInfo.updateType;
|
|
bool isSampledFromCache = (updateType == ShadowMapUpdateType.Cached);
|
|
bool needToUpdateDynamicContent = !isSampledFromCache;
|
|
HDAdditionalLightDataUpdateInfo updateInfo = additionalLightDataUpdateInfos[additionalLightDataIndex];
|
|
bool hasUpdatedRequestData = false;
|
|
|
|
if (needToUpdateCachedContent)
|
|
{
|
|
cachedViewPositionsStorage[shadowRequestHandle.storageIndexForCachedViewPosition] = worldSpaceCameraPos;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight,
|
|
0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
|
|
hasUpdatedRequestData = true;
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.shouldRenderCachedComponent = true;
|
|
}
|
|
else
|
|
{
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = worldSpaceCameraPos - cachedViewPositionsStorage[shadowRequestHandle.storageIndexForCachedViewPosition];
|
|
shadowRequest.shouldUseCachedShadowData = true;
|
|
shadowRequest.shouldRenderCachedComponent = false;
|
|
}
|
|
|
|
if (needToUpdateDynamicContent && !hasUpdatedRequestData)
|
|
{
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight,
|
|
0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateDynamicSpotShadowRequestsAndResolutionRequests()
|
|
{
|
|
int spotCount = dynamicSpotUpdateInfos.Length;
|
|
|
|
for (int i = 0; i < spotCount; i++)
|
|
{
|
|
ref ShadowRequestIntermediateUpdateData spotUpdateInfo = ref dynamicSpotUpdateInfos.ElementAt(i);
|
|
ref HDShadowCullingSplit newShadowCullingSplit = ref dynamicSpotHDSplits.ElementAt(i);
|
|
HDShadowRequestHandle shadowRequestHandle = spotUpdateInfo.shadowRequestHandle;
|
|
ref HDShadowRequest shadowRequest = ref requestStorage.ElementAt(shadowRequestHandle.storageIndexForRequestIndex);
|
|
int additionalLightDataIndex = spotUpdateInfo.additionalLightDataIndex;
|
|
int lightIndex = spotUpdateInfo.lightIndex;
|
|
Vector2 viewportSize = spotUpdateInfo.viewportSize;
|
|
HDAdditionalLightDataUpdateInfo updateInfo = additionalLightDataUpdateInfos[additionalLightDataIndex];
|
|
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight,
|
|
0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
}
|
|
}
|
|
|
|
public void UpdateCachedAreaShadowRequestsAndResolutionRequests(NativeList<ShadowRequestIntermediateUpdateData> areaUpdateInfos)
|
|
{
|
|
int areaCount = areaUpdateInfos.Length;
|
|
|
|
for (int i = 0; i < areaCount; i++)
|
|
{
|
|
ref ShadowRequestIntermediateUpdateData areaUpdateInfo = ref areaUpdateInfos.ElementAt(i);
|
|
ref HDShadowCullingSplit newShadowCullingSplit = ref cachedAreaRectangleHDSplits.ElementAt(i);
|
|
bool needToUpdateCachedContent = areaUpdateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent];
|
|
HDShadowRequestHandle shadowRequestHandle = areaUpdateInfo.shadowRequestHandle;
|
|
ref HDShadowRequest shadowRequest = ref requestStorage.ElementAt(shadowRequestHandle.storageIndexForRequestIndex);
|
|
int additionalLightDataIndex = areaUpdateInfo.additionalLightDataIndex;
|
|
int lightIndex = areaUpdateInfo.lightIndex;
|
|
Vector2 viewportSize = areaUpdateInfo.viewportSize;
|
|
VisibleLight visibleLight = visibleLights[lightIndex];
|
|
ShadowMapUpdateType updateType = areaUpdateInfo.updateType;
|
|
bool isSampledFromCache = (updateType == ShadowMapUpdateType.Cached);
|
|
bool needToUpdateDynamicContent = !isSampledFromCache;
|
|
bool hasUpdatedRequestData = false;
|
|
|
|
HDAdditionalLightDataUpdateInfo updateInfo = additionalLightDataUpdateInfos[additionalLightDataIndex];
|
|
if (needToUpdateCachedContent)
|
|
{
|
|
cachedViewPositionsStorage[shadowRequestHandle.storageIndexForCachedViewPosition] = worldSpaceCameraPos;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetAreaRequestSettings(ref shadowRequest, shadowRequestHandle, visibleLight,
|
|
shadowRequest.cullingSplit.forwardOffset, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, shadowManager.areaShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
|
|
hasUpdatedRequestData = true;
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.shouldRenderCachedComponent = true;
|
|
}
|
|
else
|
|
{
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = worldSpaceCameraPos - cachedViewPositionsStorage[shadowRequestHandle.storageIndexForCachedViewPosition];
|
|
shadowRequest.shouldUseCachedShadowData = true;
|
|
shadowRequest.shouldRenderCachedComponent = false;
|
|
}
|
|
|
|
if (needToUpdateDynamicContent && !hasUpdatedRequestData)
|
|
{
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetAreaRequestSettings(ref shadowRequest, shadowRequestHandle, visibleLight,
|
|
shadowRequest.cullingSplit.forwardOffset, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, shadowManager.areaShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateDynamicAreaShadowRequestsAndResolutionRequests(NativeList<ShadowRequestIntermediateUpdateData> areaUpdateInfos)
|
|
{
|
|
int areaCount = areaUpdateInfos.Length;
|
|
|
|
for (int i = 0; i < areaCount; i++)
|
|
{
|
|
ref ShadowRequestIntermediateUpdateData areaUpdateInfo = ref areaUpdateInfos.ElementAt(i);
|
|
ref HDShadowCullingSplit newShadowCullingSplit = ref dynamicAreaRectangleHDSplits.ElementAt(i);
|
|
HDShadowRequestHandle shadowRequestHandle = areaUpdateInfo.shadowRequestHandle;
|
|
ref HDShadowRequest shadowRequest = ref requestStorage.ElementAt(shadowRequestHandle.storageIndexForRequestIndex);
|
|
int additionalLightDataIndex = areaUpdateInfo.additionalLightDataIndex;
|
|
int lightIndex = areaUpdateInfo.lightIndex;
|
|
Vector2 viewportSize = areaUpdateInfo.viewportSize;
|
|
HDAdditionalLightDataUpdateInfo updateInfo = additionalLightDataUpdateInfos[additionalLightDataIndex];
|
|
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.cachedShadowData.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f);
|
|
shadowRequest.cullingSplit = newShadowCullingSplit;
|
|
|
|
HDGpuLightsBuilder.SetAreaRequestSettings(ref shadowRequest, shadowRequestHandle, areaUpdateInfo.visibleLight,
|
|
shadowRequest.cullingSplit.forwardOffset, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize,
|
|
lightIndex, shadowManager.areaShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage);
|
|
}
|
|
}
|
|
|
|
public void UpdateNonDirectionalCachedRequests(LightType lightType,
|
|
HDCachedShadowAtlasDataForShadowRequestUpdateJob cachedShadowAtlas,
|
|
HDDynamicShadowAtlasDataForShadowRequestUpdateJob dynamicShadowAtlas,
|
|
UnsafeList<ShadowIndicesAndVisibleLightData> visibleLightsAndIndices,
|
|
NativeList<ShadowRequestIntermediateUpdateData> updateDataList,
|
|
NativeArray<int> shadowIndices,
|
|
int shadowManagerRequestCount)
|
|
{
|
|
for (int i = 0; i < visibleLightsAndIndices.Length; i++)
|
|
{
|
|
ref ShadowIndicesAndVisibleLightData shadowIndicesAndVisibleLightData = ref visibleLightsAndIndices.ElementAt(i);
|
|
HDShadowRequestSetHandle shadowRequestSetHandle = shadowIndicesAndVisibleLightData.shadowRequestSetHandle;
|
|
ShadowMapUpdateType updateType = shadowIndicesAndVisibleLightData.shadowUpdateType;
|
|
BitArray8 needCacheUpdateMask = shadowIndicesAndVisibleLightData.needCacheUpdateMask;
|
|
int lightIdxForCachedShadows = shadowIndicesAndVisibleLightData.additionalLightUpdateInfo.lightIdxForCachedShadows;
|
|
|
|
// If we force evicted the light, it will have lightIdxForCachedShadows == -1
|
|
bool shadowHasAtlasPlacement = !(cachedShadowAtlas.registeredLightDataPendingPlacement.ContainsKey(lightIdxForCachedShadows) ||
|
|
cachedShadowAtlas.recordsPendingPlacement.ContainsKey(lightIdxForCachedShadows)) && lightIdxForCachedShadows != -1;
|
|
|
|
if (!shadowHasAtlasPlacement)
|
|
shadowIndices[shadowIndicesAndVisibleLightData.sortKeyIndex] = -1;
|
|
|
|
for (int index = 0; index < shadowIndicesAndVisibleLightData.splitCount; index++)
|
|
{
|
|
HDShadowRequestHandle indexHandle = shadowRequestSetHandle[index];
|
|
int shadowRequestIndex = requestIndicesStorage[indexHandle.storageIndexForRequestIndex];
|
|
ref HDShadowResolutionRequest resolutionRequest = ref shadowManager.shadowResolutionRequestStorage.ElementAt(shadowRequestIndex);
|
|
bool needToUpdateCachedContent = needCacheUpdateMask[(uint)index];
|
|
|
|
ref var shadowRequest = ref requestStorage.ElementAt(indexHandle.storageIndexForShadowRequest);
|
|
shadowRequest.isInCachedAtlas = updateType == ShadowMapUpdateType.Cached;
|
|
shadowRequest.isMixedCached = updateType == ShadowMapUpdateType.Mixed;
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.dynamicAtlasViewport = resolutionRequest.dynamicAtlasViewport;
|
|
shadowRequest.cachedAtlasViewport = resolutionRequest.cachedAtlasViewport;
|
|
|
|
int updateDataListIndex = updateDataList.Length;
|
|
updateDataList.Length = updateDataListIndex + 1;
|
|
ref ShadowRequestIntermediateUpdateData updateInfo = ref updateDataList.ElementAt(updateDataListIndex);
|
|
|
|
updateInfo.visibleLight = shadowIndicesAndVisibleLightData.visibleLight;
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_HasCachedComponent] = true;
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent] = needToUpdateCachedContent;
|
|
updateInfo.shadowRequestHandle = shadowRequestSetHandle[index];
|
|
updateInfo.additionalLightDataIndex = shadowIndicesAndVisibleLightData.dataIndex;
|
|
updateInfo.updateType = updateType;
|
|
updateInfo.viewportSize = resolutionRequest.resolution;
|
|
updateInfo.lightIndex = shadowIndicesAndVisibleLightData.lightIndex;
|
|
|
|
if (shadowRequestIndex < shadowManagerRequestCount)
|
|
{
|
|
bool addToCached = updateType == ShadowMapUpdateType.Cached || updateType == ShadowMapUpdateType.Mixed;
|
|
bool addDynamic = updateType == ShadowMapUpdateType.Dynamic || updateType == ShadowMapUpdateType.Mixed;
|
|
HDShadowRequestHandle shadowRequestHandle = shadowRequestSetHandle[index];
|
|
|
|
if (addToCached)
|
|
cachedShadowAtlas.shadowRequests.Add(shadowRequestHandle);
|
|
|
|
if (addDynamic)
|
|
{
|
|
dynamicShadowAtlas.shadowRequests.Add(shadowRequestHandle);
|
|
|
|
if(updateType == ShadowMapUpdateType.Mixed)
|
|
dynamicShadowAtlas.mixedRequestsPendingBlits.Add(shadowRequestHandle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateNonDirectionalDynamicRequests(LightType lightType,
|
|
HDCachedShadowAtlasDataForShadowRequestUpdateJob cachedShadowAtlas,
|
|
HDDynamicShadowAtlasDataForShadowRequestUpdateJob dynamicShadowAtlas,
|
|
UnsafeList<ShadowIndicesAndVisibleLightData> visibleLightsAndIndices,
|
|
NativeList<ShadowRequestIntermediateUpdateData> updateDataList,
|
|
int shadowManagerRequestCount)
|
|
{
|
|
for (int i = 0; i < visibleLightsAndIndices.Length; i++)
|
|
{
|
|
ref ShadowIndicesAndVisibleLightData shadowIndicesAndVisibleLightData = ref visibleLightsAndIndices.ElementAt(i);
|
|
HDShadowRequestSetHandle shadowRequestSetHandle = shadowIndicesAndVisibleLightData.shadowRequestSetHandle;
|
|
|
|
for (int index = 0; index < shadowIndicesAndVisibleLightData.splitCount; index++)
|
|
{
|
|
HDShadowRequestHandle indexHandle = shadowRequestSetHandle[index];
|
|
int shadowRequestIndex = requestIndicesStorage[indexHandle.storageIndexForRequestIndex];
|
|
ref HDShadowResolutionRequest resolutionRequest = ref shadowManager.shadowResolutionRequestStorage.ElementAt(shadowRequestIndex);
|
|
|
|
ref var shadowRequest = ref requestStorage.ElementAt(indexHandle.storageIndexForShadowRequest);
|
|
shadowRequest.isInCachedAtlas = false;
|
|
shadowRequest.isMixedCached = false;
|
|
shadowRequest.shouldUseCachedShadowData = false;
|
|
shadowRequest.dynamicAtlasViewport = resolutionRequest.dynamicAtlasViewport;
|
|
shadowRequest.cachedAtlasViewport = resolutionRequest.cachedAtlasViewport;
|
|
|
|
int updateDataListIndex = updateDataList.Length;
|
|
updateDataList.Length = updateDataListIndex + 1;
|
|
ref ShadowRequestIntermediateUpdateData updateInfo = ref updateDataList.ElementAt(updateDataListIndex);
|
|
|
|
updateInfo.visibleLight = shadowIndicesAndVisibleLightData.visibleLight;
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_HasCachedComponent] = false;
|
|
updateInfo.states[ShadowRequestIntermediateUpdateData.k_NeedToUpdateCachedContent] = false;
|
|
updateInfo.shadowRequestHandle = shadowRequestSetHandle[index];
|
|
updateInfo.additionalLightDataIndex = shadowIndicesAndVisibleLightData.dataIndex;
|
|
updateInfo.updateType = ShadowMapUpdateType.Dynamic;
|
|
updateInfo.viewportSize = resolutionRequest.resolution;
|
|
updateInfo.lightIndex = shadowIndicesAndVisibleLightData.lightIndex;
|
|
|
|
if (shadowRequestIndex < shadowManagerRequestCount)
|
|
dynamicShadowAtlas.shadowRequests.Add(shadowRequestSetHandle[index]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal struct ShadowRequestIntermediateUpdateData
|
|
{
|
|
public VisibleLight visibleLight;
|
|
public HDShadowRequestHandle shadowRequestHandle;
|
|
public int additionalLightDataIndex;
|
|
public Vector2 viewportSize;
|
|
|
|
public int lightIndex;
|
|
|
|
public ShadowMapUpdateType updateType;
|
|
public BitArray8 states;
|
|
|
|
public const int k_HasCachedComponent = 0;
|
|
public const int k_IsSampledFromCache = 1;
|
|
public const int k_NeedsRenderingDueToTransformChange = 2;
|
|
public const int k_ShadowHasAtlasPlacement = 3;
|
|
public const int k_NeedToUpdateCachedContent = 4;
|
|
}
|
|
|
|
internal class ShadowRequestUpdateProfiling
|
|
{
|
|
internal static ProfilerMarker dynamicDirectionalRequestsMarker = new ProfilerMarker("UpdateDynamicDirectionalRequests");
|
|
internal static ProfilerMarker dynamicPointRequestsMarker = new ProfilerMarker("UpdateDynamicPointRequests");
|
|
internal static ProfilerMarker dynamicSpotRequestsMarker = new ProfilerMarker("UpdateDynamicSpotRequests");
|
|
internal static ProfilerMarker dynamicAreaRectangleRequestsMarker = new ProfilerMarker("UpdateDynamicAreaRectangleRequests");
|
|
internal static ProfilerMarker cachedDirectionalRequestsMarker = new ProfilerMarker("UpdateCachedDirectionalRequests");
|
|
internal static ProfilerMarker cachedPointRequestsMarker = new ProfilerMarker("UpdateCachedPointRequests");
|
|
internal static ProfilerMarker cachedSpotRequestsMarker = new ProfilerMarker("UpdateCachedSpotRequests");
|
|
internal static ProfilerMarker cachedAreaRectangleRequestsMarker = new ProfilerMarker("UpdateCachedAreaRectangleRequests");
|
|
}
|
|
}
|