Files
UnrealEngineUWP/Engine/Shaders/Private/MeshParticleVertexFactory.ush
Arciel Rekman 5e5328ed0f Fix duplicated instance id semantic (UE-150289).
- Duplicating semantics in vertex shader signature is no longer allowed (by DXC). This change moves such parameters from VS signature into the vertex factory input structures, reusing existing parameters where applicable.

#rb Yuriy.ODonnell, Rob.Srinivasiah
#review @Robert.Srinivasiah, @Jason.Nadro, @Yuriy.ODonnell, @Jules.Blok
#jira UE-150289
#preflight 6282a8857b284e82082f905e

[CL 20242895 by Arciel Rekman in ue5-main branch]
2022-05-17 10:45:04 -04:00

695 lines
23 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
MeshParticleVertexFactory.usf: Mesh particle vertex factory shader code.
=============================================================================*/
#include "VertexFactoryCommon.ush"
#define USE_PARTICLE_POSITION (NEEDS_PARTICLE_POSITION || PASS_NEEDS_PRIMITIVE_VOLUME_BOUNDS)
#define USE_PARTICLE_VELOCITY (NEEDS_PARTICLE_VELOCITY)
#define USE_PARTICLE_TIME (NEEDS_PARTICLE_TIME)
#define USE_PARTICLE_LOCAL_TO_WORLD (NEEDS_PARTICLE_LOCAL_TO_WORLD || NEEDS_INSTANCE_LOCAL_TO_WORLD_PS)
#define USE_PARTICLE_WORLD_TO_LOCAL (NEEDS_PARTICLE_WORLD_TO_LOCAL || NEEDS_INSTANCE_WORLD_TO_LOCAL_PS)
// Only support previous transform for deferred feature level
#define USE_PREVIOUS_TRANSFORM (FEATURE_LEVEL >= FEATURE_LEVEL_SM4)
#if USE_PREVIOUS_TRANSFORM
#if PARTICLE_MESH_INSTANCED
Buffer<float4> PrevTransformBuffer;
#else
float4 PrevTransform0;
float4 PrevTransform1;
float4 PrevTransform2;
#endif
#endif
#if !PARTICLE_MESH_INSTANCED
float4 Transform1;
float4 Transform2;
float4 Transform3;
float4 SubUVParams;
float SubUVLerp;
float4 ParticleDirection;
float RelativeTime;
float4 DynamicParameter;
float4 ParticleColor;
#endif
struct FVertexFactoryInput
{
float4 Position : ATTRIBUTE0;
HALF3_TYPE TangentX : ATTRIBUTE1;
// TangentZ.w contains sign of tangent basis determinant
HALF4_TYPE TangentZ : ATTRIBUTE2;
HALF4_TYPE VertexColor : ATTRIBUTE3;
#if NUM_MATERIAL_TEXCOORDS_VERTEX
float2 TexCoords0 : ATTRIBUTE4;
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 1
float2 TexCoords1 : ATTRIBUTE5;
#endif
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 2
float2 TexCoords2 : ATTRIBUTE6;
#endif
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 3
float2 TexCoords3 : ATTRIBUTE7;
#endif
#elif USE_PARTICLE_SUBUVS
float2 TexCoords0 : ATTRIBUTE4;
#endif
#if PARTICLE_MESH_INSTANCED
float4 Transform1 : ATTRIBUTE8;
float4 Transform2 : ATTRIBUTE9;
float4 Transform3 : ATTRIBUTE10;
int4 SubUVParams : ATTRIBUTE11;
/** X: SubUV lerp Y: Particle relative time. */
float2 SubUVLerpAndRelTime : ATTRIBUTE12;
#if USE_DYNAMIC_PARAMETERS
float4 DynamicParameter : ATTRIBUTE13;
#endif //USE_DYNAMIC_PARAMETERS
float4 ParticleColor : ATTRIBUTE14;
/** The velocity of the particle, XYZ: direction, W: speed. */
float4 ParticleVelocity : ATTRIBUTE15;
#endif
/** Optional instance ID for vertex layered rendering */
#if (PARTICLE_MESH_INSTANCED)
uint InstanceId : SV_InstanceID;
#else
VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
#endif
#if PASS_NEEDS_VERTEX_ID
uint VertexId : SV_VertexID;
#endif // #if PASS_NEEDS_VERTEX_ID
};
struct FVertexFactoryInterpolantsVSToPS
{
TANGENTTOWORLD_INTERPOLATOR_BLOCK
#if USE_PARTICLE_SUBUVS
float4 SubUV0AndTexCoord0 : TEXCOORD1;
float4 SubUV1AndLerp : TEXCOORD2;
#else
#if NUM_TEX_COORD_INTERPOLATORS
float4 TexCoords[(NUM_TEX_COORD_INTERPOLATORS+1)/2] : TEXCOORD0;
#endif
#endif
#if INTERPOLATE_VERTEX_COLOR
float4 VertexColor : COLOR0;
#endif
#if NEEDS_PARTICLE_COLOR
float4 ParticleColor : COLOR1;
#endif
#if USE_DYNAMIC_PARAMETERS
nointerpolation float4 DynamicParameter : COLOR2;
#endif
#if USE_PARTICLE_POSITION
/** Particle position in camera-centered translated world space */
float3 ParticleTranslatedWorldPosition : PARTICLE_POSITION;
#endif
#if USE_PARTICLE_VELOCITY
/** The velocity of the particle, XYZ: direction, W: speed. */
float4 ParticleVelocity : PARTICLE_VELOCITY;
#endif
#if USE_PARTICLE_TIME
/** Relative alive time of the particle */
float ParticleTime : PARTICLE_TIME;
#endif
#if USE_PARTICLE_LOCAL_TO_WORLD
nointerpolation float4 ParticleToWorld[3] : PARTICLE_LOCAL_TO_WORLD;
#endif
#if USE_PARTICLE_WORLD_TO_LOCAL
nointerpolation float4 WorldToParticle[3] : PARTICLE_WORLD_TO_LOCAL;
#endif
#if INSTANCED_STEREO
nointerpolation uint EyeIndex : PACKED_EYE_INDEX;
#endif
};
struct FVertexFactoryIntermediates
{
/** The color of the vertex. */
float4 VertexColor;
/** The color of the particle. */
float4 ParticleColor;
/** The texture coordinates for the vertex. */
#if NUM_MATERIAL_TEXCOORDS_VERTEX
float2 TexCoords[NUM_MATERIAL_TEXCOORDS_VERTEX];
#endif
#if USE_PARTICLE_SUBUVS
float4 SubUVCoords;
float SubUVLerp;
#endif
#if USE_DYNAMIC_PARAMETERS
/** Optional dynamic parameter for the particle. */
float4 DynamicParameter;
#endif //USE_DYNAMIC_PARAMETERS
/** The velocity of the particle, XYZ: direction, W: speed. */
float4 ParticleVelocity;
/** Particle position in camera-centered translated world space. */
float3 ParticleTranslatedWorldPosition;
/** Relative time. */
float RelativeTime;
float4x4 ParticleToWorld;
float4x4 WorldToParticle;
/** Cached primitive and instance data */
FSceneDataIntermediates SceneData;
};
FPrimitiveSceneData GetPrimitiveData(FVertexFactoryIntermediates Intermediates)
{
return Intermediates.SceneData.Primitive;
}
float4x4 GetParticleTransform(FVertexFactoryInput Input)
{
//Transform is transposed on CPU and position is packed into W. Transpose again to get the correct transform back.
#if PARTICLE_MESH_INSTANCED
return transpose(float4x4(Input.Transform1, Input.Transform2, Input.Transform3, float4(0, 0, 0, 1)));
#else
return transpose(float4x4(Transform1, Transform2, Transform3, float4(0, 0, 0, 1)));
#endif
}
#if USE_PREVIOUS_TRANSFORM
float4x4 GetParticlePrevTransform(FVertexFactoryInput Input)
{
#if PARTICLE_MESH_INSTANCED
uint TransformBaseIdx = GetInstanceId(Input.InstanceId) * 3;
float4x4 PrevTransform4x4 = float4x4(
PrevTransformBuffer[TransformBaseIdx + 0],
PrevTransformBuffer[TransformBaseIdx + 1],
PrevTransformBuffer[TransformBaseIdx + 2],
float4(0, 0, 0, 1)
);
#else
float4x4 PrevTransform4x4 = float4x4(
PrevTransform0,
PrevTransform1,
PrevTransform2,
float4(0, 0, 0, 1)
);
#endif
//Transform is transposed on CPU and position is packed into W. Transpose again to get the correct transform back.
return transpose(PrevTransform4x4);
}
#endif
float4x4 PseudoInverseTransform(float4x4 LocalToWorld)
{
float3 Scale2;
Scale2.x = length2(LocalToWorld[0].xyz);
Scale2.y = length2(LocalToWorld[1].xyz);
Scale2.z = length2(LocalToWorld[2].xyz);
float3 InvNonUniformScale = rsqrt(Scale2);
float4x4 WorldToLocal = 0;
WorldToLocal[0].xyz = LocalToWorld[0].xyz * Pow2(InvNonUniformScale.x);
WorldToLocal[1].xyz = LocalToWorld[1].xyz * Pow2(InvNonUniformScale.y);
WorldToLocal[2].xyz = LocalToWorld[2].xyz * Pow2(InvNonUniformScale.z);
WorldToLocal[3].w = 1.0f;
WorldToLocal = transpose(WorldToLocal);
WorldToLocal[3].xyz = mul(float4(-LocalToWorld[3].xyz, 0.0f), WorldToLocal).xyz;
return WorldToLocal;
}
/** 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 USE_PARTICLE_SUBUVS
#if NUM_MATERIAL_TEXCOORDS
UNROLL
for( int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS; CoordinateIndex++ )
{
Result.TexCoords[CoordinateIndex] = Interpolants.SubUV0AndTexCoord0.zw;
}
#endif
Result.Particle.SubUVCoords[0] = Interpolants.SubUV0AndTexCoord0.xy;
Result.Particle.SubUVCoords[1] = Interpolants.SubUV1AndLerp.xy;
Result.Particle.SubUVLerp = Interpolants.SubUV1AndLerp.z;
#elif NUM_TEX_COORD_INTERPOLATORS
UNROLL
for (int CoordinateIndex = 0; CoordinateIndex * 2 + 1 < NUM_TEX_COORD_INTERPOLATORS; ++CoordinateIndex)
{
Result.TexCoords[CoordinateIndex * 2] = Interpolants.TexCoords[CoordinateIndex].xy;
Result.TexCoords[CoordinateIndex * 2 + 1] = Interpolants.TexCoords[CoordinateIndex].wz;
}
#if NUM_TEX_COORD_INTERPOLATORS & 1
Result.TexCoords[NUM_TEX_COORD_INTERPOLATORS - 1] = Interpolants.TexCoords[NUM_TEX_COORD_INTERPOLATORS / 2].xy;
#endif // #if NUM_TEX_COORD_INTERPOLATORS & 1
#endif
half3 TangentToWorld0 = Interpolants.TangentToWorld0.xyz;
half4 TangentToWorld2 = Interpolants.TangentToWorld2;
Result.UnMirrored = TangentToWorld2.w;
#if INTERPOLATE_VERTEX_COLOR
Result.VertexColor = Interpolants.VertexColor;
#else
Result.VertexColor = 0;
#endif
#if NEEDS_PARTICLE_COLOR
Result.Particle.Color = Interpolants.ParticleColor;
#endif
#if USE_DYNAMIC_PARAMETERS
Result.Particle.DynamicParameter = Interpolants.DynamicParameter;
#else
Result.Particle.DynamicParameter = float4(1,1,1,1);
#endif //USE_DYNAMIC_PARAMETERS
#if USE_PARTICLE_POSITION
Result.Particle.TranslatedWorldPositionAndSize.xyz = Interpolants.ParticleTranslatedWorldPosition.xyz;
Result.Particle.TranslatedWorldPositionAndSize.w = 1;
#endif
#if USE_PARTICLE_VELOCITY
Result.Particle.Velocity = Interpolants.ParticleVelocity;
#endif
#if USE_PARTICLE_TIME
Result.Particle.RelativeTime = Interpolants.ParticleTime;
#endif
#if USE_PARTICLE_LOCAL_TO_WORLD
FLWCMatrix ParticleToWorld = LWCPromote(transpose(float4x4(Interpolants.ParticleToWorld[0], Interpolants.ParticleToWorld[1], Interpolants.ParticleToWorld[2], float4(0.0f, 0.0f, 0.0f, 1.0f))));
#if NEEDS_PARTICLE_LOCAL_TO_WORLD
Result.Particle.ParticleToWorld = ParticleToWorld;
#endif
#if NEEDS_INSTANCE_LOCAL_TO_WORLD_PS
Result.InstanceLocalToWorld = ParticleToWorld;
#endif
#endif
#if USE_PARTICLE_WORLD_TO_LOCAL
FLWCInverseMatrix WorldToParticle = LWCPromoteInverse(transpose(float4x4(Interpolants.WorldToParticle[0], Interpolants.WorldToParticle[1], Interpolants.WorldToParticle[2], float4(0.0f, 0.0f, 0.0f, 1.0f))));
#if NEEDS_PARTICLE_WORLD_TO_LOCAL
Result.Particle.WorldToParticle = WorldToParticle;
#endif
#if NEEDS_INSTANCE_WORLD_TO_LOCAL_PS
Result.InstanceWorldToLocal = WorldToParticle;
#endif
#endif
Result.Particle.MotionBlurFade = 1.0f;
Result.TangentToWorld = AssembleTangentToWorld( TangentToWorld0, TangentToWorld2 );
Result.TwoSidedSign = 1;
#if USE_WORLDVERTEXNORMAL_CENTER_INTERPOLATION
Result.WorldVertexNormal_Center = Interpolants.TangentToWorld2_Center.xyz;
#endif
return Result;
}
/** 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)
{
FMaterialVertexParameters Result = (FMaterialVertexParameters)0;
Result.SceneData = Intermediates.SceneData;
Result.WorldPosition = WorldPosition;
Result.VertexColor = Intermediates.VertexColor;
Result.PreSkinnedPosition = Input.Position.xyz;
Result.PreSkinnedNormal = TangentBias(Input.TangentZ.xyz);
Result.Particle.TranslatedWorldPositionAndSize.xyz = Intermediates.ParticleTranslatedWorldPosition.xyz;
Result.Particle.TranslatedWorldPositionAndSize.w = 1;
Result.Particle.Velocity = Intermediates.ParticleVelocity;
Result.Particle.RelativeTime = Intermediates.RelativeTime;
#if USE_DYNAMIC_PARAMETERS
Result.Particle.DynamicParameter = Intermediates.DynamicParameter;
#endif //USE_DYNAMIC_PARAMETERS
float4x4 ParticleTransform = GetParticleTransform(Input);
Result.InstanceLocalToWorld = LWCPromote(ParticleTransform);
Result.InstanceWorldToLocal = LWCPromoteInverse(PseudoInverseTransform(ParticleTransform));
Result.Particle.Color = Intermediates.ParticleColor;
Result.Particle.ParticleToWorld = Result.InstanceLocalToWorld;
Result.Particle.WorldToParticle = Result.InstanceWorldToLocal;
Result.TangentToWorld = mul(TangentToLocal, (float3x3)ParticleTransform );
#if USE_PREVIOUS_TRANSFORM
Result.PrevFrameLocalToWorld = LWCPromote(GetParticlePrevTransform(Input));
#else
Result.PrevFrameLocalToWorld = LWCPromote(ParticleTransform);
#endif
#if NUM_MATERIAL_TEXCOORDS_VERTEX
for(int CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS_VERTEX; CoordinateIndex++)
{
Result.TexCoords[CoordinateIndex] = Intermediates.TexCoords[CoordinateIndex];
}
#endif
return Result;
}
float4 CalcWorldPosition(FVertexFactoryInput Input)
{
float4x4 Transform = GetParticleTransform(Input);
float3 WorldPosition = mul(Input.Position, Transform).xyz + LWCHackToFloat(ResolvedView.PreViewTranslation);
return float4(WorldPosition, Input.Position.w);
}
float4 CalcPrevWorldPosition(FVertexFactoryInput Input)
{
#if USE_PREVIOUS_TRANSFORM
if (MeshParticleVF.PrevTransformAvailable > 0)
{
float4x4 PrevTransform = GetParticlePrevTransform(Input);
float3 PrevWorldPosition = mul(Input.Position, PrevTransform).xyz + LWCHackToFloat(ResolvedView.PrevPreViewTranslation);
return float4(PrevWorldPosition, Input.Position.w);
}
else
#endif
{
return CalcWorldPosition(Input);
}
}
FVertexFactoryIntermediates GetVertexFactoryIntermediates(FVertexFactoryInput Input)
{
FVertexFactoryIntermediates Intermediates = (FVertexFactoryIntermediates)0;
Intermediates.SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
// Swizzle vertex color.
Intermediates.VertexColor = Input.VertexColor FCOLOR_COMPONENT_SWIZZLE;
// World position and localtoworld transform.
float4x4 LocalToWorldMat = GetParticleTransform(Input);
Intermediates.ParticleToWorld = LocalToWorldMat;
Intermediates.WorldToParticle = PseudoInverseTransform(LocalToWorldMat);
float3 ParticleWorldPosition = LocalToWorldMat[3].xyz;
Intermediates.ParticleTranslatedWorldPosition = ParticleWorldPosition + LWCHackToFloat(ResolvedView.PreViewTranslation);
#if PARTICLE_MESH_INSTANCED
Intermediates.ParticleColor = Input.ParticleColor;
#else
Intermediates.ParticleColor = ParticleColor;
#endif
#if NUM_MATERIAL_TEXCOORDS_VERTEX
Intermediates.TexCoords[0] = Input.TexCoords0;
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 1
Intermediates.TexCoords[1] = Input.TexCoords1;
#endif
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 2
Intermediates.TexCoords[2] = Input.TexCoords2;
#endif
#if NUM_MATERIAL_TEXCOORDS_VERTEX > 3
Intermediates.TexCoords[3] = Input.TexCoords3;
#endif
#endif
#if USE_PARTICLE_SUBUVS
#if PARTICLE_MESH_INSTANCED
Intermediates.SubUVCoords.xy = (float2( Input.SubUVParams.x, Input.SubUVParams.y ) + Input.TexCoords0.xy) * MeshParticleVF.SubImageSize.xy;
Intermediates.SubUVCoords.zw = (float2( Input.SubUVParams.z, Input.SubUVParams.w ) + Input.TexCoords0.xy) * MeshParticleVF.SubImageSize.xy;
Intermediates.SubUVLerp = Input.SubUVLerpAndRelTime.x;
#else
Intermediates.SubUVCoords.xy = (float2( SubUVParams.x, SubUVParams.y ) + Input.TexCoords0.xy) * MeshParticleVF.SubImageSize.xy;
Intermediates.SubUVCoords.zw = (float2( SubUVParams.z, SubUVParams.w ) + Input.TexCoords0.xy) * MeshParticleVF.SubImageSize.xy;
Intermediates.SubUVLerp = SubUVLerp.x;
#endif
#endif
#if USE_DYNAMIC_PARAMETERS
#if PARTICLE_MESH_INSTANCED
Intermediates.DynamicParameter = Input.DynamicParameter;
#else
Intermediates.DynamicParameter = DynamicParameter;
#endif
#endif //USE_DYNAMIC_PARAMETERS
Intermediates.ParticleTranslatedWorldPosition = ParticleWorldPosition.xyz + LWCHackToFloat(ResolvedView.PreViewTranslation);
#if PARTICLE_MESH_INSTANCED
Intermediates.ParticleVelocity = Input.ParticleVelocity;
Intermediates.RelativeTime = Input.SubUVLerpAndRelTime.y;
#else
Intermediates.ParticleVelocity = ParticleDirection;
Intermediates.RelativeTime = RelativeTime;
#endif
return Intermediates;
}
/**
* Get the 3x3 tangent basis vectors for this vertex factory
* this vertex factory will calculate the binormal on-the-fly
*
* @param Input - vertex input stream structure
* @return 3x3 matrix
*/
float3x3 VertexFactoryGetTangentToLocal( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates )
{
float3x3 Result=0;
float3 TangentX = TangentBias(Input.TangentX);
float4 TangentZ = TangentBias(Input.TangentZ);
// pass-thru the tangent
Result[0] = TangentX;
// pass-thru the normal
Result[2] = TangentZ.xyz;
// derive the binormal by getting the cross product of the normal and tangent
Result[1] = cross(Result[2], Result[0]) * TangentZ.w;
// Recalculate TangentX off of the other two vectors
// This corrects quantization error since TangentX was passed in as a quantized 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(Result[1], Result[2]) * TangentZ.w;
return Result;
}
// @return translated world position
float4 VertexFactoryGetWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
{
return CalcWorldPosition(Input);
}
float3 VertexFactoryGetWorldNormal(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
{
return TangentBias(Input.TangentZ.xyz);
}
float4 VertexFactoryGetRasterizedWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, float4 InWorldPosition)
{
return InWorldPosition;
}
float3 VertexFactoryGetPositionForVertexLighting(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, float3 TranslatedWorldPosition)
{
return TranslatedWorldPosition;
}
void CalcTangentToWorld(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, out float3 TangentToWorld0, out float4 TangentToWorld2)
{
float3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, Intermediates);
float4x4 Transform = GetParticleTransform(Input);
float3x3 TangentToWorld = mul(TangentToLocal, (float3x3)Transform);
// Normalize to remove scaling. Incorrect but faster than computing the inverse-transpose.
TangentToWorld0 = normalize(TangentToWorld[0]);
TangentToWorld2 = float4(normalize(TangentToWorld[2]), TangentBias(Input.TangentZ.w) * GetPrimitive_DeterminantSign_FromFlags(Primitive.Flags));
}
FVertexFactoryInterpolantsVSToPS VertexFactoryGetInterpolantsVSToPS(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, FMaterialVertexParameters VertexParameters)
{
FVertexFactoryInterpolantsVSToPS Interpolants;
#if USE_PARTICLE_SUBUVS
Interpolants.SubUV0AndTexCoord0.xy = Intermediates.SubUVCoords.xy;
Interpolants.SubUV1AndLerp.xy = Intermediates.SubUVCoords.zw;
Interpolants.SubUV1AndLerp.zw = Intermediates.SubUVLerp.xx;
#if NUM_MATERIAL_TEXCOORDS
float2 CustomizedUVs[NUM_MATERIAL_TEXCOORDS];
GetMaterialCustomizedUVs(VertexParameters, CustomizedUVs);
Interpolants.SubUV0AndTexCoord0.zw = CustomizedUVs[0];
#else
Interpolants.SubUV0AndTexCoord0.zw = 0;
#endif
#elif NUM_TEX_COORD_INTERPOLATORS
// Ensure the unused components of the last packed texture coordinate are initialized.
Interpolants.TexCoords[(NUM_TEX_COORD_INTERPOLATORS + 1) / 2 - 1] = 0;
float2 CustomizedUVs[NUM_TEX_COORD_INTERPOLATORS];
GetMaterialCustomizedUVs(VertexParameters, CustomizedUVs);
GetCustomInterpolators(VertexParameters, CustomizedUVs);
UNROLL
for (int CoordinateIndex = 0; CoordinateIndex * 2 + 1 < NUM_TEX_COORD_INTERPOLATORS; ++CoordinateIndex)
{
Interpolants.TexCoords[CoordinateIndex].xy = CustomizedUVs[CoordinateIndex * 2];
Interpolants.TexCoords[CoordinateIndex].wz = CustomizedUVs[CoordinateIndex * 2 + 1];
}
#if NUM_TEX_COORD_INTERPOLATORS & 1
Interpolants.TexCoords[NUM_TEX_COORD_INTERPOLATORS / 2].xy = CustomizedUVs[NUM_TEX_COORD_INTERPOLATORS - 1];
#endif // #if NUM_TEX_COORD_INTERPOLATORS & 1
#endif
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.VertexColor = Intermediates.VertexColor;
#endif
#if NEEDS_PARTICLE_COLOR
Interpolants.ParticleColor = Intermediates.ParticleColor;
#endif
#if USE_DYNAMIC_PARAMETERS
Interpolants.DynamicParameter = Intermediates.DynamicParameter;
#endif //USE_DYNAMIC_PARAMETERS
#if USE_PARTICLE_POSITION
Interpolants.ParticleTranslatedWorldPosition = Intermediates.ParticleTranslatedWorldPosition;
#endif
#if USE_PARTICLE_VELOCITY
Interpolants.ParticleVelocity = Intermediates.ParticleVelocity;
#endif
#if USE_PARTICLE_TIME
Interpolants.ParticleTime = Intermediates.RelativeTime;
#endif
#if USE_PARTICLE_LOCAL_TO_WORLD
float4x4 ParticleToWorldT = transpose(Intermediates.ParticleToWorld);
Interpolants.ParticleToWorld[0] = ParticleToWorldT[0];
Interpolants.ParticleToWorld[1] = ParticleToWorldT[1];
Interpolants.ParticleToWorld[2] = ParticleToWorldT[2];
#endif
#if USE_PARTICLE_WORLD_TO_LOCAL
float4x4 WorldToParticleT = transpose(Intermediates.WorldToParticle);
Interpolants.WorldToParticle[0] = WorldToParticleT[0];
Interpolants.WorldToParticle[1] = WorldToParticleT[1];
Interpolants.WorldToParticle[2] = WorldToParticleT[2];
#endif
#if INSTANCED_STEREO
Interpolants.EyeIndex = 0;
#endif
return Interpolants;
}
// @return previous translated world position
float4 VertexFactoryGetPreviousWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
{
return CalcPrevWorldPosition(Input);
}
#if NEEDS_VERTEX_FACTORY_INTERPOLATION
struct FVertexFactoryRayTracingInterpolants
{
FVertexFactoryInterpolantsVSToPS InterpolantsVSToPS;
};
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;
// Do we really need to interpolate TangentToWorld2 here? It should be replaced by the
// interpolated normal from 'whatever' interpolation scheme we're using
INTERPOLATE_MEMBER(InterpolantsVSToPS.TangentToWorld0.xyz);
INTERPOLATE_MEMBER(InterpolantsVSToPS.TangentToWorld2);
#if INTERPOLATE_VERTEX_COLOR
INTERPOLATE_MEMBER(InterpolantsVSToPS.VertexColor);
#endif
#if NEEDS_PARTICLE_COLOR
INTERPOLATE_MEMBER(InterpolantsVSToPS.ParticleColor);
#endif
#if NUM_TEX_COORD_INTERPOLATORS
for (int i = 0; i < (NUM_TEX_COORD_INTERPOLATORS + 1) / 2; ++i)
{
INTERPOLATE_MEMBER(InterpolantsVSToPS.TexCoords[i]);
}
#endif
#if USE_DYNAMIC_PARAMETERS
INTERPOLATE_MEMBER(InterpolantsVSToPS.DynamicParameter);
#endif //USE_DYNAMIC_PARAMETERS
return O;
}
#endif // #if NEEDS_VERTEX_FACTORY_INTERPOLATION
float4 VertexFactoryGetTranslatedPrimitiveVolumeBounds(FVertexFactoryInterpolantsVSToPS Interpolants)
{
return 0;
}
uint VertexFactoryGetPrimitiveId(FVertexFactoryInterpolantsVSToPS Interpolants)
{
return 0;
}
#include "VertexFactoryDefaultInterface.ush"