Fix bad state after setIndirectLight(null).
This cleans up 3 related issues, but only the first of these caused an actual user-visible bug: (1) When the IBL was null, prepareLighting was failing to bind the black 1x1 texture. (2) If you added and removed an IBL from a Scene, then Scene was not returned to its initial state. (3) The default 1x1 IBL used an intensity of 1 rather than 30000, which is inconsistent with the null IBL. Fixes #1940.
This commit is contained in:
@@ -8,6 +8,8 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
- Improve high roughness material rendering by default when regenerating environments maps
|
||||
|
||||
- Fix bad state after removing an IBL from the Scene.
|
||||
|
||||
## v1.4.3
|
||||
|
||||
- Fixed an assertion when a parameter array occurs last in a material definition.
|
||||
|
||||
@@ -236,7 +236,6 @@ void FEngine::init() {
|
||||
mDefaultIbl = upcast(IndirectLight::Builder()
|
||||
.reflections(mDefaultIblTexture)
|
||||
.irradiance(3, reinterpret_cast<const float3*>(sh))
|
||||
.intensity(1.0f)
|
||||
.build(*this));
|
||||
|
||||
// Always initialize the default material, most materials' depth shaders fallback on it.
|
||||
|
||||
@@ -45,7 +45,7 @@ struct IndirectLight::BuilderDetails {
|
||||
Texture const* mIrradianceMap = nullptr;
|
||||
float3 mIrradianceCoefs[9] = {};
|
||||
mat3f mRotation = {};
|
||||
float mIntensity = 30000.0f;
|
||||
float mIntensity = FIndirectLight::DEFAULT_INTENSITY;
|
||||
};
|
||||
|
||||
using BuilderType = IndirectLight;
|
||||
|
||||
@@ -42,8 +42,7 @@ namespace details {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
FScene::FScene(FEngine& engine) :
|
||||
mEngine(engine),
|
||||
mIndirectLight(engine.getDefaultIndirectLight()) {
|
||||
mEngine(engine) {
|
||||
}
|
||||
|
||||
FScene::~FScene() noexcept = default;
|
||||
|
||||
@@ -337,24 +337,29 @@ void FView::prepareLighting(FEngine& engine, FEngine::DriverApi& driver, ArenaSc
|
||||
u.setUniform(offsetof(PerViewUib, exposure), exposure);
|
||||
u.setUniform(offsetof(PerViewUib, ev100), ev100);
|
||||
|
||||
// IBL
|
||||
FIndirectLight const* const ibl = scene->getIndirectLight();
|
||||
// If the scene does not have an IBL, use the black 1x1 IBL and honor the fallback intensity
|
||||
// associated with the skybox.
|
||||
FIndirectLight const* ibl = scene->getIndirectLight();
|
||||
float intensity;
|
||||
if (UTILS_LIKELY(ibl)) {
|
||||
float2 iblMaxMipLevel{ ibl->getMaxMipLevel(), 1u << ibl->getMaxMipLevel() };
|
||||
u.setUniform(offsetof(PerViewUib, iblMaxMipLevel), iblMaxMipLevel);
|
||||
u.setUniform(offsetof(PerViewUib, iblLuminance), ibl->getIntensity() * exposure);
|
||||
u.setUniformArray(offsetof(PerViewUib, iblSH), ibl->getSH(), 9);
|
||||
if (ibl->getReflectionMap()) {
|
||||
mPerViewSb.setSampler(PerViewSib::IBL_SPECULAR, {
|
||||
ibl->getReflectionMap(), {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR
|
||||
}});
|
||||
}
|
||||
intensity = ibl->getIntensity();
|
||||
} else {
|
||||
ibl = engine.getDefaultIndirectLight();
|
||||
FSkybox const* const skybox = scene->getSkybox();
|
||||
const float intensity = skybox ? skybox->getIntensity() : FIndirectLight::DEFAULT_INTENSITY;
|
||||
u.setUniform(offsetof(PerViewUib, iblLuminance), intensity * exposure);
|
||||
intensity = skybox ? skybox->getIntensity() : FIndirectLight::DEFAULT_INTENSITY;
|
||||
}
|
||||
|
||||
// Set up uniforms and sampler for the IBL, guaranteed to be non-null at this point.
|
||||
float2 iblMaxMipLevel{ ibl->getMaxMipLevel(), 1u << ibl->getMaxMipLevel() };
|
||||
u.setUniform(offsetof(PerViewUib, iblMaxMipLevel), iblMaxMipLevel);
|
||||
u.setUniform(offsetof(PerViewUib, iblLuminance), intensity * exposure);
|
||||
u.setUniformArray(offsetof(PerViewUib, iblSH), ibl->getSH(), 9);
|
||||
if (ibl->getReflectionMap()) {
|
||||
mPerViewSb.setSampler(PerViewSib::IBL_SPECULAR, {
|
||||
ibl->getReflectionMap(), {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR
|
||||
}});
|
||||
}
|
||||
|
||||
// Directional light (always at index 0)
|
||||
|
||||
@@ -35,7 +35,7 @@ class FEngine;
|
||||
|
||||
class FIndirectLight : public IndirectLight {
|
||||
public:
|
||||
static constexpr float DEFAULT_INTENSITY = 30000.0f; // lux
|
||||
static constexpr float DEFAULT_INTENSITY = 30000.0f; // lux of the sun
|
||||
|
||||
FIndirectLight(FEngine& engine, const Builder& builder) noexcept;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user