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"
							 |