mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-16 17:01:53 +00:00
[vulkan] Make near and far clip explicit parameters
This improves the projection API in that near clip is a parameter rather than being taken directly from the cvar, and a far clip (ie, finite far plane) version is available (necessary for cascaded shadow maps as it's rather hard to fit a box to an infinite frustum). Also, the orthographic projection matrix is now reversed as per the perspective matrix (and the code tidied up a little), and a version that takes min and max vectors is available.
This commit is contained in:
parent
2b879af3e1
commit
558e11e9b7
5 changed files with 87 additions and 42 deletions
|
@ -5,9 +5,17 @@
|
|||
|
||||
void QFV_Orthographic (mat4f_t proj, float xmin, float xmax,
|
||||
float ymin, float ymax, float znear, float zfar);
|
||||
void QFV_OrthographicV (mat4f_t proj, vec4f_t mins, vec4f_t maxs);
|
||||
// fov_x and fov_y are tan(fov/2) for x and y respectively
|
||||
void QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y);
|
||||
void QFV_PerspectiveCos (mat4f_t proj, float fov);
|
||||
void QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip);
|
||||
void QFV_InversePerspectiveTan (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip);
|
||||
void QFV_PerspectiveTanFar (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip, float farclip);
|
||||
void QFV_InversePerspectiveTanFar (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip, float farclip);
|
||||
void QFV_PerspectiveCos (mat4f_t proj, float fov, float nearclip);
|
||||
|
||||
extern const mat4f_t qfv_z_up;
|
||||
extern const mat4f_t qfv_box_rotations[6];
|
||||
|
|
|
@ -359,7 +359,7 @@ vulkan_set_fov (float x, float y)
|
|||
__auto_type mctx = vulkan_ctx->matrix_context;
|
||||
__auto_type mat = &mctx->matrices;
|
||||
|
||||
QFV_PerspectiveTan (mat->Projection3d, x, y);
|
||||
QFV_PerspectiveTan (mat->Projection3d, x, y, r_nearclip);
|
||||
|
||||
mctx->dirty = mctx->frames.size;
|
||||
}
|
||||
|
|
|
@ -89,50 +89,86 @@ void
|
|||
QFV_Orthographic (mat4f_t proj, float xmin, float xmax, float ymin, float ymax,
|
||||
float znear, float zfar)
|
||||
{
|
||||
proj[0] = (vec4f_t) {
|
||||
2 / (xmax - xmin),
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
proj[1] = (vec4f_t) {
|
||||
0,
|
||||
2 / (ymax - ymin),
|
||||
0,
|
||||
0
|
||||
};
|
||||
proj[2] = (vec4f_t) {
|
||||
0,
|
||||
0,
|
||||
1 / (znear - zfar),
|
||||
0
|
||||
};
|
||||
proj[3] = (vec4f_t) {
|
||||
-(xmax + xmin) / (xmax - xmin),
|
||||
-(ymax + ymin) / (ymax - ymin),
|
||||
znear / (znear - zfar),
|
||||
1,
|
||||
};
|
||||
float d = zfar - znear;
|
||||
float w = xmax - xmin;
|
||||
float h = ymax - ymin;
|
||||
float m = xmax + xmin;
|
||||
float c = ymax + ymin;
|
||||
float f = zfar;
|
||||
|
||||
proj[0] = (vec4f_t) { 2/w, 0, 0, 0 };
|
||||
proj[1] = (vec4f_t) { 0, 2/h, 0, 0 };
|
||||
proj[2] = (vec4f_t) { 0, 0, -1/d, 0 };
|
||||
proj[3] = (vec4f_t) { -m/w, -c/h, f/d, 1 };
|
||||
}
|
||||
|
||||
void
|
||||
QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y)
|
||||
QFV_OrthographicV (mat4f_t proj, vec4f_t mins, vec4f_t maxs)
|
||||
{
|
||||
float neard;
|
||||
|
||||
neard = r_nearclip;
|
||||
|
||||
proj[0] = (vec4f_t) { 1 / fov_x, 0, 0, 0 };
|
||||
proj[1] = (vec4f_t) { 0, 1 / fov_y, 0, 0 };
|
||||
proj[2] = (vec4f_t) { 0, 0, 0, 1 };
|
||||
proj[3] = (vec4f_t) { 0, 0, neard, 0 };
|
||||
QFV_Orthographic (proj, mins[0], maxs[0], mins[1], maxs[1],
|
||||
mins[2], maxs[2]);
|
||||
}
|
||||
|
||||
void
|
||||
QFV_PerspectiveCos (mat4f_t proj, float fov)
|
||||
QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y, float nearclip)
|
||||
{
|
||||
float n = nearclip;
|
||||
float fx = fov_x;
|
||||
float fy = fov_y;
|
||||
|
||||
proj[0] = (vec4f_t) { 1/fx, 0, 0, 0 };
|
||||
proj[1] = (vec4f_t) { 0, 1/fy, 0, 0 };
|
||||
proj[2] = (vec4f_t) { 0, 0, 0, 1 };
|
||||
proj[3] = (vec4f_t) { 0, 0, n, 0 };
|
||||
}
|
||||
|
||||
void
|
||||
QFV_InversePerspectiveTan (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip)
|
||||
{
|
||||
float n = r_nearclip;
|
||||
float fx = fov_x;
|
||||
float fy = fov_y;
|
||||
proj[0] = (vec4f_t) { fx, 0, 0, 0 };
|
||||
proj[1] = (vec4f_t) { 0, fy, 0, 0 };
|
||||
proj[2] = (vec4f_t) { 0, 0, 0, 1/n };
|
||||
proj[3] = (vec4f_t) { 0, 0, 1, 0 };
|
||||
}
|
||||
|
||||
void
|
||||
QFV_PerspectiveTanFar (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip, float farclip)
|
||||
{
|
||||
float n = nearclip;
|
||||
float f = farclip;
|
||||
float fx = fov_x;
|
||||
float fy = fov_y;
|
||||
|
||||
proj[0] = (vec4f_t) { 1/fx, 0, 0, 0 };
|
||||
proj[1] = (vec4f_t) { 0, 1/fy, 0, 0 };
|
||||
proj[2] = (vec4f_t) { 0, 0, n/(n-f), 1 };
|
||||
proj[3] = (vec4f_t) { 0, 0, n*f/(n-f), 0 };
|
||||
}
|
||||
|
||||
void
|
||||
QFV_InversePerspectiveTanFar (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip, float farclip)
|
||||
{
|
||||
float n = r_nearclip;
|
||||
float f = farclip;
|
||||
float fx = fov_x;
|
||||
float fy = fov_y;
|
||||
proj[0] = (vec4f_t) { fx, 0, 0, 0 };
|
||||
proj[1] = (vec4f_t) { 0, fy, 0, 0 };
|
||||
proj[2] = (vec4f_t) { 0, 0, 0, (f-n)/(n*f) };
|
||||
proj[3] = (vec4f_t) { 0, 0, 1, 1/f };
|
||||
}
|
||||
|
||||
void
|
||||
QFV_PerspectiveCos (mat4f_t proj, float fov, float nearclip)
|
||||
{
|
||||
// square first for auto-abs (no support for > 180 degree fov)
|
||||
fov = fov * fov;
|
||||
float t = sqrt ((1 - fov) / fov);
|
||||
QFV_PerspectiveTan (proj, t, t);
|
||||
QFV_PerspectiveTan (proj, t, t, nearclip);
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "vid_vulkan.h"
|
||||
#include "vkparse.h"
|
||||
|
||||
#define lnearclip 4
|
||||
#define ico_verts 12
|
||||
#define cone_verts 7
|
||||
static int ico_inds[] = {
|
||||
|
@ -336,7 +337,7 @@ cube_mat (mat4f_t *mat, vec4f_t position)
|
|||
view[3][3] = 1;
|
||||
|
||||
mat4f_t proj;
|
||||
QFV_PerspectiveTan (proj, 1, 1);
|
||||
QFV_PerspectiveTan (proj, 1, 1, lnearclip);
|
||||
for (int j = 0; j < 6; j++) {
|
||||
mat4f_t side_view;
|
||||
mat4f_t rotinv;
|
||||
|
@ -1275,7 +1276,7 @@ create_light_matrices (lightingctx_t *lctx)
|
|||
case ST_NONE:
|
||||
continue;
|
||||
case ST_CUBE:
|
||||
QFV_PerspectiveTan (proj, 1, 1);
|
||||
QFV_PerspectiveTan (proj, 1, 1, lnearclip);
|
||||
for (int j = 0; j < 6; j++) {
|
||||
mat4f_t side_view;
|
||||
mat4f_t rotinv;
|
||||
|
@ -1294,7 +1295,7 @@ create_light_matrices (lightingctx_t *lctx)
|
|||
}
|
||||
break;
|
||||
case ST_PLANE:
|
||||
QFV_PerspectiveCos (proj, -light->direction[3]);
|
||||
QFV_PerspectiveCos (proj, -light->direction[3], lnearclip);
|
||||
mmulf (view, qfv_z_up, view);
|
||||
mmulf (lm[0], proj, view);
|
||||
break;
|
||||
|
|
|
@ -64,7 +64,7 @@ setup_view (vulkan_ctx_t *ctx)
|
|||
//FIXME this should check for cube map rather than fisheye
|
||||
if (scr_fisheye) {
|
||||
__auto_type mctx = ctx->matrix_context;
|
||||
QFV_PerspectiveTan (mctx->matrices.Projection3d, 1, 1);
|
||||
QFV_PerspectiveTan (mctx->matrices.Projection3d, 1, 1, r_nearclip);
|
||||
mat4f_t views[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
mat4f_t rotinv;
|
||||
|
|
Loading…
Reference in a new issue