it-swarm.com.de

glm :: perspektivische erklärung

Ich versuche zu verstehen, was der folgende Code bewirkt:

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

Erzeugt es eine Projektionsmatrix ? Clips von etwas, das sich nicht in der Ansicht des Benutzers befindet, kann ich auf der API-Seite nicht finden , und das einzige, was ich in der PDF auf ihrer Website finden konnte, war Folgendes:

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>

Aber es erklärt nicht die Parameter. Vielleicht habe ich etwas verpasst.

24
Trt Trt

Es erstellt eine Projektionsmatrix, d. H. Die Matrix, die den Satz linearer Gleichungen beschreibt, der Vektoren aus dem Augenraum in den Clipraum transformiert. Matrizen sind wirklich keine schwarze Magie. Bei OpenGL handelt es sich um eine 4-mal-4-Anordnung von Zahlen:

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

Sie können einen 4-Vektor mit einer 4 × 4-Matrix multiplizieren:

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

Nach dem Erreichen des Clipraums (d. H. Nach dem Projektionsschritt) werden die Grundelemente abgeschnitten. Die aus dem Abschneiden resultierenden Scheitelpunkte erfahren dann die perspektivische Unterteilung, d.h.

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 )

Und das ist es. In all diesen Transformationsschritten ist wirklich nichts weiter los als die gewöhnliche Matrix-Vektor-Multiplikation.

Das Tolle daran ist, dass man mit Matrizen die relative Ausrichtung eines Koordinatensystems innerhalb eines anderen Koordinatensystems beschreiben kann. Die Perspektiventransformation bewirkt, dass die Z-Werte der Scheitelpunkte auch in ihre projizierten w-Werte "gleiten". Durch die perspektivische Unterteilung wird eine Nicht-Einheit w "Verzerrung" der Scheitelpunktkoordinaten verursachen. Scheitelpunkte mit kleinem z werden durch ein kleines w geteilt, wodurch ihre Koordinaten "explodieren", während Scheitelpunkte mit großem z "gequetscht" werden, was den perspektivischen Effekt verursacht.

22
datenwolf

Dies ist eine eigenständige Version der gleichen Funktion. Dies ist ungefähr eine Kopie-Einfügen-Version von dem 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);
}
2
Moebius