189 lines
5.6 KiB
HLSL
189 lines
5.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved..
|
|
|
|
/*=============================================================================
|
|
InstancedStereo.usf: Resolve which view uniforms in a stereo pair to use.
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
// Explictly include view uniform buffers
|
|
#include "/Engine/Generated/UniformBuffers/View.ush"
|
|
#include "/Engine/Generated/UniformBuffers/InstancedView.ush"
|
|
|
|
// ViewState, GetPrimaryView and GetInstancedView are generated by the shader compiler to ensure View uniform buffer changes are up to date.
|
|
// see GenerateInstancedStereoCode()
|
|
#include "/Engine/Generated/GeneratedInstancedStereo.ush"
|
|
|
|
void FinalizeViewState(inout ViewState InOutView)
|
|
{
|
|
InOutView.WorldToClip = MakeDFInverseMatrix(InOutView.ViewOriginHigh, InOutView.RelativeWorldToClip);
|
|
InOutView.ClipToWorld = MakeDFMatrix(InOutView.ViewOriginHigh, InOutView.ClipToRelativeWorld);
|
|
InOutView.ScreenToWorld = MakeDFMatrix(InOutView.ViewOriginHigh, InOutView.ScreenToRelativeWorld);
|
|
InOutView.PrevClipToWorld = MakeDFMatrix(InOutView.ViewOriginHigh, InOutView.PrevClipToRelativeWorld);
|
|
|
|
InOutView.WorldCameraOrigin = MakeDFVector3(InOutView.ViewOriginHigh, InOutView.ViewOriginLow);
|
|
InOutView.WorldViewOrigin = MakeDFVector3(InOutView.WorldViewOriginHigh, InOutView.WorldViewOriginLow);
|
|
InOutView.PrevWorldCameraOrigin = MakeDFVector3(InOutView.PrevWorldCameraOriginHigh, InOutView.PrevWorldCameraOriginLow);
|
|
InOutView.PrevWorldViewOrigin = MakeDFVector3(InOutView.PrevWorldViewOriginHigh, InOutView.PrevWorldViewOriginLow);
|
|
InOutView.PreViewTranslation = MakeDFVector3(InOutView.PreViewTranslationHigh, InOutView.PreViewTranslationLow);
|
|
InOutView.PrevPreViewTranslation = MakeDFVector3(InOutView.PrevPreViewTranslationHigh, InOutView.PrevPreViewTranslationLow);
|
|
|
|
#if VIEW_HAS_TILEOFFSET_DATA
|
|
InOutView.TileOffset.WorldCameraOrigin = MakeLWCVector3(InOutView.ViewTilePosition, InOutView.RelativeWorldCameraOriginTO);
|
|
InOutView.TileOffset.WorldViewOrigin = MakeLWCVector3(InOutView.ViewTilePosition, InOutView.RelativeWorldViewOriginTO);
|
|
InOutView.TileOffset.PrevWorldCameraOrigin = MakeLWCVector3(InOutView.ViewTilePosition, InOutView.PrevRelativeWorldCameraOriginTO);
|
|
InOutView.TileOffset.PrevWorldViewOrigin = MakeLWCVector3(InOutView.ViewTilePosition, InOutView.PrevRelativeWorldViewOriginTO);
|
|
InOutView.TileOffset.PreViewTranslation = MakeLWCVector3(-InOutView.ViewTilePosition, InOutView.RelativePreViewTranslationTO);
|
|
InOutView.TileOffset.PrevPreViewTranslation = MakeLWCVector3(-InOutView.ViewTilePosition, InOutView.RelativePrevPreViewTranslationTO);
|
|
#endif
|
|
}
|
|
|
|
#define PrimaryView GetPrimaryView()
|
|
|
|
static ViewState ResolvedView = (ViewState)0.0f;
|
|
|
|
ViewState ResolveView()
|
|
{
|
|
return GetPrimaryView();
|
|
}
|
|
|
|
#if (INSTANCED_STEREO || MOBILE_MULTI_VIEW)
|
|
ViewState ResolveView(uint ViewIndex)
|
|
{
|
|
return GetInstancedView(ViewIndex);
|
|
}
|
|
#endif
|
|
|
|
#if INSTANCED_STEREO
|
|
static const float EyeOffsetScale[2] = { -1.0, 1.0 };
|
|
static const float4 EyeClipEdge[2] = { float4(-1.0, 0.0, 0.0, 1.0), float4(1.0, 0.0, 0.0, 1.0) };
|
|
#endif
|
|
|
|
bool IsInstancedStereo()
|
|
{
|
|
#if INSTANCED_STEREO
|
|
return (uint)InstancedView.StereoPassIndex[1] > 0;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
uint GetEyeIndex(uint InstanceId)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
return IsInstancedStereo() ? InstanceId & 1 : 0;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
uint GetInstanceId(uint InstanceId)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
return IsInstancedStereo() ? InstanceId / 2 : InstanceId;
|
|
#else
|
|
return InstanceId;
|
|
#endif
|
|
}
|
|
|
|
#define MOBILE_MULTI_VIEW_FALLBACK (INSTANCED_STEREO && MOBILE_MULTI_VIEW)
|
|
|
|
struct FStereoVSInput
|
|
{
|
|
#if INSTANCED_STEREO
|
|
uint InstanceId : SV_InstanceID;
|
|
#elif MOBILE_MULTI_VIEW
|
|
nointerpolation uint ViewId : SV_ViewID;
|
|
#endif
|
|
};
|
|
|
|
struct FStereoVSToPS
|
|
{
|
|
#if INSTANCED_STEREO
|
|
nointerpolation uint EyeIndex : VIEW_ID;
|
|
#endif
|
|
};
|
|
|
|
struct FStereoVSOutput
|
|
{
|
|
FStereoVSToPS StereoInterpolants;
|
|
#if INSTANCED_STEREO
|
|
#if MOBILE_MULTI_VIEW
|
|
uint TargetIndex : SV_RenderTargetArrayIndex;
|
|
#else
|
|
uint TargetIndex : SV_ViewPortArrayIndex;
|
|
#endif
|
|
#endif
|
|
};
|
|
|
|
struct FStereoPSInput
|
|
{
|
|
#if MOBILE_MULTI_VIEW && !INSTANCED_STEREO
|
|
nointerpolation uint ViewId : SV_ViewID;
|
|
#endif
|
|
FStereoVSToPS StereoInterpolants;
|
|
};
|
|
|
|
void StereoSetupVS(const uint EyeIndex, out FStereoVSOutput Output)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
Output.TargetIndex = EyeIndex;
|
|
Output.StereoInterpolants.EyeIndex = EyeIndex;
|
|
ResolvedView = ResolveView(EyeIndex);
|
|
#elif MOBILE_MULTI_VIEW
|
|
ResolvedView = ResolveView(EyeIndex);
|
|
#else
|
|
ResolvedView = ResolveView();
|
|
#endif
|
|
}
|
|
|
|
void StereoSetupVS(FStereoVSInput StereoInput, out FStereoVSOutput Output)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
StereoSetupVS(GetEyeIndex(StereoInput.InstanceId), Output);
|
|
#elif MOBILE_MULTI_VIEW
|
|
StereoSetupVS(StereoInput.ViewId, Output);
|
|
#else
|
|
StereoSetupVS(0, Output);
|
|
#endif
|
|
}
|
|
|
|
void ScreenPassStereoOutputSetupVS(FStereoVSInput StereoInput, out FStereoVSOutput Output)
|
|
{
|
|
// Screen passes are only drawn twice so the instance id corresponds to the eye index.
|
|
#if INSTANCED_STEREO
|
|
Output.StereoInterpolants.EyeIndex = StereoInput.InstanceId;
|
|
Output.TargetIndex = StereoInput.InstanceId;
|
|
#endif
|
|
}
|
|
|
|
void StereoSetupPS(FStereoPSInput StereoInput)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
ResolvedView = ResolveView(StereoInput.StereoInterpolants.EyeIndex);
|
|
#elif MOBILE_MULTI_VIEW
|
|
ResolvedView = ResolveView(StereoInput.ViewId);
|
|
#else
|
|
ResolvedView = ResolveView();
|
|
#endif
|
|
}
|
|
|
|
void StereoSetupCS(uint EyeIndex = 0)
|
|
{
|
|
#if INSTANCED_STEREO || MOBILE_MULTI_VIEW
|
|
ResolvedView = ResolveView(EyeIndex);
|
|
#else
|
|
ResolvedView = ResolveView();
|
|
#endif
|
|
}
|
|
|
|
uint GetEyeIndex(FStereoPSInput StereoInput)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
return StereoInput.StereoInterpolants.EyeIndex;
|
|
#elif MOBILE_MULTI_VIEW
|
|
return StereoInput.ViewId;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
} |