summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/storage_rd
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2022-09-20 14:21:31 -0700
committerclayjohn <claynjohn@gmail.com>2022-09-20 23:40:01 -0700
commit27a3014f5052ae40f89684a5559c17fbebe7aa8d (patch)
tree7bf20c7a8150f15e1732c020d05ba0654d3402fd /servers/rendering/renderer_rd/storage_rd
parent6f5704d86f95171ba8b6b2ac9f56e284c4d35d7a (diff)
Emulate double precision for regular rendering operation.
We calculate the lost precision on the CPU and pass it into the GPU so that it can calculate an error-corrected version of the vertex position
Diffstat (limited to 'servers/rendering/renderer_rd/storage_rd')
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.h12
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp6
2 files changed, 18 insertions, 0 deletions
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index db2e4cfa2a..2ce6550cc1 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -311,6 +311,18 @@ public:
}
}
+ // http://andrewthall.org/papers/df64_qf128.pdf
+#ifdef REAL_T_IS_DOUBLE
+ static _FORCE_INLINE_ void split_double(double a, float *ahi, float *alo) {
+ const double SPLITTER = (1 << 29) + 1;
+ double t = a * SPLITTER;
+ double thi = t - (t - a);
+ double tlo = a - thi;
+ *ahi = (float)thi;
+ *alo = (float)tlo;
+ }
+#endif
+
/* Samplers */
_FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) {
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
index f925f87cbe..7dd790d1da 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
@@ -59,6 +59,12 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
RendererRD::MaterialStorage::store_transform(cam_transform, ubo.inv_view_matrix);
RendererRD::MaterialStorage::store_transform(cam_transform.affine_inverse(), ubo.view_matrix);
+#ifdef REAL_T_IS_DOUBLE
+ RendererRD::MaterialStorage::split_double(-cam_transform.origin.x, &ubo.inv_view_matrix[12], &ubo.inv_view_matrix[3]);
+ RendererRD::MaterialStorage::split_double(-cam_transform.origin.y, &ubo.inv_view_matrix[13], &ubo.inv_view_matrix[7]);
+ RendererRD::MaterialStorage::split_double(-cam_transform.origin.z, &ubo.inv_view_matrix[14], &ubo.inv_view_matrix[11]);
+#endif
+
for (uint32_t v = 0; v < view_count; v++) {
projection = correction * view_projection[v];
RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix_view[v]);