1

私が読み込んでシェーディングを適用しようとしている 3D obj(wavefront) モデル (簡単にするために結合された固定パイプライン + シェーダーを介して) が間違って表示されています。

今、私が見つけられると思ういくつかの問題があります。光の問題: 静的ではないようです。オブジェクトを変換して回転させると回転するようです。ビュー マトリックスを設定するために gluLookAt+gluPerspective を使用しています。ここではそうではないようです。

問題 2 は、モデルのシェーディング方法です。滑らかではなく途切れ途切れで、なぜそのリング効果が現れるのかさえわかりません. メッシュを ShaderMaker にロードし、頂点 + フラグメント シェーダーも適用したところ、すべてが完璧に描画されました。描画ルーチンで何か間違ったことをしているようです。

ここに画像の説明を入力

私の頂点シェーダー:

#version 120

varying vec3 N;
varying vec3 v;
void main(void)  
{    
   v = vec3(gl_ModelViewMatrix * gl_Vertex);      
   N = normalize(gl_NormalMatrix * gl_Normal);
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  
}

私のフラグメントシェーダー:

#version 120

varying vec3 N;
varying vec3 v;
#define MAX_LIGHTS 2
void main (void)  
{  
   vec4 finalColour;

        vec4 amb;
        amb = vec4(0.2,0.2,0.2,1.0);

        vec4 diff;
        diff = vec4(1.0,1.0,1.0,1.0);

       vec3 L = normalize(gl_LightSource[0].position.xyz - v);  
       vec3 E = normalize(v);
       vec3 R = normalize(reflect(L,-N));  
       //vec4 Iamb = gl_FrontLightProduct[i].ambient;    
        vec4 Iamb = amb;

        //vec4 Idiff = gl_FrontLightProduct[i].diffuse * max(dot(N,L), 0.0);
       vec4 Idiff = diff * max(dot(N,L), 0.0);

        Idiff = clamp(Idiff, 0.0, 1.0);    
       vec4 Ispec = gl_FrontLightProduct[0].specular
                    * pow(max(dot(R,E),0.0),0.0*gl_FrontMaterial.shininess);
       Ispec = clamp(Ispec, 0.0, 1.0);
       finalColour += Iamb + Idiff;

   gl_FragColor = gl_FrontLightModelProduct.sceneColor + finalColour;
}

EDIT ::私の描画ルーチンを追加しました。

 [[self openGLContext] makeCurrentContext];
    [sM useProgram];


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glClearColor(0.0f,0.0f,0.0f,1.0f);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float aspect = (float)1024 / (float)576;

    gluPerspective(15.0, aspect, 1.0, 15.0);

    glMatrixMode(GL_MODELVIEW);
    float lpos[4] = {0.0,2.0,0.0,1.0};
    glLoadIdentity();
    glLightfv(GL_LIGHT0, GL_POSITION, lpos);

    gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);


    glTranslatef(0.0f, 0.0f, 0.0f);
    glScalef(0.5f, 0.5f, 0.5f);

    glRotatef(self.rotValue, 1.0f, 1.0f, 0.0f);



    glEnableClientState(GL_VERTEX_ARRAY);  
    glEnableClientState(GL_NORMAL_ARRAY);
    NSLog(@"%i", self.W);

    if(self.W == NO)
    {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    } 
    if (self.W == YES)
    {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }
    glColor3f(1.0f,0.0f,0.0f);
    glBindBuffer(GL_ARRAY_BUFFER, vBo[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vBo[1]);
    glNormalPointer(GL_FLOAT, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vBo[2]);
    glDrawElements(GL_TRIANGLES, object.indicesCount, GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);





    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
        NSLog(@"glGetError(): %i", (int)err);

    [[self openGLContext] flushBuffer];

私のシェーダーは、実際にはオンライン ソースから借用しています。私は自分で作成しましたが、経験豊富な人からのしっかりしたものを使用したかったのです. この問題を解決できるまで、それらを保持するつもりはありません。

4

1 に答える 1

0

私は問題を見つけたと思います。まだ解決策を実装していませんが、問題がそこにあると確信しています。この質問は私の問題にも非常に関連しています:

Wavefront Obj で法線インデックスを理解する

問題は、(obj ファイルから) コア データを処理する方法にありました。私はそれらを解析するときに(VBOを介して)OpenGLに直接渡すことがうまくいくと信じるほど単純でした。ここに私の間違いに付随するユーモアがあります。私のリンクがガイドラインに違反していないことを願っています。問題の追跡を手伝ってくれた Andreas に感謝します。 リンク

更新:ソリューションが実装され、モデルが正しいシェーディングでレンダリングされるようになりました。

頂点と法線面を使用して、波面データ (頂点 + 法線) を新しいベクトルに再配置しました。また、glDrawElements は法線ベクトルと UV ベクトルの異なるインデックスの送信をサポートしていないため、glDrawElements から glDrawArrays に切り替えました。このソリューションはロード時間と占有スペースを増加させますが (重複した頂点はバッファから削除されないため)、機能しており、私のニーズを満たしています。

于 2013-07-15T11:28:25.240 に答える