大学向けにコア OpenGL 3.3 のみを使用して Wolfenstein 3D のクローンを作成していますが、スプライトで少し問題が発生しました。つまり、スプライトを距離に基づいて正しくスケーリングすることです。
私が知る限り、以前のバージョンの OGL は実際にこれを行っていましたが、その機能は削除されており、再実装しようとする試みはすべて完全に失敗しました。
私の現在の実装は、遠距離ではまずまずで、中距離ではあまり粗末ではなく、近距離では奇妙です。
主な問題 (私が思うに) は、私が使用している数学を理解していないことです。
スプライトのターゲット サイズはビューポートよりもわずかに大きいため、そのサイズに近づくと「画像から外れる」はずですが、そうではありません。それは小さくなり、それは私を大いに混乱させます。
言葉が足りない場合に備えて、これの小さなビデオを記録しました。(私のは右側です)
誰かが私が間違っている場所に私を導き、その理由を説明できますか?
コード:
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);
頂点シェーダー
#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;
}
フラグメントシェーダー
#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;
}