Прежде всего, я не очень понимаю, почему вы используете pos.x + 1
.
Далее, как сказал Натан, вы не должны использовать точку пространства клипа, а точку глаза. Это означает, что вы используете только точку, преобразованную из вида модели (без проекции), чтобы вычислить расстояние.
uniform mat4 MV; //modelview matrix
vec3 eyePos = MV * vec4(pos.x, pos.y, 0.5, 1);
Кроме того, я не совсем понимаю ваше вычисление ослабления. На данный момент более высокое значение constAtten
означает меньшее затухание. Почему бы вам просто не использовать модель, которую использовали устаревшие параметры точки OpenGL:
float dist = length(eyePos); //since the distance to (0,0,0) is just the length
float attn = inversesqrt(constAtten + linearAtten*dist + quadAtten*dist*dist);
РЕДАКТИРОВАТЬ: Но в целом я думаю, что эта модель затухания не является хорошим способом, потому что часто вы просто хотите, чтобы спрайт сохранял размер своего пространства объектов, что вам приходится довольно сильно возиться с коэффициентами затухания, чтобы достичь того, что я думаю.
Лучший способ - ввести размер пространства объекта и просто вычислить размер экранного пространства в пикселях (что на самом деле является gl_PointSize
) на основе этого с использованием текущего вида и настройки проекции:
uniform mat4 MV; //modelview matrix
uniform mat4 P; //projection matrix
uniform float spriteWidth; //object space width of sprite (maybe an per-vertex in)
uniform float screenWidth; //screen width in pixels
vec4 eyePos = MV * vec4(pos.x, pos.y, 0.5, 1);
vec4 projCorner = P * vec4(0.5*spriteWidth, 0.5*spriteWidth, eyePos.z, eyePos.w);
gl_PointSize = screenWidth * projCorner.x / projCorner.w;
gl_Position = P * eyePos;
Таким образом, спрайт всегда получает размер, который он будет иметь при рендеринге в виде текстурированного четырехугольника с шириной spriteWidth
.
РЕДАКТИРОВАТЬ: Конечно, вы также должны иметь в виду ограничения точечных спрайтов. Точечный спрайт обрезается в зависимости от его центрального положения. Это означает, что когда его центр выходит за пределы экрана, весь спрайт исчезает. С большими спрайтами (как в вашем случае, я думаю) это действительно может быть проблемой.
Поэтому я бы лучше предложил вам использовать простые текстурированные четырехугольники. Таким образом, вы обойдете всю эту проблему ослабления, поскольку квады просто трансформируются, как и любой другой трехмерный объект. Вам нужно только осуществить поворот к средству просмотра, что может быть сделано либо на процессоре, либо в вершинном шейдере.