Add support for baking env probes in cooked game

This commit is contained in:
Wojciech Figat
2022-07-18 16:32:50 +02:00
parent fb3601dac6
commit 6061a0a344
9 changed files with 62 additions and 60 deletions

View File

@@ -64,6 +64,7 @@ bool DeployDataStep::Perform(CookingData& data)
data.AddRootEngineAsset(TEXT("Shaders/Histogram"));
data.AddRootEngineAsset(TEXT("Shaders/Lights"));
data.AddRootEngineAsset(TEXT("Shaders/MultiScaler"));
data.AddRootEngineAsset(TEXT("Shaders/ProbesFilter"));
data.AddRootEngineAsset(TEXT("Shaders/PostProcessing"));
data.AddRootEngineAsset(TEXT("Shaders/MotionBlur"));
data.AddRootEngineAsset(TEXT("Shaders/BitonicSort"));

View File

@@ -176,33 +176,7 @@ bool Texture::LoadFile(const StringView& path, bool generateMips)
}
auto initData = New<InitData>();
initData->Format = textureData.Format;
initData->Width = textureData.Width;
initData->Height = textureData.Height;
initData->ArraySize = 1;
if (generateMips)
initData->Mips.Resize(MipLevelsCount(textureData.Width, textureData.Height));
else
initData->Mips.Resize(textureData.GetMipLevels());
for (int32 mipIndex = 0; mipIndex < textureData.GetMipLevels(); mipIndex++)
{
auto& mip = initData->Mips[mipIndex];
auto& data = *textureData.GetData(0, mipIndex);
mip.Data.Copy(data.Data);
mip.RowPitch = data.RowPitch;
mip.SlicePitch = data.DepthPitch;
}
if (generateMips)
{
for (int32 mipIndex = textureData.GetMipLevels(); mipIndex < initData->Mips.Count(); mipIndex++)
{
initData->GenerateMip(mipIndex, true);
}
}
initData->FromTextureData(textureData, generateMips);
return Init(initData);
}

View File

@@ -886,3 +886,43 @@ bool TextureBase::InitData::GenerateMip(int32 mipIndex, bool linear)
return false;
}
void TextureBase::InitData::FromTextureData(const TextureData& textureData, bool generateMips)
{
Format = textureData.Format;
Width = textureData.Width;
Height = textureData.Height;
ArraySize = textureData.GetArraySize();
if (generateMips)
Mips.Resize(MipLevelsCount(textureData.Width, textureData.Height));
else
Mips.Resize(textureData.GetMipLevels());
for (int32 mipIndex = 0; mipIndex < textureData.GetMipLevels(); mipIndex++)
{
auto& mip = Mips[mipIndex];
auto& data = *textureData.GetData(0, mipIndex);
mip.Data.Allocate(data.Data.Length() * ArraySize);
mip.RowPitch = data.RowPitch;
mip.SlicePitch = data.Data.Length();
byte* dst = mip.Data.Get();
for (int32 arrayIndex = 0; arrayIndex < ArraySize; arrayIndex++)
{
auto& d = *textureData.GetData(arrayIndex, mipIndex);
ASSERT(data.RowPitch == d.RowPitch);
ASSERT(data.Data.Length() == d.Data.Length());
Platform::MemoryCopy(dst, d.Data.Get(), d.Data.Length());
dst += data.Data.Length();
ASSERT((int32)(dst - mip.Data.Get()) <= mip.Data.Length());
}
}
if (generateMips)
{
for (int32 mipIndex = textureData.GetMipLevels(); mipIndex < Mips.Count(); mipIndex++)
{
GenerateMip(mipIndex, true);
}
}
}

View File

@@ -45,6 +45,8 @@ API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API TextureBase : public BinaryAss
/// <param name="linear">True if use linear filer, otherwise point filtering.</param>
/// <returns>True if failed, otherwise false.</returns>
bool GenerateMip(int32 mipIndex, bool linear = false);
void FromTextureData(const TextureData& textureData, bool generateMips = false);
};
protected:

View File

@@ -84,16 +84,12 @@ void EnvironmentProbe::SetCustomProbe(CubeTexture* probe)
void EnvironmentProbe::Bake(float timeout)
{
#if COMPILE_WITH_PROBES_BAKING
ProbesRenderer::Bake(this, timeout);
#else
LOG(Warning, "Baking probes is not supported.");
#endif
}
void EnvironmentProbe::SetProbeData(GPUContext* context, GPUTexture* data)
{
// Remove any probe asset
// Remove probe asset (if used)
_isUsingCustomProbe = false;
_probe = nullptr;
@@ -128,11 +124,14 @@ void EnvironmentProbe::SetProbeData(TextureData& data)
_probe = nullptr;
}
Guid id = Guid::New();
// Remove probe texture (if used)
SAFE_DELETE_GPU_RESOURCE(_probeTexture);
#if COMPILE_WITH_ASSETS_IMPORTER
// Create asset file
const String path = GetScene()->GetDataFolderPath() / TEXT("EnvProbes/") / GetID().ToString(Guid::FormatType::N) + ASSET_FILES_EXTENSION_WITH_DOT;
AssetInfo info;
Guid id = Guid::New();
if (FileSystem::FileExists(path) && Content::GetAssetInfo(path, info))
id = info.ID;
if (AssetsImportingManager::Create(AssetsImportingManager::CreateCubeTextureTag, path, id, &data))
@@ -141,14 +140,6 @@ void EnvironmentProbe::SetProbeData(TextureData& data)
return;
}
// Remove probe texture
SAFE_DELETE_GPU_RESOURCE(_probeTexture);
#else
// TODO: create or reuse virtual texture and use it
LOG(Error, "Changing probes at runtime in game is not supported.");
return;
#endif
// Check if has loaded probe and it has different ID
if (_probe && _probe->GetID() != id)
{
@@ -159,6 +150,19 @@ void EnvironmentProbe::SetProbeData(TextureData& data)
// Link probe texture
_probe = Content::LoadAsync<CubeTexture>(id);
#else
// Create virtual asset
if (!_probe || !_probe->IsVirtual())
_probe = Content::CreateVirtualAsset<CubeTexture>();
auto initData = New<TextureBase::InitData>();
initData->FromTextureData(data);
if (_probe->Init(initData))
{
Delete(initData);
LOG(Error, "Cannot load generated env probe!");
return;
}
#endif
}
void EnvironmentProbe::UpdateBounds()
@@ -175,10 +179,8 @@ void EnvironmentProbe::Draw(RenderContext& renderContext)
(renderContext.View.Flags & ViewFlags::Reflections) != 0 &&
renderContext.View.Pass & DrawPass::GBuffer)
{
#if COMPILE_WITH_PROBES_BAKING
if (UpdateMode == ProbeUpdateMode::Realtime)
ProbesRenderer::Bake(this, 0.0f);
#endif
if ((_probe != nullptr && _probe->IsLoaded()) || _probeTexture != nullptr)
{
renderContext.List->EnvironmentProbes.Add(this);

View File

@@ -48,11 +48,7 @@ CubeTexture* SkyLight::GetSource() const
void SkyLight::Bake(float timeout)
{
#if COMPILE_WITH_PROBES_BAKING
ProbesRenderer::Bake(this, timeout);
#else
LOG(Warning, "Baking probes is not supported.");
#endif
}
void SkyLight::SetProbeData(TextureData& data)

View File

@@ -1,7 +1,5 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#if COMPILE_WITH_PROBES_BAKING
#include "ProbesRenderer.h"
#include "Renderer.h"
#include "ReflectionsPass.h"
@@ -602,5 +600,3 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
_current.Type = EntryType::Invalid;
}
}
#endif

View File

@@ -2,8 +2,6 @@
#pragma once
#if COMPILE_WITH_PROBES_BAKING
#include "Engine/Scripting/ScriptingObjectReference.h"
#include "Engine/Level/Actor.h"
@@ -107,5 +105,3 @@ private:
static void onRender(RenderTask* task, GPUContext* context);
};
#endif

View File

@@ -15,10 +15,5 @@ public class Renderer : EngineModule
options.PrivateDependencies.Add("Graphics");
options.PrivateDependencies.Add("Content");
if (options.Target.IsEditor)
{
options.PublicDefinitions.Add("COMPILE_WITH_PROBES_BAKING");
}
}
}