Add support for baking env probes in cooked game
This commit is contained in:
@@ -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"));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user