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;
}
在depth framebuffer中渲染场景。着色器:
顶点着色器:
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
进行采样是一致的。
相关文章:
- 除非重新绘制大小,否则SDL_Texture在调整大小后呈现黑色
- 为什么我会得到黑色纹理?
- C++声明模板参数阴影模板参数错误
- DirectX 11 - 点光源阴影
- 具有 GPU 时间表的卤化物产生黑色图像
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- OpenGL只是渲染一个黑色的方块
- 模板中的Typedef导致阴影模板parm错误
- C++具有内置缓存 - 阴影模板参数的对象工厂
- 黑色纹理,如果图片大小在第二个 OpenGL 线程中> 1 * 1
- 将未签名的字符转换为红黑色树的签名字符
- CImage::D raw() 画了一幅黑色的图画
- 纹理显示为黑色
- 使用 GCC 5 进行模板参数阴影
- OpenGL - 阴影贴图/深度贴图给出奇怪的结果
- openCV中的Absdiff可以编译,但显示黑色图像
- 在图像上的矩形区域之外填充黑色
- 警告派生的类成员阴影级班级成员
- 多个快速读取器 单个慢速写入器:使用具有原子索引的阴影数据安全吗?
- OpenGL场景渲染为黑色与阴影映射