Files
UnrealEngineUWP/Engine/Shaders/Private/VariableRateShading.usf
steve smith bf5d1a6918 Fix shader name in comments
#jira none
#rb trivial
#rnx

[CL 17361071 by steve smith in ue5-main branch]
2021-08-30 19:20:02 -04:00

170 lines
6.1 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
VariableRateShading.usf
=============================================================================*/
#include "Common.ush"
// Supplied defines:
// SHADING_RATE_1x1 - Shading rate of 1x1
// SHADING_RATE_1x2 - Shading rate of 1x2
// SHADING_RATE_2x1 - Shading rate of 2x1
// SHADING_RATE_2x2 - Shading rate of 2x2
// SHADING_RATE_2x4 - Shading rate of 2x4
// SHADING_RATE_4x2 - Shading rate of 4x2
// SHADING_RATE_4x4 - Shading rate of 4x4
// MAX_COMBINED_SOURCES_IN - Maximum
// SHADING_RATE_TILE_WIDTH - Shading rate tile width
// SHADING_RATE_TILE_HEIGHT - Shading rate tile height
// THREADGROUP_SIZEX - Threadgroup size (X)
// THREADGROUP_SIZEY - Threadgroup size (Y)
// Generated output shading rate attachment.
RWTexture2D<uint> RWOutputTexture;
// Input shading rate sources.
Texture2D<uint> CombineSourceIn_0;
Texture2D<uint> CombineSourceIn_1;
Texture2D<uint> CombineSourceIn_2;
Texture2D<uint> CombineSourceIn_3;
// Horizontal and vertical field of view for the current view.
float2 FieldOfView;
// Center pixel coordinate for the left eye.
float2 LeftEyeCenterPixelXY;
// Center pixel coordinate for the right eye.
float2 RightEyeCenterPixelXY;
// Diagonal of the view in pixels, squared.
float ViewDiagonalSquaredInPixels;
// Cutoff percentage for full-rate shading, fixed foveation (0.0 to 1.0), squared. Outside this range will be shaded at half-rate in x and y.
float FixedFoveationFullRateCutoffSquared;
// Cutoff percentage for half-rate shading, fixed foveation (0.0 to 1.0), squared. Outside this range will be shaded at quarter-rate in x and y.
float FixedFoveationHalfRateCutoffSquared;
// Number of (optional) extra shading rate sources that we'll pull in to generate the final attachment.
uint CombineSourceCount;
// Bitfield indicating optional supporting things (defined in the EVRSGenerationFlags enum:)
// EVRSGenerationFlags::None = 0x0,
// EVRSGenerationFlags::StereoRendering = 0x1,
// EVRSGenerationFlags::SideBySideStereo = 0x2,
// EVRSGenerationFlags::HMDFixedFoveation = 0x4,
// EVRSGenerationFlags::HMDEyeTrackedFoveation = 0x8,
uint ShadingRateAttachmentGenerationFlags;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the shading rate based on foveation (either fixed (distortion-based) or eye-tracked
// FOV based).
////////////////////////////////////////////////////////////////////////////////////////////////////
uint GetFoveationShadingRate(float FractionalOffset, float FullCutoffSquared, float HalfCutoffSquared)
{
if (FractionalOffset > HalfCutoffSquared)
{
return SHADING_RATE_4x4;
}
if (FractionalOffset > FullCutoffSquared)
{
return SHADING_RATE_2x2;
}
return SHADING_RATE_1x1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the fractional offset of the pixel coordinate from the center of the eye-view target
// 0.0 = center of view.
// 1.0 = diagonal far edge of view.
////////////////////////////////////////////////////////////////////////////////////////////////////
float GetFractionalOffsetFromEyeOrigin(float2 PixelPosition)
{
if ((ShadingRateAttachmentGenerationFlags & SIDE_BY_SIDE_STEREO) != 0)
{
const float2 VecToLeft = PixelPosition - LeftEyeCenterPixelXY;
const float2 VecToRight = PixelPosition - RightEyeCenterPixelXY;
return min(dot(VecToLeft, VecToLeft), dot(VecToRight, VecToRight)) / ViewDiagonalSquaredInPixels;
}
else
{
// Single eye, just return this case.
const float2 Vec = PixelPosition - LeftEyeCenterPixelXY;
return dot(Vec, Vec) / ViewDiagonalSquaredInPixels;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the shading rate at the specified pixel position, for HMD-based fixed foveation.
////////////////////////////////////////////////////////////////////////////////////////////////////
uint GetFixedFoveationRate(uint2 PixelPositionIn)
{
const float2 PixelPosition = float2((float)PixelPositionIn.x, (float)PixelPositionIn.y);
const float FractionalOffset = GetFractionalOffsetFromEyeOrigin(PixelPosition);
return GetFoveationShadingRate(FractionalOffset, FixedFoveationFullRateCutoffSquared, FixedFoveationHalfRateCutoffSquared);
}
uint GetEyetrackedFoveationRate(uint2 PixelPositionIn)
{
// @todo
return SHADING_RATE_1x1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Return the ideal combination of two specified shading rate values.
////////////////////////////////////////////////////////////////////////////////////////////////////
uint CombineShadingRates(uint Rate1, uint Rate2)
{
// @todo: Right now just apply the max, but possibly break out rates in X and Y and do something smarter?
return max(Rate1, Rate2);
}
[numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, 1)]
void GenerateShadingRateTexture(uint3 DispatchThreadId : SV_DispatchThreadID)
{
const uint2 TexelCoord = DispatchThreadId.xy;
uint ShadingRateOut = 0;
#if 0 // Disable for now since this breaks GLES 3_1 ("sampler arrays indexed with non-constant expressions is forbidden in GLSL 1.30 and later") and is currently unused anyway.
Texture2D<uint> CombineSourceIn[] =
{
CombineSourceIn_0,
#if MAX_COMBINED_SOURCES_IN > 1
CombineSourceIn_1,
#endif
#if MAX_COMBINED_SOURCES_IN > 2
CombineSourceIn_2,
#endif
#if MAX_COMBINED_SOURCES_IN > 3
CombineSourceIn_3,
#endif
};
for (uint Source = 0; Source < CombineSourceCount; ++Source)
{
ShadingRateOut = CombineShadingRates(ShadingRateOut, CombineSourceIn[Source][TexelCoord]);
}
#endif
if ((ShadingRateAttachmentGenerationFlags & HMD_FIXED_FOVEATION) != 0)
{
ShadingRateOut = CombineShadingRates(ShadingRateOut, GetFixedFoveationRate(TexelCoord));
}
if ((ShadingRateAttachmentGenerationFlags & HMD_EYETRACKED_FOVEATION) != 0)
{
ShadingRateOut = CombineShadingRates(ShadingRateOut, GetEyetrackedFoveationRate(TexelCoord));
}
// Conservative combination, just return the max of the two.
RWOutputTexture[TexelCoord] = ShadingRateOut;
}