Merge remote-tracking branch 'origin/master' into dotnet7
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -221,7 +221,6 @@ struct DrawCall
|
||||
float UVOffsetX;
|
||||
float UVOffsetY;
|
||||
uint32 SegmentCount;
|
||||
GPUBuffer* SegmentDistances;
|
||||
} Ribbon;
|
||||
|
||||
struct
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -64,7 +64,7 @@ PACK_STRUCT(struct ModelsRasterizeData
|
||||
Int3 ChunkCoord;
|
||||
float MaxDistance;
|
||||
Float3 CascadeCoordToPosMul;
|
||||
int32 ObjectsCount;
|
||||
uint32 ObjectsCount;
|
||||
Float3 CascadeCoordToPosAdd;
|
||||
int32 CascadeResolution;
|
||||
int32 CascadeIndex;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user