我尝试使用点精灵渲染OpenGL 3+的粒子。我刚刚意识到我的问题存在重大问题。它们相对于相机距离自动增大。导致以下结果:
靠近粒子发射器:
远在外,一切看起来都模糊不清:
在旧版本中,似乎可以使用glPointParameter
调整磅值比例。该功能仍可在新的3+ OpenGL中使用,但它仅支持两个参数。 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;
}
答案 0 :(得分:12)
事实证明我的问题是由于我对gl_PointSize
的误解。正如评论中所述并在文档中明确说明的那样,gl_PointSize
包含栅格化点的大小(以像素为单位)。因此,一旦我们离开它们,点精灵就会变得更大,但不是因为它们被缩放,而是因为它们仍然占据相同的屏幕空间,而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;
}
答案 1 :(得分:4)
使用带有three.js的GLSL时遇到同样的问题。根据glampert的答案解决了这个问题,但首先要解决这三个问题。需要使用某些predefined variable names:
uniform vec4 origin;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
float cameraDist = distance( mvPosition, origin );
gl_PointSize = 200.0 / cameraDist;
gl_Position = projectionMatrix * mvPosition;
}
其次请注意,modelViewMatrix首先应用于粒子位置,然后计算距离到该位置。因为如果将变换应用于粒子系统对象,则粒子位于不等于全局坐标的对象坐标中。因此,我计算视图坐标中的距离(相机始终位于原点)。