You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
301 lines
8.2 KiB
Plaintext
301 lines
8.2 KiB
Plaintext
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
ShadowDepthVertexShader.usf: Vertex shader for writing shadow depth.
|
|
=============================================================================*/
|
|
|
|
// needs to before Common.usf
|
|
#define SHADOW_DEPTH_SHADER 1
|
|
|
|
#include "Common.usf"
|
|
#include "Material.usf"
|
|
#include "VertexFactory.usf"
|
|
#include "ShadowDepthCommon.usf"
|
|
|
|
float4x4 ProjectionMatrix;
|
|
|
|
//@todo - make this a bool, bool shader parameters currently do not work in vertex shaders on Xbox 360 (TTP 125134)
|
|
float bClampToNearPlane;
|
|
|
|
void SetShadowDepthOutputs(float4 WorldPosition, out float4 OutPosition, out float ShadowDepth)
|
|
{
|
|
OutPosition = mul(WorldPosition, ProjectionMatrix);
|
|
|
|
// Clamp the vertex to the near plane if it is in front of the near plane
|
|
// This has problems if some vertices of a triangle get clamped and others do not, also causes artifacts with non-ortho projections
|
|
if (bClampToNearPlane && OutPosition.z < 0)
|
|
{
|
|
OutPosition.z = 0.000001f;
|
|
OutPosition.w = 1.0f;
|
|
}
|
|
|
|
#if PERSPECTIVE_CORRECT_DEPTH
|
|
ShadowDepth = OutPosition.z;
|
|
#else
|
|
float DepthBias = ShadowParams.x;
|
|
float InvMaxSubjectDepth = ShadowParams.y;
|
|
|
|
// Output linear, normalized depth
|
|
ShadowDepth = OutPosition.z * InvMaxSubjectDepth + DepthBias;
|
|
OutPosition.z = ShadowDepth * OutPosition.w;
|
|
#endif
|
|
}
|
|
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4 && ONEPASS_POINTLIGHT_SHADOW
|
|
|
|
/** View projection matrix for each cube map face. */
|
|
float4x4 ShadowViewProjectionMatrices[6];
|
|
/** Flag indicating which faces of the cube map the object is visible to. This just needs 6 bits, but there's no int parameter type yet. */
|
|
float4 MeshVisibleToFace[6];
|
|
|
|
#define FPassSpecificVSToGS FShadowDepthVSToPS
|
|
|
|
struct FShadowDepthGSToPS
|
|
{
|
|
#if INTERPOLATE_VF_ATTRIBUTES
|
|
FShadowDepthVSToPS PSInputs;
|
|
#endif
|
|
float4 OutPosition : SV_POSITION;
|
|
|
|
/** Controls which of the cube map faces to rasterize the primitive to, only the value from the first vertex is used. */
|
|
uint RTIndex : SV_RenderTargetArrayIndex;
|
|
};
|
|
|
|
/** Allocate space for cloning to all 6 faces which is the worst case. */
|
|
[maxvertexcount(18)]
|
|
void MainOnePassPointLightGS(triangle FPassSpecificVSToGS Input[3], inout TriangleStream<FShadowDepthGSToPS> OutStream)
|
|
{
|
|
UNROLL
|
|
// Clone the triangle to each face
|
|
for (int CubeFaceIndex = 0; CubeFaceIndex < 6; CubeFaceIndex++)
|
|
{
|
|
BRANCH
|
|
// Skip this cube face if the object is not visible to it
|
|
if (MeshVisibleToFace[CubeFaceIndex].x > 0)
|
|
{
|
|
float4 ClipSpacePositions[3];
|
|
UNROLL
|
|
for (int VertexIndex = 0; VertexIndex < 3; VertexIndex++)
|
|
{
|
|
// Calculate the clip space position for each cube face
|
|
ClipSpacePositions[VertexIndex] = mul(Input[VertexIndex].GSPosition, ShadowViewProjectionMatrices[CubeFaceIndex]);
|
|
}
|
|
|
|
float4 FrustumTests0 = saturate(ClipSpacePositions[0].xyxy * float4(-1, -1, 1, 1) - ClipSpacePositions[0].w);
|
|
float4 FrustumTests1 = saturate(ClipSpacePositions[1].xyxy * float4(-1, -1, 1, 1) - ClipSpacePositions[1].w);
|
|
float4 FrustumTests2 = saturate(ClipSpacePositions[2].xyxy * float4(-1, -1, 1, 1) - ClipSpacePositions[2].w);
|
|
float4 FrustumTests = FrustumTests0 * FrustumTests1 * FrustumTests2;
|
|
|
|
BRANCH
|
|
// Frustum culling, saves GPU time with high poly meshes
|
|
if (!any(FrustumTests != 0))
|
|
{
|
|
FShadowDepthGSToPS Output;
|
|
Output.RTIndex = CubeFaceIndex;
|
|
|
|
UNROLL
|
|
for (int VertexIndex = 0; VertexIndex < 3; VertexIndex++)
|
|
{
|
|
Output.OutPosition = ClipSpacePositions[VertexIndex];
|
|
|
|
#if INTERPOLATE_VF_ATTRIBUTES
|
|
Output.PSInputs.FactoryInterpolants = Input[VertexIndex].FactoryInterpolants;
|
|
Output.PSInputs.GSPosition = Output.OutPosition;
|
|
#endif
|
|
|
|
#if INTERPOLATE_POSITION
|
|
Output.PSInputs.PixelPosition = Input[VertexIndex].GSPosition;
|
|
#endif
|
|
OutStream.Append(Output);
|
|
}
|
|
OutStream.RestartStrip();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
#if USING_TESSELLATION
|
|
|
|
struct FShadowDepthVSToDS
|
|
{
|
|
FVertexFactoryInterpolantsVSToDS FactoryInterpolants;
|
|
float4 Position : VS_to_DS_Position;
|
|
OPTIONAL_VertexID_VS_To_DS
|
|
};
|
|
|
|
struct FShadowDepthDSToPS : FShadowDepthVSToPS
|
|
{
|
|
float4 Position : SV_POSITION;
|
|
};
|
|
|
|
#define FPassSpecificVSToDS FShadowDepthVSToDS
|
|
#define FPassSpecificVSToPS FShadowDepthDSToPS
|
|
|
|
FShadowDepthVSToDS PassInterpolate(FShadowDepthVSToDS a, float aInterp, FShadowDepthVSToDS b, float bInterp)
|
|
{
|
|
FShadowDepthVSToDS O;
|
|
O.FactoryInterpolants = VertexFactoryInterpolate(a.FactoryInterpolants, aInterp, b.FactoryInterpolants, bInterp);
|
|
return O;
|
|
}
|
|
|
|
FShadowDepthDSToPS PassFinalizeTessellationOutput(FShadowDepthVSToDS Interpolants, float4 WorldPosition, FMaterialTessellationParameters MaterialParameters)
|
|
{
|
|
FShadowDepthDSToPS O;
|
|
|
|
#if INTERPOLATE_VF_ATTRIBUTES
|
|
O.FactoryInterpolants = VertexFactoryAssignInterpolants(Interpolants.FactoryInterpolants);
|
|
#endif
|
|
|
|
|
|
#if ONEPASS_POINTLIGHT_SHADOW
|
|
O.Position = O.GSPosition = WorldPosition;
|
|
#else
|
|
|
|
float ShadowDepth;
|
|
SetShadowDepthOutputs(
|
|
WorldPosition,
|
|
O.Position,
|
|
#if PERSPECTIVE_CORRECT_DEPTH
|
|
O.ShadowDepth
|
|
#else
|
|
ShadowDepth
|
|
#endif
|
|
);
|
|
#endif
|
|
|
|
#if !(ONEPASS_POINTLIGHT_SHADOW || PERSPECTIVE_CORRECT_DEPTH) && COMPILER_SUPPORTS_EMPTY_STRUCTS
|
|
O.Dummy = 0;
|
|
#endif
|
|
|
|
return O;
|
|
}
|
|
|
|
#include "Tessellation.usf"
|
|
|
|
#endif // #if USING_TESSELLATION
|
|
|
|
void Main(
|
|
FVertexFactoryInput Input,
|
|
#if USING_TESSELLATION
|
|
out FShadowDepthVSToDS OutParameters,
|
|
#else
|
|
out FShadowDepthVSToPS OutParameters,
|
|
#endif
|
|
OPTIONAL_VertexID
|
|
out float4 OutPosition : SV_POSITION
|
|
)
|
|
{
|
|
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
|
|
float4 WorldPos = VertexFactoryGetWorldPosition(Input, VFIntermediates);
|
|
float3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
|
|
|
|
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPos.xyz, TangentToLocal);
|
|
WorldPos.xyz += GetMaterialWorldPositionOffset(VertexParameters);
|
|
|
|
#if USING_TESSELLATION
|
|
OutPosition = OutParameters.Position = WorldPos;
|
|
|
|
// Tessellated materials need vertex coords for displacement
|
|
OutParameters.FactoryInterpolants = VertexFactoryGetInterpolantsVSToDS(Input, VFIntermediates, VertexParameters);
|
|
|
|
#elif ONEPASS_POINTLIGHT_SHADOW
|
|
|
|
OutPosition = OutParameters.GSPosition = WorldPos;
|
|
|
|
#if INTERPOLATE_VF_ATTRIBUTES
|
|
// Masked materials need texture coords to clip
|
|
OutParameters.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters);
|
|
#endif
|
|
|
|
#if INTERPOLATE_POSITION
|
|
OutParameters.PixelPosition = WorldPos;
|
|
#endif
|
|
|
|
#else
|
|
float Dummy;
|
|
|
|
SetShadowDepthOutputs(
|
|
WorldPos,
|
|
OutPosition,
|
|
#if !PERSPECTIVE_CORRECT_DEPTH
|
|
Dummy
|
|
#else
|
|
OutParameters.ShadowDepth
|
|
#endif
|
|
);
|
|
|
|
#if INTERPOLATE_VF_ATTRIBUTES
|
|
// Masked materials need texture coords to clip
|
|
OutParameters.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters);
|
|
|
|
#if INTERPOLATE_POSITION
|
|
OutParameters.PixelPosition = WorldPos;
|
|
#endif
|
|
#endif
|
|
|
|
#if !PERSPECTIVE_CORRECT_DEPTH && !COMPILER_SUPPORTS_EMPTY_STRUCTS
|
|
OutParameters.Dummy = 0;
|
|
#endif
|
|
#endif
|
|
|
|
OutputVertexID( OutParameters );
|
|
}
|
|
|
|
void MainForGS(
|
|
FVertexFactoryInput Input,
|
|
#if USING_TESSELLATION
|
|
out FShadowDepthVSToDS OutParameters,
|
|
#else
|
|
out FShadowDepthVSToPS OutParameters,
|
|
#endif
|
|
OPTIONAL_VertexID
|
|
out float4 OutPosition : SV_POSITION
|
|
)
|
|
{
|
|
Main(Input,
|
|
OutParameters,
|
|
OPTIONAL_VertexID_PARAM
|
|
OutPosition);
|
|
}
|
|
|
|
|
|
#if POSITION_ONLY
|
|
void PositionOnlyMain(
|
|
in FPositionOnlyVertexFactoryInput Input,
|
|
out FShadowDepthVSToPS OutParameters,
|
|
out float4 OutPosition : SV_POSITION
|
|
)
|
|
{
|
|
float4 WorldPos = VertexFactoryGetWorldPosition(Input);
|
|
|
|
#if ONEPASS_POINTLIGHT_SHADOW
|
|
OutPosition = OutParameters.GSPosition = WorldPos;
|
|
#else // #if ONEPASS_POINTLIGHT_SHADOW
|
|
float ShadowDepth;
|
|
SetShadowDepthOutputs(WorldPos,OutPosition,ShadowDepth);
|
|
#if PERSPECTIVE_CORRECT_DEPTH
|
|
OutParameters.ShadowDepth = ShadowDepth;
|
|
#elif !COMPILER_SUPPORTS_EMPTY_STRUCTS
|
|
OutParameters.Dummy = 0;
|
|
#endif
|
|
#endif // #if ONEPASS_POINTLIGHT_SHADOW
|
|
|
|
#if INTERPOLATE_POSITION
|
|
OutputParameters.PixelPosition = WorldPos;
|
|
#endif
|
|
}
|
|
|
|
|
|
void PositionOnlyMainForGS(
|
|
in FPositionOnlyVertexFactoryInput Input,
|
|
out FShadowDepthVSToPS OutParameters,
|
|
out float4 OutPosition : SV_POSITION
|
|
)
|
|
{
|
|
PositionOnlyMain(Input, OutParameters, OutPosition);
|
|
}
|
|
|
|
#endif
|