2016-04-24 16 views
1

ポイントスプライトを使用して標準的な基本変換フィードバックパーティクルシステムを作成しました。フリッカーは発生せず、パーティクルはあるバッファから次のバッファに更新され、次にレンダリングされ、次に出力バッファは次の反復で入力バッファになります。すべてのGPU側の標準変換フィードバック。 素晴らしい! 1つの大きな問題:gl_PointCoordを使用しない場合にのみ機能します。私のポイントスプライトのためのフラットカラーを使用して正常に動作します。しかし、何か意味のあることをするにはgl_PointCoordが必要です。私のすべてのシェーダは、gl_PointCoordを使用するかどうかに関係なく、コンパイルしてリンクするだけです。しかし、実行時に、シェーダがgl_PointCoordを使用する場合(gl_PointCoordが実際に実行パスにあるかどうかに関係なく)、プログラムはクラッシュします。私は明示的にglEnable(GL_POINT_SPRITE)です。これは何の効果もありません。 gl_PointCoordを省略し、glPointSize(100.0f)を設定し、vec4(1.0,1.0,1.0,1。)を使用すると、パーティクルシステムは(期待通りに)大きな白い四角形のレンダリングを行います。しかしgl_PointCoordを(標準的なテクスチャルックアップ座標または手続き的な色などの)何らかの方法で使用すると、コンパイルとリンクが正常に実行された後、実行時にシェーダがクラッシュします。私は単に理由を理解していない。 glShaderSource、glCompileShader、glAttachShader、glLinkProgramを渡しました。私はシェーダを#430、440としてコンパイルしていますが、300個も試しました。すべてのコンパイル、リンク、コンパイルとリンクの状態を確認しました。すべての良い。私はハイエンドのmicrosoft surface book pro、visual studio 2015を使用しています。NVIDIA GeForce GPU。私はまた、すべてのドライバーが最新であることを確認しました。残念なことに、ポイントスプライトでは、頂点シェーダからビルボードの頂点を使用して、フラグメントシェーダにテクスチャ座標として補間する必要はありません。 gl_FragCoordはどちらも動作しません(私はポイントスプライトに期待しています)。誰かがこれを解決するか、ポイントスプライトのテクスチャ座標のための別のテクニックを使用する方法を知っていますか?gl_PointCoordはコンパイルとリンクを行いますが、実行時にクラッシュします

glBeginTransformFeedback(GL_POINTS); //私のフラグメントシェーダーがgl_PointCoordを使用すると、ここでハードクラッシュします。

返信する際には、シェーダ、頂点シェーダ、ピクセルシェーダ、テッセレーションコントロール、テッセレーション評価、およびジオメトリシェーダをGLSLおよびHLSLで記述する経験があります。しかし、私はすべてを知っていると主張していません。私は単純なことを忘れていた可能性があります。私はそれが何であるか分かりません。私はそれが有効になっていない状態になる可能性があると考えています。限り、私はglTransformFeedbackVaryingsを介して様々な属性を正しく設定します。 C++:フィードバックVS

void Render(void* pData) 
{ 
    auto pOwner = static_cast<CPointSpriteSystem*>(pData); 
    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); 
    glEnable(GL_POINT_SPRITE); 
    glEnable(GL_POINT_SMOOTH); 
    //glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 
    m_Shader.Activate(); 
    auto num_particles = pOwner->m_NumPointSprites; 
    FeedbackIndex = 0; 
    while (true) 
    { 
     m_Shader.SetSubroutine(GL_VERTEX_SHADER, "RenderPass", 
      vssubroutines[FeedbackIndex], 
      vsprevSubLoc[FeedbackIndex], 
      vsupdateSub[FeedbackIndex]); 
     m_Shader.SetSubroutine(GL_FRAGMENT_SHADER, "RenderPixelPass", 
      pssubroutines[0], 
      psprevSubLoc[0], 
      psrenderSub[0]); 
     if (!FeedbackIndex) 
     { 
      glEnable(GL_RASTERIZER_DISCARD); 
      glBindVertexArray(m_vao[bufferIndex]); 
      glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_Feedback[bufferIndex]); 
      glBeginTransformFeedback(GL_POINTS);//if feedback fragment shader uses gl_PointCoord, will always hard-crash here 
      glDrawArrays(GL_POINTS, 0, num_particles); 
      glEndTransformFeedback(); 
      glFlush(); 
     } 
     else 
     { 
      m_Shader.SetSubroutine(GL_FRAGMENT_SHADER, "RenderPixelPass", 
       pssubroutines[(int)pOwner->m_ParticleType], 
       psprevSubLoc[(int)pOwner->m_ParticleType], 
       psrenderSub[(int)pOwner->m_ParticleType]); 
      glPointSize(100.0f); 
      glDisable(GL_RASTERIZER_DISCARD); 
      glDrawTransformFeedback(GL_POINTS, m_Feedback[bufferIndex]); 
      bufferIndex = 1 - bufferIndex; 
      break; 
     } 
     FeedbackIndex = 1 - FeedbackIndex; 
    } 
} 

#version 310 es 
subroutine void RenderPassType(); 
subroutine uniform RenderPassType RenderPass; 
layout(location=0) in vec3 VertexPosition; 
layout(location=1) in vec3 VertexVelocity; 
layout(location=2) in float VertexStartTime; 
layout(location=3) in vec3 VertexInitialVelocity; 
out vec3 Position; 
out vec3 Velocity; 
out float StartTime; 
out float Transp; 
uniform float g_fCurSeconds; 
uniform float g_fElapsedSeconds; 
uniform float Time; 
uniform float H; 
uniform vec3 Accel; 

#ifdef USE_VIEW_BLOCK 
layout(std140) uniform view_block{ 
    mat4 g_mView, 
     g_mInvView, 
     g_mPrevView, 
     g_mPrevInvView, 
     g_mProj, 
     g_mInvProj; 
}; 
uniform mat4 g_mWorld; 
#endif 

subroutine(RenderPassType) void UpdateSphere(){ 
    Position=VertexPosition+VertexVelocity*g_fElapsedSeconds; 
    Velocity=VertexVelocity; 
    StartTime=VertexStartTime; 
} 
subroutine(RenderPassType) void Render(){ 
    gl_Position=g_mProj*g_mInvView*vec4(VertexPosition,1.0); 
} 

void main(){ 
    RenderPass();" 
} 

PSのフィードバック:

#version 310 es //version 430 and 440 same results 
subroutine void RenderPixelType(); 
subroutine uniform RenderPixelType RenderPixelPass; 
uniform sampler2D tex0; 
layout(location=0) out vec4 g_FragColor; 

subroutine(RenderPixelType) void Basic(){ 
    g_FragColor=vec4(1.0,1.0,1.0,1.0); 
} 

subroutine(RenderPixelType) void ProceduralSphere(){ 
#if 1 
    vec2 coord=gl_PointCoord;//at runtime: BOOM! 
    coord=coord*2.0-1.0; 
    float len=length(coord); 
    if(len>1.0) discard; 
    g_FragColor=vec4(1.0-len,1.0-len,1.0-len,1.0); 
#else 
    g_FragColor=vec4(1.0,1.0,1.0,1.0);//always works 
#endif 
} 

subroutine(RenderPixelType) void StandardImage(){ 
    g_FragColor=texture2D(tex0,gl_PointCoord); //boom!! 
    g_FragColor=vec4(1.0,1.0,1.0,1.0); 
} 

void main(){ 
    RenderPixelPass(); 
} 
+0

問題を再現できるようにソースコードを提供してください。 – datenwolf

+0

ちょうど更新されたオリジナルのポスト – Frankoguy

+0

これは、ドライバやプログラムのどこかにバグがある可能性があります。完全なソースコードがないと(pOwnerとは何ですか?)、伝えるのは難しいです。 – Rei

答えて

3

私はこの問題を解決!問題は、実際にはTranspに値を書き込まなかったことです(float Transp; //とvsで宣言されています)。私は気軽に私がこれをする必要はないと思った。しかし、私はいくつかの脂肪を整え始めました。一般的な浮動小数点(後でシェーダステージで使用されるわけではありません:Transp = 0.0f)を書いた後、#version 430としてコンパイルすると、小さな白い球

関連する問題