You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
- Raytracing shadows/reflections/AO/GI/etc and path tracer now work in large worlds. - Updated parts of Lumen using raytracing to work in large worlds. - This change doesn't not address (all) GPU Lightmass issues in large worlds. Changes: - Build TLAS with instances in translated world space. - Move ray origin to translated world space. - Updated raytracing shaders to use translated world space (most LWCHackToFloat in these shaders are now gone). - Store gather points positions in translated world space. - Removed unused RayTracingDynamicMeshVS(...) #rb Yuriy.ODonnell, Patrick.Kelly, chris.kulla, rob.krajcarski #jira UE-140558 #preflight 620bb3ff4353dc61c7f51e64 [CL 18995354 by tiago costa in ue5-main branch]
112 lines
4.3 KiB
Plaintext
112 lines
4.3 KiB
Plaintext
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
RayTracingDynamicMesh.usf
|
|
=============================================================================*/
|
|
|
|
#define RAY_TRACING_DYNAMIC_MESH_SHADER_VERSION 0xFA5CE282 // Change to force shader compilation of this shader
|
|
|
|
#include "/Engine/Private/Common.ush"
|
|
#include "/Engine/Generated/Material.ush"
|
|
#include "/Engine/Generated/VertexFactory.ush"
|
|
|
|
struct FRayTracingDynamicMeshVSToGS
|
|
{
|
|
float4 WorldPosition : SV_POSITION;
|
|
};
|
|
|
|
// Must match GetUniformMeshStreamOutLayout and TRIANGLE_VERTEX_DATA_STRIDE
|
|
struct FRayTracingDynamicMeshVertex
|
|
{
|
|
float4 WorldPosition : SV_POSITION;
|
|
};
|
|
|
|
[maxvertexcount(3)]
|
|
void RayTracingDynamicMeshGS(triangle FRayTracingDynamicMeshVSToGS Inputs[3], inout TriangleStream<FRayTracingDynamicMeshVertex> OutStream)
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
FRayTracingDynamicMeshVSToGS Input = Inputs[i];
|
|
|
|
FRayTracingDynamicMeshVertex Vertex;
|
|
Vertex.WorldPosition = Input.WorldPosition;
|
|
|
|
OutStream.Append(Vertex);
|
|
}
|
|
}
|
|
|
|
#if COMPUTESHADER
|
|
uint UsingIndirectDraw;
|
|
uint NumVertices;
|
|
uint MinVertexIndex;
|
|
uint PrimitiveId;
|
|
uint OutputVertexBaseIndex;
|
|
int InstanceId;
|
|
float4x4 WorldToInstance;
|
|
|
|
RWBuffer<float> RWVertexPositions;
|
|
int bApplyWorldPositionOffset;
|
|
|
|
[numthreads(64, 1, 1)]
|
|
void RayTracingDynamicGeometryConverterCS(uint3 DispatchThreadId : SV_DispatchThreadID)
|
|
{
|
|
if (DispatchThreadId.x >= NumVertices) return;
|
|
|
|
ResolvedView = ResolveView();
|
|
|
|
bool bUsingIndirectDraw = UsingIndirectDraw != 0;
|
|
uint NumActualVertices = bUsingIndirectDraw ? GetNumRayTracingDynamicMeshVerticesIndirect() : NumVertices;
|
|
|
|
uint VertexIndex = MinVertexIndex + DispatchThreadId.x;
|
|
|
|
if (DispatchThreadId.x < NumActualVertices)
|
|
{
|
|
FVertexFactoryInput Input = LoadVertexFactoryInputForDynamicUpdate(VertexIndex / 3, VertexIndex % 3, PrimitiveId);
|
|
|
|
#if USE_INSTANCING
|
|
Input.InstanceId = InstanceId;
|
|
#elif USE_INSTANCE_CULLING
|
|
Input.DrawInstanceId = InstanceId;
|
|
#endif
|
|
FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
|
|
|
|
float4 WorldPosition = VertexFactoryGetWorldPosition(Input, VFIntermediates);
|
|
float3x3 TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
|
|
FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPosition.xyz, TangentToLocal);
|
|
|
|
WorldPosition.xyz -= LWCHackToFloat(ResolvedView.PreViewTranslation);
|
|
if (bApplyWorldPositionOffset)
|
|
{
|
|
// We must guarantee that no NaNs are produced by WPO to avoid a possibility of producing invalid BLAS.
|
|
// DXR specification allows NaN positions to mark "inactive" primitives, but only when X component each vertex is NaN.
|
|
// This is impossible to guarantee here, since WPO is evaluated per vertex and not per triangle.
|
|
WorldPosition.xyz += MakeFinite(GetMaterialWorldPositionOffset(VertexParameters));
|
|
}
|
|
|
|
#if USE_INSTANCING || USE_INSTANCE_CULLING
|
|
//Reverse transform to neutral space
|
|
WorldPosition = mul(WorldPosition, WorldToInstance);
|
|
#elif RAY_TRACING_DYNAMIC_MESH_IN_LOCAL_SPACE
|
|
// Move the point back into local space because the RT instance will be placed there
|
|
// This the recommended default behavior so that the transform applied by the VertexFactory and the RT transform are always the same
|
|
WorldPosition.xyz = LWCMultiply(LWCPromote(WorldPosition), VertexFactoryGetWorldToLocal(VFIntermediates));
|
|
#elif RAY_TRACING_DYNAMIC_MESH_IN_WORLD_SPACE
|
|
// There are a few geometry types which natively generate positions in world space and therefore not need any extra processing here.
|
|
// This behavior must be explicitly opted-in to so as to make the code more self-documenting and avoid un-intended mismatched transforms.
|
|
#else
|
|
#error "Are you sure you want mesh vertices to be in world space? Please update the VertexFactory to report its requirement!"
|
|
#endif
|
|
|
|
RWVertexPositions[OutputVertexBaseIndex + VertexIndex * 3 + 0] = WorldPosition.x;
|
|
RWVertexPositions[OutputVertexBaseIndex + VertexIndex * 3 + 1] = WorldPosition.y;
|
|
RWVertexPositions[OutputVertexBaseIndex + VertexIndex * 3 + 2] = WorldPosition.z;
|
|
}
|
|
else
|
|
{
|
|
RWVertexPositions[OutputVertexBaseIndex + VertexIndex * 3 + 0] = asfloat(0xFFFFFFFF);
|
|
RWVertexPositions[OutputVertexBaseIndex + VertexIndex * 3 + 1] = 0;
|
|
RWVertexPositions[OutputVertexBaseIndex + VertexIndex * 3 + 2] = 0;
|
|
}
|
|
}
|
|
#endif
|