541 lines
18 KiB
HLSL
541 lines
18 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
GeometryCacheVertexFactory.hlsl: Vertex factory for geometry caches (supports motion blur data)
|
|
=============================================================================*/
|
|
|
|
|
|
#include "VertexFactoryCommon.ush"
|
|
|
|
/*
|
|
Meshes vertices can optionally still be packed and will be unpacked using the following formula:
|
|
VertextBuffer.Position*MeshExtension+MeshOrigin
|
|
*/
|
|
float3 MeshOrigin;
|
|
float3 MeshExtension;
|
|
|
|
/* This vertex type is passed in an extra float4 MotionBlurData. This allows specifying motion blur data in a generic way. The previous
|
|
frame's object space position is derived from the MotionBlurData and the current unpacked object space position fields in the following way:
|
|
|
|
(Vertex.MotionBlurData * MotionBlurDataExtension + MotionBlurDataOrigin) + (UnpackePosition * MotionBlurPositionScale)
|
|
|
|
Using this formula a number of effects can be achieved with a single vertex shader. Some common examples
|
|
- Packed previous vertex positions are bound to MotionBlurData
|
|
- MotionBlurDataOrigin: Pevious frame's packed origin
|
|
- MotionBlurDataExtension: Previous frame's packed scale multiplied with a time factor (to make motion blur fps independent)
|
|
- MotionBlurPositionScale: 0
|
|
- Explicit float 3 motion vectors are bound
|
|
- MotionBlurDataOrigin: 0
|
|
- MotionBlurDataExtension: A negative time factor (to make motion blur fps independent and move the velocities back in time)
|
|
- MotionBlurPositionScale: 1
|
|
- No motion blur data is not available for this frame (an undefined buffer is bound)
|
|
- MotionBlurDataOrigin: 0
|
|
- MotionBlurDataExtension: 0
|
|
- MotionBlurPositionScale: 1
|
|
*/
|
|
float3 MotionBlurDataOrigin;
|
|
float3 MotionBlurDataExtension;
|
|
float MotionBlurPositionScale;
|
|
|
|
struct FVertexFactoryInput
|
|
{
|
|
float4 Position : ATTRIBUTE0;
|
|
// 0..1
|
|
HALF3_TYPE TangentX : ATTRIBUTE1;
|
|
// 0..1
|
|
// TangentZ.w contains sign of tangent basis determinant
|
|
HALF4_TYPE TangentZ : ATTRIBUTE2;
|
|
|
|
// Per vertex color
|
|
float4 Color : ATTRIBUTE3;
|
|
|
|
// Motion blur input
|
|
float4 MotionBlurData : ATTRIBUTE4;
|
|
|
|
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX
|
|
float2 TexCoords0 : ATTRIBUTE5;
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 1
|
|
float2 TexCoords1 : ATTRIBUTE6;
|
|
#endif
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 2
|
|
float2 TexCoords2 : ATTRIBUTE7;
|
|
#endif
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 3
|
|
float2 TexCoords3 : ATTRIBUTE8;
|
|
#endif
|
|
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 4
|
|
#error Too many texture coordinate sets defined on Geometry cache vertex input. Max: 4.
|
|
#endif
|
|
#endif
|
|
|
|
VF_GPUSCENE_DECLARE_INPUT_BLOCK(13)
|
|
VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
|
|
VF_MOBILE_MULTI_VIEW_DECLARE_INPUT_BLOCK()
|
|
};
|
|
|
|
// RHI_RAYTRACING
|
|
#if RAYHITGROUPSHADER
|
|
FVertexFactoryInput LoadVertexFactoryInputForHGS(uint TriangleIndex, int VertexIndex)
|
|
{
|
|
FVertexFactoryInput Input;
|
|
|
|
FTriangleBaseAttributes Tri = LoadTriangleBaseAttributes(TriangleIndex);
|
|
uint VertexId = Tri.Indices[VertexIndex];
|
|
|
|
Input.Position.x = GeomCacheMVF.Position[VertexId * 3 + 0];
|
|
Input.Position.y = GeomCacheMVF.Position[VertexId * 3 + 1];
|
|
Input.Position.z = GeomCacheMVF.Position[VertexId * 3 + 2];
|
|
Input.TangentX = GeomCacheMVF.TangentX[VertexId].xyz;
|
|
Input.TangentZ = GeomCacheMVF.TangentZ[VertexId];
|
|
Input.Color = GeomCacheMVF.Color[VertexId];
|
|
Input.MotionBlurData.x = GeomCacheMVF.MotionBlurData[VertexId * 3 + 0];
|
|
Input.MotionBlurData.y = GeomCacheMVF.MotionBlurData[VertexId * 3 + 1];
|
|
Input.MotionBlurData.z = GeomCacheMVF.MotionBlurData[VertexId * 3 + 2];
|
|
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX
|
|
float2 TexCoordXY = float2(GeomCacheMVF.TexCoords[VertexId * 2 + 0], GeomCacheMVF.TexCoords[VertexId * 2 + 1]);
|
|
|
|
Input.TexCoords0 = TexCoordXY;
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 1
|
|
Input.TexCoords1 = TexCoordXY;
|
|
#endif
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 2
|
|
Input.TexCoords2 = TexCoordXY;
|
|
#endif
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 3
|
|
Input.TexCoords3 = TexCoordXY;
|
|
#endif
|
|
#endif
|
|
|
|
VF_GPUSCENE_SET_INPUT_FOR_RT(Input, GetInstanceUserData(), 0U);
|
|
|
|
return Input;
|
|
}
|
|
#endif
|
|
|
|
struct FPositionOnlyVertexFactoryInput
|
|
{
|
|
float4 Position : ATTRIBUTE0;
|
|
VF_GPUSCENE_DECLARE_INPUT_BLOCK(1)
|
|
VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
|
|
VF_MOBILE_MULTI_VIEW_DECLARE_INPUT_BLOCK()
|
|
};
|
|
|
|
struct FPositionAndNormalOnlyVertexFactoryInput
|
|
{
|
|
float4 Position : ATTRIBUTE0;
|
|
float4 Normal : ATTRIBUTE1;
|
|
VF_GPUSCENE_DECLARE_INPUT_BLOCK(2)
|
|
VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
|
|
VF_MOBILE_MULTI_VIEW_DECLARE_INPUT_BLOCK()
|
|
};
|
|
|
|
/** for depth-only pass */
|
|
float4 VertexFactoryGetWorldPosition(FPositionOnlyVertexFactoryInput Input)
|
|
{
|
|
FSceneDataIntermediates SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
|
|
return TransformLocalToTranslatedWorld(Input.Position.xyz, SceneData.InstanceData.LocalToWorld);
|
|
}
|
|
|
|
/** for shadow pass (used for slope bias) */
|
|
float4 VertexFactoryGetWorldPosition(FPositionAndNormalOnlyVertexFactoryInput Input)
|
|
{
|
|
FSceneDataIntermediates SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
|
|
return TransformLocalToTranslatedWorld(Input.Position.xyz, SceneData.InstanceData.LocalToWorld);
|
|
}
|
|
|
|
float3 VertexFactoryGetWorldNormal(FPositionAndNormalOnlyVertexFactoryInput Input)
|
|
{
|
|
FSceneDataIntermediates SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
|
|
return RotateLocalToWorld(Input.Normal.xyz, SceneData.InstanceData.LocalToWorld, SceneData.InstanceData.InvNonUniformScale);
|
|
}
|
|
|
|
struct FVertexFactoryInterpolantsVSToPS
|
|
{
|
|
#if INTERPOLATE_VERTEX_COLOR
|
|
float4 Color : COLOR0;
|
|
#endif
|
|
|
|
#if NUM_TEX_COORD_INTERPOLATORS
|
|
// Pack interpolators to reduce the number of semantics used
|
|
float4 TexCoords[(NUM_TEX_COORD_INTERPOLATORS + 1) / 2] : TEXCOORD0;
|
|
#endif
|
|
|
|
#if VF_USE_PRIMITIVE_SCENE_DATA
|
|
nointerpolation uint PrimitiveId : PRIMITIVE_ID;
|
|
#endif
|
|
|
|
TANGENTTOWORLD_INTERPOLATOR_BLOCK
|
|
};
|
|
|
|
#if NUM_TEX_COORD_INTERPOLATORS
|
|
float2 GetUV(FVertexFactoryInterpolantsVSToPS Interpolants, int UVIndex)
|
|
{
|
|
float4 UVVector = Interpolants.TexCoords[UVIndex / 2];
|
|
return UVIndex % 2 ? UVVector.zw : UVVector.xy;
|
|
}
|
|
|
|
void SetUV(inout FVertexFactoryInterpolantsVSToPS Interpolants, int UVIndex, float2 InValue)
|
|
{
|
|
FLATTEN
|
|
if (UVIndex % 2)
|
|
{
|
|
Interpolants.TexCoords[UVIndex / 2].zw = InValue;
|
|
}
|
|
else
|
|
{
|
|
Interpolants.TexCoords[UVIndex / 2].xy = InValue;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
struct FVertexFactoryRayTracingInterpolants
|
|
{
|
|
FVertexFactoryInterpolantsVSToPS InterpolantsVSToPS;
|
|
};
|
|
|
|
/** Converts from vertex factory specific interpolants to a FMaterialPixelParameters, which is used by material inputs. */
|
|
FMaterialPixelParameters GetMaterialPixelParameters(FVertexFactoryInterpolantsVSToPS Interpolants, float4 SvPosition)
|
|
{
|
|
// GetMaterialPixelParameters is responsible for fully initializing the result
|
|
FMaterialPixelParameters Result = MakeInitializedMaterialPixelParameters();
|
|
|
|
#if NUM_TEX_COORD_INTERPOLATORS
|
|
UNROLL
|
|
for(int CoordinateIndex = 0;CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS;CoordinateIndex++)
|
|
{
|
|
Result.TexCoords[CoordinateIndex] = GetUV(Interpolants, CoordinateIndex);
|
|
}
|
|
#endif
|
|
|
|
half3 TangentToWorld0 = Interpolants.TangentToWorld0.xyz;
|
|
half4 TangentToWorld2 = Interpolants.TangentToWorld2;
|
|
Result.TangentToWorld = AssembleTangentToWorld( TangentToWorld0, TangentToWorld2 );
|
|
#if USE_WORLDVERTEXNORMAL_CENTER_INTERPOLATION
|
|
Result.WorldVertexNormal_Center = Interpolants.TangentToWorld2_Center.xyz;
|
|
#endif
|
|
Result.UnMirrored = TangentToWorld2.w;
|
|
#if INTERPOLATE_VERTEX_COLOR
|
|
Result.VertexColor = Interpolants.Color;
|
|
#else
|
|
Result.VertexColor = 0;
|
|
#endif
|
|
Result.TwoSidedSign = 1;
|
|
|
|
#if VF_USE_PRIMITIVE_SCENE_DATA
|
|
Result.PrimitiveId = Interpolants.PrimitiveId;
|
|
#endif
|
|
|
|
return Result;
|
|
}
|
|
|
|
#define FBoneMatrix float3x4
|
|
|
|
|
|
// Cache data to avoid multiple calculation
|
|
struct FVertexFactoryIntermediates
|
|
{
|
|
// Unpacked position
|
|
float3 UnpackedPosition;
|
|
|
|
// Tangent Basis
|
|
float3x3 TangentToLocal;
|
|
float3x3 TangentToWorld;
|
|
|
|
// Vertex Color
|
|
float4 Color;
|
|
/** Cached primitive and instance data */
|
|
FSceneDataIntermediates SceneData;
|
|
};
|
|
|
|
FPrimitiveSceneData GetPrimitiveData(FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return Intermediates.SceneData.Primitive;
|
|
}
|
|
|
|
float3 VertexFactoryGetPreviousInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates);
|
|
float3 VertexFactoryGetInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates);
|
|
|
|
/** Converts from vertex factory specific input to a FMaterialVertexParameters, which is used by vertex shader material inputs. */
|
|
FMaterialVertexParameters GetMaterialVertexParameters(
|
|
FVertexFactoryInput Input,
|
|
FVertexFactoryIntermediates Intermediates,
|
|
float3 WorldPosition,
|
|
float3x3 TangentToLocal,
|
|
bool bIsPreviousFrame = false)
|
|
{
|
|
FMaterialVertexParameters Result = MakeInitializedMaterialVertexParameters();
|
|
Result.SceneData = Intermediates.SceneData;
|
|
Result.WorldPosition = WorldPosition;
|
|
|
|
if (bIsPreviousFrame)
|
|
{
|
|
Result.PositionInstanceSpace = VertexFactoryGetPreviousInstanceSpacePosition(Input, Intermediates);
|
|
Result.PositionPrimitiveSpace = mul(float4(WorldPosition, 1), DFFastToTranslatedWorld(Intermediates.SceneData.Primitive.PreviousWorldToLocal, ResolvedView.PrevPreViewTranslation)).xyz;
|
|
}
|
|
else
|
|
{
|
|
Result.PositionInstanceSpace = VertexFactoryGetInstanceSpacePosition(Input, Intermediates);
|
|
Result.PositionPrimitiveSpace = mul(float4(WorldPosition, 1), DFFastToTranslatedWorld(Intermediates.SceneData.Primitive.WorldToLocal, ResolvedView.PreViewTranslation)).xyz;
|
|
}
|
|
|
|
Result.VertexColor = Intermediates.Color;
|
|
Result.TangentToWorld = Intermediates.TangentToWorld;
|
|
Result.PreSkinnedPosition = Intermediates.UnpackedPosition.xyz;
|
|
Result.PreSkinnedNormal = Input.TangentZ.xyz * 2.f - 1.f;
|
|
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX
|
|
Result.TexCoords[0] = Input.TexCoords0;
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 1
|
|
Result.TexCoords[1] = Input.TexCoords1;
|
|
#endif
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 2
|
|
Result.TexCoords[2] = Input.TexCoords2;
|
|
#endif
|
|
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 3
|
|
Result.TexCoords[3] = Input.TexCoords3;
|
|
#endif
|
|
#endif
|
|
|
|
#if VF_USE_PRIMITIVE_SCENE_DATA
|
|
Result.PrimitiveId = Intermediates.SceneData.PrimitiveId;
|
|
#endif
|
|
|
|
Result.LWCData = MakeMaterialLWCData(Result);
|
|
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
* Unpack position - uncompress xyz position to object space position
|
|
*/
|
|
float3 UnpackedPosition( FVertexFactoryInput Input )
|
|
{
|
|
return float3(Input.Position.xyz * GeomCache.MeshExtension + GeomCache.MeshOrigin);
|
|
}
|
|
|
|
/**
|
|
* Derive tangent space matrix from vertex interpolants
|
|
*/
|
|
half3x3 CalcTangentToLocal(FVertexFactoryInput Input)
|
|
{
|
|
half3x3 Result;
|
|
|
|
// Unpack to -1 .. 1
|
|
half3 TangentX = TangentBias(Input.TangentX);
|
|
half4 TangentZ = TangentBias(Input.TangentZ);
|
|
|
|
// derive the binormal by getting the cross product of the normal and tangent
|
|
half3 TangentY = cross(TangentZ.xyz, TangentX) * TangentZ.w;
|
|
|
|
// Recalculate TangentX off of the other two vectors
|
|
// This corrects quantization error since TangentX was passed in as a quantized 8 bit vertex input
|
|
// The error shows up most in specular off of a mesh with a smoothed UV seam (normal is smooth, but tangents vary across the seam)
|
|
Result[0] = cross(TangentY, TangentZ.xyz) * TangentZ.w;
|
|
Result[1] = TangentY;
|
|
Result[2] = TangentZ.xyz;
|
|
|
|
return Result;
|
|
}
|
|
|
|
void CalcTangentToWorld(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, out float3 TangentToWorld0, out float4 TangentToWorld2)
|
|
{
|
|
float3x3 LocalToWorld = DFToFloat3x3(Intermediates.SceneData.InstanceData.LocalToWorld);
|
|
|
|
// Remove scaling.
|
|
half3 InvScale = GetPrimitiveData(Intermediates).InvNonUniformScale;
|
|
LocalToWorld[0] *= InvScale.x;
|
|
LocalToWorld[1] *= InvScale.y;
|
|
LocalToWorld[2] *= InvScale.z;
|
|
|
|
float3x3 TangentToWorld = mul(Intermediates.TangentToLocal, LocalToWorld);
|
|
|
|
TangentToWorld0 = TangentToWorld[0];
|
|
TangentToWorld2 = float4(TangentToWorld[2], Input.TangentZ.w * GetPrimitive_DeterminantSign_FromFlags(GetPrimitiveData(Intermediates).Flags));
|
|
}
|
|
|
|
FVertexFactoryIntermediates GetVertexFactoryIntermediates(FVertexFactoryInput Input)
|
|
{
|
|
FVertexFactoryIntermediates Intermediates;
|
|
Intermediates.SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
|
|
Intermediates.UnpackedPosition = UnpackedPosition(Input);
|
|
|
|
// Fill TangentToLocal
|
|
Intermediates.TangentToLocal = CalcTangentToLocal(Input);
|
|
|
|
float3 TangentToWorld0;
|
|
float4 TangentToWorld2;
|
|
CalcTangentToWorld(Input, Intermediates, TangentToWorld0, TangentToWorld2);
|
|
Intermediates.TangentToWorld = AssembleTangentToWorld(TangentToWorld0, TangentToWorld2);
|
|
|
|
// Swizzle vertex color.
|
|
Intermediates.Color = Input.Color FCOLOR_COMPONENT_SWIZZLE;
|
|
|
|
return Intermediates;
|
|
}
|
|
|
|
float3 VertexFactoryGetWorldNormal(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return Intermediates.TangentToWorld[2];
|
|
}
|
|
|
|
/**
|
|
* Get the 3x3 tangent basis vectors for this vertex factory
|
|
*
|
|
* @param Input - vertex input stream structure
|
|
* @return 3x3 matrix
|
|
*/
|
|
float3x3 VertexFactoryGetTangentToLocal( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return Intermediates.TangentToLocal;
|
|
}
|
|
|
|
float4 VertexFactoryGetWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return TransformLocalToTranslatedWorld(Intermediates.UnpackedPosition, Intermediates.SceneData.InstanceData.LocalToWorld);
|
|
}
|
|
|
|
// local position relative to instance
|
|
float3 VertexFactoryGetInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return Intermediates.UnpackedPosition;
|
|
}
|
|
|
|
float4 VertexFactoryGetRasterizedWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, float4 InWorldPosition)
|
|
{
|
|
return InWorldPosition;
|
|
}
|
|
|
|
float3 VertexFactoryGetPositionForVertexLighting(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, float3 TranslatedWorldPosition)
|
|
{
|
|
return TranslatedWorldPosition;
|
|
}
|
|
|
|
FVertexFactoryInterpolantsVSToPS VertexFactoryGetInterpolantsVSToPS(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, FMaterialVertexParameters VertexParameters)
|
|
{
|
|
FVertexFactoryInterpolantsVSToPS Interpolants;
|
|
|
|
// Initialize the whole struct to 0
|
|
Interpolants = (FVertexFactoryInterpolantsVSToPS)0;
|
|
|
|
#if NUM_TEX_COORD_INTERPOLATORS
|
|
float2 CustomizedUVs[NUM_TEX_COORD_INTERPOLATORS];
|
|
GetMaterialCustomizedUVs(VertexParameters, CustomizedUVs);
|
|
GetCustomInterpolators(VertexParameters, CustomizedUVs);
|
|
|
|
UNROLL
|
|
for (int CoordinateIndex = 0; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++)
|
|
{
|
|
SetUV(Interpolants, CoordinateIndex, CustomizedUVs[CoordinateIndex]);
|
|
}
|
|
#endif
|
|
|
|
//Packs the TangentToWorld matrix into the interpolants.
|
|
Interpolants.TangentToWorld0.w = 0;
|
|
CalcTangentToWorld(Input, Intermediates, Interpolants.TangentToWorld0.xyz, Interpolants.TangentToWorld2);
|
|
#if USE_WORLDVERTEXNORMAL_CENTER_INTERPOLATION
|
|
Interpolants.TangentToWorld2_Center = Interpolants.TangentToWorld2;
|
|
#endif
|
|
|
|
#if INTERPOLATE_VERTEX_COLOR
|
|
Interpolants.Color = Intermediates.Color;
|
|
#endif
|
|
|
|
#if VF_USE_PRIMITIVE_SCENE_DATA
|
|
Interpolants.PrimitiveId = Intermediates.SceneData.PrimitiveId;
|
|
#endif
|
|
|
|
return Interpolants;
|
|
}
|
|
|
|
// @return The previous position of the vertex in object space.
|
|
float3 CalcPreviousPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
float3 PreviousPosition = (Input.MotionBlurData.xyz * GeomCache.MotionBlurDataExtension + GeomCache.MotionBlurDataOrigin) + Intermediates.UnpackedPosition * GeomCache.MotionBlurPositionScale;
|
|
#if 0
|
|
float ExaggerateMotion = 10.0;
|
|
float3 Delta = Intermediates.UnpackedPosition - PreviousPosition;
|
|
PreviousPosition = Intermediates.UnpackedPosition - Delta * ExaggerateMotion;
|
|
#endif
|
|
return PreviousPosition;
|
|
}
|
|
|
|
// @return previous translated world position
|
|
float4 VertexFactoryGetPreviousWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return TransformPreviousLocalPositionToTranslatedWorld(CalcPreviousPosition(Input, Intermediates), GetPrimitiveData(Intermediates).PreviousLocalToWorld);
|
|
}
|
|
|
|
// local position relative to instance
|
|
float3 VertexFactoryGetPreviousInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
|
|
{
|
|
return CalcPreviousPosition(Input, Intermediates);
|
|
}
|
|
|
|
#if NEEDS_VERTEX_FACTORY_INTERPOLATION
|
|
float2 VertexFactoryGetRayTracingTextureCoordinate( FVertexFactoryRayTracingInterpolants Interpolants )
|
|
{
|
|
#if NUM_MATERIAL_TEXCOORDS
|
|
return Interpolants.InterpolantsVSToPS.TexCoords[0].xy;
|
|
#else // #if NUM_MATERIAL_TEXCOORDS
|
|
return float2(0,0);
|
|
#endif // #if NUM_MATERIAL_TEXCOORDS
|
|
}
|
|
|
|
FVertexFactoryInterpolantsVSToPS VertexFactoryAssignInterpolants(FVertexFactoryRayTracingInterpolants Input)
|
|
{
|
|
return Input.InterpolantsVSToPS;
|
|
}
|
|
|
|
FVertexFactoryRayTracingInterpolants VertexFactoryGetRayTracingInterpolants(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, FMaterialVertexParameters VertexParameters)
|
|
{
|
|
FVertexFactoryRayTracingInterpolants Interpolants;
|
|
|
|
Interpolants.InterpolantsVSToPS = VertexFactoryGetInterpolantsVSToPS(Input, Intermediates, VertexParameters);
|
|
|
|
return Interpolants;
|
|
}
|
|
|
|
FVertexFactoryRayTracingInterpolants VertexFactoryInterpolate(FVertexFactoryRayTracingInterpolants a, float aInterp, FVertexFactoryRayTracingInterpolants b, float bInterp)
|
|
{
|
|
FVertexFactoryRayTracingInterpolants O;
|
|
|
|
INTERPOLATE_MEMBER(InterpolantsVSToPS.TangentToWorld0.xyz);
|
|
INTERPOLATE_MEMBER(InterpolantsVSToPS.TangentToWorld2);
|
|
#if INTERPOLATE_VERTEX_COLOR
|
|
INTERPOLATE_MEMBER(InterpolantsVSToPS.Color);
|
|
#endif
|
|
|
|
#if NUM_TEX_COORD_INTERPOLATORS
|
|
UNROLL
|
|
for(int tc = 0; tc < (NUM_TEX_COORD_INTERPOLATORS + 1) / 2; ++tc)
|
|
{
|
|
INTERPOLATE_MEMBER(InterpolantsVSToPS.TexCoords[tc]);
|
|
}
|
|
#endif
|
|
|
|
#if VF_USE_PRIMITIVE_SCENE_DATA
|
|
O.InterpolantsVSToPS.PrimitiveId = a.InterpolantsVSToPS.PrimitiveId;
|
|
#endif
|
|
|
|
return O;
|
|
}
|
|
#endif // #if NEEDS_VERTEX_FACTORY_INTERPOLATION
|
|
|
|
float4 VertexFactoryGetTranslatedPrimitiveVolumeBounds(FVertexFactoryInterpolantsVSToPS Interpolants)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
uint VertexFactoryGetPrimitiveId(FVertexFactoryInterpolantsVSToPS Interpolants)
|
|
{
|
|
#if VF_USE_PRIMITIVE_SCENE_DATA
|
|
return Interpolants.PrimitiveId;
|
|
#else // VF_USE_PRIMITIVE_SCENE_DATA
|
|
return 0;
|
|
#endif // VF_USE_PRIMITIVE_SCENE_DATA
|
|
}
|
|
|
|
#include "VertexFactoryDefaultInterface.ush" |