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.
This commit is contained in:
Sungun Park
2024-02-26 13:02:58 -08:00
committed by Sungun Park
parent 4836f94635
commit ef488fdf57
4 changed files with 127 additions and 0 deletions

View File

@@ -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

View File

@@ -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<FrameGraphTexture> PostProcessManager::debugShadowCascades(FrameGra
return debugShadowCascadePass->output;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(FrameGraph& fg,
bool translucent, FrameGraphId<FrameGraphTexture> 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<FrameGraphTexture> input;
FrameGraphId<FrameGraphTexture> output;
};
auto& ppQuadBlit = fg.addPass<QuadBlitData>("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<FrameGraphTexture> PostProcessManager::debugDisplayShadowTexture(
FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,

View File

@@ -288,6 +288,15 @@ public:
FrameGraphId<FrameGraphTexture> 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<FrameGraphTexture> debugCombineArrayTexture(FrameGraph& fg, bool translucent,
FrameGraphId<FrameGraphTexture> input,
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
backend::SamplerMagFilter filterMag,
backend::SamplerMinFilter filterMin) noexcept;
backend::Handle<backend::HwTexture> getOneTexture() const;
backend::Handle<backend::HwTexture> getZeroTexture() const;
backend::Handle<backend::HwTexture> getOneTextureArray() const;

View File

@@ -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);
}
}