Files
UnrealEngine/Engine/Shaders/Private/VectorFieldVisualizationVertexFactory.ush
2025-05-18 13:04:45 +08:00

245 lines
8.4 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
VectorFieldVisualizationVertexFactory.usf: Vertex factory for GPU simulated particles.
=============================================================================*/
#define PARTICLE_SPRITE_FACTORY 1
#include "VertexFactoryCommon.ush"
/** Texture containing the vector field. */
Texture3D VectorFieldTexture;
SamplerState VectorFieldTextureSampler;
#undef GetInstanceIdFromVF
#define GetInstanceIdFromVF(VFInput) (GetInstanceId(VFInput.InstanceId))
/**
* Vertex attributes to fetch.
*/
struct FVertexFactoryInput
{
/** Unique vertex ID. */
uint VertexId : SV_VertexID;
/** Unique instance ID. */
uint InstanceId : SV_InstanceID;
VF_MOBILE_MULTI_VIEW_DECLARE_INPUT_BLOCK()
};
/**
* Attributes to interpolate from the vertex shader to the pixel shader.
*/
struct FVertexFactoryInterpolantsVSToPS
{
/** Dummy value to interpolate. */
float2 DummyTexCoord : TEXCOORD0;
};
/**
* Intermediate values computed in the vertex shader.
*/
struct FVertexFactoryIntermediates
{
/** Dummy value. */
float4 WorldPosition;
/** Position before transformation to worldspace */
float4 PositionInstanceSpace;
/** Cached primitive and instance data */
FSceneDataIntermediates SceneData;
};
FPrimitiveSceneData GetPrimitiveData(FVertexFactoryIntermediates Intermediates)
{
return Intermediates.SceneData.Primitive;
}
/**
* Computes intermediates for the given vertex.
* @param Input - Vertex attributes.
* @returns the computed intermediate values.
*/
FVertexFactoryIntermediates GetVertexFactoryIntermediates( FVertexFactoryInput Input )
{
// Determine how to index in to the volume texture.
const float3 VoxelSize = VectorFieldVis.VoxelSize.xyz;
const float3 HalfVoxelOffset = VoxelSize.xyz * 0.5f;
const float3 VoxelMultipliers = float3(1, VoxelSize.x, VoxelSize.x * VoxelSize.y);
const float3 VoxelIndex = floor((float3)GetInstanceId(Input.InstanceId).xxx * VoxelMultipliers.xyz);
const float3 VoxelUV = frac(VoxelIndex.xyz * VoxelSize.xyz) + HalfVoxelOffset;
// Read vector for this voxel.
const float3 Force = Texture3DSampleLevel(VectorFieldTexture, VectorFieldTextureSampler, VoxelUV, 0).xyz;
const float ForceScale = min(length(Force) * VectorFieldVis.Scale, 10.0f);
const float3 Vec = normalize(Force) * ForceScale;
// The base position for this vector.
const FDFMatrix VolumeToWorld = MakeDFMatrix(VectorFieldVis.VolumeToWorldHigh, VectorFieldVis.RelativeVolumeToWorld);
const float4 VolumeSpacePosition = float4(VoxelUV.xyz, 1);
float3 BasePosition = DFTransformLocalToTranslatedWorld(VolumeSpacePosition.xyz, VolumeToWorld, ResolvedView.PreViewTranslation).xyz;
const float3 Position = BasePosition + float(Input.VertexId) * mul(float4(Vec,0), VectorFieldVis.VolumeToWorldNoScale).xyz;
// Build and return the set of intermediates.
FVertexFactoryIntermediates Intermediates;
Intermediates.SceneData = VF_GPUSCENE_GET_INTERMEDIATES(Input);
Intermediates.WorldPosition = float4(Position.xyz,1);
Intermediates.PositionInstanceSpace = VolumeSpacePosition;
return Intermediates;
}
/**
* Computes material parameterss for a given pixel.
* @param Interpolants - Attributes interpolated from the vertex shader.
* @returns per-pixel material parameters.
*/
FMaterialPixelParameters GetMaterialPixelParameters( FVertexFactoryInterpolantsVSToPS Interpolants, float4 SvPosition )
{
// GetMaterialPixelParameters is responsible for fully initializing the result
FMaterialPixelParameters Result = MakeInitializedMaterialPixelParameters();
// Note that a non-zero texture coordinate is used to prevent the compiler
// from optimizing out texture lookups that can cause mandatory requirements
// to not be bound.
#if NUM_MATERIAL_TEXCOORDS
UNROLL
for(int CoordinateIndex = 0;CoordinateIndex < NUM_MATERIAL_TEXCOORDS;CoordinateIndex++)
{
Result.TexCoords[CoordinateIndex] = Interpolants.DummyTexCoord;
}
#endif //NUM_MATERIAL_TEXCOORDS
Result.VertexColor = 1;
Result.TwoSidedSign = 1;
return Result;
}
float3 VertexFactoryGetPreviousInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates);
float3 VertexFactoryGetInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates);
/**
* Computes material parameters for a given vertex.
* @param Input - Attributes for this vertex.
* @param Intermediates - Intermediates computed for this vertex.
* @param WorldPosition - The position of this vertex in world space.
* @param TangentToLocal - The tangent basis for this vertex.
* @returns per-vertex material parameters.
*/
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);
}
else
{
Result.PositionInstanceSpace = VertexFactoryGetInstanceSpacePosition(Input, Intermediates);
}
Result.PositionPrimitiveSpace = Result.PositionInstanceSpace; // No support for instancing, so instance == primitive
Result.VertexColor = float4(1,1,1,1);
Result.TangentToWorld = mul(TangentToLocal, GetLocalToWorld3x3());
Result.PrevFrameLocalToWorld = GetPrimitiveDataFromUniformBuffer().LocalToWorld;
Result.LWCData = MakeMaterialLWCData(Result);
return Result;
}
/**
* Computes the world space position of this vertex.
* @param Input - Vertex attributes.
* @param Intermediates - Intermediates computed for this vertex.
* @returns the position of this vertex in world space.
*/
float4 VertexFactoryGetWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates )
{
return Intermediates.WorldPosition;
}
float3 VertexFactoryGetPreviousInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
{
return Intermediates.PositionInstanceSpace.xyz;
}
float3 VertexFactoryGetWorldNormal(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
{
return float3(0,0,1);
}
float4 VertexFactoryGetRasterizedWorldPosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, float4 TranslatedWorldPosition)
{
return TranslatedWorldPosition;
}
float3 VertexFactoryGetPositionForVertexLighting(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, float3 TranslatedWorldPosition)
{
return TranslatedWorldPosition;
}
/**
* Constructs values that need to be interpolated from the vertex shader to the pixel shader.
* @param Input - Vertex attributes.
* @param Intermediates - Intermediates computed for this vertex.
* @returns interpolants.
*/
FVertexFactoryInterpolantsVSToPS VertexFactoryGetInterpolantsVSToPS( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates, FMaterialVertexParameters VertexParameters )
{
FVertexFactoryInterpolantsVSToPS Interpolants;
Interpolants.DummyTexCoord = float2(0,0);
return Interpolants;
}
/**
* Computes the position of this vertex last frame in world space.
* @param Input - Vertex attributes.
* @param Intermediates - Intermediates computed for this vertex.
* @returns the previous position of this vertex in world space.
*/
float4 VertexFactoryGetPreviousWorldPosition( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates )
{
return Intermediates.WorldPosition;
}
float3 VertexFactoryGetInstanceSpacePosition(FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates)
{
return Intermediates.PositionInstanceSpace.xyz;
}
/**
* Computes the tangent basis for this vertex in world space.
* @param Input - Vertex attributes.
* @param Intermediates - Intermediates computed for this vertex.
* @returns the tangent basis for this vertex in world space.
*/
float3x3 VertexFactoryGetTangentToLocal( FVertexFactoryInput Input, FVertexFactoryIntermediates Intermediates )
{
float3x3 TangentToLocal;
TangentToLocal[0] = float3(1,0,0);
TangentToLocal[1] = float3(0,1,0);
TangentToLocal[2] = float3(0,0,1);
return TangentToLocal;
}
float4 VertexFactoryGetTranslatedPrimitiveVolumeBounds(FVertexFactoryInterpolantsVSToPS Interpolants)
{
return 0;
}
uint VertexFactoryGetPrimitiveId(FVertexFactoryInterpolantsVSToPS Interpolants)
{
return 0;
}
#include "VertexFactoryDefaultInterface.ush"