Skip to content

Commit

Permalink
fix TAA when camera is far from the origin
Browse files Browse the repository at this point in the history
The intermediate transforms needed to be kept in double precision.
  • Loading branch information
pixelflinger committed Sep 21, 2023
1 parent 5d30435 commit d68fcf5
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 30 deletions.
4 changes: 2 additions & 2 deletions filament/src/FrameHistory.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ struct FrameHistoryEntry {
struct TemporalAA{
FrameGraphTexture color;
FrameGraphTexture::Descriptor desc;
math::mat4f projection; // world space to clip space
math::mat4 projection; // world space to clip space
math::float2 jitter{};
uint32_t frameId = 0; // used for halton sequence
} taa;
struct {
FrameGraphTexture color;
FrameGraphTexture::Descriptor desc;
math::mat4f projection;
math::mat4 projection;
} ssr;
};

Expand Down
40 changes: 17 additions & 23 deletions filament/src/PostProcessManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,23 +482,20 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> history;
};

mat4f historyProjection;
FrameGraphId<FrameGraphTexture> history;

FrameHistoryEntry const& entry = frameHistory[0];
if (entry.ssr.color.handle) {
// the first time around we may not have a history buffer
history = fg.import("SSR history", entry.ssr.desc,
FrameGraphTexture::Usage::SAMPLEABLE, entry.ssr.color);
historyProjection = entry.ssr.projection;
auto const& previous = frameHistory.getPrevious().ssr;
if (!previous.color.handle) {
return {};
}

FrameGraphId<FrameGraphTexture> history = fg.import("SSR history", previous.desc,
FrameGraphTexture::Usage::SAMPLEABLE, previous.color);
mat4 const& historyProjection = previous.projection;
auto const& uvFromClipMatrix = mEngine.getUvFromClipMatrix();

auto& ssrPass = fg.addPass<SSRPassData>("SSR Pass",
[&](FrameGraph::Builder& builder, auto& data) {

// create our reflection buffer. We need an alpha channel, so we have to use RGBA16F
// Create our reflection buffer. We need an alpha channel, so we have to use RGBA16F
data.reflections = builder.createTexture("Reflections Texture", {
.width = desc.width, .height = desc.height,
.format = TextureFormat::RGBA16F });
Expand Down Expand Up @@ -537,8 +534,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,

// set screen-space reflections and screen-space refractions
mat4f const uvFromViewMatrix = uvFromClipMatrix * projection;
mat4f const reprojection = mat4f{ uvFromClipMatrix * historyProjection
* inverse(userViewMatrix) };
mat4f const reprojection = uvFromClipMatrix *
mat4f{ historyProjection * inverse(userViewMatrix) };

// the history sampler is a regular texture2D
TextureHandle const history = data.history ?
Expand Down Expand Up @@ -2493,7 +2490,7 @@ void PostProcessManager::prepareTaa(FrameGraph& fg, filament::Viewport const& sv
auto& current = frameHistory.getCurrent().*pTaa;

// compute projection
current.projection = mat4f{ inoutCameraInfo->projection * inoutCameraInfo->getUserViewMatrix() };
current.projection = inoutCameraInfo->projection * inoutCameraInfo->getUserViewMatrix();
current.frameId = previous.frameId + 1;

// sample position within a pixel [-0.5, 0.5]
Expand Down Expand Up @@ -2527,18 +2524,16 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
auto const& previous = frameHistory.getPrevious().*pTaa;
auto& current = frameHistory.getCurrent().*pTaa;

FrameGraphId<FrameGraphTexture> colorHistory;
mat4f historyProjection;
if (UTILS_UNLIKELY(!previous.color.handle)) {
// if we don't have a history yet, just use the current color buffer as history
colorHistory = input;
historyProjection = current.projection;
} else {
// if we don't have a history yet, just use the current color buffer as history
FrameGraphId<FrameGraphTexture> colorHistory = input;
if (UTILS_LIKELY(previous.color.handle)) {
colorHistory = fg.import("TAA history", previous.desc,
FrameGraphTexture::Usage::SAMPLEABLE, previous.color);
historyProjection = previous.projection;
}

mat4 const& historyProjection = previous.color.handle ?
previous.projection : current.projection;

struct TAAData {
FrameGraphId<FrameGraphTexture> color;
FrameGraphId<FrameGraphTexture> depth;
Expand Down Expand Up @@ -2617,8 +2612,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
});
mi->setParameter("filterWeights", weights, 9);
mi->setParameter("reprojection",
historyProjection *
inverse(current.projection) *
mat4f{ historyProjection * inverse(current.projection) } *
normalizedToClip);

mi->commit(driver);
Expand Down
10 changes: 6 additions & 4 deletions filament/src/details/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,9 +854,11 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
ssReflectionsOptions,
{ .width = svp.width, .height = svp.height });

// generate the mipchain
PostProcessManager::generateMipmapSSR(ppm, fg,
reflections, ssrConfig.reflection, false, ssrConfig);
if (UTILS_LIKELY(reflections)) {
// generate the mipchain
PostProcessManager::generateMipmapSSR(ppm, fg,
reflections, ssrConfig.reflection, false, ssrConfig);
}
}

// --------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -956,7 +958,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
FrameGraphId<FrameGraphTexture> history;
};
// FIXME: should we use the TAA-modified cameraInfo here or not? (we are).
auto projection = mat4f{ cameraInfo.projection * cameraInfo.getUserViewMatrix() };
mat4 const projection = cameraInfo.projection * cameraInfo.getUserViewMatrix();
fg.addPass<ExportSSRHistoryData>("Export SSR history",
[&](FrameGraph::Builder& builder, auto& data) {
// We need to use sideEffect here to ensure this pass won't be culled.
Expand Down
2 changes: 1 addition & 1 deletion filament/src/details/View.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ CameraInfo FView::computeCameraInfo(FEngine& engine) const noexcept {

/*
* We apply a "world origin" to "everything" in order to implement the IBL rotation.
* The "world origin" is also be used to kee the origin close to the camera position to
* The "world origin" is also used to keep the origin close to the camera position to
* improve fp precision in the shader for large scenes.
*/
mat4 translation;
Expand Down

0 comments on commit d68fcf5

Please sign in to comment.