From ef488fdf5709ea6bbf76111f1a7653b950d906ac Mon Sep 17 00:00:00 2001 From: Sungun Park Date: Mon, 26 Feb 2024 13:02:58 -0800 Subject: [PATCH] Add blit array shader This shader takes an array texture and a layer index to draw to the current render target. This will be used for debugging purpose to combine an array texture rendered from the multiview feature that is going to be implemented later, so that we can verify the feature properly performed. --- filament/CMakeLists.txt | 1 + filament/src/PostProcessManager.cpp | 79 ++++++++++++++++++++++++++++ filament/src/PostProcessManager.h | 9 ++++ filament/src/materials/blitArray.mat | 38 +++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 filament/src/materials/blitArray.mat diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index 1855eec649..698c139332 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -215,6 +215,7 @@ set(MATERIAL_SRCS src/materials/antiAliasing/fxaa.mat src/materials/antiAliasing/taa.mat src/materials/blitLow.mat + src/materials/blitArray.mat src/materials/bloom/bloomDownsample.mat src/materials/bloom/bloomDownsample2x.mat src/materials/bloom/bloomDownsample9.mat diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index eb4fcf55f8..3a1b2b18a3 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -262,6 +262,7 @@ static const PostProcessManager::MaterialInfo sMaterialListFeatureLevel0[] = { static const PostProcessManager::MaterialInfo sMaterialList[] = { { "bilateralBlur", MATERIAL(BILATERALBLUR) }, { "bilateralBlurBentNormals", MATERIAL(BILATERALBLURBENTNORMALS) }, + { "blitArray", MATERIAL(BLITARRAY) }, { "bloomDownsample", MATERIAL(BLOOMDOWNSAMPLE) }, { "bloomDownsample2x", MATERIAL(BLOOMDOWNSAMPLE2X) }, { "bloomDownsample9", MATERIAL(BLOOMDOWNSAMPLE9) }, @@ -3283,6 +3284,84 @@ FrameGraphId PostProcessManager::debugShadowCascades(FrameGra return debugShadowCascadePass->output; } +FrameGraphId PostProcessManager::debugCombineArrayTexture(FrameGraph& fg, + bool translucent, FrameGraphId input, + filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc, + SamplerMagFilter filterMag, + SamplerMinFilter filterMin) noexcept { + + assert_invariant(fg.getDescriptor(input).depth > 1); + assert_invariant(fg.getDescriptor(input).type == SamplerType::SAMPLER_2D_ARRAY); + + // TODO: add support for sub-resources + assert_invariant(fg.getSubResourceDescriptor(input).layer == 0); + assert_invariant(fg.getSubResourceDescriptor(input).level == 0); + + struct QuadBlitData { + FrameGraphId input; + FrameGraphId output; + }; + + auto& ppQuadBlit = fg.addPass("combining array tex", + [&](FrameGraph::Builder& builder, auto& data) { + data.input = builder.sample(input); + data.output = builder.createTexture("upscaled output", outDesc); + data.output = builder.write(data.output, + FrameGraphTexture::Usage::COLOR_ATTACHMENT); + builder.declareRenderPass(builder.getName(data.output), { + .attachments = {.color = { data.output }}, + .clearFlags = TargetBufferFlags::DEPTH }); + }, + [=](FrameGraphResources const& resources, + auto const& data, DriverApi& driver) { + auto color = resources.getTexture(data.input); + auto const& inputDesc = resources.getDescriptor(data.input); + auto out = resources.getRenderPassInfo(); + + // -------------------------------------------------------------------------------- + // set uniforms + + PostProcessMaterial const& material = getPostProcessMaterial("blitArray"); + auto* mi = material.getMaterialInstance(mEngine); + mi->setParameter("color", color, { + .filterMag = filterMag, + .filterMin = filterMin + }); + mi->setParameter("layerIndex", 0); + mi->setParameter("viewport", float4{ + float(vp.left) / inputDesc.width, + float(vp.bottom) / inputDesc.height, + float(vp.width) / inputDesc.width, + float(vp.height) / inputDesc.height + }); + mi->commit(driver); + mi->use(driver); + + auto pipeline = material.getPipelineState(mEngine); + if (translucent) { + pipeline.first.rasterState.blendFunctionSrcRGB = BlendFunction::ONE; + pipeline.first.rasterState.blendFunctionSrcAlpha = BlendFunction::ONE; + pipeline.first.rasterState.blendFunctionDstRGB = BlendFunction::ONE_MINUS_SRC_ALPHA; + pipeline.first.rasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_ALPHA; + } + + // Blit the scene rendered to the first layer to the left half of the screen. + out.params.viewport.width /= 2; + render(out, pipeline, driver); + + // Blit the scene rendered to the second layer to the right half of the screen. + // Don't clear or discard the target to keep the previously rendered left half image. + mi->setParameter("layerIndex", 1); + mi->commit(driver); + out.params.flags.clear = filament::backend::TargetBufferFlags::NONE; + out.params.flags.discardStart = filament::backend::TargetBufferFlags::NONE; + out.params.viewport.left += out.params.viewport.width; + render(out, pipeline, driver); + }); + + return ppQuadBlit->output; +} + FrameGraphId PostProcessManager::debugDisplayShadowTexture( FrameGraph& fg, FrameGraphId input, diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index badf5b9a8c..432a9e3fff 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -288,6 +288,15 @@ public: FrameGraphId shadowmap, float scale, uint8_t layer, uint8_t level, uint8_t channel, float power) noexcept; + // Combine an array texture pointed to by `input` into a single image, then return it. + // This is only useful to check the multiview rendered scene as a debugging purpose, thus this + // is not expected to be used in normal cases. + FrameGraphId debugCombineArrayTexture(FrameGraph& fg, bool translucent, + FrameGraphId input, + filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc, + backend::SamplerMagFilter filterMag, + backend::SamplerMinFilter filterMin) noexcept; + backend::Handle getOneTexture() const; backend::Handle getZeroTexture() const; backend::Handle getOneTextureArray() const; diff --git a/filament/src/materials/blitArray.mat b/filament/src/materials/blitArray.mat new file mode 100644 index 0000000000..2d7cfc4da3 --- /dev/null +++ b/filament/src/materials/blitArray.mat @@ -0,0 +1,38 @@ +material { + name : blitArray, + parameters : [ + { + type : sampler2dArray, + name : color, + precision: medium + }, + { + type : int, + name : layerIndex + }, + { + type : float4, + name : viewport, + precision: high + } + ], + variables : [ + vertex + ], + depthWrite : false, + depthCulling : false, + domain: postprocess +} + +vertex { + void postProcessVertex(inout PostProcessVertexInputs postProcess) { + postProcess.vertex.xy = materialParams.viewport.xy + postProcess.normalizedUV * materialParams.viewport.zw; + postProcess.vertex.xy = uvToRenderTargetUV(postProcess.vertex.xy); + } +} + +fragment { + void postProcess(inout PostProcessInputs postProcess) { + postProcess.color = textureLod(materialParams_color, vec3(variable_vertex.xy, materialParams.layerIndex), 0.0); + } +}