opengl - 现代 OpenGL 的点 Sprite 尺寸衰减

标签 opengl glsl particle-system point-sprites

我正在尝试使用点 Sprite 通过 OpenGL 3+ 渲染一些粒子。我刚刚意识到我对这些点有一个重大问题。它们的尺寸会根据相机距离自动增加。结果如下:

靠近粒子发射器:

colse

当距离很远时,一切看起来都模糊而臃肿:

far

在旧版本中,似乎可以使用 glPointParameter 调整点大小比例。 。该函数在新的 OpenGL 3+ 中仍然可用,但仅支持两个参数。 GL_POINT_FADE_THRESHOLD_SIZE似乎是我所需要的,但我已经尝试过但没有结果。我还使用 glEnable(GL_PROGRAM_POINT_SIZE);

还有其他方法可以避免根据相机距离自动缩放点吗?我宁愿不必更改代码来使用由三角形组成的标准广告牌。

不确定目前是否相关,但这是我正在使用的顶点着色器:

layout(location = 0) in vec4 a_position_size; // Point size in w coord
layout(location = 1) in vec4 a_color;         // RGBA color modulated with texture

layout(location = 0) out vec4 v_color;

uniform mat4 u_MVPMatrix;

void main()
{
    gl_Position  = u_MVPMatrix * vec4(a_position_size.xyz, 1.0);
    gl_PointSize = a_position_size.w;
    v_color      = a_color;
}

最佳答案

事实证明我的问题是由于我对 gl_PointSize 的误解造成的。正如评论中所指出的和文档中明确指出的,gl_PointSize 包含光栅化点的大小(以像素为单位)。因此,一旦我们远离点 Sprite ,它们就会看起来更大,但这并不是因为它们被缩放,而是因为它们仍然占据相同的屏幕空间,而 3D 场景的其余部分根据透视投影按比例缩小。

我通过对顶点着色器进行一些调整来解决该问题,以根据距观看者的距离实际缩放点大小:

uniform mat4 u_MVPMatrix;
uniform vec3 u_cameraPos;

// Constants (tweakable):
const float minPointScale = 0.1;
const float maxPointScale = 0.7;
const float maxDistance   = 100.0;

void main()
{
    // Calculate point scale based on distance from the viewer
    // to compensate for the fact that gl_PointSize is the point
    // size in rasterized points / pixels.
    float cameraDist = distance(a_position_size.xyz, u_cameraPos);
    float pointScale = 1.0 - (cameraDist / maxDistance);
    pointScale = max(pointScale, minPointScale);
    pointScale = min(pointScale, maxPointScale);

    // Set GL globals and forward the color:
    gl_Position  = u_MVPMatrix * vec4(a_position_size.xyz, 1.0);
    gl_PointSize = a_position_size.w * pointScale;
    v_color      = a_color;
}

关于opengl - 现代 OpenGL 的点 Sprite 尺寸衰减,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26387730/

相关文章:

c++ - 如何将 glRotatef() 转换为 glMultMatrixd() 的乘法矩阵

ios - 为什么 GLSL 的算术函数在 iPad 上与在模拟器上产生如此不同的结果?

javascript - 在 Three.JS 粒子系统中移动单个粒子

ios - 将颜色应用于片段着色器中的 OpenGL ES 2.0 点 Sprite 纹理?

opengl - 可接受的 glPolygonMode 第一个参数值是多少?

c++ - 您应该如何在 OpenGL 4.5 中初始化立方体贴图数组?

c++ - 旋转粒子系统

opengl - 为什么 GL_MAX_ARRAY_TEXTURE_LAYERS 比 GL_MAX_TEXTURE_SIZE 小很多?

c++ - GLSL/OpenGL FBO 不会解除绑定(bind)

spring - 如何在使用粒子系统进行处理中制作滑动构件