You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Support velocity for WPO on static objects. Support Optimized WPO on all actors, not just nanite. Optimized WPO now also affects WPO velocity. Moved logic for forcing velocity output to proxy init and removed from view. Update all proxies when force velocity output CVar changes. Used nicer mechanism to update all proxies when CVar changes for r.Velocity.EnableVertexDeformation. Disable bEvaluateWorldPositionOffset UI unless Optimized WPO is enabled. #preflight 6284e958925bbe69dfd26af2 #fyi graham.wihlidal [CL 20268399 by Jeremy Moore in ue5-main branch]
247 lines
11 KiB
Plaintext
247 lines
11 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
BasePassVertexShader.usf: Base pass vertex shader
|
|
=============================================================================*/
|
|
|
|
#include "BasePassVertexCommon.ush"
|
|
#include "SHCommon.ush"
|
|
#include "VolumetricLightmapShared.ush"
|
|
|
|
#if TRANSLUCENCY_PERVERTEX_FORWARD_SHADING
|
|
#include "ReflectionEnvironmentShared.ush"
|
|
#include "ForwardLightingCommon.ush"
|
|
#endif
|
|
|
|
#if NEEDS_BASEPASS_VERTEX_FOGGING && PROJECT_SUPPORT_SKY_ATMOSPHERE
|
|
#include "SkyAtmosphereCommon.ush"
|
|
#endif
|
|
|
|
#if (NEEDS_BASEPASS_VERTEX_FOGGING && MATERIAL_ENABLE_TRANSLUCENCY_CLOUD_FOGGING) || SUPPORT_CLOUD_SHADOW_ON_FORWARD_LIT_TRANSLUCENT
|
|
#include "VolumetricCloudCommon.ush"
|
|
#endif
|
|
|
|
/** Entry point for the base pass vertex shader. */
|
|
void Main(
|
|
FVertexFactoryInput Input,
|
|
out FBasePassVSOutput Output
|
|
#if USE_GLOBAL_CLIP_PLANE
|
|
, out float OutGlobalClipPlaneDistance : SV_ClipDistance
|
|
#endif
|
|
#if INSTANCED_STEREO
|
|
#if !MULTI_VIEW
|
|
, out float OutClipDistance : SV_ClipDistance1
|
|
#else
|
|
, out uint ViewportIndex : SV_ViewPortArrayIndex
|
|
#endif
|
|
#endif
|
|
)
|
|
{
|
|
#if INSTANCED_STEREO
|
|
const uint EyeIndex = GetEyeIndexFromVF(Input);
|
|
#if !MULTI_VIEW
|
|
OutClipDistance = 0.0;
|
|
#else
|
|
ViewportIndex = EyeIndex;
|
|
#endif
|
|
#endif
|
|
ResolvedView = ResolveViewFromVF(Input);
|
|
|
|
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
|
|
float4 WorldPositionExcludingWPO = VertexFactoryGetWorldPosition(Input, VFIntermediates);
|
|
float4 WorldPosition = WorldPositionExcludingWPO;
|
|
float4 ClipSpacePosition;
|
|
|
|
float3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
|
|
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPosition.xyz, TangentToLocal);
|
|
|
|
// Isolate instructions used for world position offset
|
|
// 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.
|
|
{
|
|
WorldPosition.xyz += GetMaterialWorldPositionOffset(VertexParameters);
|
|
}
|
|
|
|
{
|
|
float4 RasterizedWorldPosition = VertexFactoryGetRasterizedWorldPosition(Input, VFIntermediates, WorldPosition);
|
|
#if ODS_CAPTURE
|
|
float3 ODS = OffsetODS(RasterizedWorldPosition.xyz, ResolvedView.TranslatedWorldCameraOrigin.xyz, ResolvedView.StereoIPD);
|
|
ClipSpacePosition = mul(float4(RasterizedWorldPosition.xyz + ODS, 1.0), ResolvedView.TranslatedWorldToClip);
|
|
#else
|
|
ClipSpacePosition = mul(RasterizedWorldPosition, ResolvedView.TranslatedWorldToClip);
|
|
#endif
|
|
Output.Position = INVARIANT(ClipSpacePosition);
|
|
}
|
|
|
|
#if INSTANCED_STEREO && !MULTI_VIEW
|
|
BRANCH
|
|
if (IsInstancedStereo())
|
|
{
|
|
// Clip at the center of the screen
|
|
OutClipDistance = dot(Output.Position, EyeClipEdge[EyeIndex]);
|
|
|
|
// Scale to the width of a single eye viewport
|
|
Output.Position.x *= 0.5 * ResolvedView.HMDEyePaddingOffset;
|
|
|
|
// Shift to the eye viewport
|
|
Output.Position.x += (EyeOffsetScale[EyeIndex] * Output.Position.w) * (1.0f - 0.5 * ResolvedView.HMDEyePaddingOffset);
|
|
}
|
|
#endif
|
|
|
|
#if USE_GLOBAL_CLIP_PLANE
|
|
OutGlobalClipPlaneDistance = dot(ResolvedView.GlobalClippingPlane, float4(WorldPosition.xyz, 1));
|
|
#endif
|
|
#if USE_WORLD_POSITION_EXCLUDING_SHADER_OFFSETS
|
|
Output.BasePassInterpolants.PixelPositionExcludingWPO = WorldPositionExcludingWPO.xyz;
|
|
#endif
|
|
|
|
Output.FactoryInterpolants = VertexFactoryGetInterpolants(Input, VFIntermediates, VertexParameters);
|
|
|
|
#if INSTANCED_STEREO
|
|
Output.FactoryInterpolants.EyeIndex = EyeIndex;
|
|
#endif
|
|
|
|
// Calculate the fog needed for translucency
|
|
#if NEEDS_BASEPASS_VERTEX_FOGGING
|
|
Output.BasePassInterpolants.VertexFog = CalculateHeightFog(WorldPosition.xyz - ResolvedView.TranslatedWorldCameraOrigin);
|
|
|
|
const float OneOverPreExposure = ResolvedView.OneOverPreExposure;
|
|
|
|
#if PROJECT_SUPPORT_SKY_ATMOSPHERE && BASEPASS_SKYATMOSPHERE_AERIALPERSPECTIVE && MATERIAL_IS_SKY==0 // Do not apply aerial perpsective on sky materials
|
|
if (ResolvedView.SkyAtmosphereApplyCameraAerialPerspectiveVolume > 0.0f)
|
|
{
|
|
// Sample the aerial perspective (AP). It is also blended under the VertexFog parameter.
|
|
Output.BasePassInterpolants.VertexFog = GetAerialPerspectiveLuminanceTransmittanceWithFogOver(
|
|
ResolvedView.RealTimeReflectionCapture, ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeSizeAndInvSize,
|
|
Output.Position, (WorldPosition.xyz - ResolvedView.TranslatedWorldCameraOrigin) * CM_TO_SKY_UNIT,
|
|
View.CameraAerialPerspectiveVolume, View.CameraAerialPerspectiveVolumeSampler,
|
|
ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthResolutionInv,
|
|
ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthResolution,
|
|
ResolvedView.SkyAtmosphereAerialPerspectiveStartDepthKm,
|
|
ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthSliceLengthKm,
|
|
ResolvedView.SkyAtmosphereCameraAerialPerspectiveVolumeDepthSliceLengthKmInv,
|
|
OneOverPreExposure, Output.BasePassInterpolants.VertexFog);
|
|
}
|
|
#endif
|
|
|
|
#if MATERIAL_ENABLE_TRANSLUCENCY_CLOUD_FOGGING
|
|
if (TranslucentBasePass.ApplyVolumetricCloudOnTransparent > 0.0f)
|
|
{
|
|
Output.BasePassInterpolants.VertexFog = GetCloudLuminanceTransmittanceOverFog(
|
|
Output.Position, WorldPosition.xyz, ResolvedView.TranslatedWorldCameraOrigin,
|
|
TranslucentBasePass.VolumetricCloudColor, TranslucentBasePass.VolumetricCloudColorSampler,
|
|
TranslucentBasePass.VolumetricCloudDepth, TranslucentBasePass.VolumetricCloudDepthSampler,
|
|
OneOverPreExposure, Output.BasePassInterpolants.VertexFog);
|
|
}
|
|
#endif
|
|
|
|
#endif // NEEDS_BASEPASS_VERTEX_FOGGING
|
|
|
|
#if TRANSLUCENCY_ANY_PERVERTEX_LIGHTING || SUPPORT_CLOUD_SHADOW_ON_FORWARD_LIT_TRANSLUCENT
|
|
float3 WorldPositionForVertexLightingTranslated = VertexFactoryGetPositionForVertexLighting(Input, VFIntermediates, WorldPosition.xyz);
|
|
float3 WorldPositionForVertexLighting = WorldPositionForVertexLightingTranslated - LWCHackToFloat(ResolvedView.PreViewTranslation);
|
|
#endif
|
|
|
|
#if TRANSLUCENCY_PERVERTEX_LIGHTING_VOLUME
|
|
float4 VolumeLighting;
|
|
float3 InterpolatedLighting = 0;
|
|
|
|
float3 InnerVolumeUVs;
|
|
float3 OuterVolumeUVs;
|
|
float FinalLerpFactor;
|
|
|
|
//@todo - get from VF
|
|
float3 LightingPositionOffset = 0;
|
|
ComputeVolumeUVs(WorldPositionForVertexLightingTranslated, LightingPositionOffset, InnerVolumeUVs, OuterVolumeUVs, FinalLerpFactor);
|
|
|
|
#if TRANSLUCENCY_LIGHTING_VOLUMETRIC_PERVERTEX_DIRECTIONAL
|
|
|
|
Output.BasePassInterpolants.AmbientLightingVector = GetAmbientLightingVectorFromTranslucentLightingVolume(InnerVolumeUVs, OuterVolumeUVs, FinalLerpFactor).xyz;
|
|
Output.BasePassInterpolants.DirectionalLightingVector = GetDirectionalLightingVectorFromTranslucentLightingVolume(InnerVolumeUVs, OuterVolumeUVs, FinalLerpFactor);
|
|
|
|
#elif TRANSLUCENCY_LIGHTING_VOLUMETRIC_PERVERTEX_NONDIRECTIONAL
|
|
|
|
Output.BasePassInterpolants.AmbientLightingVector = GetAmbientLightingVectorFromTranslucentLightingVolume(InnerVolumeUVs, OuterVolumeUVs, FinalLerpFactor).xyz;
|
|
|
|
#endif
|
|
#elif TRANSLUCENCY_PERVERTEX_FORWARD_SHADING
|
|
|
|
float4 VertexLightingClipSpacePosition = mul(float4(WorldPositionForVertexLightingTranslated, 1), ResolvedView.TranslatedWorldToClip);
|
|
float2 SvPosition = (VertexLightingClipSpacePosition.xy / VertexLightingClipSpacePosition.w * float2(.5f, -.5f) + .5f) * ResolvedView.ViewSizeAndInvSize.xy;
|
|
uint GridIndex = ComputeLightGridCellIndex((uint2)(SvPosition* View.LightProbeSizeRatioAndInvSizeRatio.zw - ResolvedView.ViewRectMin.xy), VertexLightingClipSpacePosition.w, EyeIndex);
|
|
|
|
float DirectionalLightCloudShadow = 1.0f;
|
|
#if SUPPORT_CLOUD_SHADOW_ON_FORWARD_LIT_TRANSLUCENT
|
|
float OutOpticalDepth = 0.0f;
|
|
if (TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapStrength > 0.0f)
|
|
{
|
|
DirectionalLightCloudShadow = lerp(
|
|
1.0f,
|
|
GetCloudVolumetricShadow(
|
|
WorldPositionForVertexLightingTranslated,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapTranslatedWorldToLightClipMatrix,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapFarDepthKm,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapTexture,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapSampler,
|
|
OutOpticalDepth),
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapStrength);
|
|
}
|
|
#endif
|
|
|
|
Output.BasePassInterpolants.VertexDiffuseLighting = GetForwardDirectLightingForVertexLighting(GridIndex, WorldPositionForVertexLightingTranslated, Output.Position.w, VertexParameters.TangentToWorld[2], EyeIndex, DirectionalLightCloudShadow);
|
|
|
|
#elif NEEDS_BASEPASS_CLOUD_SHADOW_INTERPOLATOR
|
|
|
|
Output.BasePassInterpolants.VertexCloudShadow = 1.0f;
|
|
if (TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapStrength > 0.0f)
|
|
{
|
|
float OutOpticalDepth = 0.0f;
|
|
Output.BasePassInterpolants.VertexCloudShadow = lerp(
|
|
1.0f,
|
|
GetCloudVolumetricShadow(
|
|
WorldPositionForVertexLightingTranslated,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapTranslatedWorldToLightClipMatrix,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapFarDepthKm,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapTexture,
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapSampler,
|
|
OutOpticalDepth),
|
|
TranslucentBasePass.ForwardDirLightCloudShadow.CloudShadowmapStrength);
|
|
}
|
|
|
|
#endif
|
|
|
|
#if PRECOMPUTED_IRRADIANCE_VOLUME_LIGHTING && TRANSLUCENCY_ANY_PERVERTEX_LIGHTING
|
|
float3 BrickTextureUVs = ComputeVolumetricLightmapBrickTextureUVs(WorldPositionForVertexLighting);
|
|
|
|
#if TRANSLUCENCY_LIGHTING_VOLUMETRIC_PERVERTEX_NONDIRECTIONAL
|
|
FOneBandSHVectorRGB IrradianceSH = GetVolumetricLightmapSH1(BrickTextureUVs);
|
|
Output.BasePassInterpolants.VertexIndirectAmbient = float3(IrradianceSH.R.V, IrradianceSH.G.V, IrradianceSH.B.V);
|
|
#elif TRANSLUCENCY_LIGHTING_VOLUMETRIC_PERVERTEX_DIRECTIONAL
|
|
// Need to interpolate directional lighting so we can incorporate a normal in the pixel shader
|
|
FTwoBandSHVectorRGB IrradianceSH = GetVolumetricLightmapSH2(BrickTextureUVs);
|
|
Output.BasePassInterpolants.VertexIndirectSH[0] = IrradianceSH.R.V;
|
|
Output.BasePassInterpolants.VertexIndirectSH[1] = IrradianceSH.G.V;
|
|
Output.BasePassInterpolants.VertexIndirectSH[2] = IrradianceSH.B.V;
|
|
#endif
|
|
#endif
|
|
|
|
#if WRITES_VELOCITY_TO_GBUFFER
|
|
{
|
|
float4 PrevTranslatedWorldPosition = float4(0, 0, 0, 1);
|
|
// Use 'FLATTEN' instead of 'BRANCH' because of nVidia driver compiler bug: see UE-108339 - nVidia is working on a driver side fix right now
|
|
FLATTEN
|
|
if ((GetPrimitiveData(VertexParameters).Flags & PRIMITIVE_SCENE_DATA_FLAG_OUTPUT_VELOCITY) != 0)
|
|
{
|
|
PrevTranslatedWorldPosition = VertexFactoryGetPreviousWorldPosition( Input, VFIntermediates );
|
|
VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, PrevTranslatedWorldPosition.xyz, TangentToLocal);
|
|
PrevTranslatedWorldPosition.xyz += GetMaterialPreviousWorldPositionOffset(VertexParameters);
|
|
|
|
PrevTranslatedWorldPosition = mul(float4(PrevTranslatedWorldPosition.xyz, 1), ResolvedView.PrevTranslatedWorldToClip);
|
|
}
|
|
|
|
// compute the old screen pos with the old world position and the old camera matrix
|
|
Output.BasePassInterpolants.VelocityPrevScreenPosition = INVARIANT(PrevTranslatedWorldPosition);
|
|
}
|
|
#endif // WRITES_VELOCITY_TO_GBUFFER
|
|
}
|