世界是由球体组成的。由于在OpenGL中绘制球体需要很多三角形,因此我认为使用点和半径表示球体然后在OpenGL中使用Billboarding绘制起来会更快。我目前采用的方法是在旋转视图时使相邻的球体不接触。
以下是一个示例:
有两个领域:
球体1 位置(0,0,-3)半径(0.5)
球体2 位置(-1,0,-3)半径(0.5)
使用以下方法定义投影矩阵:
glm::perspective(glm::radians(120.0f), 1.0f, 1.0f, 100.0f);
图片1 :当没有旋转时,它看起来像预期的那样。
图像2 :当发生旋转时,广告牌将按预期方式对摄像机做出响应,但球体不再接触。而且,如果它们实际上是彼此相邻的球体,那么您会期望它们相互接触。
我尝试过的事情:
GL_POINTS
,他们的表现不佳,因为它似乎并没有
为我正确处理深度测试。 这是我现在创建图像的代码:
顶点着色器
#version 460
layout(location = 0) in vec3 position;
layout(location = 1) in float radius;
out float radius_vs;
void main()
{
gl_Position = vec4(position, 1.0);
radius_vs = radius;
}
几何着色器
#version 460
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
layout(location = 2) uniform mat4 view_mat;
layout(location = 3) uniform mat4 projection_mat;
in float radius_vs[];
out vec2 bounds;
void main()
{
vec3 x_dir = vec3(view_mat[0][0], view_mat[1][0], view_mat[2][0]) * radius_vs[0];
vec3 y_dir = vec3(view_mat[0][1], view_mat[1][1], view_mat[2][1]) * radius_vs[0];
mat4 fmat = projection_mat * view_mat;
gl_Position = fmat * vec4(gl_in[0].gl_Position.xyz - x_dir - y_dir, 1.0f);
bounds = vec2(-1.0f, -1.0f);
EmitVertex();
gl_Position = fmat * vec4(gl_in[0].gl_Position.xyz - x_dir + y_dir, 1.0f);
bounds = vec2(-1.0f, 1.0f);
EmitVertex();
gl_Position = fmat * vec4(gl_in[0].gl_Position.xyz + x_dir - y_dir, 1.0f);
bounds = vec2(1.0f, -1.0f);
EmitVertex();
gl_Position = fmat * vec4(gl_in[0].gl_Position.xyz + x_dir + y_dir, 1.0f);
bounds = vec2(1.0f, 1.0f);
EmitVertex();
EndPrimitive();
}
片段着色器
#version 460
out vec4 colorOut;
in vec2 bounds;
void main()
{
vec2 circCoord = bounds;
if (dot(circCoord, circCoord) > 1.0)
{
discard;
}
colorOut = vec4(1.0f, 1.0f, 0.0f, 1.0);
}