compute projection inverse in double precision
also concatenate transforms used for rendering using double precision intermediates.
This commit is contained in:
committed by
Mathias Agopian
parent
53d4fa3095
commit
3671469046
@@ -213,7 +213,7 @@ mat4 FCamera::getModelMatrix() const noexcept {
|
||||
}
|
||||
|
||||
mat4 UTILS_NOINLINE FCamera::getViewMatrix() const noexcept {
|
||||
return FCamera::getViewMatrix(getModelMatrix());
|
||||
return inverse(getModelMatrix());
|
||||
}
|
||||
|
||||
Frustum FCamera::getFrustum() const noexcept {
|
||||
@@ -281,13 +281,6 @@ math::details::TMat44<T> inverseProjection(const math::details::TMat44<T>& p) no
|
||||
return r;
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
mat4 FCamera::getViewMatrix(mat4 const& model) noexcept {
|
||||
// We can't use rigidTransformInverse here. The camera's model matrix might have scaling, which
|
||||
// would make it non-rigid.
|
||||
return inverse(model);
|
||||
}
|
||||
|
||||
Frustum FCamera::getFrustum(mat4 const& projection, mat4 const& viewMatrix) noexcept {
|
||||
return Frustum(mat4f{ projection * viewMatrix });
|
||||
}
|
||||
@@ -298,7 +291,7 @@ CameraInfo::CameraInfo(FCamera const& camera) noexcept {
|
||||
projection = mat4f{ camera.getProjectionMatrix() };
|
||||
cullingProjection = mat4f{ camera.getCullingProjectionMatrix() };
|
||||
model = mat4f{ camera.getModelMatrix() };
|
||||
view = mat4f{camera.getViewMatrix() };
|
||||
view = mat4f{ camera.getViewMatrix() };
|
||||
zn = camera.getNear();
|
||||
zf = camera.getCullingFar();
|
||||
ev100 = Exposure::ev100(camera);
|
||||
@@ -312,7 +305,7 @@ CameraInfo::CameraInfo(FCamera const& camera, const math::mat4& worldOriginCamer
|
||||
projection = mat4f{ camera.getProjectionMatrix() };
|
||||
cullingProjection = mat4f{ camera.getCullingProjectionMatrix() };
|
||||
model = mat4f{ modelMatrix };
|
||||
view = mat4f{ FCamera::getViewMatrix(modelMatrix) };
|
||||
view = mat4f{ inverse(modelMatrix) };
|
||||
zn = camera.getNear();
|
||||
zf = camera.getCullingFar();
|
||||
ev100 = Exposure::ev100(camera);
|
||||
|
||||
@@ -423,7 +423,7 @@ void FView::prepare(FEngine& engine, backend::DriverApi& driver, ArenaScope& are
|
||||
|
||||
mCullingFrustum = FCamera::getFrustum(
|
||||
mCullingCamera->getCullingProjectionMatrix(),
|
||||
FCamera::getViewMatrix(worldOriginScene * mCullingCamera->getModelMatrix()));
|
||||
inverse(worldOriginScene * mCullingCamera->getModelMatrix()));
|
||||
|
||||
/*
|
||||
* Gather all information needed to render this scene. Apply the world origin to all
|
||||
@@ -639,23 +639,22 @@ UTILS_NOINLINE
|
||||
void FView::prepareCamera(const CameraInfo& camera) const noexcept {
|
||||
SYSTRACE_CALL();
|
||||
|
||||
const mat4f viewFromWorld(camera.view);
|
||||
const mat4f worldFromView(camera.model);
|
||||
const mat4f projectionMatrix(camera.projection);
|
||||
mat4f const& viewFromWorld = camera.view;
|
||||
mat4f const& worldFromView = camera.model;
|
||||
mat4f const& clipFromView = camera.projection;
|
||||
|
||||
const mat4f clipFromView(projectionMatrix);
|
||||
const mat4f viewFromClip(inverse(clipFromView));
|
||||
const mat4f clipFromWorld(clipFromView * viewFromWorld);
|
||||
const mat4f worldFromClip(worldFromView * viewFromClip);
|
||||
const mat4f viewFromClip{ inverse((mat4)camera.projection) };
|
||||
const mat4f clipFromWorld{ highPrecisionMultiply(clipFromView, viewFromWorld) };
|
||||
const mat4f worldFromClip{ highPrecisionMultiply(worldFromView, viewFromClip) };
|
||||
|
||||
auto& s = mPerViewUb.edit();
|
||||
s.viewFromWorldMatrix = viewFromWorld; // view
|
||||
s.worldFromViewMatrix = worldFromView; // model
|
||||
s.clipFromViewMatrix = clipFromView; // projection
|
||||
s.viewFromClipMatrix = viewFromClip; // 1/projection
|
||||
s.clipFromViewMatrix = clipFromView; // projection
|
||||
s.viewFromClipMatrix = viewFromClip; // 1/projection
|
||||
s.clipFromWorldMatrix = clipFromWorld; // projection * view
|
||||
s.worldFromClipMatrix = worldFromClip; // 1/(projection * view)
|
||||
s.cameraPosition = float3{camera.getPosition()};
|
||||
s.cameraPosition = float3{ camera.getPosition() };
|
||||
s.worldOffset = camera.worldOffset;
|
||||
s.cameraFar = camera.zf;
|
||||
s.clipControl = mClipControl;
|
||||
|
||||
@@ -183,7 +183,6 @@ public:
|
||||
return mEntity;
|
||||
}
|
||||
|
||||
static math::mat4 getViewMatrix(math::mat4 const& model) noexcept;
|
||||
static Frustum getFrustum(math::mat4 const& projection, math::mat4 const& viewMatrix) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
@@ -557,6 +557,26 @@ constexpr typename TMat44<T>::col_type MATH_PURE operator*(const TMat44<T>& lhs,
|
||||
typedef details::TMat44<double> mat4;
|
||||
typedef details::TMat44<float> mat4f;
|
||||
|
||||
// mat4 * float4, with double precision intermediates
|
||||
constexpr float4 highPrecisionMultiply(mat4f const& lhs, float4 const& rhs) noexcept {
|
||||
double4 result{};
|
||||
result += lhs[0] * rhs[0];
|
||||
result += lhs[1] * rhs[1];
|
||||
result += lhs[2] * rhs[2];
|
||||
result += lhs[3] * rhs[3];
|
||||
return float4{ result };
|
||||
}
|
||||
|
||||
// mat4 * mat4, with double precision intermediates
|
||||
constexpr mat4f highPrecisionMultiply(mat4f const& lhs, mat4f const& rhs) noexcept {
|
||||
return {
|
||||
highPrecisionMultiply(lhs, rhs[0]),
|
||||
highPrecisionMultiply(lhs, rhs[1]),
|
||||
highPrecisionMultiply(lhs, rhs[2]),
|
||||
highPrecisionMultiply(lhs, rhs[3])
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
} // namespace math
|
||||
} // namespace filament
|
||||
|
||||
Reference in New Issue
Block a user