2011-08-14 132 views
1

我想渲染点精灵,但我得到了积分。哪里有问题 ? (改变通过glUniform3f彩色作品)opengl - 点精灵渲染问题

顶点着色器:

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); 
+0

我不明白,你能点精灵或设置代码相应的参数。我也不确定它们是否已被弃用(如果您有核心环境,可能会出现问题)。 –

+0

解决。我只是忘记了设置glPointSize(默认值球体看起来像点)。如果在OpenGL 3.3和以上版本中不推荐使用点精灵,那么实现类似效果的最佳方法是什么?我需要一种可用于渲染粒子引擎的高效方法。 –

+1

点精灵并未从3.3内核中移除。但总的来说,你不应该使用点精灵,因为他们的一些行为,特别是在裁剪周围,是有问题的。在NVIDIA硬件上,他们遵循您期望的规则。在AMD的硬件上,他们遵循规范所规定的规则:它们被限制在重点的中心。所以如果中心在屏幕外,整个点就会消失,即使它的一部分应该是可见的。 –

回答

0

你为什么不干脆去做使用几何着色器? 您只需将变换后的顶点位置传递给几何着色器,并让几何着色器输出该点周围的四个顶点,即可完成。 它更加灵活和稳定。

例子:

顶点着色器:

void main() 
{ 
    gl_TexCoord[0] = gl_MultiTexCoord0; 

    // Output vertex position 
    gl_Position = gl_ModelViewMatrix * gl_Vertex; 
} 

几何着色器:

#extension GL_EXT_geometry_shader4 : enable 

uniform float particle_size; 

void main() 
{ 
    float halfsize = particle_size * 0.5; 

    gl_TexCoord[0] = gl_TexCoordIn[0][0]; 
    gl_FrontColor = gl_FrontColorIn[0]; 

    // Vertex 4 
    gl_TexCoord[0].st = vec2(1.0,1.0); 
    gl_Position = gl_PositionIn[0]; 
    gl_Position = gl_ProjectionMatrix * gl_Position; 
    gl_Position.xy += vec2(halfsize, halfsize); 
    EmitVertex(); 

    // Vertex 3 
    gl_TexCoord[0].st = vec2(1.0,-1.0); 
    gl_Position = gl_PositionIn[0]; 
    gl_Position = gl_ProjectionMatrix * gl_Position; 
    gl_Position.xy += vec2(halfsize, -halfsize); 
    EmitVertex(); 

    // Vertex 2 
    gl_TexCoord[0].st = vec2(-1.0,1.0); 
    gl_Position = gl_PositionIn[0]; 
    gl_Position = gl_ProjectionMatrix * gl_Position; 
    gl_Position.xy += vec2(-halfsize, halfsize); 
    EmitVertex(); 

    // Vertex 1 
    gl_TexCoord[0].st = vec2(-1.0,-1.0); 
    gl_Position = gl_PositionIn[0]; 
    gl_Position = gl_ProjectionMatrix * gl_Position; 
    gl_Position.xy += vec2(-halfsize, -halfsize); 
    EmitVertex(); 



    EndPrimitive(); 
} 
+0

实际上,我认为你可以简单地将顶点位置与顶点着色器中的gl_ModelViewProjectionMatrix相乘,而不是在顶点和几何着色器中单独进行顶点位置...我没有测试代码,但它只是作为示例。 – Tara