diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ef9a3814..b4aa5b2b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1122,6 +1122,7 @@ set (PCH_SOURCES common/rendering/hwrenderer/data/hw_collision.cpp common/rendering/hwrenderer/data/hw_levelmesh.cpp common/rendering/hwrenderer/data/hw_meshbuilder.cpp + common/rendering/hwrenderer/data/hw_lightprobe.cpp common/rendering/hwrenderer/postprocessing/hw_postprocessshader.cpp common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp common/rendering/hwrenderer/postprocessing/hw_postprocess_cvars.cpp diff --git a/src/common/rendering/hwrenderer/data/hw_lightprobe.cpp b/src/common/rendering/hwrenderer/data/hw_lightprobe.cpp new file mode 100644 index 000000000..3a5b873a9 --- /dev/null +++ b/src/common/rendering/hwrenderer/data/hw_lightprobe.cpp @@ -0,0 +1,52 @@ +#include "hw_lightprobe.h" + +void LightProbeIncrementalBuilder::Step(const TArray& probes, std::function&, TArray&)> renderScene, std::function&&, TArray&&)> uploadEnv) +{ + if (lastIndex >= probes.size()) + { + lastIndex = 0; + + if (!probes.size()) + { + return; + } + } + + TArray irradianceMap; + TArray 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(); + collected = 0; + } +} + +void LightProbeIncrementalBuilder::Full(const TArray& probes, std::function&, TArray&)> renderScene, std::function&&, TArray&&)> uploadEnv) +{ + if (lastIndex >= probes.size()) + { + lastIndex = 0; + + if (!probes.size()) + { + return; + } + } + + while (lastIndex < probes.size()) + { + Step(probes, renderScene, uploadEnv); + } +} diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index f28fef875..40f7681f1 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -404,56 +404,42 @@ 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 = level.GetThinkerIterator(NAME_LightProbe, STAT_DEFAULT).Next(); + AActor* lightprobe = level.GetThinkerIterator(NAME_LightProbe, STAT_INFO).Next(); if (lightprobe) { - /*TArray irradianceMap; - TArray prefilteredMap; + auto renderEnvMap = [&](const LightProbe& probe, TArray& irradianceMap, TArray& prefilteredMap) { + lightprobe->SetOrigin(DVector3(probe.position), false); // crime against nature - screen->RenderEnvironmentMap([=](IntRect& bounds, int side) - { + // The renderer interpolates camera in its own mechanism that has to be disabled when moving around the single probe + bool noInterpolate = r_NoInterpolate; + r_NoInterpolate = true; + + 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));*/ + r_NoInterpolate = noInterpolate; + }; - auto renderEnvMap = [&](const LightProbe& probe, TArray& irradianceMap, TArray& 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; - }; + auto renderEnvScreen = [&](TArray&& irradianceMaps, TArray&& prefilteredMaps) { + screen->UploadEnvironmentMaps(level.lightProbes.size(), std::move(irradianceMaps), std::move(prefilteredMaps)); + }; lightProbeBuilder.Step( level.lightProbes, renderEnvMap, - [&](TArray&& irradianceMaps, TArray&& prefilteredMaps) { - screen->UploadEnvironmentMaps(level.lightProbes.size(), std::move(irradianceMaps), std::move(prefilteredMaps)); - } + renderEnvScreen ); } else { Printf("Warning: spawning LightProbe\n"); - Spawn(&level, NAME_LightProbe); + auto probe = Spawn(&level, NAME_LightProbe); + probe->ChangeStatNum(STAT_INFO); } } @@ -479,57 +465,6 @@ sector_t* RenderView(player_t* player) return retsec; } -void LightProbeIncrementalBuilder::Step(const TArray& probes, std::function&, TArray&)> renderScene, std::function&&, TArray&&)> uploadEnv) -{ - if (lastIndex >= probes.size()) - { - lastIndex = 0; - - if (!probes.size()) - { - return; - } - } - - TArray irradianceMap; - TArray 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(); - collected = 0; - } -} - -void LightProbeIncrementalBuilder::Full(const TArray& probes, std::function&, TArray&)> renderScene, std::function&&, TArray&&)> uploadEnv) -{ - if (lastIndex >= probes.size()) - { - lastIndex = 0; - - if (!probes.size()) - { - return; - } - } - - while (lastIndex < probes.size()) - { - Step(probes, renderScene, uploadEnv); - } -} - ADD_STAT(lightprobes) { FString out; diff --git a/wadsrc/static/zscript/actors/shared/lightprobe.zs b/wadsrc/static/zscript/actors/shared/lightprobe.zs index e56a6a726..79d61720a 100644 --- a/wadsrc/static/zscript/actors/shared/lightprobe.zs +++ b/wadsrc/static/zscript/actors/shared/lightprobe.zs @@ -4,6 +4,8 @@ class LightProbe : Actor { + // note: thinker is set to STAT_INFO + Default { +NOINTERACTION