separate native methods for creating IBL from irradiance texture and harmonics

This commit is contained in:
Nick Fisher
2025-06-12 11:33:38 +08:00
parent ad26fc4563
commit 47807d560f
4 changed files with 69 additions and 26 deletions

View File

@@ -58,7 +58,8 @@ EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tM
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstance(TEngine *tEngine, TMaterialInstance *tMaterialInstance);
EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine);
EMSCRIPTEN_KEEPALIVE TSkybox *Engine_buildSkybox(TEngine *tEngine, TTexture* tTexture);
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLight(TEngine *tEngine, TTexture* tTexture, float intensity, float *harmonics);
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceTexture(TEngine *tEngine, TTexture *tReflectionsTexture, TTexture* tIrradianceTexture, float intensity);
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceHarmonics(TEngine *tEngine, TTexture *tReflectionsTexture, float *irradianceHarmonics, float intensity);
EMSCRIPTEN_KEEPALIVE void Engine_destroySkybox(TEngine *tEngine, TSkybox *tSkybox);
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLight(TEngine *tEngine, TIndirectLight *tIndirectLight);
EMSCRIPTEN_KEEPALIVE EntityId EntityManager_createEntity(TEntityManager *tEntityManager);

View File

@@ -68,7 +68,8 @@ namespace thermion
void Engine_flushAndWaitRenderThread(TEngine *tEngine, uint32_t requestId, VoidCallback onComplete);
void Engine_executeRenderThread(TEngine *tEngine, uint32_t requestId, VoidCallback onComplete);
void Engine_buildSkyboxRenderThread(TEngine *tEngine, TTexture *tTexture, void (*onComplete)(TSkybox *));
void Engine_buildIndirectLightRenderThread(TEngine *tEngine, TTexture *tTexture, float intensity, float *harmonics, void (*onComplete)(TIndirectLight *));
void Engine_buildIndirectLightFromIrradianceTextureRenderThread(TEngine *tEngine, TTexture *tReflectionsTexture, TTexture* tIrradianceTexture, float intensity, void (*onComplete)(TIndirectLight *));
void Engine_buildIndirectLightFromIrradianceHarmonicsRenderThread(TEngine *tEngine, TTexture *tReflectionsTexture, float *harmonics, float intensity, void (*onComplete)(TIndirectLight *));
void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, uint32_t requestId, VoidCallback onComplete);
void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));

View File

@@ -316,19 +316,46 @@ namespace thermion
return reinterpret_cast<TSkybox *>(skybox);
}
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLight(TEngine *tEngine, TTexture *tTexture, float intensity, float *harmonics)
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceTexture(TEngine *tEngine, TTexture *tReflectionsTexture, TTexture* tIrradianceTexture, float intensity)
{
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto *texture = reinterpret_cast<Texture *>(tTexture);
auto *reflectionsTexture = reinterpret_cast<Texture *>(tReflectionsTexture);
auto *irradianceTexture = reinterpret_cast<Texture *>(tIrradianceTexture);
filament::math::float3 sphericalHarmonics[9];
memcpy(sphericalHarmonics, harmonics, 27 * sizeof(float));
auto indirectLightBuilder = filament::IndirectLight::Builder().intensity(intensity);
auto *indirectLight = filament::IndirectLight::Builder()
.reflections(texture)
.irradiance(3, sphericalHarmonics)
.intensity(intensity)
.build(*engine);
if(!irradianceTexture) {
Log("Irradiance texture must not be empty");
return std::nullptr_t();
}
if(reflectionsTexture) {
indirectLightBuilder.reflections(reflectionsTexture);
}
auto *indirectLight = indirectLightBuilder.build(*engine);
return reinterpret_cast<TIndirectLight *>(indirectLight);
}
EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceHarmonics(TEngine *tEngine, TTexture *tReflectionsTexture, float *harmonics, float intensity)
{
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto *reflectionsTexture = reinterpret_cast<Texture *>(tReflectionsTexture);
auto indirectLightBuilder = filament::IndirectLight::Builder().intensity(intensity);
if(reflectionsTexture) {
indirectLightBuilder.reflections(reflectionsTexture);
}
if(harmonics) {
filament::math::float3 sphericalHarmonics[9];
memcpy(sphericalHarmonics, harmonics, 27 * sizeof(float));
indirectLightBuilder.irradiance(3, sphericalHarmonics);
}
auto *indirectLight = indirectLightBuilder.build(*engine);
return reinterpret_cast<TIndirectLight *>(indirectLight);
}
@@ -344,12 +371,6 @@ namespace thermion
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLight(TEngine *tEngine, TIndirectLight *tIndirectLight) {
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
auto *indirectLight = reinterpret_cast<filament::IndirectLight *>(tIndirectLight);
if(indirectLight->getReflectionsTexture()) {
engine->destroy(indirectLight->getReflectionsTexture());
}
if(indirectLight->getIrradianceTexture()) {
engine->destroy(indirectLight->getIrradianceTexture());
}
engine->destroy(indirectLight);
}

View File

@@ -361,16 +361,36 @@ extern "C"
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightRenderThread(TEngine *tEngine, TTexture *tTexture, float intensity, float *harmonics, void (*onComplete)(TIndirectLight *))
{
std::packaged_task<void()> lambda(
[=]() mutable
{
auto *indirectLight = Engine_buildIndirectLight(tEngine, tTexture, intensity, harmonics);
PROXY(onComplete(indirectLight));
});
auto fut = _renderThread->add_task(lambda);
EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightFromIrradianceTextureRenderThread(
TEngine *tEngine,
TTexture *tReflectionsTexture,
TTexture* tIrradianceTexture,
float intensity,
void (*onComplete)(TIndirectLight *)) {
std::packaged_task<void()> lambda(
[=]() mutable
{
auto *indirectLight = Engine_buildIndirectLightFromIrradianceTexture(tEngine, tReflectionsTexture, tIrradianceTexture, intensity);
PROXY(onComplete(indirectLight));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightFromIrradianceHarmonicsRenderThread(
TEngine *tEngine,
TTexture *tReflectionsTexture,
float *harmonics,
float intensity,
void (*onComplete)(TIndirectLight *)) {
std::packaged_task<void()> lambda(
[=]() mutable
{
auto *indirectLight = Engine_buildIndirectLightFromIrradianceHarmonics(tEngine, tReflectionsTexture, harmonics, intensity);
PROXY(onComplete(indirectLight));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool))
{