Изменение размера точечных спрайтов в зависимости от расстояния от камеры

Я пишу клон Wolfenstein 3D, используя только ядро ​​OpenGL 3.3 для университета, и я столкнулся с небольшой проблемой со спрайтами, а именно с их правильным масштабированием в зависимости от расстояния.

Насколько я могу судить, предыдущие версии OGL действительно делали это за вас, но эта функциональность была удалена, и все мои попытки реализовать ее заново привели к полному провалу.

Моя текущая реализация проходима на дистанциях, не слишком плохая на средних и причудливая на близких.

Основная проблема (я думаю) в том, что я не понимаю математику, которую использую.
Целевой размер спрайта немного больше, чем область просмотра, поэтому он должен «выходить из поля зрения», когда вы подходите к нему, но это не так. Он становится меньше, и это меня сильно сбивает с толку.
Я записал небольшое видео об этом, на случай, если слов недостаточно. (Моя справа)

Expected Result Actual Result

Может ли кто-нибудь указать мне, где я ошибаюсь, и объяснить, почему?

Код:
C ++

// setup
glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
glEnable(GL_PROGRAM_POINT_SIZE);

// Drawing
glUseProgram(StaticsProg);
glBindVertexArray(statixVAO);
glUniformMatrix4fv(uStatixMVP, 1, GL_FALSE, glm::value_ptr(MVP));
glDrawArrays(GL_POINTS, 0, iNumSprites);

Vertex Shader

#version 330 core

layout(location = 0) in vec2 pos;
layout(location = 1) in int spriteNum_;

flat out int spriteNum;

uniform mat4 MVP;

const float constAtten  = 0.9;
const float linearAtten = 0.6;
const float quadAtten   = 0.001;

void main() {
    spriteNum = spriteNum_;
    gl_Position = MVP * vec4(pos.x + 1, pos.y, 0.5, 1); // Note: I have fiddled the MVP so that z is height rather than depth, since this is how I learned my vectors.
    float dist = distance(gl_Position, vec4(0,0,0,1));
    float attn = constAtten / ((1 + linearAtten * dist) * (1 + quadAtten * dist * dist));
    gl_PointSize = 768.0 * attn;
}

Fragment Shader

#version 330 core

flat in int spriteNum;

out vec4 color;

uniform sampler2DArray Sprites;

void main() {
    color = texture(Sprites, vec3(gl_PointCoord.s, gl_PointCoord.t, spriteNum));
    if (color.a < 0.2)
        discard;
}
7
задан Appleshell 15 September 2013 в 01:37
поделиться