簡體   English   中英

帶有陰影映射的OpenGL場景渲染為黑色

[英]OpenGL scene rendering as black with shadow mapping

我正在嘗試使用本教程在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

}



結果 ? 我所有的場景都蒙上陰影!



看起來您的代碼在紋理設置和着色器之間存在不一致。 在紋理設置代碼中,您需要執行以下操作:

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()以采樣紋理。

另一個選擇是將GL_TEXTURE_COMPARE_FUNC保留為默認值GL_NONE 然后,這與使用sampler2D進行采樣是一致的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM