Improve env probes rendering if DDGI is enabled
This commit is contained in:
BIN
Content/Shaders/GI/DDGI.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/DDGI.flax
(Stored with Git LFS)
Binary file not shown.
@@ -403,7 +403,7 @@ void SceneRenderTask::OnBegin(GPUContext* context)
|
||||
|
||||
void SceneRenderTask::OnRender(GPUContext* context)
|
||||
{
|
||||
if (Buffers && Buffers->GetWidth() > 0)
|
||||
if (!IsCustomRendering && Buffers && Buffers->GetWidth() > 0)
|
||||
Renderer::Render(this);
|
||||
|
||||
RenderTask::OnRender(context);
|
||||
|
||||
@@ -228,6 +228,11 @@ public:
|
||||
/// </summary>
|
||||
bool IsCameraCut = true;
|
||||
|
||||
/// <summary>
|
||||
/// True if the task is used for custom scene rendering and default scene drawing into output should be skipped. Enable it if you use Render event and draw scene manually.
|
||||
/// </summary>
|
||||
API_FIELD() bool IsCustomRendering = false;
|
||||
|
||||
/// <summary>
|
||||
/// Marks the next rendered frame as camera cut. Used to clear the temporal effects history and prevent visual artifacts blended from the previous frames.
|
||||
/// </summary>
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace AtmospherePreComputeImpl
|
||||
GPUPipelineState* _psCopyInscatterNAdd = nullptr;
|
||||
GPUPipelineState* _psInscatterS = nullptr;
|
||||
GPUPipelineState* _psInscatterN = nullptr;
|
||||
RenderTask* _task = nullptr;
|
||||
SceneRenderTask* _task = nullptr;
|
||||
|
||||
//
|
||||
GPUTexture* AtmosphereTransmittance = nullptr;
|
||||
@@ -166,12 +166,10 @@ bool init()
|
||||
return true;
|
||||
}
|
||||
auto shader = _shader->GetShader();
|
||||
|
||||
// Validate shader constant buffers sizes
|
||||
ASSERT(shader->GetCB(0) != nullptr);
|
||||
if (shader->GetCB(0)->GetSize() != sizeof(Data))
|
||||
{
|
||||
LOG(Fatal, "Shader {0} has incorrect constant buffer {1} size: {2} bytes. Expected: {3} bytes", _shader->ToString(), 0, shader->GetCB(0)->GetSize(), sizeof(Data));
|
||||
REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -252,6 +250,7 @@ bool init()
|
||||
// Init rendering pipeline
|
||||
_task = New<SceneRenderTask>();
|
||||
_task->Enabled = false;
|
||||
_task->IsCustomRendering = true;
|
||||
_task->Render.Bind(onRender);
|
||||
|
||||
// Init render targets
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
|
||||
int32 CascadesCount = 0;
|
||||
int32 ProbeRaysCount = 0;
|
||||
int32 ProbesCountTotal = 0;
|
||||
Int3 ProbeCounts = Int3::Zero;
|
||||
GPUTexture* ProbesTrace = nullptr; // Probes ray tracing: (RGB: hit radiance, A: hit distance)
|
||||
GPUTexture* ProbesState = nullptr; // Probes state: (RGB: world-space offset, A: state)
|
||||
@@ -194,7 +195,7 @@ bool DynamicDiffuseGlobalIlluminationPass::setupResources()
|
||||
{
|
||||
_psIndirectLighting = device->CreatePipelineState();
|
||||
psDesc.PS = shader->GetPS("PS_IndirectLighting");
|
||||
psDesc.BlendMode = BlendingMode::Additive;
|
||||
psDesc.BlendMode = BlendingMode::Add;
|
||||
if (_psIndirectLighting->Init(psDesc))
|
||||
return true;
|
||||
}
|
||||
@@ -251,15 +252,8 @@ bool DynamicDiffuseGlobalIlluminationPass::Get(const RenderBuffers* buffers, Bin
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, GPUContext* context, GPUTextureView* lightBuffer)
|
||||
bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderContext, GPUContext* context, DDGICustomBuffer& ddgiData)
|
||||
{
|
||||
// Skip if not supported
|
||||
if (checkIfSkipPass())
|
||||
return true;
|
||||
if (renderContext.List->Scenes.Count() == 0)
|
||||
return true;
|
||||
auto& ddgiData = *renderContext.Buffers->GetCustomBuffer<DDGICustomBuffer>(TEXT("DDGI"));
|
||||
|
||||
// Render Global SDF and Global Surface Atlas for software raytracing
|
||||
GlobalSignDistanceFieldPass::BindingData bindingDataSDF;
|
||||
if (GlobalSignDistanceFieldPass::Instance()->Render(renderContext, context, bindingDataSDF))
|
||||
@@ -269,13 +263,6 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
return true;
|
||||
GPUTextureView* skybox = GBufferPass::Instance()->RenderSkybox(renderContext, context);
|
||||
|
||||
// Skip if already done in the current frame
|
||||
const auto currentFrame = Engine::FrameCount;
|
||||
if (ddgiData.LastFrameUsed == currentFrame)
|
||||
return false;
|
||||
ddgiData.LastFrameUsed = currentFrame;
|
||||
PROFILE_GPU_CPU("Dynamic Diffuse Global Illumination");
|
||||
|
||||
// Setup options
|
||||
auto& settings = renderContext.List->Settings.GlobalIllumination;
|
||||
auto* graphicsSettings = GraphicsSettings::Get();
|
||||
@@ -299,7 +286,6 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
return true;
|
||||
}
|
||||
ASSERT_LOW_LAYER(probeRaysCount <= DDGI_TRACE_RAYS_LIMIT);
|
||||
bool debugProbes = renderContext.View.Mode == ViewMode::GlobalIllumination;
|
||||
const float indirectLightingIntensity = settings.Intensity;
|
||||
const float probeHistoryWeight = Math::Clamp(settings.TemporalResponse, 0.0f, 0.98f);
|
||||
const float distance = settings.Distance;
|
||||
@@ -314,7 +300,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
idealDistance *= 2;
|
||||
cascadesCount++;
|
||||
}
|
||||
|
||||
|
||||
// Calculate the probes count based on the amount of cascades and the distance to cover
|
||||
const float cascadesDistanceScales[] = { 1.0f, 3.0f, 6.0f, 10.0f }; // Scales each cascade further away from the camera origin
|
||||
const float distanceExtent = distance / cascadesDistanceScales[cascadesCount - 1];
|
||||
@@ -369,6 +355,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
ddgiData.Release();
|
||||
ddgiData.CascadesCount = cascadesCount;
|
||||
ddgiData.ProbeRaysCount = probeRaysCount;
|
||||
ddgiData.ProbesCountTotal = probesCountTotal;
|
||||
ddgiData.ProbeCounts = probesCounts;
|
||||
for (int32 cascadeIndex = 0; cascadeIndex < cascadesCount; cascadeIndex++)
|
||||
{
|
||||
@@ -408,6 +395,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
context->ClearUA(ddgiData.ProbesIrradiance, Float4::Zero);
|
||||
context->ClearUA(ddgiData.ProbesDistance, Float4::Zero);
|
||||
}
|
||||
ddgiData.LastFrameUsed = Engine::FrameCount;
|
||||
|
||||
// Calculate which cascades should be updated this frame
|
||||
const uint64 cascadeFrequencies[] = { 2, 3, 5, 7 };
|
||||
@@ -416,7 +404,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
bool cascadeSkipUpdate[4];
|
||||
for (int32 cascadeIndex = 0; cascadeIndex < cascadesCount; cascadeIndex++)
|
||||
{
|
||||
cascadeSkipUpdate[cascadeIndex] = !clear && (currentFrame % cascadeFrequencies[cascadeIndex]) != 0;
|
||||
cascadeSkipUpdate[cascadeIndex] = !clear && (ddgiData.LastFrameUsed % cascadeFrequencies[cascadeIndex]) != 0;
|
||||
}
|
||||
|
||||
// Compute scrolling (probes are placed around camera but are scrolling to increase stability during movement)
|
||||
@@ -622,6 +610,54 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext, GPUContext* context, GPUTextureView* lightBuffer)
|
||||
{
|
||||
if (checkIfSkipPass())
|
||||
return true;
|
||||
if (renderContext.List->Scenes.Count() == 0)
|
||||
return true;
|
||||
RenderBuffers* renderBuffers = renderContext.Buffers;
|
||||
bool render = true;
|
||||
if (renderContext.View.IsOfflinePass)
|
||||
{
|
||||
// During offline pass (eg. probes rendering) we can try reuse main game viewport or editor viewport DDGI probes
|
||||
// TODO: apply it for transparency too (in DynamicDiffuseGlobalIlluminationPass::Get)
|
||||
for (auto* task : RenderTask::Tasks)
|
||||
{
|
||||
if (auto* sceneTask = ScriptingObject::Cast<SceneRenderTask>(task))
|
||||
{
|
||||
auto* sceneTaskDDGI = sceneTask->Buffers ? sceneTask->Buffers->FindCustomBuffer<DDGICustomBuffer>(TEXT("DDGI")) : nullptr;
|
||||
if (sceneTaskDDGI && sceneTaskDDGI->LastFrameUsed + 1 >= Engine::FrameCount)
|
||||
{
|
||||
// Reuse DDGI from this task
|
||||
renderBuffers = sceneTask->Buffers;
|
||||
render = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto& ddgiData = *renderBuffers->GetCustomBuffer<DDGICustomBuffer>(TEXT("DDGI"));
|
||||
if (render && ddgiData.LastFrameUsed == Engine::FrameCount)
|
||||
render = false;
|
||||
|
||||
PROFILE_GPU_CPU("Dynamic Diffuse Global Illumination");
|
||||
|
||||
if (render)
|
||||
{
|
||||
if (RenderInner(renderContext, context, ddgiData))
|
||||
{
|
||||
context->ResetRenderTarget();
|
||||
context->ResetSR();
|
||||
context->ResetUA();
|
||||
context->SetViewportAndScissors(renderContext.View.ScreenSize.X, renderContext.View.ScreenSize.Y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Render indirect lighting
|
||||
if (lightBuffer)
|
||||
{
|
||||
@@ -630,6 +666,15 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
// DDGI indirect lighting debug preview
|
||||
context->Clear(lightBuffer, Color::Transparent);
|
||||
#endif
|
||||
if (!render)
|
||||
{
|
||||
Data0 data;
|
||||
data.DDGI = ddgiData.Result.Constants;
|
||||
data.TemporalTime = 0.0f;
|
||||
GBufferPass::SetInputs(renderContext.View, data.GBuffer);
|
||||
context->UpdateCB(_cb0, &data);
|
||||
context->BindCB(0, _cb0);
|
||||
}
|
||||
context->BindSR(0, renderContext.Buffers->GBuffer0->View());
|
||||
context->BindSR(1, renderContext.Buffers->GBuffer1->View());
|
||||
context->BindSR(2, renderContext.Buffers->GBuffer2->View());
|
||||
@@ -645,7 +690,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
|
||||
#if USE_EDITOR
|
||||
// Probes debug drawing
|
||||
if (debugProbes && lightBuffer)
|
||||
if (renderContext.View.Mode == ViewMode::GlobalIllumination && lightBuffer)
|
||||
{
|
||||
PROFILE_GPU_CPU("Debug Probes");
|
||||
if (!_debugModel)
|
||||
@@ -661,7 +706,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
Matrix world;
|
||||
Matrix::Scaling(Float3(0.2f), world);
|
||||
const Mesh& debugMesh = _debugModel->LODs[0].Meshes[0];
|
||||
for (int32 probeIndex = 0; probeIndex < probesCountTotal; probeIndex++)
|
||||
for (int32 probeIndex = 0; probeIndex < ddgiData.ProbesCountTotal; probeIndex++)
|
||||
debugMesh.Draw(debugRenderContext, _debugMaterial, world, StaticFlags::None, true, DrawPass::GBuffer, (float)probeIndex);
|
||||
debugRenderContext.List->SortDrawCalls(debugRenderContext, false, DrawCallsListType::GBuffer);
|
||||
context->SetViewportAndScissors(debugRenderContext.View.ScreenSize.X, debugRenderContext.View.ScreenSize.Y);
|
||||
@@ -688,14 +733,13 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
}
|
||||
debugRenderContext.List->ExecuteDrawCalls(debugRenderContext, DrawCallsListType::GBuffer);
|
||||
RenderList::ReturnToPool(debugRenderContext.List);
|
||||
context->UnBindCB(3);
|
||||
context->ResetRenderTarget();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
context->ResetRenderTarget();
|
||||
context->ResetSR();
|
||||
|
||||
context->ResetUA();
|
||||
context->SetViewportAndScissors(renderContext.View.ScreenSize.X, renderContext.View.ScreenSize.Y);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ private:
|
||||
uint64 LastFrameShaderReload = 0;
|
||||
void OnShaderReloading(Asset* obj);
|
||||
#endif
|
||||
bool RenderInner(RenderContext& renderContext, GPUContext* context, class DDGICustomBuffer& ddgiData);
|
||||
|
||||
public:
|
||||
// [RendererPass]
|
||||
|
||||
@@ -1043,14 +1043,14 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context->ResetSR();
|
||||
context->ResetRenderTarget();
|
||||
}
|
||||
|
||||
// TODO: explore atlas tiles optimization with feedback from renderer (eg. when tile is sampled by GI/Reflections mark it as used, then sort tiles by importance and prioritize updates for ones frequently used)
|
||||
|
||||
#undef WRITE_TILE
|
||||
context->ResetSR();
|
||||
context->ResetRenderTarget();
|
||||
context->SetViewportAndScissors(renderContext.View.ScreenSize.X, renderContext.View.ScreenSize.Y);
|
||||
return notReady;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
/// <summary>
|
||||
/// Custom task called after downloading probe texture data to save it.
|
||||
/// </summary>
|
||||
/// <seealso cref="ThreadPoolTask" />
|
||||
class DownloadProbeTask : public ThreadPoolTask
|
||||
{
|
||||
private:
|
||||
@@ -38,31 +37,19 @@ private:
|
||||
ProbesRenderer::Entry _entry;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DownloadProbeTask"/> class.
|
||||
/// </summary>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <param name="entry">The entry.</param>
|
||||
DownloadProbeTask(GPUTexture* target, const ProbesRenderer::Entry& entry)
|
||||
: _texture(target)
|
||||
, _entry(entry)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the texture data container.
|
||||
/// </summary>
|
||||
FORCE_INLINE TextureData& GetData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
protected:
|
||||
// [ThreadPoolTask]
|
||||
bool Run() override
|
||||
{
|
||||
// Switch type
|
||||
if (_entry.Type == ProbesRenderer::EntryType::EnvProbe)
|
||||
{
|
||||
if (_entry.Actor)
|
||||
@@ -78,7 +65,6 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fire event
|
||||
ProbesRenderer::OnFinishBake(_entry);
|
||||
|
||||
return false;
|
||||
@@ -239,13 +225,9 @@ bool ProbesRenderer::Init()
|
||||
if (!_shader->IsLoaded())
|
||||
return false;
|
||||
const auto shader = _shader->GetShader();
|
||||
|
||||
LOG(Info, "Starting Probes Renderer service");
|
||||
|
||||
// Validate shader constant buffers sizes
|
||||
if (shader->GetCB(0)->GetSize() != sizeof(Data))
|
||||
{
|
||||
LOG(Fatal, "Shader {0} has incorrect constant buffer {1} size: {2} bytes. Expected: {3} bytes", _shader.ToString(), 0, shader->GetCB(0)->GetSize(), sizeof(Data));
|
||||
REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, 0, Data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -296,6 +278,7 @@ bool ProbesRenderer::Init()
|
||||
_task = New<SceneRenderTask>();
|
||||
auto task = _task;
|
||||
task->Enabled = false;
|
||||
task->IsCustomRendering = true;
|
||||
task->Output = _output;
|
||||
auto& view = task->View;
|
||||
view.Flags =
|
||||
@@ -310,6 +293,7 @@ bool ProbesRenderer::Init()
|
||||
ViewFlags::Fog;
|
||||
view.Mode = ViewMode::NoPostFx;
|
||||
view.IsOfflinePass = true;
|
||||
view.IsSingleFrame = true;
|
||||
view.StaticFlagsMask = StaticFlags::ReflectionProbe;
|
||||
view.MaxShadowsQuality = Quality::Low;
|
||||
task->IsCameraCut = true;
|
||||
@@ -320,7 +304,7 @@ bool ProbesRenderer::Init()
|
||||
_probe = GPUDevice::Instance->CreateTexture(TEXT("ProbesUpdate.Probe"));
|
||||
if (_probe->Init(GPUTextureDescription::NewCube(probeResolution, _output->Format(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews, 0)))
|
||||
return true;
|
||||
_tmpFace = GPUDevice::Instance->CreateTexture(TEXT("ProbesUpdate.TmpFae"));
|
||||
_tmpFace = GPUDevice::Instance->CreateTexture(TEXT("ProbesUpdate.TmpFace"));
|
||||
if (_tmpFace->Init(GPUTextureDescription::New2D(probeResolution, probeResolution, 0, _output->Format(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews)))
|
||||
return true;
|
||||
|
||||
@@ -335,8 +319,6 @@ void ProbesRenderer::Release()
|
||||
return;
|
||||
ASSERT(_updateFrameNumber == 0);
|
||||
|
||||
LOG(Info, "Disposing Probes Renderer service");
|
||||
|
||||
// Release GPU data
|
||||
if (_output)
|
||||
_output->ReleaseGPU();
|
||||
@@ -471,7 +453,6 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
return;
|
||||
}
|
||||
|
||||
bool setLowerHemisphereToBlack = false;
|
||||
auto shader = _shader->GetShader();
|
||||
PROFILE_GPU("Render Probe");
|
||||
|
||||
@@ -487,7 +468,6 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
float nearPlane = Math::Max(0.1f, envProbe->CaptureNearPlane);
|
||||
|
||||
// Fix far plane distance
|
||||
// TODO: investigate performance of this action, maybe we could skip it?
|
||||
float farPlane = Math::Max(radius, nearPlane + 100.0f);
|
||||
Function<bool(Actor*, const Vector3&, float&)> f(&fixFarPlaneTreeExecute);
|
||||
SceneQuery::TreeExecute<const Vector3&, float&>(f, position, farPlane);
|
||||
@@ -505,12 +485,11 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
float farPlane = Math::Max(nearPlane + 1000.0f, skyLight->SkyDistanceThreshold * 2.0f);
|
||||
customCullingNear = skyLight->SkyDistanceThreshold;
|
||||
|
||||
// TODO: use setLowerHemisphereToBlack feature for SkyLight?
|
||||
|
||||
// Setup view
|
||||
LargeWorlds::UpdateOrigin(_task->View.Origin, position);
|
||||
_task->View.SetUpCube(nearPlane, farPlane, position - _task->View.Origin);
|
||||
}
|
||||
_task->CameraCut();
|
||||
|
||||
// Resize buffers
|
||||
bool resizeFailed = _output->Resize(probeResolution, probeResolution);
|
||||
@@ -527,7 +506,6 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
// Render scene for all faces
|
||||
for (int32 faceIndex = 0; faceIndex < 6; faceIndex++)
|
||||
{
|
||||
// Set view
|
||||
_task->View.SetFace(faceIndex);
|
||||
|
||||
// Handle custom frustum for the culling (used to skip objects near the camera)
|
||||
@@ -547,21 +525,7 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
PROFILE_GPU("Copy Face");
|
||||
context->SetRenderTarget(_probe->View(faceIndex));
|
||||
context->SetViewportAndScissors((float)probeResolution, (float)probeResolution);
|
||||
auto probeFrame = _output->View();
|
||||
if (setLowerHemisphereToBlack && faceIndex != 2)
|
||||
{
|
||||
MISSING_CODE("set lower hemisphere of the probe to black");
|
||||
/*
|
||||
ProbesFilter_Tmp.Set(_core.Rendering.Pool.RT2_FloatRGB.Handle);
|
||||
ProbesFilter_CoefficientMask2.Set(f != 3 ? 1.0f : 0.0f);
|
||||
ProbesFilter_Shader.Apply(5);
|
||||
_device.DrawFullscreenTriangle();
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
context->Draw(probeFrame);
|
||||
}
|
||||
context->Draw(_output->View());
|
||||
context->ResetRenderTarget();
|
||||
}
|
||||
}
|
||||
@@ -577,16 +541,9 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
auto cb = shader->GetCB(0);
|
||||
for (int32 mipIndex = 1; mipIndex < mipLevels; mipIndex++)
|
||||
{
|
||||
// Cache data
|
||||
int32 srcMipIndex = mipIndex - 1;
|
||||
int32 mipSize = 1 << (mipLevels - mipIndex - 1);
|
||||
data.SourceMipIndex = srcMipIndex;
|
||||
|
||||
// Set viewport
|
||||
float mipSizeFloat = (float)mipSize;
|
||||
context->SetViewportAndScissors(mipSizeFloat, mipSizeFloat);
|
||||
|
||||
// Filter all faces
|
||||
data.SourceMipIndex = mipIndex - 1;
|
||||
context->SetViewportAndScissors((float)mipSize, (float)mipSize);
|
||||
for (int32 faceIndex = 0; faceIndex < 6; faceIndex++)
|
||||
{
|
||||
context->ResetSR();
|
||||
@@ -600,12 +557,14 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
context->SetRenderTarget(_tmpFace->View(0, mipIndex));
|
||||
context->SetState(_psFilterFace);
|
||||
context->DrawFullscreenTriangle();
|
||||
|
||||
context->ResetSR();
|
||||
context->ResetRenderTarget();
|
||||
|
||||
// Copy face back to the cubemap
|
||||
copyTmpToFace(context, mipIndex, faceIndex);
|
||||
context->SetRenderTarget(_probe->View(faceIndex, mipIndex));
|
||||
context->BindSR(1, _tmpFace->View(0, mipIndex));
|
||||
context->SetState(_psCopyFace);
|
||||
context->DrawFullscreenTriangle();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -618,17 +577,4 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
_task->Enabled = false;
|
||||
}
|
||||
|
||||
void ProbesRenderer::copyTmpToFace(GPUContext* context, int32 mipIndex, int32 faceIndex)
|
||||
{
|
||||
// Set destination render target
|
||||
context->SetRenderTarget(_probe->View(faceIndex, mipIndex));
|
||||
|
||||
// Setup shader constants
|
||||
context->BindSR(1, _tmpFace->View(0, mipIndex));
|
||||
|
||||
// Copy pixels
|
||||
context->SetState(_psCopyFace);
|
||||
context->DrawFullscreenTriangle();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -105,7 +105,6 @@ public:
|
||||
private:
|
||||
|
||||
static void onRender(RenderTask* task, GPUContext* context);
|
||||
static void copyTmpToFace(GPUContext* context, int32 mipIndex, int32 faceIndex);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -112,4 +112,4 @@ class RendererPass : public Singleton<T>, public RendererPassBase
|
||||
{
|
||||
};
|
||||
|
||||
#define REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, index, dataType) LOG(Fatal, "Shader {0} has incorrect constant buffer {1} size: {2} bytes. Expected: {3} bytes", ToString(), index, shader->GetCB(index)->GetSize(), sizeof(dataType));
|
||||
#define REPORT_INVALID_SHADER_PASS_CB_SIZE(shader, index, dataType) LOG(Fatal, "Shader {0} has incorrect constant buffer {1} size: {2} bytes. Expected: {3} bytes", shader->ToString(), index, shader->GetCB(index)->GetSize(), sizeof(dataType));
|
||||
|
||||
@@ -569,7 +569,7 @@ void PS_IndirectLighting(Quad_VS2PS input, out float4 output : SV_Target0)
|
||||
// Calculate lighting
|
||||
float3 diffuseColor = GetDiffuseColor(gBuffer);
|
||||
float3 diffuse = Diffuse_Lambert(diffuseColor);
|
||||
output = float4(diffuse * irradiance * gBuffer.AO, 1);
|
||||
output = float4(diffuse * irradiance * gBuffer.AO, saturate(length(irradiance)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user