2022-05-02 19:01:55 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "Components/BaseDynamicMeshSceneProxy.h"
2022-12-15 16:01:51 -05:00
# include "MaterialDomain.h"
2022-05-03 10:31:45 -04:00
# include "Materials/Material.h"
2022-12-16 16:24:02 -05:00
# include "Materials/MaterialRenderProxy.h"
2022-05-03 10:31:45 -04:00
# include "RayTracingDefinitions.h"
# include "RayTracingInstance.h"
2023-01-06 18:57:09 -05:00
# include "SceneInterface.h"
2022-10-26 12:57:32 -04:00
# include "SceneManagement.h"
2023-03-01 16:55:26 -05:00
# include "Engine/Engine.h" // for GEngine definition
2022-05-02 19:01:55 -04:00
FBaseDynamicMeshSceneProxy : : FBaseDynamicMeshSceneProxy ( UBaseDynamicMeshComponent * Component )
: FPrimitiveSceneProxy ( Component ) ,
ParentBaseComponent ( Component ) ,
2023-05-17 11:12:48 -04:00
ColorSpaceTransformMode ( Component - > GetVertexColorSpaceTransformMode ( ) ) ,
2022-05-02 19:01:55 -04:00
bEnableRaytracing ( Component - > GetEnableRaytracing ( ) ) ,
bEnableViewModeOverrides ( Component - > GetViewModeOverridesEnabled ( ) )
{
2022-06-15 16:49:13 -04:00
if ( Component - > GetColorOverrideMode ( ) = = EDynamicMeshComponentColorOverrideMode : : Constant )
{
ConstantVertexColor = Component - > GetConstantOverrideColor ( ) ;
2022-10-15 13:03:38 -04:00
bIgnoreVertexColors = true ;
2022-06-15 16:49:13 -04:00
}
bUsePerTriangleNormals = Component - > GetFlatShadingEnabled ( ) ;
2022-05-02 19:01:55 -04:00
}
FBaseDynamicMeshSceneProxy : : ~ FBaseDynamicMeshSceneProxy ( )
{
// we are assuming in code below that this is always called from the rendering thread
check ( IsInRenderingThread ( ) ) ;
// destroy all existing renderbuffers
for ( FMeshRenderBufferSet * BufferSet : AllocatedBufferSets )
{
FMeshRenderBufferSet : : DestroyRenderBufferSet ( BufferSet ) ;
}
}
FMeshRenderBufferSet * FBaseDynamicMeshSceneProxy : : AllocateNewRenderBufferSet ( )
{
// should we hang onto these and destroy them in constructor? leaving to subclass seems risky?
FMeshRenderBufferSet * RenderBufferSet = new FMeshRenderBufferSet ( GetScene ( ) . GetFeatureLevel ( ) ) ;
RenderBufferSet - > Material = UMaterial : : GetDefaultMaterial ( MD_Surface ) ;
2022-09-21 14:37:40 -04:00
RenderBufferSet - > bEnableRaytracing = this - > bEnableRaytracing & & this - > IsVisibleInRayTracing ( ) ;
2022-05-02 19:01:55 -04:00
AllocatedSetsLock . Lock ( ) ;
AllocatedBufferSets . Add ( RenderBufferSet ) ;
AllocatedSetsLock . Unlock ( ) ;
return RenderBufferSet ;
}
void FBaseDynamicMeshSceneProxy : : ReleaseRenderBufferSet ( FMeshRenderBufferSet * BufferSet )
{
FScopeLock Lock ( & AllocatedSetsLock ) ;
if ( ensure ( AllocatedBufferSets . Contains ( BufferSet ) ) )
{
AllocatedBufferSets . Remove ( BufferSet ) ;
Lock . Unlock ( ) ;
FMeshRenderBufferSet : : DestroyRenderBufferSet ( BufferSet ) ;
}
}
int32 FBaseDynamicMeshSceneProxy : : GetNumMaterials ( ) const
{
return ParentBaseComponent - > GetNumMaterials ( ) ;
}
UMaterialInterface * FBaseDynamicMeshSceneProxy : : GetMaterial ( int32 k ) const
{
UMaterialInterface * Material = ParentBaseComponent - > GetMaterial ( k ) ;
return ( Material ! = nullptr ) ? Material : UMaterial : : GetDefaultMaterial ( MD_Surface ) ;
}
void FBaseDynamicMeshSceneProxy : : UpdatedReferencedMaterials ( )
{
# if WITH_EDITOR
TArray < UMaterialInterface * > Materials ;
ParentBaseComponent - > GetUsedMaterials ( Materials , true ) ;
// Temporarily disable material verification while the enqueued render command is in flight.
// The original value for bVerifyUsedMaterials gets restored when the command is executed.
// If we do not do this, material verification might spuriously fail in cases where the render command for changing
// the verfifcation material is still in flight but the render thread is already trying to render the mesh.
const uint8 bRestoreVerifyUsedMaterials = bVerifyUsedMaterials ;
bVerifyUsedMaterials = false ;
ENQUEUE_RENDER_COMMAND ( FMeshRenderBufferSetDestroy ) (
[ this , Materials , bRestoreVerifyUsedMaterials ] ( FRHICommandListImmediate & RHICmdList )
2022-06-15 16:49:13 -04:00
{
this - > SetUsedMaterialForVerification ( Materials ) ;
this - > bVerifyUsedMaterials = bRestoreVerifyUsedMaterials ;
} ) ;
2022-05-02 19:01:55 -04:00
# endif
}
2023-07-18 15:56:19 -04:00
FMaterialRenderProxy * FBaseDynamicMeshSceneProxy : : GetEngineVertexColorMaterialProxy ( FMeshElementCollector & Collector , const FEngineShowFlags & EngineShowFlags , bool bProxyIsSelected , bool bIsHovered )
{
FMaterialRenderProxy * ForceOverrideMaterialProxy = nullptr ;
# if UE_ENABLE_DEBUG_DRAWING
if ( bProxyIsSelected & & EngineShowFlags . VertexColors & & AllowDebugViewmodes ( ) )
{
// Override the mesh's material with our material that draws the vertex colors
UMaterial * VertexColorVisualizationMaterial = NULL ;
switch ( GVertexColorViewMode )
{
case EVertexColorViewMode : : Color :
VertexColorVisualizationMaterial = GEngine - > VertexColorViewModeMaterial_ColorOnly ;
break ;
case EVertexColorViewMode : : Alpha :
VertexColorVisualizationMaterial = GEngine - > VertexColorViewModeMaterial_AlphaAsColor ;
break ;
case EVertexColorViewMode : : Red :
VertexColorVisualizationMaterial = GEngine - > VertexColorViewModeMaterial_RedOnly ;
break ;
case EVertexColorViewMode : : Green :
VertexColorVisualizationMaterial = GEngine - > VertexColorViewModeMaterial_GreenOnly ;
break ;
case EVertexColorViewMode : : Blue :
VertexColorVisualizationMaterial = GEngine - > VertexColorViewModeMaterial_BlueOnly ;
break ;
}
check ( VertexColorVisualizationMaterial ! = NULL ) ;
// Note: static mesh renderer does something more complicated involving per-section selection,
// but whole component selection seems ok for now
bool bSectionIsSelected = bProxyIsSelected ;
auto VertexColorVisualizationMaterialInstance = new FColoredMaterialRenderProxy (
VertexColorVisualizationMaterial - > GetRenderProxy ( ) ,
GetSelectionColor ( FLinearColor : : White , bSectionIsSelected , bIsHovered )
) ;
Collector . RegisterOneFrameMaterialProxy ( VertexColorVisualizationMaterialInstance ) ;
ForceOverrideMaterialProxy = VertexColorVisualizationMaterialInstance ;
}
# endif
return ForceOverrideMaterialProxy ;
}
2022-05-02 19:01:55 -04:00
void FBaseDynamicMeshSceneProxy : : GetDynamicMeshElements ( const TArray < const FSceneView * > & Views , const FSceneViewFamily & ViewFamily , uint32 VisibilityMap , FMeshElementCollector & Collector ) const
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_BaseDynamicMeshSceneProxy_GetDynamicMeshElements ) ;
2023-07-18 15:56:19 -04:00
const FEngineShowFlags & EngineShowFlags = ViewFamily . EngineShowFlags ;
bool bIsWireframeViewMode = ( AllowDebugViewmodes ( ) & & EngineShowFlags . Wireframe ) ;
2023-03-01 15:45:50 -05:00
bool bWantWireframeOnShaded = ParentBaseComponent - > GetEnableWireframeRenderPass ( ) ;
bool bWireframe = bIsWireframeViewMode | | bWantWireframeOnShaded ;
2023-07-18 15:56:19 -04:00
const bool bProxyIsSelected = IsSelected ( ) ;
2022-05-02 19:01:55 -04:00
2022-06-15 16:49:13 -04:00
// Get wireframe material proxy if requested and available, otherwise disable wireframe
2022-05-02 19:01:55 -04:00
FMaterialRenderProxy * WireframeMaterialProxy = nullptr ;
if ( bWireframe )
{
2022-06-15 16:49:13 -04:00
UMaterialInterface * WireframeMaterial = UBaseDynamicMeshComponent : : GetDefaultWireframeMaterial_RenderThread ( ) ;
if ( WireframeMaterial ! = nullptr )
{
2023-07-18 15:56:19 -04:00
FLinearColor UseWireframeColor = ( bProxyIsSelected & & ( bWantWireframeOnShaded = = false | | bIsWireframeViewMode ) ) ?
2023-03-01 15:45:50 -05:00
GEngine - > GetSelectedMaterialColor ( ) : ParentBaseComponent - > WireframeColor ;
2022-06-15 16:49:13 -04:00
FColoredMaterialRenderProxy * WireframeMaterialInstance = new FColoredMaterialRenderProxy (
2023-03-01 15:45:50 -05:00
WireframeMaterial - > GetRenderProxy ( ) , UseWireframeColor ) ;
2022-06-15 16:49:13 -04:00
Collector . RegisterOneFrameMaterialProxy ( WireframeMaterialInstance ) ;
WireframeMaterialProxy = WireframeMaterialInstance ;
}
else
{
bWireframe = false ;
}
}
2023-07-18 15:56:19 -04:00
FMaterialRenderProxy * ForceOverrideMaterialProxy = GetEngineVertexColorMaterialProxy ( Collector , EngineShowFlags , bProxyIsSelected , IsHovered ( ) ) ;
// If engine show flags aren't setting vertex color, also check if the component requested custom vertex color modes for the dynamic mesh
if ( ! ForceOverrideMaterialProxy )
2022-06-15 16:49:13 -04:00
{
2023-07-18 15:56:19 -04:00
const bool bVertexColor = ParentBaseComponent - > ColorMode = = EDynamicMeshComponentColorOverrideMode : : VertexColors | |
ParentBaseComponent - > ColorMode = = EDynamicMeshComponentColorOverrideMode : : Polygroups | |
ParentBaseComponent - > ColorMode = = EDynamicMeshComponentColorOverrideMode : : Constant ;
if ( bVertexColor )
{
ForceOverrideMaterialProxy = UBaseDynamicMeshComponent : : GetDefaultVertexColorMaterial_RenderThread ( ) - > GetRenderProxy ( ) ;
}
2022-05-02 19:01:55 -04:00
}
ESceneDepthPriorityGroup DepthPriority = SDPG_World ;
TArray < FMeshRenderBufferSet * > Buffers ;
GetActiveRenderBufferSets ( Buffers ) ;
2023-07-18 15:56:19 -04:00
FMaterialRenderProxy * SecondaryMaterialProxy = ForceOverrideMaterialProxy ;
if ( ParentBaseComponent - > HasSecondaryRenderMaterial ( ) & & ForceOverrideMaterialProxy = = nullptr )
2022-06-15 16:49:13 -04:00
{
2023-07-18 15:56:19 -04:00
SecondaryMaterialProxy = ParentBaseComponent - > GetSecondaryRenderMaterial ( ) - > GetRenderProxy ( ) ;
2022-06-15 16:49:13 -04:00
}
2022-05-02 19:01:55 -04:00
bool bDrawSecondaryBuffers = ParentBaseComponent - > GetSecondaryBuffersVisibility ( ) ;
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
if ( VisibilityMap & ( 1 < < ViewIndex ) )
{
const FSceneView * View = Views [ ViewIndex ] ;
bool bHasPrecomputedVolumetricLightmap ;
FMatrix PreviousLocalToWorld ;
int32 SingleCaptureIndex ;
bool bOutputVelocity ;
GetScene ( ) . GetPrimitiveUniformShaderParameters_RenderThread ( GetPrimitiveSceneInfo ( ) , bHasPrecomputedVolumetricLightmap , PreviousLocalToWorld , SingleCaptureIndex , bOutputVelocity ) ;
2022-05-19 10:08:15 -04:00
bOutputVelocity | = AlwaysHasVelocity ( ) ;
2022-05-02 19:01:55 -04:00
// Draw the mesh.
for ( FMeshRenderBufferSet * BufferSet : Buffers )
{
2023-07-18 15:56:19 -04:00
FMaterialRenderProxy * MaterialProxy = ForceOverrideMaterialProxy ;
if ( ! MaterialProxy )
2022-05-02 19:01:55 -04:00
{
2023-07-18 15:56:19 -04:00
UMaterialInterface * UseMaterial = BufferSet - > Material ;
if ( ParentBaseComponent - > HasOverrideRenderMaterial ( 0 ) )
{
UseMaterial = ParentBaseComponent - > GetOverrideRenderMaterial ( 0 ) ;
}
MaterialProxy = UseMaterial - > GetRenderProxy ( ) ;
2022-05-02 19:01:55 -04:00
}
if ( BufferSet - > TriangleCount = = 0 )
{
continue ;
}
// lock buffers so that they aren't modified while we are submitting them
FScopeLock BuffersLock ( & BufferSet - > BuffersLock ) ;
// do we need separate one of these for each MeshRenderBufferSet?
FDynamicPrimitiveUniformBuffer & DynamicPrimitiveUniformBuffer = Collector . AllocateOneFrameResource < FDynamicPrimitiveUniformBuffer > ( ) ;
2022-05-19 10:08:15 -04:00
DynamicPrimitiveUniformBuffer . Set ( GetLocalToWorld ( ) , PreviousLocalToWorld , GetBounds ( ) , GetLocalBounds ( ) , GetLocalBounds ( ) , true , bHasPrecomputedVolumetricLightmap , bOutputVelocity , GetCustomPrimitiveData ( ) ) ;
2022-05-02 19:01:55 -04:00
2023-03-01 15:45:50 -05:00
// If we want Wireframe-on-Shaded, we have to draw the solid. If View Mode Overrides are enabled, the solid
// will be replaced with it's wireframe, so we might as well not.
bool bDrawSolidWithWireframe = ( bWantWireframeOnShaded & & ( bIsWireframeViewMode = = false | | bEnableViewModeOverrides = = false ) ) ;
2022-05-02 19:01:55 -04:00
if ( BufferSet - > IndexBuffer . Indices . Num ( ) > 0 )
{
if ( bWireframe )
{
2023-03-01 15:45:50 -05:00
if ( bDrawSolidWithWireframe )
{
DrawBatch ( Collector , * BufferSet , BufferSet - > IndexBuffer , MaterialProxy , /*bWireframe*/ false , DepthPriority , ViewIndex , DynamicPrimitiveUniformBuffer ) ;
}
DrawBatch ( Collector , * BufferSet , BufferSet - > IndexBuffer , WireframeMaterialProxy , /*bWireframe*/ true , DepthPriority , ViewIndex , DynamicPrimitiveUniformBuffer ) ;
}
else
{
DrawBatch ( Collector , * BufferSet , BufferSet - > IndexBuffer , MaterialProxy , /*bWireframe*/ false , DepthPriority , ViewIndex , DynamicPrimitiveUniformBuffer ) ;
2022-05-02 19:01:55 -04:00
}
}
// draw secondary buffer if we have it, falling back to base material if we don't have the Secondary material
2023-07-18 15:56:19 -04:00
FMaterialRenderProxy * UseSecondaryMaterialProxy = ( SecondaryMaterialProxy ! = nullptr ) ? SecondaryMaterialProxy : MaterialProxy ;
2022-05-02 19:01:55 -04:00
if ( bDrawSecondaryBuffers & & BufferSet - > SecondaryIndexBuffer . Indices . Num ( ) > 0 & & UseSecondaryMaterialProxy ! = nullptr )
{
if ( bWireframe )
{
2023-03-01 15:45:50 -05:00
if ( bDrawSolidWithWireframe )
{
DrawBatch ( Collector , * BufferSet , BufferSet - > SecondaryIndexBuffer , UseSecondaryMaterialProxy , /*bWireframe*/ false , DepthPriority , ViewIndex , DynamicPrimitiveUniformBuffer ) ;
}
DrawBatch ( Collector , * BufferSet , BufferSet - > SecondaryIndexBuffer , UseSecondaryMaterialProxy , /*bWireframe*/ true , DepthPriority , ViewIndex , DynamicPrimitiveUniformBuffer ) ;
}
else
{
DrawBatch ( Collector , * BufferSet , BufferSet - > SecondaryIndexBuffer , UseSecondaryMaterialProxy , /*bWireframe*/ false , DepthPriority , ViewIndex , DynamicPrimitiveUniformBuffer ) ;
2022-05-02 19:01:55 -04:00
}
}
}
}
}
}
void FBaseDynamicMeshSceneProxy : : DrawBatch ( FMeshElementCollector & Collector , const FMeshRenderBufferSet & RenderBuffers , const FDynamicMeshIndexBuffer32 & IndexBuffer , FMaterialRenderProxy * UseMaterial , bool bWireframe , ESceneDepthPriorityGroup DepthPriority , int ViewIndex , FDynamicPrimitiveUniformBuffer & DynamicPrimitiveUniformBuffer ) const
{
FMeshBatch & Mesh = Collector . AllocateMesh ( ) ;
FMeshBatchElement & BatchElement = Mesh . Elements [ 0 ] ;
BatchElement . IndexBuffer = & IndexBuffer ;
Mesh . bWireframe = bWireframe ;
2023-03-01 15:45:50 -05:00
//Mesh.bDisableBackfaceCulling = bWireframe; // todo: doing this would be more consistent w/ other meshes in wireframe mode, but it is problematic for modeling tools - perhaps should be configurable
2022-05-02 19:01:55 -04:00
Mesh . VertexFactory = & RenderBuffers . VertexFactory ;
Mesh . MaterialRenderProxy = UseMaterial ;
BatchElement . PrimitiveUniformBufferResource = & DynamicPrimitiveUniformBuffer . UniformBuffer ;
BatchElement . FirstIndex = 0 ;
BatchElement . NumPrimitives = IndexBuffer . Indices . Num ( ) / 3 ;
BatchElement . MinVertexIndex = 0 ;
BatchElement . MaxVertexIndex = RenderBuffers . PositionVertexBuffer . GetNumVertices ( ) - 1 ;
Mesh . ReverseCulling = IsLocalToWorldDeterminantNegative ( ) ;
Mesh . Type = PT_TriangleList ;
Mesh . DepthPriorityGroup = DepthPriority ;
2023-03-01 15:45:50 -05:00
// if this is a wireframe draw pass then we do not want to apply View Mode Overrides
Mesh . bCanApplyViewModeOverrides = ( bWireframe ) ? false : this - > bEnableViewModeOverrides ;
2022-05-02 19:01:55 -04:00
Collector . AddMesh ( ViewIndex , Mesh ) ;
}
# if RHI_RAYTRACING
bool FBaseDynamicMeshSceneProxy : : IsRayTracingRelevant ( ) const
{
return true ;
}
2022-09-21 14:37:40 -04:00
bool FBaseDynamicMeshSceneProxy : : HasRayTracingRepresentation ( ) const
{
return true ;
}
2022-05-02 19:01:55 -04:00
void FBaseDynamicMeshSceneProxy : : GetDynamicRayTracingInstances ( FRayTracingMaterialGatheringContext & Context , TArray < FRayTracingInstance > & OutRayTracingInstances )
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_BaseDynamicMeshSceneProxy_GetDynamicRayTracingInstances ) ;
ESceneDepthPriorityGroup DepthPriority = SDPG_World ;
TArray < FMeshRenderBufferSet * > Buffers ;
GetActiveRenderBufferSets ( Buffers ) ;
2022-06-15 16:49:13 -04:00
// will use this material instead of any others below, if it becomes non-null
UMaterialInterface * ForceOverrideMaterial = nullptr ;
const bool bVertexColor = ParentBaseComponent - > ColorMode = = EDynamicMeshComponentColorOverrideMode : : VertexColors | |
ParentBaseComponent - > ColorMode = = EDynamicMeshComponentColorOverrideMode : : Polygroups | |
ParentBaseComponent - > ColorMode = = EDynamicMeshComponentColorOverrideMode : : Constant ;
if ( bVertexColor )
{
ForceOverrideMaterial = UBaseDynamicMeshComponent : : GetDefaultVertexColorMaterial_RenderThread ( ) ;
}
UMaterialInterface * UseSecondaryMaterial = ForceOverrideMaterial ;
if ( ParentBaseComponent - > HasSecondaryRenderMaterial ( ) & & ForceOverrideMaterial = = nullptr )
{
UseSecondaryMaterial = ParentBaseComponent - > GetSecondaryRenderMaterial ( ) ;
}
2022-05-02 19:01:55 -04:00
bool bDrawSecondaryBuffers = ParentBaseComponent - > GetSecondaryBuffersVisibility ( ) ;
bool bHasPrecomputedVolumetricLightmap ;
FMatrix PreviousLocalToWorld ;
int32 SingleCaptureIndex ;
bool bOutputVelocity ;
GetScene ( ) . GetPrimitiveUniformShaderParameters_RenderThread ( GetPrimitiveSceneInfo ( ) , bHasPrecomputedVolumetricLightmap , PreviousLocalToWorld , SingleCaptureIndex , bOutputVelocity ) ;
2022-05-19 10:08:15 -04:00
bOutputVelocity | = AlwaysHasVelocity ( ) ;
2022-05-02 19:01:55 -04:00
// is it safe to share this between primary and secondary raytracing batches?
FDynamicPrimitiveUniformBuffer & DynamicPrimitiveUniformBuffer = Context . RayTracingMeshResourceCollector . AllocateOneFrameResource < FDynamicPrimitiveUniformBuffer > ( ) ;
2022-05-19 10:08:15 -04:00
DynamicPrimitiveUniformBuffer . Set ( GetLocalToWorld ( ) , PreviousLocalToWorld , GetBounds ( ) , GetLocalBounds ( ) , true , bHasPrecomputedVolumetricLightmap , bOutputVelocity ) ;
2022-05-02 19:01:55 -04:00
// Draw the active buffer sets
for ( FMeshRenderBufferSet * BufferSet : Buffers )
{
UMaterialInterface * UseMaterial = BufferSet - > Material ;
if ( ParentBaseComponent - > HasOverrideRenderMaterial ( 0 ) )
{
UseMaterial = ParentBaseComponent - > GetOverrideRenderMaterial ( 0 ) ;
}
2022-06-15 16:49:13 -04:00
if ( ForceOverrideMaterial )
{
UseMaterial = ForceOverrideMaterial ;
}
2022-05-02 19:01:55 -04:00
FMaterialRenderProxy * MaterialProxy = UseMaterial - > GetRenderProxy ( ) ;
if ( BufferSet - > TriangleCount = = 0 )
{
continue ;
}
if ( BufferSet - > bIsRayTracingDataValid = = false )
{
continue ;
}
// Lock buffers so that they aren't modified while we are submitting them.
FScopeLock BuffersLock ( & BufferSet - > BuffersLock ) ;
// draw primary index buffer
if ( BufferSet - > IndexBuffer . Indices . Num ( ) > 0
& & BufferSet - > PrimaryRayTracingGeometry . RayTracingGeometryRHI . IsValid ( ) )
{
ensure ( BufferSet - > PrimaryRayTracingGeometry . Initializer . IndexBuffer . IsValid ( ) ) ;
DrawRayTracingBatch ( Context , * BufferSet , BufferSet - > IndexBuffer , BufferSet - > PrimaryRayTracingGeometry , MaterialProxy , DepthPriority , DynamicPrimitiveUniformBuffer , OutRayTracingInstances ) ;
}
// draw secondary index buffer if we have it, falling back to base material if we don't have the Secondary material
2022-06-15 16:49:13 -04:00
FMaterialRenderProxy * UseSecondaryMaterialProxy = ( UseSecondaryMaterial ! = nullptr ) ? UseSecondaryMaterial - > GetRenderProxy ( ) : MaterialProxy ;
2022-05-02 19:01:55 -04:00
if ( bDrawSecondaryBuffers
& & BufferSet - > SecondaryIndexBuffer . Indices . Num ( ) > 0
& & UseSecondaryMaterialProxy ! = nullptr
& & BufferSet - > SecondaryRayTracingGeometry . RayTracingGeometryRHI . IsValid ( ) )
{
ensure ( BufferSet - > SecondaryRayTracingGeometry . Initializer . IndexBuffer . IsValid ( ) ) ;
DrawRayTracingBatch ( Context , * BufferSet , BufferSet - > SecondaryIndexBuffer , BufferSet - > SecondaryRayTracingGeometry , UseSecondaryMaterialProxy , DepthPriority , DynamicPrimitiveUniformBuffer , OutRayTracingInstances ) ;
}
}
}
void FBaseDynamicMeshSceneProxy : : DrawRayTracingBatch ( FRayTracingMaterialGatheringContext & Context , const FMeshRenderBufferSet & RenderBuffers , const FDynamicMeshIndexBuffer32 & IndexBuffer , FRayTracingGeometry & RayTracingGeometry , FMaterialRenderProxy * UseMaterialProxy , ESceneDepthPriorityGroup DepthPriority , FDynamicPrimitiveUniformBuffer & DynamicPrimitiveUniformBuffer , TArray < FRayTracingInstance > & OutRayTracingInstances ) const
{
ensure ( RayTracingGeometry . Initializer . IndexBuffer . IsValid ( ) ) ;
FRayTracingInstance RayTracingInstance ;
RayTracingInstance . Geometry = & RayTracingGeometry ;
RayTracingInstance . InstanceTransforms . Add ( GetLocalToWorld ( ) ) ;
uint32 SectionIdx = 0 ;
FMeshBatch MeshBatch ;
MeshBatch . VertexFactory = & RenderBuffers . VertexFactory ;
MeshBatch . SegmentIndex = 0 ;
MeshBatch . MaterialRenderProxy = UseMaterialProxy ;
MeshBatch . ReverseCulling = IsLocalToWorldDeterminantNegative ( ) ;
MeshBatch . Type = PT_TriangleList ;
MeshBatch . DepthPriorityGroup = DepthPriority ;
MeshBatch . bCanApplyViewModeOverrides = this - > bEnableViewModeOverrides ;
MeshBatch . CastRayTracedShadow = IsShadowCast ( Context . ReferenceView ) ;
FMeshBatchElement & BatchElement = MeshBatch . Elements [ 0 ] ;
BatchElement . IndexBuffer = & IndexBuffer ;
BatchElement . PrimitiveUniformBufferResource = & DynamicPrimitiveUniformBuffer . UniformBuffer ;
BatchElement . FirstIndex = 0 ;
BatchElement . NumPrimitives = IndexBuffer . Indices . Num ( ) / 3 ;
BatchElement . MinVertexIndex = 0 ;
BatchElement . MaxVertexIndex = RenderBuffers . PositionVertexBuffer . GetNumVertices ( ) - 1 ;
RayTracingInstance . Materials . Add ( MeshBatch ) ;
OutRayTracingInstances . Add ( RayTracingInstance ) ;
}
# endif // RHI_RAYTRACING