Workaround the skybox issue on webgl build (#8974) (BUGS=419664914)

* duplicate the material instance in webgl

* Use default instance

* Update comments

* Update

* Address the comments

* Update the naming
This commit is contained in:
Doris Wu
2025-07-31 09:56:07 +08:00
committed by GitHub
parent 86d19e53ea
commit 433fded025

View File

@@ -50,16 +50,18 @@
#include "generated/resources/iblprefilter_materials.h"
namespace {
using namespace filament::math;
using namespace filament;
constexpr static float4 sFullScreenTriangleVertices[3] = {
{ -1.0f, -1.0f, 1.0f, 1.0f },
{ 3.0f, -1.0f, 1.0f, 1.0f },
{ -1.0f, 3.0f, 1.0f, 1.0f }
constexpr float4 sFullScreenTriangleVertices[3] = {
{ -1.0f, -1.0f, 1.0f, 1.0f },
{ 3.0f, -1.0f, 1.0f, 1.0f },
{ -1.0f, 3.0f, 1.0f, 1.0f }
};
constexpr static const uint16_t sFullScreenTriangleIndices[3] = { 0, 1, 2 };
constexpr uint16_t sFullScreenTriangleIndices[3] = { 0, 1, 2 };
static float lodToPerceptualRoughness(float lod) noexcept {
// Inverse perceptualRoughness-to-LOD mapping:
@@ -75,10 +77,22 @@ static float lodToPerceptualRoughness(float lod) noexcept {
}
template<typename T>
static inline constexpr T log4(T x) {
constexpr T log4(T x) {
return std::log2(x) * T(0.5);
}
static void cleanupMaterialInstance(MaterialInstance const* mi, Engine& engine, RenderableManager& rcm,
RenderableManager::Instance const& ci) {
// mi is already nullptr, there is no need to clean up again.
if (mi == nullptr)
return;
rcm.clearMaterialInstanceAt(ci, 0);
engine.destroy(mi);
}
} // anonymous
IBLPrefilterContext::IBLPrefilterContext(Engine& engine)
: mEngine(engine) {
@@ -256,7 +270,6 @@ Texture* IBLPrefilterContext::EquirectangularToCubemap::operator()(
RenderableManager& rcm = engine.getRenderableManager();
auto const ci = rcm.getInstance(mContext.mFullScreenQuadEntity);
rcm.setMaterialInstanceAt(ci, 0, mi);
TextureSampler environmentSampler;
environmentSampler.setMagFilter(SamplerMagFilter::LINEAR);
@@ -278,8 +291,17 @@ Texture* IBLPrefilterContext::EquirectangularToCubemap::operator()(
mi->setParameter("mirror", mConfig.mirror ? -1.0f : 1.0f);
for (size_t i = 0; i < 2; i++) {
mi->setParameter("side", i == 0 ? 1.0f : -1.0f);
mi->commit(engine);
// This is a workaround for internal bug b/419664914 to duplicate same material for each draw.
// TODO: properly address the bug and remove this workaround.
#if defined(__EMSCRIPTEN__)
MaterialInstance *const tempMi = MaterialInstance::duplicate(mi);
#else
MaterialInstance *const tempMi = mi;
#endif
rcm.setMaterialInstanceAt(ci, 0, tempMi);
tempMi->setParameter("side", i == 0 ? 1.0f : -1.0f);
tempMi->commit(engine);
builder.face(RenderTarget::AttachmentPoint::COLOR0, faces[i][0])
.face(RenderTarget::AttachmentPoint::COLOR1, faces[i][1])
@@ -289,6 +311,10 @@ Texture* IBLPrefilterContext::EquirectangularToCubemap::operator()(
view->setRenderTarget(rt);
renderer->renderStandaloneView(view);
engine.destroy(rt);
#if defined(__EMSCRIPTEN__)
cleanupMaterialInstance(tempMi, engine, rcm, ci);
#endif
}
rcm.clearMaterialInstanceAt(ci, 0);
@@ -344,10 +370,8 @@ IBLPrefilterContext::IrradianceFilter::IrradianceFilter(IBLPrefilterContext& con
renderer->renderStandaloneView(view);
rcm.clearMaterialInstanceAt(ci, 0);
cleanupMaterialInstance(mi, engine, rcm, ci);
engine.destroy(rt);
engine.destroy(mi);
}
UTILS_NOINLINE
@@ -416,7 +440,6 @@ Texture* IBLPrefilterContext::IrradianceFilter::operator()(Options options,
RenderableManager& rcm = engine.getRenderableManager();
auto const ci = rcm.getInstance(mContext.mFullScreenQuadEntity);
rcm.setMaterialInstanceAt(ci, 0, mi);
const uint32_t sampleCount = mSampleCount;
const float linear = options.hdrLinear;
@@ -448,8 +471,17 @@ Texture* IBLPrefilterContext::IrradianceFilter::operator()(Options options,
view->setViewport({ 0, 0, dim, dim });
for (size_t i = 0; i < 2; i++) {
mi->setParameter("side", i == 0 ? 1.0f : -1.0f);
mi->commit(engine);
// This is a workaround for internal bug b/419664914 to duplicate same material for each draw.
// TODO: properly address the bug and remove this workaround.
#if defined(__EMSCRIPTEN__)
MaterialInstance *const tempMi = MaterialInstance::duplicate(mi);
#else
MaterialInstance *const tempMi = mi;
#endif
rcm.setMaterialInstanceAt(ci, 0, tempMi);
tempMi->setParameter("side", i == 0 ? 1.0f : -1.0f);
tempMi->commit(engine);
builder.face(RenderTarget::AttachmentPoint::COLOR0, faces[i][0])
.face(RenderTarget::AttachmentPoint::COLOR1, faces[i][1])
@@ -459,10 +491,13 @@ Texture* IBLPrefilterContext::IrradianceFilter::operator()(Options options,
view->setRenderTarget(rt);
renderer->renderStandaloneView(view);
engine.destroy(rt);
#if defined(__EMSCRIPTEN__)
cleanupMaterialInstance(tempMi, engine, rcm, ci);
#endif
}
rcm.clearMaterialInstanceAt(ci, 0);
engine.destroy(mi);
return outIrradianceTexture;
@@ -554,10 +589,8 @@ IBLPrefilterContext::SpecularFilter::SpecularFilter(IBLPrefilterContext& context
renderer->renderStandaloneView(view);
rcm.clearMaterialInstanceAt(ci, 0);
cleanupMaterialInstance(mi, engine, rcm, ci);
engine.destroy(rt);
engine.destroy(mi);
}
UTILS_NOINLINE
@@ -655,7 +688,6 @@ Texture* IBLPrefilterContext::SpecularFilter::operator()(
RenderableManager& rcm = engine.getRenderableManager();
auto const ci = rcm.getInstance(mContext.mFullScreenQuadEntity);
rcm.setMaterialInstanceAt(ci, 0, mi);
const uint32_t sampleCount = mSampleCount;
const float linear = options.hdrLinear;
@@ -703,8 +735,17 @@ Texture* IBLPrefilterContext::SpecularFilter::operator()(
view->setViewport({ 0, 0, dim, dim });
for (size_t i = 0; i < 2; i++) {
mi->setParameter("side", i == 0 ? 1.0f : -1.0f);
mi->commit(engine);
// This is a workaround for internal bug b/419664914 to duplicate same material for each draw.
// TODO: properly address the bug and remove this workaround.
#if defined(__EMSCRIPTEN__)
MaterialInstance *const tempMi = MaterialInstance::duplicate(mi);
#else
MaterialInstance *const tempMi = mi;
#endif
rcm.setMaterialInstanceAt(ci, 0, tempMi);
tempMi->setParameter("side", i == 0 ? 1.0f : -1.0f);
tempMi->commit(engine);
builder.face(RenderTarget::AttachmentPoint::COLOR0, faces[i][0])
.face(RenderTarget::AttachmentPoint::COLOR1, faces[i][1])
@@ -714,13 +755,16 @@ Texture* IBLPrefilterContext::SpecularFilter::operator()(
view->setRenderTarget(rt);
renderer->renderStandaloneView(view);
engine.destroy(rt);
#if defined(__EMSCRIPTEN__)
cleanupMaterialInstance(tempMi, engine, rcm, ci);
#endif
}
dim >>= 1;
}
rcm.clearMaterialInstanceAt(ci, 0);
engine.destroy(mi);
return outReflectionsTexture;