[vulkan] Switch to reversed depth, infinite far plane

Based on the article
(https://developer.nvidia.com/content/depth-precision-visualized), this
should give nice precision behavior, and removes the need to worry about
large maps getting clipped. If I'm doing my math correctly, despite
being reversed, near precision is still crazy high. And (thanks to the
reversed depth) about a quarter of a unit (for near clip of 4) out at 1M
unit distance.
This commit is contained in:
Bill Currie 2023-07-21 11:36:10 +09:00
parent 9f8a6f5d62
commit 72f7fcea47
3 changed files with 9 additions and 10 deletions

View file

@ -68,15 +68,14 @@ QFV_Orthographic (mat4f_t proj, float xmin, float xmax, float ymin, float ymax,
void void
QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y) QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y)
{ {
float neard, fard; float neard;
neard = r_nearclip; neard = r_nearclip;
fard = r_farclip;
proj[0] = (vec4f_t) { 1 / fov_x, 0, 0, 0 }; proj[0] = (vec4f_t) { 1 / fov_x, 0, 0, 0 };
proj[1] = (vec4f_t) { 0, 1 / fov_y, 0, 0 }; proj[1] = (vec4f_t) { 0, 1 / fov_y, 0, 0 };
proj[2] = (vec4f_t) { 0, 0, fard / (fard - neard), 1 }; proj[2] = (vec4f_t) { 0, 0, 0, 1 };
proj[3] = (vec4f_t) { 0, 0, (neard * fard) / (neard - fard), 0 }; proj[3] = (vec4f_t) { 0, 0, neard, 0 };
} }
void void

View file

@ -130,14 +130,14 @@ properties = {
depth_test_and_write = { depth_test_and_write = {
depthTestEnable = true; depthTestEnable = true;
depthWriteEnable = true; depthWriteEnable = true;
depthCompareOp = less_or_equal; depthCompareOp = greater_or_equal;
depthBoundsTestEnable = false; depthBoundsTestEnable = false;
stencilTestEnable = false; stencilTestEnable = false;
}; };
depth_test_only = { depth_test_only = {
depthTestEnable = true; depthTestEnable = true;
depthWriteEnable = false; depthWriteEnable = false;
depthCompareOp = less_or_equal; depthCompareOp = greater_or_equal;
depthBoundsTestEnable = false; depthBoundsTestEnable = false;
stencilTestEnable = false; stencilTestEnable = false;
}; };
@ -151,7 +151,7 @@ properties = {
depth_disable = { depth_disable = {
depthTestEnable = false; depthTestEnable = false;
depthWriteEnable = false; depthWriteEnable = false;
depthCompareOp = less_or_equal; depthCompareOp = greater_or_equal;
depthBoundsTestEnable = false; depthBoundsTestEnable = false;
stencilTestEnable = false; stencilTestEnable = false;
}; };
@ -1124,7 +1124,7 @@ renderpasses = {
format = $images.depth.format; format = $images.depth.format;
loadOp = clear; loadOp = clear;
finalLayout = depth_stencil_attachment_optimal; finalLayout = depth_stencil_attachment_optimal;
clearValue = { depthStencil = { depth = 1; stencil = 0; }; }; clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
view = depth; view = depth;
}; };
color = { color = {
@ -1586,7 +1586,7 @@ renderpasses = {
format = $images.cube_depth.format; format = $images.cube_depth.format;
loadOp = clear; loadOp = clear;
finalLayout = depth_stencil_attachment_optimal; finalLayout = depth_stencil_attachment_optimal;
clearValue = { depthStencil = { depth = 1; stencil = 0; }; }; clearValue = { depthStencil = { depth = 0; stencil = 0; }; };
view = cube_depth; view = cube_depth;
}; };
color = { color = {

View file

@ -215,7 +215,7 @@ alias_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
// FIXME hack the depth range to prevent view model // FIXME hack the depth range to prevent view model
// from poking into walls // from poking into walls
if (vmod && ent.id == vr_data.view_model.id) { if (vmod && ent.id == vr_data.view_model.id) {
alias_depth_range (taskctx, 0, 0.3); alias_depth_range (taskctx, 0.7, 1);
} }
alias_draw_ent (taskctx, ent, pass); alias_draw_ent (taskctx, ent, pass);
// unhack in case the view_model is not the last // unhack in case the view_model is not the last