Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tonemapping to use new post-process material domain #1428

Merged
merged 3 commits into from
Sep 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions filament/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ set(MATERIAL_SRCS
src/materials/skybox.mat
src/materials/sao.mat
src/materials/ssao.mat
src/materials/tonemapping.mat
)

# Embed the binary resource blob for materials.
Expand Down
40 changes: 22 additions & 18 deletions filament/src/PostProcessManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ PostProcessManager::PostProcessMaterial::PostProcessMaterial(FEngine& engine,
uint8_t const* data, size_t size) noexcept {
mMaterial = upcast(Material::Builder().package(data, size).build(engine));
mMaterialInstance = mMaterial->getDefaultInstance();
// TODO: After all materials using this class have been converted to the post-process material
// domain, load both OPAQUE and TRANSPARENt variants here.
mProgram = mMaterial->getProgram(0);
}

Expand Down Expand Up @@ -89,6 +91,7 @@ void PostProcessManager::init() noexcept {
mSSAO = PostProcessMaterial(mEngine, MATERIALS_SAO_DATA, MATERIALS_SAO_SIZE);
mMipmapDepth = PostProcessMaterial(mEngine, MATERIALS_MIPMAPDEPTH_DATA, MATERIALS_MIPMAPDEPTH_SIZE);
mBlur = PostProcessMaterial(mEngine, MATERIALS_BLUR_DATA, MATERIALS_BLUR_SIZE);
mTonemapping = PostProcessMaterial(mEngine, MATERIALS_TONEMAPPING_DATA, MATERIALS_TONEMAPPING_SIZE);

// create sampler for post-process FBO
DriverApi& driver = mEngine.getDriverApi();
Expand Down Expand Up @@ -158,9 +161,6 @@ FrameGraphResource PostProcessManager::toneMapping(FrameGraph& fg, FrameGraphRes
FrameGraphResource input;
FrameGraphResource output;
};
backend::Handle<backend::HwProgram> toneMappingProgram = engine.getPostProcessProgram(
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
: PostProcessStage::TONE_MAPPING_OPAQUE);

auto& ppToneMapping = fg.addPass<PostProcessToneMapping>("tonemapping",
[&](FrameGraph::Builder& builder, PostProcessToneMapping& data) {
Expand All @@ -175,24 +175,28 @@ FrameGraphResource PostProcessManager::toneMapping(FrameGraph& fg, FrameGraphRes
data.output = builder.createTexture("tonemapping output", outputDesc);
builder.createRenderTarget(data.output);
},
[=](FrameGraphPassResources const& resources,
[=, engine = &engine](FrameGraphPassResources const& resources,
PostProcessToneMapping const& data, DriverApi& driver) {
PipelineState pipeline;
pipeline.rasterState.culling = RasterState::CullingMode::NONE;
pipeline.rasterState.colorWrite = true;
pipeline.rasterState.depthFunc = RasterState::DepthFunc::A;
pipeline.program = toneMappingProgram;

auto const& textureDesc = resources.getDescriptor(data.input);
auto const& color = resources.getTexture(data.input);
// TODO: the first parameters below are the *actual viewport* size
// (as opposed to the size of the source texture). Currently we don't allow
// the texture to be resized, so they match. We'll need something more
// sophisticated in the future.

mPostProcessUb.setUniform(offsetof(PostProcessingUib, dithering), dithering);
setSource(textureDesc.width, textureDesc.height,
color, {}, textureDesc.width, textureDesc.height);
FMaterialInstance* pInstance = mTonemapping.getMaterialInstance();
pInstance->setParameter("dithering", dithering);
SamplerParams params;
pInstance->setParameter("colorBuffer", color, params);

auto duration = engine->getEngineTime();
float fraction = (duration.count() % 1000000000) / 1000000000.0f;
mPostProcessUb.setUniform(offsetof(PostProcessingUib, time), fraction);

pInstance->commit(driver);
pInstance->use(driver);

PipelineState pipeline;
pipeline.rasterState = mTonemapping.getMaterial()->getRasterState();
const uint8_t variant = static_cast<uint8_t> (
translucent ?
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE );
pipeline.program = mTonemapping.getMaterial()->getProgram(variant);

auto const& target = resources.getRenderTarget(data.output);
driver.beginRenderPass(target.target, target.params);
Expand Down
1 change: 1 addition & 0 deletions filament/src/PostProcessManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class PostProcessManager {
PostProcessMaterial mSSAO;
PostProcessMaterial mMipmapDepth;
PostProcessMaterial mBlur;
PostProcessMaterial mTonemapping;

backend::Handle<backend::HwTexture> mNoSSAOTexture;
};
Expand Down
57 changes: 57 additions & 0 deletions filament/src/materials/tonemapping.mat
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
material {
name : tonemap,
parameters : [
{
type : sampler2d,
name : colorBuffer,
precision: high
},
{
type : int,
name : dithering
}
],
depthWrite : false,
depthCulling : false,
culling: none,
domain: postprocess
}

fragment {

#include "../../../shaders/src/tone_mapping.fs"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ideally these can be moved out of the shaders library and live next to this tonemapping.mat file, since they don't provide any user API functions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep all the shaders in the same spot. shaders/ contains more than just public APIs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, makes sense. After deprecating "old" post-process materials they can at least be removed from libshaders

#include "../../../shaders/src/conversion_functions.fs"
#include "../../../shaders/src/dithering.fs"

vec3 resolveFragment(const ivec2 uv) {
return texelFetch(materialParams_colorBuffer, uv, 0).rgb;
}

vec4 resolveAlphaFragment(const ivec2 uv) {
return texelFetch(materialParams_colorBuffer, uv, 0);
}

vec4 resolve() {
#if POST_PROCESS_OPAQUE
vec4 color = vec4(resolveFragment(ivec2(getUV())), 1.0);
color.rgb = tonemap(color.rgb);
color.rgb = OECF(color.rgb);
color.a = luminance(color.rgb);
#else
vec4 color = resolveAlphaFragment(ivec2(getUV()));
color.rgb /= color.a + FLT_EPS;
color.rgb = tonemap(color.rgb);
color.rgb = OECF(color.rgb);
color.rgb *= color.a + FLT_EPS;
#endif
return color;
}

void postProcess(inout PostProcessInputs postProcess) {
postProcess.color = resolve();
if (materialParams.dithering > 0) {
postProcess.color = dither(postProcess.color);
}
}
bejado marked this conversation as resolved.
Show resolved Hide resolved

}