1

編集:フラグメント シェーダーを変更して、実行ごとに 1 つのライトのみが可能になるようにすると、最初の問題が解決されました。私の2番目の問題はまだ残っています。

あなたが提供できる助けを前もって感謝します。ここ数週間、LWJGL レンダリング エンジンのディファード シェーディング パイプラインに取り組んでいます。私はすべてを期待どおりに動作させることができたと思っていましたが、プログラムを数人の知人に配布した後、問題が発生し始めました。これをできるだけ短くしようと思います。私と一緒にいてくれてありがとう。

タイトルにある 2 つの問題のうち最初のものから始めます。私のマシン (AMD Phenom II 965 および Nvidia GTX 480) では、レンダラーの最終製品はまさに期待どおりでした。(私は画像へのリンクを投稿しようとしましたが、私は新しいユーザーであるため、ハイパーリンクを 3 つ以上投稿することができませんでした。しかし、あるべきように見えたと言っても過言ではありません。)

これはまさに私が意図したことなので、レンダラーは正常に動作していました。友人(GT 440を使用していた)に送ったところ、同じ結果が得られました.

この後すぐに、ラップトップ (GT 540M を使用) を持っている友人にエンジンのビルドを渡しました。これは、レンダラーが生成したものです (FPS カウンターは無視してください。機能しません)。

http://i.imgur.com/DxxFEpy.png

明らかに、これは私が期待した結果ではありません。テストできた他のすべてのモバイル グラフィックス カードで同じ結果が得られました。1 週間以上机に頭をぶつけた後、glBlendFunc が呼び出されるライティング パスに問題を絞り込むことができました。私のコードは次のとおりです。

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    List<Float[]>[] listArray = LightData.getInstance().updateLights();
    List<Float[]> lightsColor = listArray[1];
    List<Float[]> lightsPos = listArray[0];
    viewMatrix.setViewMatrix(camera.getTranslation(), camera.getRotation());


    glDisable(GL_DEPTH_TEST);
    glUseProgram(0);
    glCallList(quadList);
    FBO.useShader();
    FBO.passTextures(); //Just sets the shader uniform values to the correct textures
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_BLEND);
    glLoadIdentity();
    glBlendFunc(GL_ONE, GL_ONE) ; //using GL_ONE and GL_ONE_MINUS_SRC_ALPHA have the same effect
    for (int i = 0; i < lightsPos.size(); i++) {
        glClear(GL_DEPTH_BUFFER_BIT);
        int uniformLightPosition = glGetUniformLocation(FBO.getShaderID(), "uniformLightPosition");
        int uniformLightColor = glGetUniformLocation(FBO.getShaderID(), "uniformLightColor");
        int uniformViewMatrix = glGetUniformLocation(FBO.getShaderID(), "uniformViewMatrix");
        int uniformAmbient = glGetUniformLocation(FBO.getShaderID(), "uniformAmbient");
        glUniform1(uniformLightPosition, Tools.asFloatBuffer(lightsPos.get(i)));
        glUniform1(uniformLightColor, Tools.asFloatBuffer(lightsColor.get(i)));
        glUniform1f(uniformAmbient, 0.01f);
        glUniformMatrix4(uniformViewMatrix, true, viewMatrix.asFloatBuffer());

        glCallList(quadList); //is just a display list for a fullscreen quad (using GL_QUADS)
    } 
    glDisable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);

最初に気付くのは、クワッドを描画してから深度とカラー バッファーをクリアしていることです。それは私の次の質問で対処されるでしょうが、私の次の質問の問題がこの質問の問題と密接に関連していたとしても驚かないでしょう. 問題がこの方法にあることはほぼ確実 (99%) です。これは、1 つのライトのみをサポートし、遅延パイプラインをまだ使用しているエンジンの古いビルドでテストしたときに、テストしたすべてのコンピューターで完璧な結果を得ることができたからです。 . 繰り返しになりますが、レンダラーはテストしたすべてのデスクトップ グラフィック カードで動作しますが、ラップトップ グラフィック カードでは動作しません。この方法を除いて、ほとんどすべてを除外しました。GL_RGBA32fまたはそうでない内部フォーマットのテクスチャを使用して成功しなかったことは注目に値するかもしれませんGL_RGBA16fレンダー ターゲットとして。誰かがこれを以前に見たことがありますか、または誰かが支援を提供できますか? 私は何も持っていないので、この時点でどこから問題を探し始めるか、誰かが何か考えていれば幸いです. 私は完全に自分で解決策を見つけることができませんでした。

次に、2 番目の問題と 2 番目の質問に進みます。最後のコード ブロックの冒頭に、シェーダーなしで画面上にクワッドを作成する数行のコードがありました。

glDisable(GL_DEPTH_TEST);
    glUseProgram(0);
    glCallList(quadList);
    FBO.useShader();
    FBO.passTextures(); //Just sets the shader uniform values to the correct textures
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_BLEND);

私が知る限り、このコードはまったく何もしないはずです。しかし、クワッドの描画を削除すると、ウィンドウに次のように表示されます。

http://i.imgur.com/mkMsP0F.png

これを「ゴースト」以外に何と呼べばいいのかわかりませんでした。これはゴースト イメージのようなものだからです (少なくとも、私にはそう見えます)。MV マトリックスを回転させると、回転方向に歪み、最初のライト セット (7 個のアレイを使用) がそれを照らしますが、残りは実際のモデルを照らします。なぜこれが起こるのか説明できません。なぜなら、この画像を生成するコードは上記のコードとまったく同じでありglCallList(quadList);、ループに入る直前に深度バッファとカラー バッファがまだクリアされていることを意味します。私はこの問題をまったく説明できません。何が問題なのか、それを修正する方法、または少なくとも何が問題なのかについての考えを誰かが知っていますか?

編集これは、テクスチャ座標を持つモデルでのみ発生することがわかりました。どうしてか分かりません。

編集各シェーダーで許可されるライトの量を 1 に制限すると、ゴーストが目立たなくなりますが、まだ存在するように見えます。したがって、これは、フラグメント シェーダーを 1 回実行するとこれらのゴーストが発生することを意味すると思います。

これら 2 つの問題のいずれかについて誰かが助けてくれてありがとう、それは大歓迎です。ご不明な点がございましたら、お気軽にお問い合わせください。返信に時間がかかる場合がありますが、できるだけ早く返信できるように努めます。

編集申し訳ありませんが、シェーダーコードを忘れました:GeometryPass vertex:

uniform sampler2D tex;

varying vec3 surfaceNormal;
varying vec3 varyingVertex;

void main() {
    vec4 color = vec4(texture2D(tex, gl_TexCoord[1].st));
    gl_FragColor = color;

}

GeometryPass フラグメント:

uniform sampler2D tex;

varying vec3 surfaceNormal;
varying vec3 varyingVertex;

uniform float materialValue;
uniform float specValue; 

void main() {
    vec4 color = vec4(texture2D(tex, gl_TexCoord[1].st)) ;//vec4(0.25,0.25,0.25,1);
    vec4 vertex = vec4(varyingVertex, materialValue);
    vec4 normal = vec4(surfaceNormal, specValue);
    gl_FragData[0] = color;
    gl_FragData[1] = vertex;
    gl_FragData[2] = normal;

}

LightPass フォン頂点:

void main() {
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = gl_ModelViewMatrix * gl_Vertex;
}

LightPass フォン フラグメント

uniform sampler2D location;
uniform sampler2D normal;
uniform sampler2D color;

uniform float uniformLightPosition[21];
uniform mat4 uniformViewMatrix;
uniform float uniformLightColor[28];


void main() {
    vec4 color = texture2D(color, gl_TexCoord[0].st);
    vec4 locationAndMat = texture2D(location, gl_TexCoord[0].st);
    vec4 normalAndSpec = texture2D(normal, gl_TexCoord[0].st);  

    vec3 vertexPosition = locationAndMat.xyz;
    vec3 surfaceNormal = normalAndSpec.xyz;
    float spec = normalAndSpec.a;
    float specA = locationAndMat.a;

    vec4 lightColor[7];
    int iterator = 0;
    for (int i = 0; i<28; i = i+4) {
        lightColor[iterator] = vec4(uniformLightColor[i], uniformLightColor[i+1], uniformLightColor[i+2], uniformLightColor[i+3]);
        iterator = iterator + 1;
    }
    vec3 lightPos[7];
    iterator = 0;
    for (int i = 0; i<21; i = i+3) {
        lightPos[iterator] = vec3(uniformLightPosition[i], uniformLightPosition[i+1], uniformLightPosition[i+2]);
        lightPos[iterator] =  (uniformViewMatrix * vec4(lightPos[iterator],1)).xyz ;
        iterator = iterator + 1;
    }

    vec4 fragData[7];
    vec4 endColor;
    for (int i = 0; i<7 ; i++) {
        if (lightColor[i] != vec4(0,0,0,0) && color != vec4(0,0,0,0)) {
            vec3 lightDistance = lightPos[i]-vertexPosition;
            float distance = pow((pow(lightDistance.x, 2) + pow(lightDistance.y, 2) + pow(lightDistance.z, 2)), 0.5);
            if (distance < lightColor[i].a) { 
                float att = 1/((-3/800*(lightColor[i].a) + 0.225)*pow(distance, 2));
                vec3 lightDirection = normalize(lightDistance);    

                float diffuseLightIntensity = max(0.0, dot(surfaceNormal, lightDirection));
                fragData[i] += (vec4(diffuseLightIntensity,diffuseLightIntensity,diffuseLightIntensity,1));    

                vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal));

                float specular = max(0.0, dot(reflectionDirection,  -normalize(vertexPosition)));

                if (diffuseLightIntensity != 0) {
                    float fspecular = pow(specular, spec);
                    vec4 fspec = vec4(fspecular*specA, fspecular*specA, fspecular*specA,1);
                    fragData[i] += fspec;
                }
                fragData[i] *= lightColor[i]; 
                fragData[i] *= 0.1;
                fragData[i].a = 0;
                fragData[i] *= att;
                endColor += fragData[i];
            }
        }  

    } 

    gl_FragData[0] = endColor * color;

}
4

1 に答える 1

1

根本的な問題を解決しました!私にはこれで十分でした。私が抱えていた問題は、(for ループのため) フラグメント シェーダーごとに多くの命令が必要だったようです。シェーダーを調整して 1 つのライトのみを許可すると、期待どおりに機能しました。以前と同じようにブレンディングを使用してすべてを処理しますが、シェーダーをより多く実行します。欠点は、より多くの濾液が必要なことですが、利点は、古いハードウェアやラップトップで動作することです.

ゴーストの原因はまだわかりませんが、私にはあまり重要ではありません。

于 2013-02-02T04:17:05.113 に答える