186 lines
7.5 KiB
HLSL
186 lines
7.5 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
VelocityShader.usf: Calculates velocity vectors.
|
|
=============================================================================*/
|
|
|
|
#include "Common.ush"
|
|
#include "/Engine/Generated/Material.ush"
|
|
#include "/Engine/Generated/VertexFactory.ush"
|
|
#include "VelocityCommon.ush"
|
|
|
|
// Move all geometry a little bit towards the camera to not get z fighting with existing depth
|
|
// buffer of the same meshes rendered with slightly different float computations.
|
|
// This is a positive number as our z buffer is inverted for better precision.
|
|
|
|
// 0.0f as the isolate code should do a good job to prevent this case (can be increased if that is not the case e.g. if the platform ignores the isolate)
|
|
static const float GDepthBias = 0.001f;
|
|
|
|
struct FVelocityInterpsVSToPS
|
|
{
|
|
#if !TRANSLUCENCY_VELOCITY_FROM_DEPTH
|
|
// float4(PrevScreenPos.xyzw)
|
|
float4 PackedVelocityC : TEXCOORD7;
|
|
#endif
|
|
FVertexFactoryInterpolantsVSToPS FactoryInterpolants;
|
|
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS && !IS_NANITE_PASS
|
|
float3 PixelPositionExcludingWPO : TEXCOORD8;
|
|
#endif
|
|
};
|
|
|
|
struct FVelocityVSToPS
|
|
{
|
|
INVARIANT_OUTPUT float4 Position : SV_POSITION;
|
|
FVelocityInterpsVSToPS Interps;
|
|
FStereoVSOutput StereoOutput;
|
|
};
|
|
|
|
#define FVertexOutput FVelocityVSToPS
|
|
#define VertexFactoryGetInterpolants VertexFactoryGetInterpolantsVSToPS
|
|
|
|
/*=============================================================================
|
|
* Vertex Shader
|
|
*============================================================================*/
|
|
#if VERTEXSHADER
|
|
void MainVertexShader(
|
|
FVertexFactoryInput Input,
|
|
out FVertexOutput Output
|
|
#if USE_GLOBAL_CLIP_PLANE
|
|
, out float OutGlobalClipPlaneDistance : SV_ClipDistance
|
|
#endif
|
|
)
|
|
{
|
|
StereoSetupVF(Input, Output.StereoOutput);
|
|
|
|
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
|
|
float4 TranslatedWorldPosition = VertexFactoryGetWorldPosition( Input, VFIntermediates );
|
|
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS && !IS_NANITE_PASS
|
|
Output.Interps.PixelPositionExcludingWPO = TranslatedWorldPosition.xyz;
|
|
#endif
|
|
half3x3 TangentToLocal = VertexFactoryGetTangentToLocal( Input, VFIntermediates );
|
|
|
|
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, TranslatedWorldPosition.xyz, TangentToLocal);
|
|
// Isolate instructions used for world position offset on xbox 360,
|
|
// As these cause the optimizer to generate different position calculating instructions in each pass, resulting in self-z-fighting.
|
|
// This is only necessary for shaders used in passes that have depth testing enabled.
|
|
{
|
|
TranslatedWorldPosition.xyz += GetMaterialWorldPositionOffset(VertexParameters);
|
|
ApplyMaterialFirstPersonTransform(VertexParameters, TranslatedWorldPosition.xyz);
|
|
}
|
|
|
|
Output.Interps.FactoryInterpolants = VertexFactoryGetInterpolants( Input, VFIntermediates, VertexParameters );
|
|
|
|
float4 PrevTranslatedWorldPosition = VertexFactoryGetPreviousWorldPosition( Input, VFIntermediates );
|
|
VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, PrevTranslatedWorldPosition.xyz, TangentToLocal, true);
|
|
PrevTranslatedWorldPosition.xyz += GetMaterialPreviousWorldPositionOffset(VertexParameters);
|
|
ApplyMaterialPreviousFirstPersonTransform(VertexParameters, PrevTranslatedWorldPosition.xyz);
|
|
|
|
{
|
|
// compute the old screen pos with the old world position and the old camera matrix
|
|
float4 PrevScreenPosObj = mul(float4(PrevTranslatedWorldPosition.xyz, 1), ResolvedView.PrevTranslatedWorldToClip);
|
|
Output.Position = INVARIANT(mul(float4(TranslatedWorldPosition.xyz, 1), ResolvedView.TranslatedWorldToClip));
|
|
|
|
#if USE_GLOBAL_CLIP_PLANE
|
|
OutGlobalClipPlaneDistance = dot(ResolvedView.GlobalClippingPlane, float4(TranslatedWorldPosition.xyz, 1));
|
|
#endif
|
|
|
|
#if !TRANSLUCENCY_VELOCITY_FROM_DEPTH
|
|
Output.Interps.PackedVelocityC = INVARIANT(PrevScreenPosObj);
|
|
#endif
|
|
}
|
|
|
|
// Move all geometry a little bit towards the camera (to not get z fighting with existing zbuffer of the same meshes rendered with slightly different float computations).
|
|
Output.Position.z += View.NumSceneColorMSAASamples > 1 ? GDepthBias * Output.Position.w : 0.0;
|
|
#if !TRANSLUCENCY_VELOCITY_FROM_DEPTH
|
|
Output.Interps.PackedVelocityC.z += View.NumSceneColorMSAASamples > 1 ? GDepthBias * Output.Position.w : 0.0;
|
|
#endif
|
|
}
|
|
#endif // VERTEXSHADER
|
|
|
|
/*=============================================================================
|
|
* Pixel Shader
|
|
*============================================================================*/
|
|
|
|
#ifndef VELOCITY_THIN_TRANSLUCENT_MODE
|
|
#define VELOCITY_THIN_TRANSLUCENT_MODE 0
|
|
#endif
|
|
|
|
void MainPixelShader(
|
|
in INPUT_POSITION_QUALIFIERS float4 SvPosition : SV_Position,
|
|
FVelocityInterpsVSToPS Input,
|
|
FStereoPSInput StereoInput
|
|
OPTIONAL_IsFrontFace
|
|
OPTIONAL_OutDepthConservative
|
|
|
|
,out ENCODED_VELOCITY_TYPE OutColor : SV_Target0
|
|
#if MATERIALBLENDING_MASKED_USING_COVERAGE
|
|
, out uint OutCoverage : SV_Coverage
|
|
#endif
|
|
)
|
|
{
|
|
StereoSetupPS(StereoInput);
|
|
|
|
// Manual clipping here (alpha-test, etc)
|
|
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Input.FactoryInterpolants, SvPosition);
|
|
FPixelMaterialInputs PixelMaterialInputs;
|
|
|
|
float4 ScreenPosition = SvPositionToResolvedScreenPosition(SvPosition);
|
|
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS && !IS_NANITE_PASS
|
|
float3 TranslatedWorldPosition = SvPositionToResolvedTranslatedWorld(SvPosition);
|
|
CalcMaterialParametersEx(MaterialParameters, PixelMaterialInputs, SvPosition, ScreenPosition, bIsFrontFace, TranslatedWorldPosition, Input.PixelPositionExcludingWPO);
|
|
#else
|
|
CalcMaterialParameters(MaterialParameters, PixelMaterialInputs, SvPosition, bIsFrontFace);
|
|
#endif
|
|
|
|
#if OUTPUT_PIXEL_DEPTH_OFFSET
|
|
ApplyPixelDepthOffsetToMaterialParameters(MaterialParameters, PixelMaterialInputs, OutDepth);
|
|
|
|
#if APPLE_DEPTH_BIAS_HACK
|
|
OutDepth -= APPLE_DEPTH_BIAS_VALUE;
|
|
#endif
|
|
#endif
|
|
|
|
#if MATERIALBLENDING_MASKED_USING_COVERAGE
|
|
OutCoverage = DiscardMaterialWithPixelCoverage(MaterialParameters, PixelMaterialInputs);
|
|
#else
|
|
|
|
#if SUBSTRATE_ENABLED
|
|
const bool bThinTranslucentMaterial = false;
|
|
|
|
FSubstrateData SubstrateData = PixelMaterialInputs.GetFrontSubstrateData();
|
|
FSubstratePixelHeader SubstratePixelHeader = MaterialParameters.GetFrontSubstrateHeader();
|
|
|
|
float MaterialOpacity = 1.0f;
|
|
if (SubstratePixelHeader.ClosureCount > 0)
|
|
{
|
|
// Update tree (coverage/transmittance/luminace weights)
|
|
const FSubstrateIntegrationSettings Settings = InitSubstrateIntegrationSettings();
|
|
const float3 V = MaterialParameters.CameraVector;
|
|
SubstratePixelHeader.SubstrateUpdateTree(V, Settings);
|
|
|
|
MaterialOpacity = SubstratePixelHeader.SubstrateTree.Operators[SubstrateData.OperatorIndex].Coverage;
|
|
}
|
|
|
|
#if SUBSTRATE_USE_PREMULTALPHA_OVERRIDE // AlphaComposite - Premultiplied alpha blending
|
|
MaterialOpacity = GetMaterialOpacity(PixelMaterialInputs);
|
|
#endif
|
|
|
|
#else
|
|
const bool bThinTranslucentMaterial = VELOCITY_THIN_TRANSLUCENT_MODE > 0;
|
|
const float MaterialOpacity = GetMaterialOpacity(PixelMaterialInputs);
|
|
#endif
|
|
|
|
GetMaterialClippingVelocity(MaterialParameters, PixelMaterialInputs, bThinTranslucentMaterial, MaterialOpacity);
|
|
#endif
|
|
|
|
#if !TRANSLUCENCY_VELOCITY_FROM_DEPTH
|
|
// 3d velocity, includes camera an object motion
|
|
float3 Velocity = Calculate3DVelocity(ScreenPosition, Input.PackedVelocityC);
|
|
|
|
OutColor = EncodeVelocityToTexture(Velocity, (GetPrimitiveData(MaterialParameters).Flags & PRIMITIVE_SCENE_DATA_FLAG_HAS_PIXEL_ANIMATION) != 0);
|
|
#else
|
|
// We only want velocity generated from camera movement and depth so write zero which is the special clear color value.
|
|
OutColor = 0;
|
|
#endif
|
|
}
|