Add RealtimeSkybox mode to SkyLight for dynamic skylight

This commit is contained in:
2026-06-23 13:42:46 +02:00
parent 0477d37aeb
commit 2486fecca5
7 changed files with 33 additions and 15 deletions
@@ -60,8 +60,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
{
auto& skyLight = cache->SkyLights.First();
skyLight.SetShaderData(data.SkyLight, false);
const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr;
params.GPUContext->BindSR(skyLightShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
params.GPUContext->BindSR(skyLightShaderRegisterIndex, skyLight.CubemapImageView);
}
else
{
+19 -5
View File
@@ -5,13 +5,17 @@
#include "Engine/Platform/FileSystem.h"
#include "Engine/Graphics/RenderView.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Graphics/RenderTools.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/Textures/GPUTexture.h"
#include "Engine/Graphics/Textures/TextureData.h"
#include "Engine/Renderer/RenderList.h"
#include "Engine/Renderer/ProbesRenderer.h"
#include "Engine/Renderer/GBufferPass.h"
#include "Engine/Content/Content.h"
#include "Engine/Serialization/Serialization.h"
#include "Engine/ContentImporters/AssetsImportingManager.h"
#include "Engine/Graphics/RenderTools.h"
#include "Engine/Level/Scene/Scene.h"
SkyLight::SkyLight(const SpawnParams& params)
@@ -57,10 +61,9 @@ void SkyLight::SetProbeData(TextureData& data)
// Validate input data
ASSERT(data.GetArraySize() == 6);
// Check if was using custom probe
if (Mode == Modes::CustomTexture)
// Check if wasn't using captured probe
if (Mode != Modes::CaptureScene)
{
// Set
Mode = Modes::CaptureScene;
_bakedProbe = nullptr;
}
@@ -122,7 +125,18 @@ void SkyLight::Draw(RenderContext& renderContext)
data.AdditiveColor = AdditiveColor.ToFloat3() * (AdditiveColor.A * brightness);
data.IndirectLightingIntensity = IndirectLightingIntensity;
data.Radius = GetScaledRadius();
data.Image = GetSource();
if (Mode == Modes::RealtimeSkybox)
{
if (GPUTextureView* skybox = GBufferPass::Instance()->RenderSkybox(renderContext, GPUDevice::Instance->GetMainContext()))
{
data.CubemapImageView = skybox;
}
}
else if (CubeTexture* image = GetSource())
{
data.CubemapImageView = GET_TEXTURE_VIEW_SAFE(image->GetTexture());
data.CubemapImageMip = image->StreamingTexture()->TotalMipLevels() - 2.0;
}
data.StaticFlags = GetStaticFlags();
data.ID = GetID();
data.ScreenSize = Math::Min(1.0f, Math::Sqrt(RenderTools::ComputeBoundsScreenRadiusSquared(position, (float)_sphere.Radius, renderContext.View)));
+7 -2
View File
@@ -28,6 +28,11 @@ public:
/// The custom cube texture will be used as a light source.
/// </summary>
CustomTexture = 1,
/// <summary>
/// Realtime skybox will be used as a light source. Uses low-res cubemap generated from the sky/skybox (used by Global Illumination for fallback traces). Offers optimized dynamic ambient lighting.
/// </summary>
RealtimeSkybox = 2,
};
private:
@@ -44,13 +49,13 @@ public:
/// <summary>
/// Distance from the light at which any geometry should be treated as part of the sky.
/// </summary>
API_FIELD(Attributes="EditorOrder(45), DefaultValue(150000.0f), Limit(0), EditorDisplay(\"Probe\")")
API_FIELD(Attributes="EditorOrder(45), Limit(0), EditorDisplay(\"Probe\")")
float SkyDistanceThreshold = 150000.0f;
/// <summary>
/// The current light source mode.
/// </summary>
API_FIELD(Attributes="EditorOrder(40), DefaultValue(Modes.CustomTexture), EditorDisplay(\"Probe\")")
API_FIELD(Attributes="EditorOrder(40), EditorDisplay(\"Probe\")")
Modes Mode = Modes::CustomTexture;
/// <summary>
+1 -1
View File
@@ -384,7 +384,7 @@ void LightPass::RenderLights(RenderContextBatch& renderContextBatch, GPUTextureV
Matrix::Transpose(wvp, perLight.WVP);
// Bind source image
context->BindSR(7, light.Image ? light.Image->GetTexture() : nullptr);
context->BindSR(7, light.CubemapImageView);
// Calculate lighting
if (_depthBounds)
+1 -1
View File
@@ -181,7 +181,7 @@ void RenderSkyLightData::SetShaderData(ShaderLightData& data, bool useShadow) co
data.SpotAngles.X = AdditiveColor.X;
data.SpotAngles.Y = AdditiveColor.Y;
data.SourceRadius = AdditiveColor.Z;
data.SourceLength = Image ? Image->StreamingTexture()->TotalMipLevels() - 2.0f : 0.0f;
data.SourceLength = CubemapImageMip;
data.Color = Color;
data.MinRoughness = MIN_ROUGHNESS;
data.Position = Position;
+2 -1
View File
@@ -144,7 +144,8 @@ struct RenderSkyLightData : RenderLightData
Float3 AdditiveColor;
float Radius;
CubeTexture* Image;
GPUTextureView* CubemapImageView;
float CubemapImageMip;
RenderSkyLightData()
{
+2 -3
View File
@@ -483,7 +483,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
}
// Init sky light data
GPUTexture* skyLightImage = nullptr;
GPUTextureView* skyLightImage = nullptr;
Platform::MemoryClear(&cache.Data.SkyLight, sizeof(cache.Data.SkyLight));
if (renderContext.List->SkyLights.HasItems() && !useDDGI)
{
@@ -493,8 +493,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
cache.Data.SkyLight.MultiplyColor = skyLight.Color;
cache.Data.SkyLight.AdditiveColor = skyLight.AdditiveColor;
cache.Data.SkyLight.VolumetricScatteringIntensity = skyLight.VolumetricScatteringIntensity;
const auto source = skyLight.Image;
skyLightImage = source ? source->GetTexture() : nullptr;
skyLightImage = skyLight.CubemapImageView;
}
}