Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/ConvertToUniformMesh.cpp
Gil Gribb c7b6303e56 Copying //UE4/Dev-Rendering to Dev-Main (//UE4/Dev-Main)
#lockdown nick.penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 2771498 on 2015/11/18 by Rolando.Caloca
	DevRendering - HlslParser - Do not crash if an unknown preprocessor directive is found; add proper support for #pragma
	#codereview Marcus.Wassmer

Change 2771600 on 2015/11/18 by Rolando.Caloca

	DevRendering - SCW - Added support for running the platform shader compiler for one usf file off the dumped usf
	Usage:
	ShaderCompileWorker -directcompile FILENAME.USF -entry=EntryPoint -format=PCD3D_SM5/SF_PS4/etc -vs/-ps/-gs/-hs/-ds/-cs

	-Also removed old communication enum from SCW
	#rb Daniel.Wright

Change 2771647 on 2015/11/18 by Rolando.Caloca

	DevRendering - HlslParser - Refactored removed unused outputs code in prep for reusing a lot of this code
	- Entry point string now gets modified to the optimized one
	- Fixed parser allocator when requesting pages bigger than PageSize
	#rb Chris.Bunner

Change 2772133 on 2015/11/18 by Chris.Bunner

	Removed physics shape type zeroing on Speedtree import. UE-23285
	#rb Ori.Cohen

Change 2772225 on 2015/11/18 by Rolando.Caloca

	DevRendering - Hlsl - Support for removing unused inputs on pixel shaders
	- Fix some shadow variable warnings
	#rb Chris.Bunner, Nick.Penwarden

Change 2772469 on 2015/11/18 by Daniel.Wright

	Fixed SCW always exiting after compiling a long shader, now checks idle time starting from the end of the last compile task
	Automated smoke tests aren't run in standalone programs which are frequently launched as they increase the startup time (doubles startup time of SCW as shown in sampling profile)
	#rb Rolando.Caloca

Change 2772471 on 2015/11/18 by Daniel.Wright

	Particle SubUV cutouts
	* A new asset type 'SubUV Animation' precomputes bounding geometry for every frame of a SubUV texture animation.
	* Particle emitters with a SubUV module can then use this SubUV Animation to render with much tigher bounding geometry to reduce overdraw.
	* GPU performance savings depend on how much empty space (zero alpha) existed in the texture.  Measured a reduction of 2-3x GPU time on a smoke effect.
	* This only works if the material does not modify opacity to reveal areas with zero texture alpha

Change 2772483 on 2015/11/18 by Marcus.Wassmer

	Filtering options on UnrealPak -list
	#rb Josh.Adams

Change 2772644 on 2015/11/18 by Daniel.Wright

	Integrate - Temporal AA dithering is only enabled if outputting to a low precision format
	#rb Nick.Penwarden

Change 2773336 on 2015/11/19 by Rolando.Caloca

	DevRendering - PS4 shaders - Added input/output attribute information when r.PS4StripExtraShaderBinaryData=0
	#rb Marcus.Wassmer

Change 2773476 on 2015/11/19 by Rolando.Caloca

	DevRendering - PS4 Shader attribute export stats
	Run using r.PS4DumpExportStats 1 in the console
	- Also fixed non-vertex shaders not getting optional data
	#codereview Marcus.Wassmer

Change 2773865 on 2015/11/19 by Gil.Gribb

	UE4 - Added an FName churn tracker.

Change 2773900 on 2015/11/19 by Rolando.Caloca

	DevRendering - Fix sharing shaders for material & mesh shaders
	#rb Marcus.Wassmer

Change 2774277 on 2015/11/19 by Gil.Gribb

	UE4 - Did minor optimizations to the PS4 RHI and drawlists.

Change 2774421 on 2015/11/19 by Olaf.Piesche

	Fix #2 for UE-23325 - separate translucency materials don't show in static mesh editor

	#codereview Martin.Mittring

Change 2774447 on 2015/11/19 by Rolando.Caloca

	DevRendering - Velocity and Depth shader pipelines
	#rb Marcus.Wassmer

Change 2774603 on 2015/11/19 by Marcus.Wassmer

	Windowed vsync for ps4
	#rb Rolando.Caloca

Change 2775650 on 2015/11/20 by Rolando.Caloca

	DevRendering - Added two utility overloads per UDN suggestion
	#codereview Gil.Gribb

Change 2775798 on 2015/11/20 by David.Hill

	Adding a new AutoExposure method

	#rb Martin.Mittring

Change 2776345 on 2015/11/20 by Daniel.Wright

	Capsule shadows for movable skylight
	* Gathers capsule occlusion along the unoccluded sky cone computed by Distance Field Ambient Occlusion
	* Requires DFAO to be enabled at the moment
	* Some serious artifacts remaining in indoor scenarios, as the unoccluded sky direction is not continuous

Change 2777033 on 2015/11/22 by Uriel.Doyon

	Enabled SceneTextures node validation when material domain is DeferredDecal
	#review Martin.Mittring
	#jira UE-23141

Change 2778618 on 2015/11/23 by Daniel.Wright
2015-12-10 21:55:37 -05:00

495 lines
18 KiB
C++

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
ConvertToUniformMesh.cpp
=============================================================================*/
#include "RendererPrivate.h"
#include "ScenePrivate.h"
#include "UniformBuffer.h"
#include "ShaderParameters.h"
#include "PostProcessing.h"
#include "SceneFilterRendering.h"
#include "DistanceFieldLightingShared.h"
#include "DistanceFieldSurfaceCacheLighting.h"
#include "DistanceFieldGlobalIllumination.h"
#include "RHICommandList.h"
#include "SceneUtils.h"
#include "DistanceFieldAtlas.h"
class FConvertToUniformMeshVS : public FMeshMaterialShader
{
DECLARE_SHADER_TYPE(FConvertToUniformMeshVS,MeshMaterial);
protected:
FConvertToUniformMeshVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMeshMaterialShader(Initializer)
{
}
FConvertToUniformMeshVS()
{
}
static bool ShouldCache(EShaderPlatform Platform,const FMaterial* Material,const FVertexFactoryType* VertexFactoryType)
{
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5)
&& DoesPlatformSupportDistanceFieldGI(Platform)
&& (FCString::Strstr(VertexFactoryType->GetName(), TEXT("LocalVertexFactory")) != NULL
|| FCString::Strstr(VertexFactoryType->GetName(), TEXT("InstancedStaticMeshVertexFactory")) != NULL);
}
public:
void SetParameters(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FMaterialRenderProxy* MaterialRenderProxy,const FSceneView* View)
{
FMeshMaterialShader::SetParameters(RHICmdList, GetVertexShader(), MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View->GetFeatureLevel()), *View, ESceneRenderTargetsMode::SetTextures);
}
void SetMesh(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FSceneView& View,const FPrimitiveSceneProxy* Proxy,const FMeshBatchElement& BatchElement,const FMeshDrawingRenderState& DrawRenderState)
{
FMeshMaterialShader::SetMesh(RHICmdList, GetVertexShader(),VertexFactory,View,Proxy,BatchElement,DrawRenderState);
}
};
IMPLEMENT_MATERIAL_SHADER_TYPE(,FConvertToUniformMeshVS,TEXT("ConvertToUniformMesh"),TEXT("ConvertToUniformMeshVS"),SF_Vertex);
void GetUniformMeshStreamOutLayout(FStreamOutElementList& Layout)
{
Layout.Add(FStreamOutElement(0, "SV_Position", 0, 4, 0));
Layout.Add(FStreamOutElement(0, "Tangent", 0, 3, 0));
Layout.Add(FStreamOutElement(0, "Tangent", 1, 3, 0));
Layout.Add(FStreamOutElement(0, "Tangent", 2, 3, 0));
Layout.Add(FStreamOutElement(0, "UV", 0, 2, 0));
Layout.Add(FStreamOutElement(0, "UV", 1, 2, 0));
Layout.Add(FStreamOutElement(0, "VertexColor", 0, 4, 0));
}
// In float4's, must match usf
int32 FSurfelBuffers::InterpolatedVertexDataStride = 6;
/** Returns number of float's in the uniform vertex. */
int32 ComputeUniformVertexStride()
{
FStreamOutElementList Layout;
int32 StreamStride = 0;
GetUniformMeshStreamOutLayout(Layout);
for (int32 ElementIndex = 0; ElementIndex < Layout.Num(); ElementIndex++)
{
StreamStride += Layout[ElementIndex].ComponentCount;
}
// D3D11 stream out buffer element stride must be a factor of 4
return FMath::DivideAndRoundUp(StreamStride, 4) * 4;
}
void FUniformMeshBuffers::Initialize()
{
if (MaxElements > 0)
{
const int32 VertexStride = ComputeUniformVertexStride();
FRHIResourceCreateInfo CreateInfo;
TriangleData = RHICreateVertexBuffer(MaxElements * VertexStride * GPixelFormats[PF_R32_FLOAT].BlockBytes, BUF_ShaderResource | BUF_StreamOutput, CreateInfo);
TriangleDataSRV = RHICreateShaderResourceView(TriangleData, GPixelFormats[PF_R32_FLOAT].BlockBytes, PF_R32_FLOAT);
TriangleAreas.Initialize(sizeof(float), MaxElements, PF_R32_FLOAT);
TriangleCDFs.Initialize(sizeof(float), MaxElements, PF_R32_FLOAT);
}
}
class FConvertToUniformMeshGS : public FMeshMaterialShader
{
DECLARE_SHADER_TYPE(FConvertToUniformMeshGS,MeshMaterial);
protected:
FConvertToUniformMeshGS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMeshMaterialShader(Initializer)
{
}
FConvertToUniformMeshGS()
{
}
static bool ShouldCache(EShaderPlatform Platform,const FMaterial* Material,const FVertexFactoryType* VertexFactoryType)
{
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5)
&& DoesPlatformSupportDistanceFieldGI(Platform)
&& (FCString::Strstr(VertexFactoryType->GetName(), TEXT("LocalVertexFactory")) != NULL
|| FCString::Strstr(VertexFactoryType->GetName(), TEXT("InstancedStaticMeshVertexFactory")) != NULL);
}
static void GetStreamOutElements(FStreamOutElementList& ElementList, TArray<uint32>& StreamStrides, int32& RasterizedStream)
{
StreamStrides.Add(ComputeUniformVertexStride() * 4);
GetUniformMeshStreamOutLayout(ElementList);
RasterizedStream = -1;
}
public:
void SetParameters(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FMaterialRenderProxy* MaterialRenderProxy,const FSceneView* View)
{
FMeshMaterialShader::SetParameters(RHICmdList, (FGeometryShaderRHIParamRef)GetGeometryShader(), MaterialRenderProxy, *MaterialRenderProxy->GetMaterial(View->GetFeatureLevel()), *View, ESceneRenderTargetsMode::SetTextures);
}
void SetMesh(FRHICommandList& RHICmdList, const FVertexFactory* VertexFactory,const FSceneView& View,const FPrimitiveSceneProxy* Proxy,const FMeshBatchElement& BatchElement,const FMeshDrawingRenderState& DrawRenderState)
{
FMeshMaterialShader::SetMesh(RHICmdList, (FGeometryShaderRHIParamRef)GetGeometryShader(),VertexFactory,View,Proxy,BatchElement,DrawRenderState);
}
};
IMPLEMENT_MATERIAL_SHADER_TYPE(,FConvertToUniformMeshGS,TEXT("ConvertToUniformMesh"),TEXT("ConvertToUniformMeshGS"),SF_Geometry);
class FConvertToUniformMeshDrawingPolicy : public FMeshDrawingPolicy
{
public:
/** context type */
typedef FMeshDrawingPolicy::ElementDataType ElementDataType;
/**
* Constructor
* @param InIndexBuffer - index buffer for rendering
* @param InVertexFactory - vertex factory for rendering
* @param InMaterialRenderProxy - material instance for rendering
* @param bInOverrideWithShaderComplexity - whether to override with shader complexity
*/
FConvertToUniformMeshDrawingPolicy(
const FVertexFactory* InVertexFactory,
const FMaterialRenderProxy* InMaterialRenderProxy,
const FMaterial& MaterialResouce,
ERHIFeatureLevel::Type InFeatureLevel
);
// FMeshDrawingPolicy interface.
/**
* Match two draw policies
* @param Other - draw policy to compare
* @return true if the draw policies are a match
*/
bool Matches(const FConvertToUniformMeshDrawingPolicy& Other) const;
/**
* Executes the draw commands which can be shared between any meshes using this drawer.
* @param CI - The command interface to execute the draw commands on.
* @param View - The view of the scene being drawn.
*/
void SetSharedState(FRHICommandList& RHICmdList, const FSceneView* View, const ContextDataType PolicyContext) const;
/**
* Create bound shader state using the vertex decl from the mesh draw policy
* as well as the shaders needed to draw the mesh
* @return new bound shader state object
*/
FBoundShaderStateInput GetBoundShaderStateInput(ERHIFeatureLevel::Type InFeatureLevel);
/**
* Sets the render states for drawing a mesh.
* @param PrimitiveSceneProxy - The primitive drawing the dynamic mesh. If this is a view element, this will be NULL.
* @param Mesh - mesh element with data needed for rendering
* @param ElementData - context specific data for mesh rendering
*/
void SetMeshRenderState(
FRHICommandList& RHICmdList,
const FSceneView& View,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMeshBatch& Mesh,
int32 BatchElementIndex,
bool bBackFace,
const FMeshDrawingRenderState& DrawRenderState,
const ElementDataType& ElementData,
const ContextDataType PolicyContext
) const;
private:
FConvertToUniformMeshVS* VertexShader;
FConvertToUniformMeshGS* GeometryShader;
};
FConvertToUniformMeshDrawingPolicy::FConvertToUniformMeshDrawingPolicy(
const FVertexFactory* InVertexFactory,
const FMaterialRenderProxy* InMaterialRenderProxy,
const FMaterial& InMaterialResource,
ERHIFeatureLevel::Type InFeatureLevel
)
: FMeshDrawingPolicy(InVertexFactory,InMaterialRenderProxy,InMaterialResource,false)
{
VertexShader = InMaterialResource.GetShader<FConvertToUniformMeshVS>(InVertexFactory->GetType());
GeometryShader = InMaterialResource.GetShader<FConvertToUniformMeshGS>(InVertexFactory->GetType());
}
bool FConvertToUniformMeshDrawingPolicy::Matches(
const FConvertToUniformMeshDrawingPolicy& Other
) const
{
return FMeshDrawingPolicy::Matches(Other) &&
VertexShader == Other.VertexShader &&
GeometryShader == Other.GeometryShader;
}
void FConvertToUniformMeshDrawingPolicy::SetSharedState(
FRHICommandList& RHICmdList,
const FSceneView* View,
const ContextDataType PolicyContext
) const
{
// Set shared mesh resources
FMeshDrawingPolicy::SetSharedState(RHICmdList, View, PolicyContext);
VertexShader->SetParameters(RHICmdList, VertexFactory, MaterialRenderProxy, View);
GeometryShader->SetParameters(RHICmdList, VertexFactory, MaterialRenderProxy, View);
}
FBoundShaderStateInput FConvertToUniformMeshDrawingPolicy::GetBoundShaderStateInput(ERHIFeatureLevel::Type InFeatureLevel)
{
return FBoundShaderStateInput(
FMeshDrawingPolicy::GetVertexDeclaration(),
VertexShader->GetVertexShader(),
NULL,
NULL,
NULL,
GeometryShader->GetGeometryShader());
}
void FConvertToUniformMeshDrawingPolicy::SetMeshRenderState(
FRHICommandList& RHICmdList,
const FSceneView& View,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMeshBatch& Mesh,
int32 BatchElementIndex,
bool bBackFace,
const FMeshDrawingRenderState& DrawRenderState,
const ElementDataType& ElementData,
const ContextDataType PolicyContext
) const
{
const FMeshBatchElement& BatchElement = Mesh.Elements[BatchElementIndex];
// Set transforms
VertexShader->SetMesh(RHICmdList, VertexFactory,View,PrimitiveSceneProxy,BatchElement,DrawRenderState);
GeometryShader->SetMesh(RHICmdList, VertexFactory,View,PrimitiveSceneProxy,BatchElement,DrawRenderState);
// Set rasterizer state.
RHICmdList.SetRasterizerState(GetStaticRasterizerState<true>(
(Mesh.bWireframe || IsWireframe()) ? FM_Wireframe : FM_Solid,
IsTwoSided() ? CM_None : (XOR( XOR(View.bReverseCulling,bBackFace), Mesh.ReverseCulling) ? CM_CCW : CM_CW)));
}
bool ShouldGenerateSurfelsOnMesh(const FMeshBatch& Mesh, ERHIFeatureLevel::Type FeatureLevel)
{
//@todo - support for tessellated meshes
return Mesh.Type == PT_TriangleList
&& !Mesh.IsTranslucent(FeatureLevel)
&& Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel)->GetShadingModel() != MSM_Unlit;
}
bool ShouldConvertMesh(const FMeshBatch& Mesh)
{
return Mesh.Type == PT_TriangleList
//@todo - import types and compare directly
&& (FCString::Strstr(Mesh.VertexFactory->GetType()->GetName(), TEXT("LocalVertexFactory")) != NULL
|| FCString::Strstr(Mesh.VertexFactory->GetType()->GetName(), TEXT("InstancedStaticMeshVertexFactory")) != NULL);
}
FUniformMeshBuffers GUniformMeshTemporaryBuffers;
int32 FUniformMeshConverter::Convert(
FRHICommandListImmediate& RHICmdList,
FSceneRenderer& Renderer,
FViewInfo& View,
const FPrimitiveSceneInfo* PrimitiveSceneInfo,
int32 LODIndex,
FUniformMeshBuffers*& OutUniformMeshBuffers,
const FMaterialRenderProxy*& OutMaterialRenderProxy,
FUniformBufferRHIParamRef& OutPrimitiveUniformBuffer)
{
const FPrimitiveSceneProxy* PrimitiveSceneProxy = PrimitiveSceneInfo->Proxy;
const auto FeatureLevel = View.GetFeatureLevel();
TArray<FMeshBatch> MeshElements;
PrimitiveSceneInfo->Proxy->GetMeshDescription(LODIndex, MeshElements);
int32 NumTriangles = 0;
for (int32 MeshIndex = 0; MeshIndex < MeshElements.Num(); MeshIndex++)
{
if (ShouldConvertMesh(MeshElements[MeshIndex]))
{
NumTriangles += MeshElements[MeshIndex].GetNumPrimitives();
}
}
if (NumTriangles > 0)
{
if (GUniformMeshTemporaryBuffers.MaxElements < NumTriangles * 3)
{
GUniformMeshTemporaryBuffers.MaxElements = NumTriangles * 3;
GUniformMeshTemporaryBuffers.Release();
GUniformMeshTemporaryBuffers.Initialize();
}
RHICmdList.SetRenderTargets(0, (const FRHIRenderTargetView*)NULL, NULL, 0, (const FUnorderedAccessViewRHIParamRef*)NULL);
uint32 Offsets[1] = {0};
const FVertexBufferRHIParamRef StreamOutTargets[1] = {GUniformMeshTemporaryBuffers.TriangleData.GetReference()};
RHICmdList.SetStreamOutTargets(1, StreamOutTargets, Offsets);
for (int32 MeshIndex = 0; MeshIndex < MeshElements.Num(); MeshIndex++)
{
const FMeshBatch& Mesh = MeshElements[MeshIndex];
if (ShouldConvertMesh(Mesh))
{
FConvertToUniformMeshDrawingPolicy DrawingPolicy(
Mesh.VertexFactory,
Mesh.MaterialRenderProxy,
*Mesh.MaterialRenderProxy->GetMaterial(FeatureLevel),
FeatureLevel);
//@todo - fix
OutMaterialRenderProxy = Mesh.MaterialRenderProxy;
RHICmdList.BuildAndSetLocalBoundShaderState(DrawingPolicy.GetBoundShaderStateInput(FeatureLevel));
DrawingPolicy.SetSharedState(RHICmdList, &View, FConvertToUniformMeshDrawingPolicy::ContextDataType());
for (int32 BatchElementIndex = 0; BatchElementIndex < Mesh.Elements.Num(); BatchElementIndex++)
{
//@todo - fix
OutPrimitiveUniformBuffer = IsValidRef(Mesh.Elements[BatchElementIndex].PrimitiveUniformBuffer)
? Mesh.Elements[BatchElementIndex].PrimitiveUniformBuffer
: *Mesh.Elements[BatchElementIndex].PrimitiveUniformBufferResource;
DrawingPolicy.SetMeshRenderState(RHICmdList, View,PrimitiveSceneProxy,Mesh,BatchElementIndex,false,FMeshDrawingRenderState(),FConvertToUniformMeshDrawingPolicy::ElementDataType(), FConvertToUniformMeshDrawingPolicy::ContextDataType());
DrawingPolicy.DrawMesh(RHICmdList, Mesh, BatchElementIndex);
}
}
}
RHICmdList.SetStreamOutTargets(1, (const FVertexBufferRHIParamRef*)NULL, Offsets);
}
OutUniformMeshBuffers = &GUniformMeshTemporaryBuffers;
return NumTriangles;
}
int32 GEvaluateSurfelMaterialGroupSize = 64;
class FEvaluateSurfelMaterialCS : public FMaterialShader
{
DECLARE_SHADER_TYPE(FEvaluateSurfelMaterialCS,Material)
public:
static bool ShouldCache(EShaderPlatform Platform, const FMaterial* Material)
{
//@todo - lit materials only
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5) && DoesPlatformSupportDistanceFieldGI(Platform);
}
static void ModifyCompilationEnvironment(EShaderPlatform Platform, const FMaterial* Material, FShaderCompilerEnvironment& OutEnvironment)
{
FMaterialShader::ModifyCompilationEnvironment(Platform,OutEnvironment);
OutEnvironment.SetDefine(TEXT("EVALUATE_SURFEL_MATERIAL_GROUP_SIZE"), GEvaluateSurfelMaterialGroupSize);
OutEnvironment.SetDefine(TEXT("HAS_PRIMITIVE_UNIFORM_BUFFER"), 1);
}
FEvaluateSurfelMaterialCS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FMaterialShader(Initializer)
{
SurfelBufferParameters.Bind(Initializer.ParameterMap);
SurfelStartIndex.Bind(Initializer.ParameterMap, TEXT("SurfelStartIndex"));
NumSurfelsToGenerate.Bind(Initializer.ParameterMap, TEXT("NumSurfelsToGenerate"));
Instance0InverseTransform.Bind(Initializer.ParameterMap, TEXT("Instance0InverseTransform"));
}
FEvaluateSurfelMaterialCS()
{
}
void SetParameters(
FRHICommandList& RHICmdList,
const FSceneView& View,
int32 SurfelStartIndexValue,
int32 NumSurfelsToGenerateValue,
const FMaterialRenderProxy* MaterialProxy,
FUniformBufferRHIParamRef PrimitiveUniformBuffer,
const FMatrix& Instance0Transform
)
{
FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
FMaterialShader::SetParameters(RHICmdList, ShaderRHI, MaterialProxy, *MaterialProxy->GetMaterial(View.GetFeatureLevel()), View, true, ESceneRenderTargetsMode::SetTextures);
SetUniformBufferParameter(RHICmdList, ShaderRHI,GetUniformBufferParameter<FPrimitiveUniformShaderParameters>(),PrimitiveUniformBuffer);
const FScene* Scene = (const FScene*)View.Family->Scene;
FUnorderedAccessViewRHIParamRef UniformMeshUAVs[1];
UniformMeshUAVs[0] = Scene->DistanceFieldSceneData.SurfelBuffers->Surfels.UAV;
RHICmdList.TransitionResources(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EComputeToCompute, UniformMeshUAVs, ARRAY_COUNT(UniformMeshUAVs));
SurfelBufferParameters.Set(RHICmdList, ShaderRHI, *Scene->DistanceFieldSceneData.SurfelBuffers, *Scene->DistanceFieldSceneData.InstancedSurfelBuffers);
SetShaderValue(RHICmdList, ShaderRHI, SurfelStartIndex, SurfelStartIndexValue);
SetShaderValue(RHICmdList, ShaderRHI, NumSurfelsToGenerate, NumSurfelsToGenerateValue);
SetShaderValue(RHICmdList, ShaderRHI, Instance0InverseTransform, Instance0Transform.Inverse());
}
void UnsetParameters(FRHICommandList& RHICmdList, FViewInfo& View)
{
FComputeShaderRHIParamRef ShaderRHI = GetComputeShader();
SurfelBufferParameters.UnsetParameters(RHICmdList, ShaderRHI);
const FScene* Scene = (const FScene*)View.Family->Scene;
FUnorderedAccessViewRHIParamRef UniformMeshUAVs[1];
UniformMeshUAVs[0] = Scene->DistanceFieldSceneData.SurfelBuffers->Surfels.UAV;
RHICmdList.TransitionResources(EResourceTransitionAccess::EReadable, EResourceTransitionPipeline::EComputeToCompute, UniformMeshUAVs, ARRAY_COUNT(UniformMeshUAVs));
}
virtual bool Serialize(FArchive& Ar) override
{
bool bShaderHasOutdatedParameters = FMaterialShader::Serialize(Ar);
Ar << SurfelBufferParameters;
Ar << SurfelStartIndex;
Ar << NumSurfelsToGenerate;
Ar << Instance0InverseTransform;
return bShaderHasOutdatedParameters;
}
private:
FSurfelBufferParameters SurfelBufferParameters;
FShaderParameter SurfelStartIndex;
FShaderParameter NumSurfelsToGenerate;
FShaderParameter Instance0InverseTransform;
};
IMPLEMENT_MATERIAL_SHADER_TYPE(,FEvaluateSurfelMaterialCS,TEXT("EvaluateSurfelMaterial"),TEXT("EvaluateSurfelMaterialCS"),SF_Compute);
void FUniformMeshConverter::GenerateSurfels(
FRHICommandListImmediate& RHICmdList,
FViewInfo& View,
const FPrimitiveSceneInfo* PrimitiveSceneInfo,
const FMaterialRenderProxy* MaterialProxy,
FUniformBufferRHIParamRef PrimitiveUniformBuffer,
const FMatrix& Instance0Transform,
int32 SurfelOffset,
int32 NumSurfels)
{
const FMaterial* Material = MaterialProxy->GetMaterial(View.GetFeatureLevel());
const FMaterialShaderMap* MaterialShaderMap = Material->GetRenderingThreadShaderMap();
FEvaluateSurfelMaterialCS* ComputeShader = MaterialShaderMap->GetShader<FEvaluateSurfelMaterialCS>();
RHICmdList.SetComputeShader(ComputeShader->GetComputeShader());
ComputeShader->SetParameters(RHICmdList, View, SurfelOffset, NumSurfels, MaterialProxy, PrimitiveUniformBuffer, Instance0Transform);
DispatchComputeShader(RHICmdList, ComputeShader, FMath::DivideAndRoundUp(NumSurfels, GEvaluateSurfelMaterialGroupSize), 1, 1);
ComputeShader->UnsetParameters(RHICmdList, View);
}