I am writing a Wolfenstein 3D clone using only the core OpenGL 3.3 for the university, and I had a problem with sprites, namely, that they scale correctly based on distance.
From what I can say, previous versions of OGL actually did it for you, but this functionality was removed, and all my attempts to redefine it led to a complete failure.
My current implementation is passable at distances not too shabby in the middle of the range and bizzare at close range.
The main problem (I think) is that I do not have an understanding of the math that I use.
The target size of the sprite is slightly larger than the viewing area, so it should “exit the picture” as soon as you get to it, but it’s not. It gets smaller and it scares me. I recorded a short video about this if words are not enough. (Mine on the right)


Can someone direct me to where I am wrong and explain why?
Code:
C ++
glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
glEnable(GL_PROGRAM_POINT_SIZE);
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);
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;
}