0

このチュートリアルを使用して、OpenGL エンジンにシャドウ マッピングを実装しようとしています: http://www.fabiensanglard.net/shadowmapping/index.php

シャドウ マップの作成中に問題はありません (と思います)。しかし、それを使用すると、シーンは完全に影になります。


シーンをレンダリングする方法は次のとおりです。


  • 深度 FBO を設定する

    GLuint sdepthtex;
    GLuint sframebuffer ;
    
    glGenTextures(1, &sdepthtex);
    glBindTexture(GL_TEXTURE_2D, sdepthtex);
    
    glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
    
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, sdepthtex, 0);
    
    glDrawBuffer(GL_NONE);
    glReadBuffer(GL_NONE);
    
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
     displayMessage("Error loading the Depth Framebuffer");
     return;
    }
    




  • ライトの視点から ModelViewProjection マトリックスを作成し、shadowMatrix 変数に格納します。

私が使用する機能:

Matrix getMVPmatrix(vector3 position,vector3 lookat )
{

 glPushMatrix();

 double projection[16];
 double modelView[16];
 SDL_Surface*screen = SDL_GetVideoSurface();

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(FOVY,screen->w/screen->h,NEAR,FAR);
 glMatrixMode(GL_MODELVIEW);
 glEnable(GL_DEPTH_TEST);
 glLoadIdentity();
 gluLookAt(position.x,position.y,position.z,lookat.x,lookat.y,lookat.z,0,1,0);

 glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
 glGetDoublev(GL_PROJECTION_MATRIX, projection);

 Matrix m1(projection);
 Matrix m2(modelView);

 glPopMatrix();

 return m1*m2;

}



  • 深度フレームバッファでシーンをレンダリングします。シェーダー:

頂点シェーダー:

uniform mat4 shadowMatrix;

void main()
{

    gl_Position = shadowMatrix*gl_Vertex;  

} 

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

void main(void)
{

    gl_FragDepth = gl_FragCoord.z;

}


私の 3 つのボックスのシーンでは、線形化された深度は次のようになります。

http://www.2shared.com/photo/IExy9aUo/Depth.html

だから、shadowMatrix と深度レンダリングは正しいと思います。


  • 最後のパスは、シャドウ マップを使用してシーンを描画するだけです


頂点シェーダー:

varying vec4 ShadowCoord;
uniform mat4 shadowMatrix;

mat4 biasMatrix = mat4(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);

void main (void)
{
    gl_TexCoord[0] =  gl_MultiTexCoord0;
    gl_FrontColor = gl_Color;
    gl_Position = ftransform();
    ShadowCoord = biasMatrix*shadowMatrix *vec4(gl_Vertex.xyz,1.0);
}


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

uniform sampler2D tex;
uniform sampler2D shadowtex;//the non linearized depth texture we made in the 3rd step.
varying vec4 ShadowCoord;

float getShadowFactor(void)
{
    vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;

    shadowCoordinateWdivide.z += 0.0005;

    float distanceFromLight = texture2D(shadowtex,shadowCoordinateWdivide.st).z;

    float shadow = 1.0;
    if (ShadowCoord.w > 0.0)
        shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 :1.0 ;

    return shadow ;

}

void main (void)
{

    gl_FragColor =texture2D(tex, gl_TexCoord[0].st);

    gl_FragColor.rgb *= getShadowFactor() ;//add shadows Here

}



結果 ?私のシーンはすべて影になっています!



4

1 に答える 1

1

テクスチャのセットアップとシェーダーの間でコードに矛盾があるようです。テクスチャ セットアップ コードでは、次のようになります。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

GL_TEXTURE_COMPARE_FUNCが でない場合GL_NONE、シェーダー コードでシャドウ テクスチャ サンプラーを使用する必要があります。ただし、フラグメント シェーダーでは、このテクスチャに通常のサンプラーを使用します。

uniform sampler2D shadowtex;

テクスチャ設定と互換性を持たせるには、これを次のように変更する必要があります。

uniform sampler2DShadow shadowtex;

タイプを一致させるために、テクスチャをサンプリングするshadow2D()代わりに が使用されます。texture2D()

もう 1 つのオプションはGL_TEXTURE_COMPARE_FUNC、デフォルト値の のままにすることですGL_NONEsampler2Dこれは、サンプリングに a を使用することと一致します。

于 2014-08-16T05:14:29.767 に答える