2011-08-14 14 views
1

ポイントスプライトをレンダリングしようとしていますが、ポイントを取得しています。問題はどこだ ?OpenGLポイントスプライトレンダリングの問題

頂点シェーダ(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); 
+0

私はあなたがポイントスプライトを有効にするか設定したコードが表示されません対応するパラメータ。私は彼らが既に非難されているかどうかも分かりません(あなたがコアコンテキストを持っているなら問題になるかもしれません)。 –

+0

解決済み。 glPointSize(デフォルト値の球が点のように見える)を設定するのを忘れてしまった。 OpenGL 3.3以降でポイントスプライトが推奨されなくなった場合、同様の効果を得るための最良の方法は何ですか?パーティクルエンジンをレンダリングするのに使用できる効率的なメソッドが必要です。 –

+1

ポイントのスプライトは3.3コアから削除されませんでした。しかし、一般的には、ポイントスプライトは使用しないでください。スプライトの動作の一部、特にクリッピングについては問題があります。 NVIDIAのハードウェアでは、あなたが期待するルールに従います。 AMDハードウェア上では、仕様書の規則に従って、ポイントの中央でクリップされます。したがって、画面の中心がオフスクリーンの場合、その一部が表示されていても、ポイント全体が消えます。 –

答えて

0

は、なぜあなたは、単に使用してそれをしませんジオメトリシェーダ? 変換された頂点の位置をジオメトリシェーダに渡し、ジオメトリシェーダがそのポイントを中心に4つの頂点を出力するだけです。 はるかに柔軟で安定しています。

例:

バーテックスシェーダ:

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

関連する問題