You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Basic approach is to add HLSL types FLWCScalar, FLWCMatrix, FLWCVector, etc. Inside shaders, absolute world space position values should be represented as FLWCVector3. Matrices that transform *into* absolute world space become FLWCMatrix. Matrices that transform *from* world space become FLWCInverseMatrix. Generally LWC values work by extending the regular 'float' value with an additional tile coordinate. Final tile size will be a trade-off between scale/accuracy; I'm using 256k for now, but may need to be adjusted. Value represented by a FLWCVector thus becomes V.Tile * TileSize + V.Offset. Most operations can be performed directly on LWC values. There are HLSL functions like LWCAdd, LWCSub, LWCMultiply, LWCDivide (operator overloading would be really nice here). The goal is to stay with LWC values for as long as needed, then convert to regular float values when possible. One thing that comes up a lot is working in translated (rather than absolute) world space. WorldSpace + View.PrevPreViewTranslation = TranslatedWorldspace. Except 'View.PrevPreViewTranslation' is now a FLWCVector3, and WorldSpace quantities should be as well. So that becomes LWCAdd(WorldSpace, View.PrevPreViewTranslation) = TranslatedWorldspace. Assuming that we're talking about a position that's "reasonably close" to the camera, it should be safe to convert the translated WS value to float. The 'tile' coordinate of the 2 LWC values should cancel out when added together in this case. I've done some work throughout the shader code to do this. Materials are fully supporting LWC-values as well. Projective texturing and vertex animation materials that I've tested work correctly even when positioned "far away" from the origin. Lots of work remains to fully convert all of our shader code. There's a function LWCHackToFloat(), which is a simple wrapper for LWCToFloat(). The idea of HackToFloat is to mark places that need further attention, where I'm simply converting absolute WS positions to float, to get shaders to compile. Shaders converted in this way should continue to work for all existing content (without LWC-scale values), but they will break if positions get too large. General overview of changed files: LargeWorldCoordinates.ush - This defines the FLWC types and operations GPUScene.cpp, SceneData.ush - Primitives add an extra 'float3' tile coordinate. Instance data is unchanged, so instances need to stay within single-precision range of the primitive origin. Could potentially split instances behind the scenes (I think) if we don't want this limitation HLSLMaterialDerivativeAutogen.cpp, HLSLMaterialTranslator.cpp, Preshader.cpp - Translated materials to use LWC values SceneView.cpp, SceneRelativeViewMatrices.cpp, ShaderCompiler.cpp, InstancedStereo.ush - View uniform buffer includes LWC values where appropriate #jira UE-117101 #rb arne.schober, Michael.Galetzka [CL 17787435 by Ben Ingram in ue5-main branch]
212 lines
7.1 KiB
Plaintext
212 lines
7.1 KiB
Plaintext
// 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;
|
|
|
|
/**
|
|
* Vertex attributes to fetch.
|
|
*/
|
|
struct FVertexFactoryInput
|
|
{
|
|
/** Unique vertex ID. */
|
|
uint VertexId : SV_VertexID;
|
|
/** Unique instance ID. */
|
|
uint InstanceId : SV_InstanceID;
|
|
};
|
|
|
|
/**
|
|
* Attributes to interpolate from the vertex shader to the pixel shader.
|
|
*/
|
|
struct FVertexFactoryInterpolantsVSToPS
|
|
{
|
|
/** Dummy value to interpolate. */
|
|
float2 DummyTexCoord : TEXCOORD0;
|
|
|
|
#if INSTANCED_STEREO
|
|
nointerpolation uint EyeIndex : EYE_INDEX;
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* Intermediate values computed in the vertex shader.
|
|
*/
|
|
struct FVertexFactoryIntermediates
|
|
{
|
|
/** Dummy value. */
|
|
float4 WorldPosition;
|
|
/** 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 float3 BasePosition = mul(float4(VoxelUV.xyz,1), VectorFieldVis.VolumeToWorld).xyz - LWCHackToFloat(ResolvedView.WorldCameraOrigin);
|
|
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);
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
FMaterialVertexParameters Result = (FMaterialVertexParameters)0;
|
|
Result.SceneData = Intermediates.SceneData;
|
|
Result.WorldPosition = WorldPosition;
|
|
Result.VertexColor = float4(1,1,1,1);
|
|
Result.TangentToWorld = mul(TangentToLocal, GetLocalToWorld3x3());
|
|
Result.PrevFrameLocalToWorld = GetPrimitiveDataFromUniformBuffer().LocalToWorld;
|
|
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 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);
|
|
|
|
#if INSTANCED_STEREO
|
|
Interpolants.EyeIndex = 0;
|
|
#endif
|
|
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* 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" |