【发布时间】:2013-02-07 21:23:03
【问题描述】:
我正在尝试渲染点精灵,但我得到了分数。问题出在哪里 ? (通过 glUniform3f 改变颜色有效)
顶点着色器:
private static String vertexShader =
"#version 330" + "\n" +
"layout (location = 0) in vec4 position;" + "\n" +
"uniform mat4 pMatrix;" + "\n" +
"uniform mat4 mMatrix;" + "\n" +
"void main()" + "\n" +
"{" + "\n" +
"gl_Position = pMatrix * mMatrix * position;" + "\n" +
"}";
片段着色器:
private static String fragmentShader =
"#version 330" + "\n" +
"out vec4 vFragColor;" + "\n" +
"uniform vec3 Color;" + "\n" +
"uniform vec3 lightDir;" + "\n" +
"void main()" + "\n" +
"{" + "\n" +
"vec3 N;" + "\n" +
"N.xy = gl_PointCoord* 2.0 - vec2(1.0);" + "\n" +
"float mag = dot(N.xy, N.xy);" + "\n" +
"if (mag > 1.0) discard;" + "\n" +
"N.z = sqrt(1.0-mag);" + "\n" +
"float diffuse = max(0.0, dot(lightDir, N));" + "\n" +
"vFragColor = vec4(Color,1) * diffuse;" + "\n" +
"}";
渲染:
gl.glUseProgram(shaderProgramID);
gl.glUniformMatrix4fv(projectionMatrixUniform, 1, false, projectionMatrix, 0);
gl.glUniformMatrix4fv(modelViewMatrixUniform, 1, false, modelViewMatrix, 0);
gl.glUniform3f(colorUniform, 1.0f, 0.0f, 0.0f);
gl.glUniform3f(lightDirUniform, 0.0f, 0.0f, 1.0f);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo[0]);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 4, GL3.GL_FLOAT, false, 0, 0);
gl.glDrawArrays(GL3.GL_POINTS, 0, n_particles);
gl.glDisableVertexAttribArray(0);
gl.glUseProgram(0);
【问题讨论】:
-
我没有看到启用点精灵或设置相应参数的代码。我也不确定它们是否已经被弃用(如果你有核心上下文可能是个问题)。
-
已解决。我只是忘了设置 glPointSize (默认值 spheres 看起来像点)。如果在 OpenGL 3.3 及更高版本中不推荐使用点精灵,实现类似效果的最佳方法是什么?我需要一种可以用来渲染粒子引擎的有效方法。
-
点精灵没有从 3.3 核心中移除。但一般来说,您不应该使用点精灵,因为它们的某些行为,特别是在裁剪周围,是有问题的。在 NVIDIA 硬件上,它们遵循您所期望的规则。在 AMD 硬件上,它们遵循规范规定的规则:它们被剪裁在点的中心。所以如果中心不在屏幕上,整个点就会消失,即使它的一部分应该是可见的。
-
当我尝试创建一些碰撞检测等时,使用 glPointSize 毫无意义。当我翻译点精灵时,缩放也有问题。也许我应该在顶点着色器中使用一些变量,它们代表球体的半径、距离和一些比例因子。有什么想法吗?
-
@Lynx 如果你真的想使用点精灵,在顶点着色器中计算点大小可能是个好主意,让它依赖于对象空间而不是屏幕空间,这样远距离精灵比附近的小。