glm::透视解释

发布于 2024-12-15 10:35:25 字数 668 浏览 0 评论 0原文

我试图了解以下代码的作用:

glm::mat4 Projection = glm::perspective(35.0f, 1.0f, 0.1f, 100.0f);

它是否创建 投影矩阵 ?剪掉用户视野之外的任何内容? 我在 API 页面 上找不到任何内容,我在他们网站上的 pdf 中找到的唯一内容是:

gluPerspective:

glm::mat4 perspective(float fovy, float aspect, float zNear,
float zFar);
glm::dmat4 perspective(
double fovy, double aspect, double zNear,
double zFar);
From GLM_GTC_matrix_transform extension: <glm/gtc/matrix_transform.hpp>

但它没有解释参数。也许我错过了什么。

I am trying to understand what the following code does:

glm::mat4 Projection = glm::perspective(35.0f, 1.0f, 0.1f, 100.0f);

Does it create a projection matrix? Clips off anything that is not in the user's view?
I wasn't able to find anything on the API page, and the only thing I could find in the pdf on their website was this:

gluPerspective:

glm::mat4 perspective(float fovy, float aspect, float zNear,
float zFar);
glm::dmat4 perspective(
double fovy, double aspect, double zNear,
double zFar);
From GLM_GTC_matrix_transform extension: <glm/gtc/matrix_transform.hpp>

But it doesn't explain the parameters. Maybe I missed something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尤怨 2024-12-22 10:35:26

它创建一个投影矩阵,即描述将向量从眼睛空间变换到剪辑空间的线性方程组的矩阵。矩阵确实不是黑魔法。在 OpenGL 中,它们恰好是 4×4 的数字排列:

X_x Y_x Z_x T_x
X_y Y_y Z_y T_y
X_z Y_z Z_z T_z
X_w Y_w Z_w W_w

您可以将 4 向量乘以 4×4 矩阵:

v' = M * v

v'_x = M_xx * v_x + M_yx * v_y + M_zx * v_z + M_tx * v_w
v'_y = M_xy * v_x + M_yy * v_y + M_zy * v_z + M_ty * v_w
v'_z = M_xz * v_x + M_yz * v_y + M_zz * v_z + M_tz * v_w
v'_w = M_xw * v_x + M_yw * v_y + M_zw * v_z + M_tw * v_w

到达裁剪空间后(即在投影步骤之后),基元将被裁剪。剪裁产生的顶点将经历透视划分,即就是

v'_x = v_x / v_w
v'_y = v_y / v_w
v'_z = v_z / v_w
( v_w = 1 = v_w / v_w )

这样。在所有这些转换步骤中,实际上没有什么比普通的矩阵向量乘法更多的事情了。

现在最酷的事情是,矩阵可以用来描述一个坐标系在另一个坐标系内的相对对齐。透视变换的作用是,它让顶点 z 值也“滑入”它们的投影 w 值。并且通过透视划分,非统一的 w 将导致顶点坐标的“扭曲”。 z 较小的顶点将除以 w 较小,因此它们的坐标会“爆炸”,而 z 较大的顶点将被“挤压”,这就是造成透视效果的原因。

It creates a projection matrix, i.e. the matrix that describes the set of linear equations that transforms vectors from eye space into clip space. Matrices really are not black magic. In the case of OpenGL they happen to be a 4-by-4 arrangement of numbers:

X_x Y_x Z_x T_x
X_y Y_y Z_y T_y
X_z Y_z Z_z T_z
X_w Y_w Z_w W_w

You can multply a 4-vector by a 4×4 matrix:

v' = M * v

v'_x = M_xx * v_x + M_yx * v_y + M_zx * v_z + M_tx * v_w
v'_y = M_xy * v_x + M_yy * v_y + M_zy * v_z + M_ty * v_w
v'_z = M_xz * v_x + M_yz * v_y + M_zz * v_z + M_tz * v_w
v'_w = M_xw * v_x + M_yw * v_y + M_zw * v_z + M_tw * v_w

After reaching clip space (i.e. after the projection step), the primitives are clipped. The vertices resulting from the clipping are then undergoing the perspective divide, i.e.

v'_x = v_x / v_w
v'_y = v_y / v_w
v'_z = v_z / v_w
( v_w = 1 = v_w / v_w )

And that's it. There's really nothing more going on in all those transformation steps than ordinary matrix-vector multiplication.

Now the cool thing about this is, that matrices can be used to describe the relative alignment of a coordinate system within another coordinate system. What the perspective transform does is, that it let's the vertices z-values "slip" into their projected w-values as well. And by the perspective divide a non-unity w will cause "distortion" of the vertex coordinates. Vertices with small z will be divided by a small w, thus their coordinates "blow" up, whereas vertices with large z will be "squeezed", which is what's causing the perspective effect.

偏爱你一生 2024-12-22 10:35:26

这是相同功能的独立版本。这大致是 的复制粘贴版本原创

# include <math.h>
# include <stdlib.h>
# include <string.h>

typedef struct s_mat {
    float *array;
    int width;
    int height;
} t_mat;

t_mat *mat_new(int width, int height)
{
    t_mat *to_return;

    to_return = (t_mat*)malloc(sizeof(t_mat));
    to_return->array = malloc(width * height * sizeof(float));
    to_return->width = width;
    to_return->height = height;
    return (to_return);
}

void mat_zero(t_mat *dest)
{
    bzero(dest->array, dest->width * dest->height * sizeof(float));
}

void mat_set(t_mat *m, int x, int y, float val)
{
    if (m == NULL || x > m->width || y > m->height)
        return ;
    m->array[m->width * (y - 1) + (x - 1)] = val;
}

t_mat *mat_perspective(float angle, float ratio,
        float near, float far)
{
    t_mat *to_return;
    float tan_half_angle;

    to_return = mat_new(4, 4);
    mat_zero(to_return);
    tan_half_angle = tan(angle / 2);
    mat_set(to_return, 1, 1, 1 / (ratio * tan_half_angle));
    mat_set(to_return, 2, 2, 1 / (tan_half_angle));
    mat_set(to_return, 3, 3, -(far + near) / (far - near));
    mat_set(to_return, 4, 3, -1);
    mat_set(to_return, 3, 4, -(2 * far * near) / (far - near));
    return (to_return);
}

This is a c standalone version of the same function. This is roughly a copy paste version of the original.

# include <math.h>
# include <stdlib.h>
# include <string.h>

typedef struct s_mat {
    float *array;
    int width;
    int height;
} t_mat;

t_mat *mat_new(int width, int height)
{
    t_mat *to_return;

    to_return = (t_mat*)malloc(sizeof(t_mat));
    to_return->array = malloc(width * height * sizeof(float));
    to_return->width = width;
    to_return->height = height;
    return (to_return);
}

void mat_zero(t_mat *dest)
{
    bzero(dest->array, dest->width * dest->height * sizeof(float));
}

void mat_set(t_mat *m, int x, int y, float val)
{
    if (m == NULL || x > m->width || y > m->height)
        return ;
    m->array[m->width * (y - 1) + (x - 1)] = val;
}

t_mat *mat_perspective(float angle, float ratio,
        float near, float far)
{
    t_mat *to_return;
    float tan_half_angle;

    to_return = mat_new(4, 4);
    mat_zero(to_return);
    tan_half_angle = tan(angle / 2);
    mat_set(to_return, 1, 1, 1 / (ratio * tan_half_angle));
    mat_set(to_return, 2, 2, 1 / (tan_half_angle));
    mat_set(to_return, 3, 3, -(far + near) / (far - near));
    mat_set(to_return, 4, 3, -1);
    mat_set(to_return, 3, 4, -(2 * far * near) / (far - near));
    return (to_return);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文