Merge remote-tracking branch 'origin/master' into dotnet7

This commit is contained in:
Wojtek Figat
2023-02-06 10:02:13 +01:00
158 changed files with 1077 additions and 905 deletions

View File

@@ -62,7 +62,7 @@ bool ColorGradingPass::Init()
formatSupportFlags |= FormatSupport::Texture3D;
else
formatSupportFlags |= FormatSupport::Texture2D;
if (!EnumHasAllFlags(formatSupport, formatSupportFlags))
if (EnumHasNoneFlags(formatSupport, formatSupportFlags))
{
// Fallback to format that is supported on every washing machine
_lutFormat = PixelFormat::R8G8B8A8_UNorm;

View File

@@ -117,6 +117,3 @@ PACK_STRUCT(struct ProbeData {
// Default format for the shadow map textures
#define SHADOW_MAPS_FORMAT PixelFormat::D16_UNorm
// Material distortion offsets output pass (material uses PS_Distortion, ForwardPass resolves the offsets)
#define Distortion_Pass_Output_Format PixelFormat::R8G8B8A8_UNorm

View File

@@ -221,7 +221,6 @@ struct DrawCall
float UVOffsetX;
float UVOffsetY;
uint32 SegmentCount;
GPUBuffer* SegmentDistances;
} Ribbon;
struct

View File

@@ -107,7 +107,7 @@ void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTex
const int32 height = renderContext.Buffers->GetHeight();
const int32 distortionWidth = width;
const int32 distortionHeight = height;
const auto tempDesc = GPUTextureDescription::New2D(distortionWidth, distortionHeight, Distortion_Pass_Output_Format);
const auto tempDesc = GPUTextureDescription::New2D(distortionWidth, distortionHeight, PixelFormat::R8G8B8A8_UNorm);
auto distortionRT = RenderTargetPool::Get(tempDesc);
RENDER_TARGET_POOL_SET_NAME(distortionRT, "Forward.Distortion");
@@ -119,15 +119,13 @@ void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTex
// Render distortion pass
view.Pass = DrawPass::Distortion;
mainCache->ExecuteDrawCalls(renderContext, distortionList);
// Copy combined frame with distortion from transparent materials
context->SetViewportAndScissors((float)width, (float)height);
context->ResetRenderTarget();
context->ResetSR();
// Bind inputs
context->BindSR(0, input);
context->BindSR(1, distortionRT);
// Copy combined frame with distortion from transparent materials
context->SetRenderTarget(output->View());
context->SetState(_psApplyDistortion);
context->DrawFullscreenTriangle();

View File

@@ -146,7 +146,7 @@ void DebugOverrideDrawCallsMaterial(const RenderContext& renderContext, IMateria
#endif
void GBufferPass::Fill(RenderContext& renderContext, GPUTextureView* lightBuffer)
void GBufferPass::Fill(RenderContext& renderContext, GPUTexture* lightBuffer)
{
PROFILE_GPU_CPU("GBuffer");
@@ -155,7 +155,7 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTextureView* lightBuffer
auto context = device->GetMainContext();
GPUTextureView* targetBuffers[5] =
{
lightBuffer,
lightBuffer->View(),
renderContext.Buffers->GBuffer0->View(),
renderContext.Buffers->GBuffer1->View(),
renderContext.Buffers->GBuffer2->View(),
@@ -168,7 +168,7 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTextureView* lightBuffer
PROFILE_GPU_CPU_NAMED("Clear");
context->ClearDepth(*renderContext.Buffers->DepthBuffer);
context->Clear(lightBuffer, Color::Transparent);
context->Clear(lightBuffer->View(), Color::Transparent);
context->Clear(renderContext.Buffers->GBuffer0->View(), Color::Transparent);
context->Clear(renderContext.Buffers->GBuffer1->View(), Color::Transparent);
context->Clear(renderContext.Buffers->GBuffer2->View(), Color(1, 0, 0, 0));
@@ -192,7 +192,7 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTextureView* lightBuffer
renderContext.List->Sky->ApplySky(context, renderContext, Matrix::Identity);
GPUPipelineState* materialPs = context->GetState();
const float complexity = (float)Math::Min(materialPs->Complexity, MATERIAL_COMPLEXITY_LIMIT) / MATERIAL_COMPLEXITY_LIMIT;
context->Clear(lightBuffer, Color(complexity, complexity, complexity, 1.0f));
context->Clear(lightBuffer->View(), Color(complexity, complexity, complexity, 1.0f));
renderContext.List->Sky = nullptr;
}
}
@@ -208,16 +208,20 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTextureView* lightBuffer
renderContext.List->ExecuteDrawCalls(renderContext, DrawCallsListType::GBuffer);
// Draw decals
DrawDecals(renderContext, lightBuffer);
DrawDecals(renderContext, lightBuffer->View());
// Draw objects that cannot get decals
context->SetRenderTarget(*renderContext.Buffers->DepthBuffer, ToSpan(targetBuffers, ARRAY_COUNT(targetBuffers)));
renderContext.List->ExecuteDrawCalls(renderContext, DrawCallsListType::GBufferNoDecals);
GPUTexture* nullTexture = nullptr;
renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::AfterGBufferPass, lightBuffer, nullTexture);
// Draw sky
if (renderContext.List->Sky && _skyModel && _skyModel->CanBeRendered())
if (renderContext.List->Sky && _skyModel && _skyModel->CanBeRendered() && EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Sky))
{
PROFILE_GPU_CPU_NAMED("Sky");
context->SetRenderTarget(*renderContext.Buffers->DepthBuffer, ToSpan(targetBuffers, ARRAY_COUNT(targetBuffers)));
DrawSky(renderContext, context);
}
@@ -279,7 +283,7 @@ public:
GPUTextureView* GBufferPass::RenderSkybox(RenderContext& renderContext, GPUContext* context)
{
GPUTextureView* result = nullptr;
if (renderContext.List->Sky && _skyModel && _skyModel->CanBeRendered())
if (renderContext.List->Sky && _skyModel && _skyModel->CanBeRendered() && EnumHasAnyFlags(renderContext.View.Flags, ViewFlags::Sky))
{
// Initialize skybox texture
auto& skyboxData = *renderContext.Buffers->GetCustomBuffer<SkyboxCustomBuffer>(TEXT("Skybox"));
@@ -426,7 +430,7 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light
{
// Skip if no decals to render
auto& decals = renderContext.List->Decals;
if (decals.IsEmpty() || _boxModel == nullptr || !_boxModel->CanBeRendered())
if (decals.IsEmpty() || _boxModel == nullptr || !_boxModel->CanBeRendered() || EnumHasNoneFlags(renderContext.View.Flags, ViewFlags::Decals))
return;
PROFILE_GPU_CPU("Decals");

View File

@@ -32,7 +32,7 @@ public:
/// </summary>
/// <param name="renderContext">The rendering context.</param>
/// <param name="lightBuffer">Light buffer to output material emissive light and precomputed indirect lighting</param>
void Fill(RenderContext& renderContext, GPUTextureView* lightBuffer);
void Fill(RenderContext& renderContext, GPUTexture* lightBuffer);
/// <summary>
/// Render debug view

View File

@@ -284,7 +284,7 @@ bool GlobalSurfaceAtlasPass::setupResources()
if (!_psClear)
{
_psClear = device->CreatePipelineState();
psDesc.DepthTestEnable = true;
psDesc.DepthEnable = true;
psDesc.DepthWriteEnable = true;
psDesc.DepthFunc = ComparisonFunc::Always;
psDesc.VS = shader->GetVS("VS_Atlas");
@@ -292,7 +292,7 @@ bool GlobalSurfaceAtlasPass::setupResources()
if (_psClear->Init(psDesc))
return true;
}
psDesc.DepthTestEnable = false;
psDesc.DepthEnable = false;
psDesc.DepthWriteEnable = false;
psDesc.DepthFunc = ComparisonFunc::Never;
if (!_psClearLighting)

View File

@@ -64,7 +64,7 @@ PACK_STRUCT(struct ModelsRasterizeData
Int3 ChunkCoord;
float MaxDistance;
Float3 CascadeCoordToPosMul;
int32 ObjectsCount;
uint32 ObjectsCount;
Float3 CascadeCoordToPosAdd;
int32 CascadeResolution;
int32 CascadeIndex;

View File

@@ -50,7 +50,7 @@ bool LightPass::Init()
#endif
auto format = PixelFormat::R8G8_UNorm;
if (!EnumHasAllFlags(GPUDevice::Instance->GetFormatFeatures(format).Support, (FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D)))
if (EnumHasNoneFlags(GPUDevice::Instance->GetFormatFeatures(format).Support, (FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D)))
{
format = PixelFormat::B8G8R8A8_UNorm;
}
@@ -98,7 +98,7 @@ bool LightPass::setupResources()
if (_psLightPointInverted.Create(psDesc, shader, "PS_Point"))
return true;
psDesc.CullMode = CullMode::Normal;
psDesc.DepthTestEnable = true;
psDesc.DepthEnable = true;
if (_psLightPointNormal.Create(psDesc, shader, "PS_Point"))
return true;
}
@@ -112,7 +112,7 @@ bool LightPass::setupResources()
if (_psLightSpotInverted.Create(psDesc, shader, "PS_Spot"))
return true;
psDesc.CullMode = CullMode::Normal;
psDesc.DepthTestEnable = true;
psDesc.DepthEnable = true;
if (_psLightSpotNormal.Create(psDesc, shader, "PS_Spot"))
return true;
}

View File

@@ -62,11 +62,11 @@ bool MotionBlurPass::Init()
// Prepare formats for the buffers
auto format = PixelFormat::R16G16_Float;
if (!EnumHasAllFlags(GPUDevice::Instance->GetFormatFeatures(format).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
if (EnumHasNoneFlags(GPUDevice::Instance->GetFormatFeatures(format).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
{
if (!EnumHasAllFlags(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R32G32_Float).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
if (EnumHasNoneFlags(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R32G32_Float).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
format = PixelFormat::R32G32_Float;
else if (!EnumHasAllFlags(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R16G16B16A16_Float).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
else if (EnumHasNoneFlags(GPUDevice::Instance->GetFormatFeatures(PixelFormat::R16G16B16A16_Float).Support, FormatSupport::RenderTarget | FormatSupport::ShaderSample | FormatSupport::Texture2D))
format = PixelFormat::R16G16B16A16_Float;
else
format = PixelFormat::R32G32B32A32_Float;

View File

@@ -181,24 +181,13 @@ void PostProcessingPass::Dispose()
void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output, GPUTexture* colorGradingLUT)
{
PROFILE_GPU_CPU("Post Processing");
auto device = GPUDevice::Instance;
auto context = device->GetMainContext();
auto& view = renderContext.View;
PROFILE_GPU_CPU("Post Processing");
context->ResetRenderTarget();
// Ensure to have valid data
if (checkIfSkipPass())
{
// Resources are missing. Do not perform rendering. Just copy raw frame
context->SetRenderTarget(*output);
context->Draw(input);
return;
}
// Cache data
PostProcessSettings& settings = renderContext.List->Settings;
bool useBloom = EnumHasAnyFlags(view.Flags, ViewFlags::Bloom) && settings.Bloom.Enabled && settings.Bloom.Intensity > 0.0f;
bool useToneMapping = EnumHasAnyFlags(view.Flags, ViewFlags::ToneMapping);
@@ -206,9 +195,10 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
bool useLensFlares = EnumHasAnyFlags(view.Flags, ViewFlags::LensFlares) && settings.LensFlares.Intensity > 0.0f && useBloom;
// Ensure to have valid data and if at least one effect should be applied
if (!(useBloom || useToneMapping || useCameraArtifacts))
if (checkIfSkipPass() || !(useBloom || useToneMapping || useCameraArtifacts))
{
// Resources are missing. Do not perform rendering. Just copy raw frame
context->SetViewportAndScissors((float)output->Width(), (float)output->Height());
context->SetRenderTarget(*output);
context->Draw(input);
return;

View File

@@ -73,7 +73,7 @@ PACK_STRUCT(struct Data
{
Float2 Dummy0;
int32 CubeFace;
int32 SourceMipIndex;
float SourceMipIndex;
});
namespace ProbesRendererImpl
@@ -268,6 +268,7 @@ bool ProbesRenderer::Init()
ViewFlags::SkyLights |
ViewFlags::Decals |
ViewFlags::Shadows |
ViewFlags::Sky |
ViewFlags::Fog;
view.Mode = ViewMode::NoPostFx;
view.IsOfflinePass = true;
@@ -514,8 +515,8 @@ void ProbesRenderer::OnRender(RenderTask* task, GPUContext* context)
auto cb = shader->GetCB(0);
for (int32 mipIndex = 1; mipIndex < mipLevels; mipIndex++)
{
int32 mipSize = 1 << (mipLevels - mipIndex - 1);
data.SourceMipIndex = mipIndex - 1;
const int32 mipSize = 1 << (mipLevels - mipIndex - 1);
data.SourceMipIndex = (float)mipIndex - 1.0f;
context->SetViewportAndScissors((float)mipSize, (float)mipSize);
for (int32 faceIndex = 0; faceIndex < 6; faceIndex++)
{

View File

@@ -265,7 +265,7 @@ void RenderList::RunPostFxPass(GPUContext* context, RenderContext& renderContext
{
if (fx->Location == locationB)
{
if (fx->UseSingleTarget)
if (fx->UseSingleTarget || output == nullptr)
{
fx->Render(context, renderContext, input, nullptr);
}
@@ -298,9 +298,9 @@ void RenderList::RunMaterialPostFxPass(GPUContext* context, RenderContext& rende
bindParams.Input = *input;
material->Bind(bindParams);
context->DrawFullscreenTriangle();
context->ResetRenderTarget();
Swap(output, input);
}
context->ResetRenderTarget();
}
}
@@ -312,7 +312,7 @@ void RenderList::RunCustomPostFxPass(GPUContext* context, RenderContext& renderC
{
if (fx->Location == location)
{
if (fx->UseSingleTarget)
if (fx->UseSingleTarget || output == nullptr)
{
fx->Render(context, renderContext, input, nullptr);
}
@@ -412,12 +412,28 @@ void RenderList::Clear()
_instanceBuffer.Clear();
}
FORCE_INLINE void CalculateSortKey(const RenderContext& renderContext, DrawCall& drawCall)
struct PackedSortKey
{
union
{
uint64 Data;
struct
{
uint32 DistanceKey;
uint16 BatchKey;
uint16 SortKey;
};
};
};
FORCE_INLINE void CalculateSortKey(const RenderContext& renderContext, DrawCall& drawCall, int16 sortOrder)
{
const Float3 planeNormal = renderContext.View.Direction;
const float planePoint = -Float3::Dot(planeNormal, renderContext.View.Position);
const float distance = Float3::Dot(planeNormal, drawCall.ObjectPosition) - planePoint;
const uint32 sortKey = RenderTools::ComputeDistanceSortKey(distance);
PackedSortKey key;
key.DistanceKey = RenderTools::ComputeDistanceSortKey(distance);
uint32 batchKey = GetHash(drawCall.Geometry.IndexBuffer);
batchKey = (batchKey * 397) ^ GetHash(drawCall.Geometry.VertexBuffers[0]);
batchKey = (batchKey * 397) ^ GetHash(drawCall.Geometry.VertexBuffers[1]);
@@ -427,10 +443,12 @@ FORCE_INLINE void CalculateSortKey(const RenderContext& renderContext, DrawCall&
if (drawCall.Material->CanUseInstancing(handler))
handler.GetHash(drawCall, batchKey);
batchKey += (int32)(471 * drawCall.WorldDeterminantSign);
drawCall.SortKey = (uint64)batchKey << 32 | (uint64)sortKey;
key.SortKey = (uint16)(sortOrder - MIN_int16);
key.BatchKey = (uint16)batchKey;
drawCall.SortKey = key.Data;
}
void RenderList::AddDrawCall(const RenderContext& renderContext, DrawPass drawModes, StaticFlags staticFlags, DrawCall& drawCall, bool receivesDecals)
void RenderList::AddDrawCall(const RenderContext& renderContext, DrawPass drawModes, StaticFlags staticFlags, DrawCall& drawCall, bool receivesDecals, int16 sortOrder)
{
#if ENABLE_ASSERTION_LOW_LAYERS
// Ensure that draw modes are non-empty and in conjunction with material draw modes
@@ -439,7 +457,7 @@ void RenderList::AddDrawCall(const RenderContext& renderContext, DrawPass drawMo
#endif
// Append draw call data
CalculateSortKey(renderContext, drawCall);
CalculateSortKey(renderContext, drawCall, sortOrder);
const int32 index = DrawCalls.Add(drawCall);
// Add draw call to proper draw lists
@@ -468,7 +486,7 @@ void RenderList::AddDrawCall(const RenderContext& renderContext, DrawPass drawMo
}
}
void RenderList::AddDrawCall(const RenderContextBatch& renderContextBatch, DrawPass drawModes, StaticFlags staticFlags, ShadowsCastingMode shadowsMode, const BoundingSphere& bounds, DrawCall& drawCall, bool receivesDecals)
void RenderList::AddDrawCall(const RenderContextBatch& renderContextBatch, DrawPass drawModes, StaticFlags staticFlags, ShadowsCastingMode shadowsMode, const BoundingSphere& bounds, DrawCall& drawCall, bool receivesDecals, int16 sortOrder)
{
#if ENABLE_ASSERTION_LOW_LAYERS
// Ensure that draw modes are non-empty and in conjunction with material draw modes
@@ -478,7 +496,7 @@ void RenderList::AddDrawCall(const RenderContextBatch& renderContextBatch, DrawP
const RenderContext& mainRenderContext = renderContextBatch.Contexts.Get()[0];
// Append draw call data
CalculateSortKey(mainRenderContext, drawCall);
CalculateSortKey(mainRenderContext, drawCall, sortOrder);
const int32 index = DrawCalls.Add(drawCall);
// Add draw call to proper draw lists
@@ -514,7 +532,7 @@ void RenderList::AddDrawCall(const RenderContextBatch& renderContextBatch, DrawP
{
const RenderContext& renderContext = renderContextBatch.Contexts.Get()[i];
ASSERT_LOW_LAYER(renderContext.View.Pass == DrawPass::Depth);
drawModes = (DrawPass)(modes & renderContext.View.Pass);
drawModes = modes & renderContext.View.Pass;
if (drawModes != DrawPass::None && renderContext.View.CullingFrustum.Intersects(bounds))
{
renderContext.List->ShadowDepthDrawCallsList.Indices.Add(index);
@@ -558,16 +576,17 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
#undef PREPARE_CACHE
uint64* sortedKeys = SortingKeys[0].Get();
// Generate sort keys (by depth) and batch keys (higher bits)
// Setup sort keys
if (reverseDistance)
{
const uint32 sortKeyXor = reverseDistance ? MAX_uint32 : 0;
for (int32 i = 0; i < listSize; i++)
{
const DrawCall& drawCall = drawCallsData[listData[i]];
const uint32 sortKey = (uint32)drawCall.SortKey ^ sortKeyXor;
const uint32 batchKey = (uint32)(drawCall.SortKey >> 32);
sortedKeys[i] = (uint64)batchKey << 32 | (uint64)sortKey;
PackedSortKey key;
key.Data = drawCall.SortKey;
key.DistanceKey ^= MAX_uint32; // Reverse depth
key.SortKey ^= MAX_uint16; // Reverse sort order
sortedKeys[i] = key.Data;
}
}
else
@@ -605,7 +624,7 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
}
DrawBatch batch;
batch.SortKey = sortedKeys[i] & MAX_uint32;
batch.SortKey = sortedKeys[i];
batch.StartIndex = i;
batch.BatchSize = batchSize;
batch.InstanceCount = instanceCount;
@@ -618,7 +637,7 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
Sorting::QuickSort(list.Batches.Get(), list.Batches.Count());
}
bool CanUseInstancing(DrawPass pass)
FORCE_INLINE bool CanUseInstancing(DrawPass pass)
{
return pass == DrawPass::GBuffer || pass == DrawPass::Depth;
}

View File

@@ -201,7 +201,7 @@ struct DrawBatch
/// <summary>
/// Draw calls sorting key (shared by the all draw calls withing a patch).
/// </summary>
uint32 SortKey;
uint64 SortKey;
/// <summary>
/// The first draw call index.
@@ -489,7 +489,8 @@ public:
/// <param name="staticFlags">The object static flags.</param>
/// <param name="drawCall">The draw call data.</param>
/// <param name="receivesDecals">True if the rendered mesh can receive decals.</param>
void AddDrawCall(const RenderContext& renderContext, DrawPass drawModes, StaticFlags staticFlags, DrawCall& drawCall, bool receivesDecals);
/// <param name="sortOrder">Object sorting key.</param>
void AddDrawCall(const RenderContext& renderContext, DrawPass drawModes, StaticFlags staticFlags, DrawCall& drawCall, bool receivesDecals = true, int16 sortOrder = 0);
/// <summary>
/// Adds the draw call to the draw lists and references it in other render contexts. Performs additional per-context frustum culling.
@@ -501,7 +502,8 @@ public:
/// <param name="bounds">The object bounds.</param>
/// <param name="drawCall">The draw call data.</param>
/// <param name="receivesDecals">True if the rendered mesh can receive decals.</param>
void AddDrawCall(const RenderContextBatch& renderContextBatch, DrawPass drawModes, StaticFlags staticFlags, ShadowsCastingMode shadowsMode, const BoundingSphere& bounds, DrawCall& drawCall, bool receivesDecals);
/// <param name="sortOrder">Object sorting key.</param>
void AddDrawCall(const RenderContextBatch& renderContextBatch, DrawPass drawModes, StaticFlags staticFlags, ShadowsCastingMode shadowsMode, const BoundingSphere& bounds, DrawCall& drawCall, bool receivesDecals = true, int16 sortOrder = 0);
/// <summary>
/// Sorts the collected draw calls list.

View File

@@ -236,24 +236,7 @@ void Renderer::DrawSceneDepth(GPUContext* context, SceneRenderTask* task, GPUTex
renderContext.View.Prepare(renderContext);
// Call drawing (will collect draw calls)
if (customActors.HasItems())
{
// Draw custom actors
for (auto actor : customActors)
{
if (actor && actor->GetIsActive())
actor->Draw(renderContext);
}
}
else
{
// Draw scene actors
RenderContextBatch renderContextBatch(renderContext);
Level::DrawActors(renderContextBatch);
for (const int64 label : renderContextBatch.WaitLabels)
JobSystem::Wait(label);
renderContextBatch.WaitLabels.Clear();
}
DrawActors(renderContext, customActors);
// Sort draw calls
renderContext.List->SortDrawCalls(renderContext, false, DrawCallsListType::Depth);
@@ -287,6 +270,31 @@ void Renderer::DrawPostFxMaterial(GPUContext* context, const RenderContext& rend
context->ResetRenderTarget();
}
void Renderer::DrawActors(RenderContext& renderContext, const Array<Actor*>& customActors)
{
if (customActors.HasItems())
{
// Draw custom actors
for (Actor* actor : customActors)
{
if (actor && actor->GetIsActive())
actor->Draw(renderContext);
}
}
else
{
// Draw scene actors
RenderContextBatch renderContextBatch(renderContext);
JobSystem::SetJobStartingOnDispatch(false);
Level::DrawActors(renderContextBatch, SceneRendering::DrawCategory::SceneDraw);
Level::DrawActors(renderContextBatch, SceneRendering::DrawCategory::SceneDrawAsync);
JobSystem::SetJobStartingOnDispatch(true);
for (const int64 label : renderContextBatch.WaitLabels)
JobSystem::Wait(label);
renderContextBatch.WaitLabels.Clear();
}
}
void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderContextBatch& renderContextBatch)
{
auto context = GPUDevice::Instance->GetMainContext();
@@ -304,6 +312,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
// Initialize setup
RenderSetup& setup = renderContext.List->Setup;
const bool isGBufferDebug = GBufferPass::IsDebugView(renderContext.View.Mode);
{
PROFILE_CPU_NAMED("Setup");
if (renderContext.View.Origin != renderContext.View.PrevOrigin)
@@ -311,7 +320,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
const int32 screenWidth = renderContext.Buffers->GetWidth();
const int32 screenHeight = renderContext.Buffers->GetHeight();
setup.UpscaleLocation = renderContext.Task->UpscaleLocation;
if (screenWidth < 16 || screenHeight < 16 || renderContext.Task->IsCameraCut)
if (screenWidth < 16 || screenHeight < 16 || renderContext.Task->IsCameraCut || isGBufferDebug || renderContext.View.Mode == ViewMode::NoPostFx)
setup.UseMotionVectors = false;
else
{
@@ -336,7 +345,6 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
renderContext.Buffers->Prepare();
// Build batch of render contexts (main view and shadow projections)
const bool isGBufferDebug = GBufferPass::IsDebugView(renderContext.View.Mode);
{
PROFILE_CPU_NAMED("Collect Draw Calls");
@@ -423,7 +431,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
}
// Fill GBuffer
GBufferPass::Instance()->Fill(renderContext, lightBuffer->View());
GBufferPass::Instance()->Fill(renderContext, lightBuffer);
// Debug drawing
if (renderContext.View.Mode == ViewMode::GlobalSDF)
@@ -537,6 +545,10 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
RENDER_TARGET_POOL_SET_NAME(frameBuffer, "FrameBuffer");
ForwardPass::Instance()->Render(renderContext, lightBuffer, frameBuffer);
// Material and Custom PostFx
renderContext.List->RunMaterialPostFxPass(context, renderContext, MaterialPostFxLocation::AfterForwardPass, frameBuffer, lightBuffer);
renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::AfterForwardPass, frameBuffer, lightBuffer);
// Cleanup
context->ResetRenderTarget();
context->ResetSR();

View File

@@ -14,6 +14,7 @@ namespace FlaxEngine
/// <param name="task">Render task to use it's view description and the render buffers.</param>
/// <param name="output">The output texture. Must be valid and created.</param>
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
[Unmanaged]
public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List<Actor> customActors)
{
if (customActors.Count == 0)
@@ -22,5 +23,16 @@ namespace FlaxEngine
var tempCount = temp.Length;
Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), temp, ref tempCount);
}
/// <summary>
/// Invoked drawing of the scene objects (collects draw calls into RenderList for a given RenderContext).
/// </summary>
/// <param name="renderContext">The rendering context.</param>
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
[Unmanaged]
public static void DrawActors(ref RenderContext renderContext, List<Actor> customActors)
{
DrawActors(ref renderContext, Utils.ExtractArrayFromList(customActors));
}
}
}

View File

@@ -18,22 +18,18 @@ class Actor;
/// </summary>
API_CLASS(Static) class FLAXENGINE_API Renderer
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Renderer);
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Renderer);
public:
/// <summary>
/// Determines whether the scene rendering system is ready (all shaders are loaded and helper resources are ready).
/// </summary>
/// <returns><c>true</c> if this rendering service is ready for scene rendering; otherwise, <c>false</c>.</returns>
static bool IsReady();
/// <summary>
/// Performs rendering for the input task.
/// </summary>
/// <param name="task">The scene rendering task.</param>
static void Render(SceneRenderTask* task);
public:
API_FUNCTION() static void Render(SceneRenderTask* task);
/// <summary>
/// Draws scene objects depth (to the output Z buffer). The output must be depth texture to write hardware depth to it.
@@ -53,4 +49,11 @@ public:
/// <param name="output">The output texture. Must be valid and created.</param>
/// <param name="input">The input texture. It's optional.</param>
API_FUNCTION() static void DrawPostFxMaterial(GPUContext* context, API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, GPUTexture* output, GPUTextureView* input);
/// <summary>
/// Invoked drawing of the scene objects (collects draw calls into RenderList for a given RenderContext).
/// </summary>
/// <param name="renderContext">The rendering context.</param>
/// <param name="customActors">The custom set of actors to render. If empty, the loaded scenes will be rendered.</param>
API_FUNCTION() static void DrawActors(API_PARAM(Ref) RenderContext& renderContext, API_PARAM(DefaultValue=null) const Array<Actor*, HeapAllocation>& customActors);
};

View File

@@ -76,7 +76,7 @@ bool MultiScaler::setupResources()
{
psDesc.PS = shader->GetPS("PS_HalfDepth");
psDesc.DepthWriteEnable = true;
psDesc.DepthTestEnable = true;
psDesc.DepthEnable = true;
psDesc.DepthFunc = ComparisonFunc::Always;
if (_psHalfDepth->Init(psDesc))
return true;