You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#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
495 lines
18 KiB
C++
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);
|
|
}
|