WIP multiple probes support
This commit is contained in:
parent
88115cfedd
commit
2dd7ad8eb2
11 changed files with 153 additions and 11 deletions
|
|
@ -12,3 +12,20 @@ struct LightProbeTarget
|
|||
{
|
||||
int index = 0; // parameter for renderstate.SetLightProbe
|
||||
};
|
||||
|
||||
class LightProbeIncrementalBuilder
|
||||
{
|
||||
int lastIndex = 0;
|
||||
|
||||
int collected;
|
||||
|
||||
TArray<uint16_t> irradianceMaps;
|
||||
TArray<uint16_t> prefilterMaps;
|
||||
|
||||
public:
|
||||
|
||||
void Step(const TArray<LightProbe>& probes, std::function<void(const LightProbe&, TArray<uint16_t>&, TArray<uint16_t>&)> renderScene, std::function<void(TArray<uint16_t>&&, TArray<uint16_t>&&)> uploadEnv);
|
||||
void Full(const TArray<LightProbe>& probes, std::function<void(const LightProbe&, TArray<uint16_t>&, TArray<uint16_t>&)> renderScene, std::function<void(TArray<uint16_t>&&, TArray<uint16_t>&&)> uploadEnv);
|
||||
|
||||
auto GetStep() const { return lastIndex; }
|
||||
};
|
||||
|
|
@ -221,7 +221,8 @@ public:
|
|||
// Get the array index for the material in the textures array accessible from shaders
|
||||
virtual int GetBindlessTextureIndex(FMaterial* material, int clampmode, int translation) { return -1; }
|
||||
|
||||
virtual void RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc) {}
|
||||
virtual void RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc, TArray<uint16_t>& irradianceMap, TArray<uint16_t>& prefilterMap) {}
|
||||
virtual void UploadEnvironmentMaps(int cubemapCount, TArray<uint16_t>&& irradianceMaps, TArray<uint16_t>&& prefilterMaps) {}
|
||||
|
||||
// Screen wiping
|
||||
virtual FTexture *WipeStartScreen();
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ void VkTextureManager::CreatePrefiltermap(int size, int count, TArray<uint16_t>&
|
|||
.Execute(cmdbuffer);
|
||||
|
||||
int offset = 0;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
for (int level = 0; level < miplevels; level++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -321,13 +321,18 @@ void VulkanRenderDevice::RenderTextureView(FCanvasTexture* tex, std::function<vo
|
|||
tex->SetUpdated(true);
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc)
|
||||
void VulkanRenderDevice::RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc, TArray<uint16_t>& irradianceMap, TArray<uint16_t>& prefilterMap)
|
||||
{
|
||||
mLightprober->RenderEnvironmentMap(std::move(renderFunc));
|
||||
TArray<uint16_t> irradianceMap = mLightprober->GenerateIrradianceMap();
|
||||
TArray<uint16_t> prefilterMap = mLightprober->GeneratePrefilterMap();
|
||||
mTextureManager->CreateIrradiancemap(32, 6, std::move(irradianceMap));
|
||||
mTextureManager->CreatePrefiltermap(128, 6, std::move(prefilterMap));
|
||||
irradianceMap = mLightprober->GenerateIrradianceMap();
|
||||
prefilterMap = mLightprober->GeneratePrefilterMap();
|
||||
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::UploadEnvironmentMaps(int cubemapCount, TArray<uint16_t>&& irradianceMaps, TArray<uint16_t>&& prefilterMaps)
|
||||
{
|
||||
mTextureManager->CreateIrradiancemap(32, 6 * cubemapCount, std::move(irradianceMaps));
|
||||
mTextureManager->CreatePrefiltermap(128, 6 * cubemapCount, std::move(prefilterMaps));
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ public:
|
|||
|
||||
private:
|
||||
void RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc) override;
|
||||
void RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc) override;
|
||||
void RenderEnvironmentMap(std::function<void(IntRect& bounds, int side)> renderFunc, TArray<uint16_t>& irradianceMap, TArray<uint16_t>& prefilterMap) override;
|
||||
void UploadEnvironmentMaps(int cubemapCount, TArray<uint16_t>&& irradianceMaps, TArray<uint16_t>&& prefilterMaps) override;
|
||||
void PrintStartupLog();
|
||||
void CopyScreenToBuffer(int w, int h, uint8_t *data) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -881,6 +881,9 @@ xx(light_dontlightactors)
|
|||
xx(light_dontlightmap)
|
||||
xx(light_shadowminquality)
|
||||
|
||||
// Light probe
|
||||
xx(LightProbe)
|
||||
|
||||
xx(skew_bottom_type)
|
||||
xx(skew_middle_type)
|
||||
xx(skew_top_type)
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ void FLevelLocals::ClearLevelData(bool fullgc)
|
|||
if (levelMesh) delete levelMesh;
|
||||
aabbTree = nullptr;
|
||||
levelMesh = nullptr;
|
||||
lightProbes.Clear();
|
||||
if (screen)
|
||||
screen->SetLevelMesh(nullptr);
|
||||
if (screen && screen->mShadowMap)
|
||||
|
|
|
|||
|
|
@ -333,6 +333,7 @@ static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime)
|
|||
state.firstFrame = screen->FrameTime - 1;
|
||||
}
|
||||
|
||||
LightProbeIncrementalBuilder lightProbeBuilder;
|
||||
|
||||
sector_t* RenderView(player_t* player)
|
||||
{
|
||||
|
|
@ -403,16 +404,56 @@ sector_t* RenderView(player_t* player)
|
|||
|
||||
if (gl_lightprobe)
|
||||
{
|
||||
|
||||
// Render the light probes if not found in a lump
|
||||
// To do: we need light probe actors
|
||||
AActor* lightprobe = player->camera;
|
||||
|
||||
AActor* lightprobe = level.GetThinkerIterator<AActor>(NAME_LightProbe, STAT_DEFAULT).Next();
|
||||
if (lightprobe)
|
||||
{
|
||||
/*TArray<uint16_t> irradianceMap;
|
||||
TArray<uint16_t> prefilteredMap;
|
||||
|
||||
screen->RenderEnvironmentMap([=](IntRect& bounds, int side)
|
||||
{
|
||||
FRenderViewpoint probevp;
|
||||
RenderViewpoint(probevp, lightprobe, &bounds, 90.0, 1.0f, 1.0f, false, false, side);
|
||||
});
|
||||
}, irradianceMap, prefilteredMap);
|
||||
|
||||
screen->UploadEnvironmentMaps(1, std::move(irradianceMap), std::move(prefilteredMap));*/
|
||||
|
||||
auto renderEnvMap = [&](const LightProbe& probe, TArray<uint16_t>& irradianceMap, TArray<uint16_t>& prefilteredMap)
|
||||
{
|
||||
auto oldPos = lightprobe->Pos();
|
||||
|
||||
lightprobe->SetOrigin(DVector3(probe.position), false); // crime against nature
|
||||
lightprobe->ClearInterpolation();
|
||||
|
||||
r_NoInterpolate = true;
|
||||
|
||||
// Printf("%p | %f %f %f\n", &probe, probe.position.X, probe.position.Y, probe.position.Z);
|
||||
|
||||
screen->RenderEnvironmentMap([&](IntRect& bounds, int side)
|
||||
{
|
||||
FRenderViewpoint probevp;
|
||||
RenderViewpoint(probevp, lightprobe, &bounds, 90.0, 1.0f, 1.0f, false, false, side);
|
||||
}, irradianceMap, prefilteredMap);
|
||||
|
||||
r_NoInterpolate = false;
|
||||
};
|
||||
|
||||
lightProbeBuilder.Step(
|
||||
level.lightProbes,
|
||||
renderEnvMap,
|
||||
[&](TArray<uint16_t>&& irradianceMaps, TArray<uint16_t>&& prefilteredMaps) {
|
||||
screen->UploadEnvironmentMaps(level.lightProbes.size(), std::move(irradianceMaps), std::move(prefilteredMaps));
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Warning: spawning LightProbe\n");
|
||||
Spawn(&level, NAME_LightProbe);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -438,3 +479,60 @@ sector_t* RenderView(player_t* player)
|
|||
return retsec;
|
||||
}
|
||||
|
||||
void LightProbeIncrementalBuilder::Step(const TArray<LightProbe>& probes, std::function<void(const LightProbe&, TArray<uint16_t>&, TArray<uint16_t>&)> renderScene, std::function<void(TArray<uint16_t>&&, TArray<uint16_t>&&)> uploadEnv)
|
||||
{
|
||||
if (lastIndex >= probes.size())
|
||||
{
|
||||
lastIndex = 0;
|
||||
collected = 0;
|
||||
|
||||
if (!probes.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TArray<uint16_t> irradianceMap;
|
||||
TArray<uint16_t> prefilterMap;
|
||||
|
||||
renderScene(probes[lastIndex++], irradianceMap, prefilterMap);
|
||||
++collected;
|
||||
|
||||
this->irradianceMaps.Append(irradianceMap);
|
||||
this->prefilterMaps.Append(prefilterMap);
|
||||
|
||||
if (lastIndex >= probes.size())
|
||||
{
|
||||
if (collected == probes.size())
|
||||
{
|
||||
uploadEnv(std::move(this->irradianceMaps), std::move(this->prefilterMaps));
|
||||
}
|
||||
this->irradianceMaps.Clear();
|
||||
this->prefilterMaps.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void LightProbeIncrementalBuilder::Full(const TArray<LightProbe>& probes, std::function<void(const LightProbe&, TArray<uint16_t>&, TArray<uint16_t>&)> renderScene, std::function<void(TArray<uint16_t>&&, TArray<uint16_t>&&)> uploadEnv)
|
||||
{
|
||||
if (lastIndex >= probes.size())
|
||||
{
|
||||
lastIndex = 0;
|
||||
|
||||
if (!probes.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (lastIndex < probes.size())
|
||||
{
|
||||
Step(probes, renderScene, uploadEnv);
|
||||
}
|
||||
}
|
||||
|
||||
ADD_STAT(lightprobes)
|
||||
{
|
||||
FString out;
|
||||
out.Format("Rendering probe: %d / %d", lightProbeBuilder.GetStep(), level.lightProbes.Size());
|
||||
return out;
|
||||
}
|
||||
|
|
@ -147,7 +147,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
|||
vec3 kS = F;
|
||||
vec3 kD = 1.0 - kS;
|
||||
|
||||
const float environmentScaleFactor = 0.1;
|
||||
const float environmentScaleFactor = 1.0;
|
||||
|
||||
vec3 irradiance = texture(IrradianceMap, vec4(N, uLightProbeIndex)).rgb * environmentScaleFactor;
|
||||
vec3 diffuse = irradiance * albedo;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ version "4.12"
|
|||
#include "zscript/actors/shared/dynlights.zs"
|
||||
#include "zscript/actors/shared/corona.zs"
|
||||
#include "zscript/actors/shared/fogball.zs"
|
||||
#include "zscript/actors/shared/lightprobe.zs"
|
||||
|
||||
#include "zscript/actors/doom/doomplayer.zs"
|
||||
#include "zscript/actors/doom/possessed.zs"
|
||||
|
|
|
|||
15
wadsrc/static/zscript/actors/shared/lightprobe.zs
Normal file
15
wadsrc/static/zscript/actors/shared/lightprobe.zs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
Light probe actor.
|
||||
*/
|
||||
|
||||
class LightProbe : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
+NOINTERACTION
|
||||
+NOBLOCKMAP
|
||||
+NOGRAVITY
|
||||
Height 2;
|
||||
Radius 1;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue