508 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			508 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
 | 
						|
 | 
						|
/*=============================================================================
 | 
						|
	CesiumPointAttenuationVertexFactory.ush: point attenuation vertex factory shader code.
 | 
						|
=============================================================================*/
 | 
						|
 | 
						|
#ifndef ENGINE_VERSION_5_4_OR_HIGHER
 | 
						|
#define ENGINE_VERSION_5_4_OR_HIGHER 0
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef ENGINE_VERSION_5_5_OR_HIGHER
 | 
						|
#define ENGINE_VERSION_5_5_OR_HIGHER 0
 | 
						|
#endif
 | 
						|
 | 
						|
#include "/Engine/Private/Common.ush"
 | 
						|
#include "/Engine/Private/VertexFactoryCommon.ush"
 | 
						|
 | 
						|
Buffer<float> PositionBuffer;
 | 
						|
Buffer<float4> PackedTangentsBuffer;
 | 
						|
Buffer<float4> ColorBuffer;
 | 
						|
Buffer<float2> TexCoordBuffer;
 | 
						|
uint NumTexCoords;
 | 
						|
 | 
						|
// Whether or not the point cloud has per-point colors.
 | 
						|
uint bHasPointColors;
 | 
						|
float3 AttenuationParameters;
 | 
						|
 | 
						|
#if INSTANCED_STEREO
 | 
						|
uint InstancedEyeIndex;
 | 
						|
#endif
 | 
						|
 | 
						|
// This function does not exist in UE 5.0, so remove the function call here
 | 
						|
// to avoid compilation errors.
 | 
						|
#ifndef VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK
 | 
						|
#define VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * Per-vertex input. Only a position buffer is bound.
 | 
						|
 */
 | 
						|
struct FVertexFactoryInput
 | 
						|
{
 | 
						|
  	uint    VertexId    : SV_VertexID;
 | 
						|
#if USE_INSTANCING
 | 
						|
  	uint    InstanceId  : SV_InstanceID;
 | 
						|
#else
 | 
						|
	VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Per-vertex inputs. Used by passes with a trimmed down position-only shader.
 | 
						|
 */
 | 
						|
struct FPositionOnlyVertexFactoryInput
 | 
						|
{
 | 
						|
  	float4  Position	: ATTRIBUTE0;
 | 
						|
  	uint    VertexId	: SV_VertexID;
 | 
						|
#if USE_INSTANCING
 | 
						|
  	uint    InstanceId  : SV_InstanceID;
 | 
						|
#else
 | 
						|
	VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Per-vertex inputs. Used by passes with a trimmed down position-and-normal-only shader.
 | 
						|
 */
 | 
						|
struct FPositionAndNormalOnlyVertexFactoryInput
 | 
						|
{
 | 
						|
  	float4  Position	: ATTRIBUTE0;
 | 
						|
  	float4	Normal		: ATTRIBUTE2;
 | 
						|
  	uint    VertexId	: SV_VertexID;
 | 
						|
#if USE_INSTANCING
 | 
						|
  	uint    InstanceId  : SV_InstanceID;
 | 
						|
#else
 | 
						|
	VF_INSTANCED_STEREO_DECLARE_INPUT_BLOCK()
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
/** Cached intermediates that would otherwise have to be computed multiple times. */
 | 
						|
struct FVertexFactoryIntermediates
 | 
						|
{
 | 
						|
  	uint PointIndex;
 | 
						|
  	uint CornerIndex;
 | 
						|
 | 
						|
  	float3 Position;
 | 
						|
  	float4 WorldPosition;
 | 
						|
 | 
						|
  	half3x3 TangentToLocal;
 | 
						|
  	half3x3 TangentToWorld;
 | 
						|
  	half TangentToWorldSign;
 | 
						|
 | 
						|
  	half4 Color;
 | 
						|
 | 
						|
  	/** Cached primitive and instance data */
 | 
						|
  	FSceneDataIntermediates SceneData;
 | 
						|
};
 | 
						|
 | 
						|
struct FVertexFactoryInterpolantsVSToPS
 | 
						|
{
 | 
						|
  	TANGENTTOWORLD_INTERPOLATOR_BLOCK
 | 
						|
  	half4  Color : COLOR0;
 | 
						|
 | 
						|
#if NUM_TEX_COORD_INTERPOLATORS
 | 
						|
  	float4  TexCoords[(NUM_TEX_COORD_INTERPOLATORS+1)/2]  : TEXCOORD0;
 | 
						|
#endif
 | 
						|
 | 
						|
#if INSTANCED_STEREO
 | 
						|
  	nointerpolation uint EyeIndex : PACKED_EYE_INDEX;
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
/** Helper function for position-only passes that don't require point index for other intermediates.*/
 | 
						|
float4 GetWorldPosition(uint VertexId)
 | 
						|
{
 | 
						|
  	uint PointIndex = VertexId / 4;
 | 
						|
  	float3 Position = float3(0, 0, 0);
 | 
						|
  	Position.x = PositionBuffer[PointIndex * 3 + 0];
 | 
						|
  	Position.y = PositionBuffer[PointIndex * 3 + 1];
 | 
						|
  	Position.z = PositionBuffer[PointIndex * 3 + 2];
 | 
						|
 | 
						|
  	return TransformLocalToTranslatedWorld(Position);
 | 
						|
}
 | 
						|
 | 
						|
/** Computes TangentToLocal based on the Manual Vertex Fetch method in LocalVertexFactory.ush */
 | 
						|
half3x3 CalculateTangentToLocal(uint PointIndex, out float TangentSign)
 | 
						|
{
 | 
						|
  	half3 TangentInputX = PackedTangentsBuffer[2 * PointIndex + 0].xyz;
 | 
						|
  	half4 TangentInputZ = PackedTangentsBuffer[2 * PointIndex + 1].xyzw;
 | 
						|
 | 
						|
  	half3 TangentX = TangentBias(TangentInputX);
 | 
						|
  	half4 TangentZ = TangentBias(TangentInputZ);
 | 
						|
 | 
						|
  	TangentSign = TangentZ.w;
 | 
						|
 | 
						|
  	// 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 errors since TangentX was passed in as a quantized vertex input
 | 
						|
  	half3x3 Result;
 | 
						|
  	Result[0] = cross(TangentY, TangentZ.xyz) * TangentZ.w;
 | 
						|
  	Result[1] = TangentY;
 | 
						|
  	Result[2] = TangentZ.xyz;
 | 
						|
 | 
						|
  	return Result;
 | 
						|
}
 | 
						|
 | 
						|
half3x3 CalculateTangentToWorldNoScale(half3x3 TangentToLocal)
 | 
						|
{
 | 
						|
  	half3x3 LocalToWorld = GetLocalToWorld3x3();
 | 
						|
  	half3 InvScale = Primitive.InvNonUniformScale;
 | 
						|
  	LocalToWorld[0] *= InvScale.x;
 | 
						|
  	LocalToWorld[1] *= InvScale.y;
 | 
						|
  	LocalToWorld[2] *= InvScale.z;
 | 
						|
  	return mul(TangentToLocal, LocalToWorld);
 | 
						|
}
 | 
						|
 | 
						|
/** Helper function for position and normal-only passes that don't require point index for other intermediates.*/
 | 
						|
float3 GetPointNormal(uint VertexId) {
 | 
						|
  	uint PointIndex = VertexId / 4;
 | 
						|
  	return PackedTangentsBuffer[2 * PointIndex + 1].xyz;
 | 
						|
}
 | 
						|
 | 
						|
FVertexFactoryIntermediates GetVertexFactoryIntermediates(FVertexFactoryInput Input)
 | 
						|
{
 | 
						|
  	FVertexFactoryIntermediates Intermediates = (FVertexFactoryIntermediates)0;
 | 
						|
  	Intermediates.SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
 | 
						|
 | 
						|
  	uint PointIndex = Input.VertexId / 4;
 | 
						|
  	uint CornerIndex = Input.VertexId - (PointIndex * 4);
 | 
						|
 | 
						|
  	Intermediates.PointIndex = PointIndex;
 | 
						|
  	Intermediates.CornerIndex = CornerIndex;
 | 
						|
 | 
						|
  	Intermediates.Position.x = PositionBuffer[PointIndex * 3 + 0];
 | 
						|
  	Intermediates.Position.y = PositionBuffer[PointIndex * 3 + 1];
 | 
						|
  	Intermediates.Position.z = PositionBuffer[PointIndex * 3 + 2];
 | 
						|
  	Intermediates.WorldPosition = TransformLocalToTranslatedWorld(Intermediates.Position);
 | 
						|
 | 
						|
  	float TangentSign = 1.0;
 | 
						|
  	Intermediates.TangentToLocal = CalculateTangentToLocal(Intermediates.PointIndex, TangentSign);
 | 
						|
  	Intermediates.TangentToWorld = CalculateTangentToWorldNoScale(Intermediates.TangentToLocal);
 | 
						|
  	Intermediates.TangentToWorldSign =  Intermediates.SceneData.InstanceData.DeterminantSign;
 | 
						|
 | 
						|
  	bool bHasColors = bHasPointColors;
 | 
						|
  	float4 Color = bHasColors ? ColorBuffer[PointIndex] : float4(1, 1, 1, 1);
 | 
						|
  	Intermediates.Color = Color FMANUALFETCH_COLOR_COMPONENT_SWIZZLE;
 | 
						|
 | 
						|
  	return Intermediates;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#if NUM_TEX_COORD_INTERPOLATORS
 | 
						|
/** Taken from LocalVertexFactoryCommon.ush. */
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
FVertexFactoryInterpolantsVSToPS VertexFactoryGetInterpolantsVSToPS(
 | 
						|
  	FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, FMaterialVertexParameters VertexParameters)
 | 
						|
{
 | 
						|
  	FVertexFactoryInterpolantsVSToPS Interpolants = (FVertexFactoryInterpolantsVSToPS)0;
 | 
						|
  	Interpolants.TangentToWorld0 = float4(Intermediates.TangentToWorld[0], 0);
 | 
						|
  	Interpolants.TangentToWorld2 = float4(Intermediates.TangentToWorld[2], Intermediates.TangentToWorldSign);
 | 
						|
  	Interpolants.Color = Intermediates.Color;
 | 
						|
 | 
						|
  	#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
 | 
						|
 | 
						|
#if INSTANCED_STEREO
 | 
						|
  	Interpolants.EyeIndex = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
  	return Interpolants;
 | 
						|
}
 | 
						|
 | 
						|
half3x3 VertexFactoryGetTangentToLocal(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
 | 
						|
{
 | 
						|
  	return Intermediates.TangentToLocal;
 | 
						|
}
 | 
						|
 | 
						|
float4 VertexFactoryGetWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
 | 
						|
{
 | 
						|
  	return Intermediates.WorldPosition;
 | 
						|
}
 | 
						|
 | 
						|
float4 VertexFactoryGetWorldPosition(FPositionOnlyVertexFactoryInput Input)
 | 
						|
{
 | 
						|
  	return GetWorldPosition(Input.VertexId);
 | 
						|
}
 | 
						|
 | 
						|
float4 VertexFactoryGetWorldPosition(FPositionAndNormalOnlyVertexFactoryInput Input)
 | 
						|
{
 | 
						|
  	return GetWorldPosition(Input.VertexId);
 | 
						|
}
 | 
						|
 | 
						|
// local position relative to instance
 | 
						|
float3 VertexFactoryGetInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
 | 
						|
{
 | 
						|
	// No support for instancing, so instance == primitive
 | 
						|
  return Intermediates.Position;
 | 
						|
}
 | 
						|
 | 
						|
float3 VertexFactoryGetWorldNormal(FPositionAndNormalOnlyVertexFactoryInput Input)
 | 
						|
{
 | 
						|
  	float3 PointNormal = GetPointNormal(Input.VertexId);
 | 
						|
  	return RotateLocalToWorld(PointNormal);
 | 
						|
}
 | 
						|
 | 
						|
float3 VertexFactoryGetWorldNormal(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
 | 
						|
{
 | 
						|
  	return Intermediates.TangentToWorld[2];
 | 
						|
}
 | 
						|
 | 
						|
float4 VertexFactoryGetPreviousWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
 | 
						|
{
 | 
						|
  #ifdef DFGetX
 | 
						|
    // When double floats exist (UE 5.4), use the df tranform functions
 | 
						|
    return DFTransformLocalToTranslatedWorld(Intermediates.Position, Intermediates.SceneData.InstanceData.PrevLocalToWorld, ResolvedView.PrevPreViewTranslation);
 | 
						|
  #else
 | 
						|
    return mul(float4(Intermediates.Position, 1),
 | 
						|
  	  	LWCMultiplyTranslation(Intermediates.SceneData.InstanceData.PrevLocalToWorld, ResolvedView.PrevPreViewTranslation));
 | 
						|
  #endif
 | 
						|
}
 | 
						|
 | 
						|
// local position relative to instance
 | 
						|
float3 VertexFactoryGetPreviousInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
 | 
						|
{
 | 
						|
	// No support for instancing, so instance == primitive
 | 
						|
  return Intermediates.Position;
 | 
						|
}
 | 
						|
 | 
						|
float4 ApplyAttenuation(float4 WorldPosition, uint CornerIndex) {
 | 
						|
    // These offsets generate the quad like so:
 | 
						|
   	// 1 --- 2
 | 
						|
  	// |  /  |
 | 
						|
  	// 0 --- 3
 | 
						|
  	// Unreal uses counter-clockwise winding order, but Cesium models are created
 | 
						|
    // with a y-inverting transform. To compensate, we create the quad facing the
 | 
						|
    // wrong way, such that when the transform is applied, the quad faces the right
 | 
						|
    // way.
 | 
						|
 | 
						|
  	// Results in -0.5 for 0, 1 and 0.5 for 2, 3
 | 
						|
  	float OffsetX = CornerIndex / 2 - 0.5;
 | 
						|
  	float OffsetY = -0.5f;
 | 
						|
  	if (CornerIndex == 1 || CornerIndex == 2) {
 | 
						|
  	  	OffsetY = 0.5;
 | 
						|
  	}
 | 
						|
 | 
						|
  	float4 PositionView = mul(WorldPosition, ResolvedView.TranslatedWorldToView);
 | 
						|
  	float4 PositionClip = mul(WorldPosition, ResolvedView.TranslatedWorldToClip);
 | 
						|
 | 
						|
  	float MaximumPointSize = AttenuationParameters.x;
 | 
						|
  	float GeometricError = AttenuationParameters.y;
 | 
						|
  	float DepthMultiplier = AttenuationParameters.z;
 | 
						|
  	float Depth = PositionView.z / 100; // Get depth in meters
 | 
						|
  	float PointSize = min((GeometricError / Depth) * DepthMultiplier, MaximumPointSize);
 | 
						|
 | 
						|
  	float2 PixelOffset = PointSize * float2(OffsetX, OffsetY);
 | 
						|
  	float2 ScreenOffset = PixelOffset * ResolvedView.ViewSizeAndInvSize.zw;
 | 
						|
  	float2 ClipOffset = ScreenOffset * PositionClip.w;
 | 
						|
  	float4 ViewOffset = mul(float4(ClipOffset, PositionClip.z, 1), ResolvedView.ClipToView);
 | 
						|
  	ViewOffset /= ViewOffset.w;
 | 
						|
 | 
						|
  	// Adjust x-component for the left-handed coordinate system.
 | 
						|
  	float3 AttenuatedPosition = WorldPosition.xyz + (-ViewOffset.x * ResolvedView.ViewRight + ViewOffset.y * ResolvedView.ViewUp);
 | 
						|
  	return float4(AttenuatedPosition, 1);
 | 
						|
}
 | 
						|
 | 
						|
float4 VertexFactoryGetRasterizedWorldPosition(
 | 
						|
  	FVertexFactoryInput Input,
 | 
						|
  	FVertexFactoryIntermediates Intermediates,
 | 
						|
  	float4 InWorldPosition)
 | 
						|
{
 | 
						|
  	return ApplyAttenuation(InWorldPosition, Intermediates.CornerIndex);
 | 
						|
}
 | 
						|
 | 
						|
float3 VertexFactoryGetPositionForVertexLighting(
 | 
						|
  	FVertexFactoryInput Input,
 | 
						|
  	FVertexFactoryIntermediates Intermediates,
 | 
						|
  	float3 TranslatedWorldPosition)
 | 
						|
{
 | 
						|
  	return TranslatedWorldPosition;
 | 
						|
}
 | 
						|
 | 
						|
/** 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,
 | 
						|
  	half3x3 TangentToLocal,
 | 
						|
  	bool bIsPreviousFrame = false)
 | 
						|
{
 | 
						|
#if ENGINE_VERSION_5_5_OR_HIGHER
 | 
						|
    FMaterialVertexParameters Result = MakeInitializedMaterialVertexParameters();
 | 
						|
    if (bIsPreviousFrame)
 | 
						|
    {
 | 
						|
      Result.PositionInstanceSpace = VertexFactoryGetPreviousInstanceSpacePosition(Input, Intermediates);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      Result.PositionInstanceSpace = VertexFactoryGetInstanceSpacePosition(Input, Intermediates);
 | 
						|
    }
 | 
						|
    Result.PositionPrimitiveSpace = Result.PositionInstanceSpace; // No support for instancing, so instance == primitive
 | 
						|
#else
 | 
						|
  	FMaterialVertexParameters Result = (FMaterialVertexParameters)0;
 | 
						|
#endif
 | 
						|
 | 
						|
  	Result.SceneData = Intermediates.SceneData;
 | 
						|
  	Result.WorldPosition = WorldPosition;
 | 
						|
  	Result.TangentToWorld = Intermediates.TangentToWorld;
 | 
						|
  	Result.PreSkinnedNormal = TangentToLocal[2];
 | 
						|
  	Result.PreSkinnedPosition = WorldPosition;
 | 
						|
  	Result.VertexColor = Intermediates.Color;
 | 
						|
 | 
						|
#if NUM_MATERIAL_TEXCOORDS_VERTEX
 | 
						|
  	UNROLL
 | 
						|
  	for (uint CoordinateIndex = 0; CoordinateIndex < NUM_MATERIAL_TEXCOORDS_VERTEX; CoordinateIndex++)
 | 
						|
  	{
 | 
						|
  	  	// Clamp coordinates to mesh's maximum as materials can request more than are available
 | 
						|
  	  	uint ClampedCoordinateIndex = min(CoordinateIndex, NumTexCoords - 1);
 | 
						|
  	  	Result.TexCoords[CoordinateIndex] = TexCoordBuffer[NumTexCoords * Intermediates.PointIndex + ClampedCoordinateIndex];
 | 
						|
  	}
 | 
						|
#endif
 | 
						|
 | 
						|
#if ENGINE_VERSION_5_4_OR_HIGHER
 | 
						|
  	Result.LWCData = MakeMaterialLWCData(Result);
 | 
						|
#endif
 | 
						|
  
 | 
						|
  	return Result;
 | 
						|
}
 | 
						|
 | 
						|
FMaterialPixelParameters GetMaterialPixelParameters(FVertexFactoryInterpolantsVSToPS Interpolants, float4 SvPosition)
 | 
						|
{
 | 
						|
  	FMaterialPixelParameters Result = MakeInitializedMaterialPixelParameters();
 | 
						|
 | 
						|
  	Result.Particle.Color = half4(1, 1, 1, 1);
 | 
						|
  	Result.TwoSidedSign = 1;
 | 
						|
  	Result.VertexColor = Interpolants.Color;
 | 
						|
 | 
						|
  	half3 TangentToWorld0 = Interpolants.TangentToWorld0.xyz;
 | 
						|
  	half4 TangentToWorld2 = Interpolants.TangentToWorld2;
 | 
						|
  	Result.UnMirrored = TangentToWorld2.w;
 | 
						|
  	Result.TangentToWorld = AssembleTangentToWorld(TangentToWorld0, TangentToWorld2);
 | 
						|
 | 
						|
#if NUM_TEX_COORD_INTERPOLATORS
 | 
						|
  	UNROLL
 | 
						|
  	for( int CoordinateIndex = 0; CoordinateIndex < NUM_TEX_COORD_INTERPOLATORS; CoordinateIndex++ )
 | 
						|
  	{
 | 
						|
  	  	Result.TexCoords[CoordinateIndex] = GetUV(Interpolants, CoordinateIndex);
 | 
						|
  	}
 | 
						|
#endif
 | 
						|
 | 
						|
  	return Result;
 | 
						|
}
 | 
						|
 | 
						|
#if USE_INSTANCING
 | 
						|
float4 VertexFactoryGetInstanceHitProxyId(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates) { return 0; }
 | 
						|
#endif
 | 
						|
 | 
						|
float4 VertexFactoryGetTranslatedPrimitiveVolumeBounds(FVertexFactoryInterpolantsVSToPS Interpolants)
 | 
						|
{
 | 
						|
  	FPrimitiveSceneData PrimitiveData = GetPrimitiveDataFromUniformBuffer();
 | 
						|
  	return float4(LWCToFloat(LWCAdd(PrimitiveData.ObjectWorldPosition, ResolvedView.PreViewTranslation)), PrimitiveData.ObjectRadius);
 | 
						|
}
 | 
						|
 | 
						|
#if INSTANCED_STEREO
 | 
						|
uint VertexFactoryGetEyeIndex(uint InstanceId)
 | 
						|
{
 | 
						|
#if USE_INSTANCING
 | 
						|
  	return InstancedEyeIndex;
 | 
						|
#else
 | 
						|
  	return InstanceId & 1;
 | 
						|
#endif
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#if NEEDS_VERTEX_FACTORY_INTERPOLATION
 | 
						|
struct FVertexFactoryRayTracingInterpolants
 | 
						|
{
 | 
						|
  	FVertexFactoryInterpolantsVSToPS InterpolantsVSToPS;
 | 
						|
};
 | 
						|
 | 
						|
float2 VertexFactoryGetRayTracingTextureCoordinate(FVertexFactoryRayTracingInterpolants Interpolants)
 | 
						|
{
 | 
						|
#if NUM_MATERIAL_TEXCOORDS
 | 
						|
  	return Interpolants.InterpolantsVSToPS.TexCoords[0].xy;
 | 
						|
#else
 | 
						|
  	return float2(0,0);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
  	return O;
 | 
						|
}
 | 
						|
#endif // #if NEEDS_VERTEX_FACTORY_INTERPOLATION
 | 
						|
 | 
						|
uint VertexFactoryGetPrimitiveId(FVertexFactoryInterpolantsVSToPS Interpolants)
 | 
						|
{
 | 
						|
  	return 0;
 | 
						|
}
 | 
						|
 | 
						|
#include "/Engine/Private/VertexFactoryDefaultInterface.ush"
 |