Files
UnrealEngineUWP/Engine/Shaders/Private/BasePassVertexShader.usf
Jeremy Moore e8b5823402 #jira UE-151539
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]
2022-05-18 17:01:25 -04:00

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
}