Files
UnrealEngine/Engine/Shaders/Private/ViewData.ush
2025-05-18 13:04:45 +08:00

140 lines
4.0 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Common.ush"
#include "WaveOpUtil.ush"
#include "/Engine/Shared/ViewDefinitions.h"
// define the default access mode to be via the Scene UB
#ifndef VIEW_DATA_ACCESS_MODE
#define VIEW_DATA_ACCESS_MODE VIEW_DATA_ACCESS_SCENE_UB
#endif
// API for shaders that modify the view data.
#if VIEW_DATA_ACCESS_MODE == VIEW_DATA_ACCESS_RW
int MaxPersistentViewId;
uint InstanceMaskWordStride;
uint NumSceneRendererPrimaryViews;
RWStructuredBuffer<uint> OutDeformingInstanceViewMask;
StructuredBuffer<int> PersistentIdToIndexMap;
void MarkInstanceAsDeforming(uint InstanceId, uint ViewIndex)
{
uint Mask = 1u << (InstanceId % 32u);
uint MaskWordOffset = InstanceId / 32u;
// Mark for the particular view
InterlockedOr(OutDeformingInstanceViewMask[(InstanceMaskWordStride * ViewIndex) + MaskWordOffset], Mask);
}
void MarkInstanceAsDeformingWithViewMask(uint InstanceId, uint ViewMask)
{
uint Mask = 1u << (InstanceId % 32u);
uint MaskWordOffset = InstanceId / 32u;
if (ViewMask != 0u)
{
// Mark for the view in the mask
for (uint ViewIndex = 0u; ViewIndex < NumSceneRendererPrimaryViews; ++ViewIndex)
{
if (((1u << ViewIndex) & ViewMask) != 0u)
{
InterlockedOr(OutDeformingInstanceViewMask[(InstanceMaskWordStride * ViewIndex) + MaskWordOffset], Mask);
}
}
}
}
#endif
struct FViewData
{
int MaxPersistentViewId;
uint InstanceMaskWordStride;
uint NumSceneRendererPrimaryViews;
};
FViewData GetViewData()
{
FViewData ViewData;
#if VIEW_DATA_ACCESS_MODE == VIEW_DATA_ACCESS_RW
ViewData.MaxPersistentViewId = MaxPersistentViewId;
ViewData.InstanceMaskWordStride = InstanceMaskWordStride;
ViewData.NumSceneRendererPrimaryViews = NumSceneRendererPrimaryViews;
#else
ViewData.MaxPersistentViewId = Scene.ViewData.MaxPersistentViewId;
ViewData.InstanceMaskWordStride = Scene.ViewData.InstanceMaskWordStride;
ViewData.NumSceneRendererPrimaryViews = Scene.ViewData.NumSceneRendererPrimaryViews;
#endif
return ViewData;
}
/**
* Returns a 32-bit word with instance-deforming flags for 32 consecutive instances starting from InstanceId = MaskWordOffset * 32
*/
uint LoadInstanceDeformingWord(uint MaskWordOffset, int ViewIndex)
{
uint BaseOffset = ViewIndex * GetViewData().InstanceMaskWordStride;
#if VIEW_DATA_ACCESS_MODE == VIEW_DATA_ACCESS_RW
return OutDeformingInstanceViewMask[BaseOffset + MaskWordOffset];
#else // VIEW_DATA_ACCESS_SCENE_UB
return Scene.ViewData.DeformingInstanceViewMask[BaseOffset + MaskWordOffset];
#endif
}
/**
* Returns true if the instance is marked as deforming.
*/
bool IsInstanceDeforming(uint InstanceId, int SceneRendererPrimaryViewId)
{
uint Mask = 1u << (InstanceId % 32u);
uint MaskWordOffset = InstanceId / 32u;
return (LoadInstanceDeformingWord(MaskWordOffset, SceneRendererPrimaryViewId) & Mask) != 0u;
}
/**
* Map a persistent view ID to a current SceneRendererPrimaryViewId, returns -1 if the view is not current (part of the ongoing scenerenderer)
*/
int RemapPersisitentViewId(int PersistentViewId)
{
if (PersistentViewId < GetViewData().MaxPersistentViewId)
{
#if VIEW_DATA_ACCESS_MODE == VIEW_DATA_ACCESS_RW
return int(PersistentIdToIndexMap[PersistentViewId]) - 1;
#else
return int(Scene.ViewData.PersistentIdToIndexMap[PersistentViewId]) - 1;
#endif
}
return -1;
}
/**
*/
struct FInstanceViewData
{
bool bIsValid;
bool bIsDeforming;
// Convenience / derived data
uint InstanceId;
int SceneRendererPrimaryViewId;
};
FInstanceViewData GetInstanceViewData(uint InstanceId, int SceneRendererPrimaryViewId)
{
checkSlow(SceneRendererPrimaryViewId < GetViewData().NumSceneRendererPrimaryViews && SceneRendererPrimaryViewId >= 0);
FInstanceViewData InstanceViewData;
// Convenience / derived data
InstanceViewData.SceneRendererPrimaryViewId = SceneRendererPrimaryViewId;
InstanceViewData.InstanceId = InstanceId;
InstanceViewData.bIsValid = true;
InstanceViewData.bIsDeforming = IsInstanceDeforming(InstanceId, SceneRendererPrimaryViewId);
return InstanceViewData;
}