Sto scrivendo un clone di Wolfenstein 3D utilizzando solo core OpenGL 3.3 per l'università e mi sono imbattuto in un po 'di problemi con gli sprite, ovvero farli scalare correttamente in base sulla distanza.Ridimensionamento degli sprite in base alla distanza dalla telecamera
Da quello che posso dire, le versioni precedenti di OGL farebbero effettivamente questo per voi, ma quella funzionalità è stata rimossa, e tutti i miei tentativi di reimplementare hanno portato ad un completo fallimento.
La mia attuale implementazione è percorribile a distanze, non troppo squallide a metà campo e bizzare a distanza ravvicinata.
Il problema principale (penso) è che non ho alcuna comprensione della matematica che sto usando.
La dimensione di destinazione dello sprite è leggermente più grande del viewport, quindi dovrebbe "uscire dall'immagine" appena ci si arriva, ma non è così. Diventa più piccolo e questo mi confonde molto.
Ho registrato un piccolo video di questo, nel caso in cui le parole non siano sufficienti. (Il mio è a destra)
Qualcuno può indicarmi dove sto andando male, e spiegare perché?
Codice:
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;
}
Perché si usa 'pos.x + 1'? –
Penso che sia perché ha impostato la posizione del centro dello sprite in basso a sinistra, ma vuole davvero il punto di ancoraggio in alto al centro. –
Voglio che il punto di attacco si trovi al centro del bordo inferiore, ma a causa di una serie di problemi di allineamento che non ho ancora risolto, devo spostare un po 'di cose in un modo un po' strano. –