LearnOpenGL 总结记录<12> Shadow Mapping

本文总结了OpenGL阴影映射的关键点,包括使用FrameBuffer生成深度图、透视除法的处理、解决Shadow acne问题的阴影偏移以及避免Peter panning现象的正面剔除技术。通过对深度值的直接读取和特定的顶点着色器操作,实现更逼真的光照效果。
摘要由CSDN通过智能技术生成

Shadow Mapping的基本思路就不进行记录了,可以直接看 :

https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping

这里记录一些值得注意的地方

1.  FrameBuffer 绑定了 GL_DEPTH_ATTACHMENT 为 depthMap,渲染场景生成depthMap的时候,没有写入任何颜色,只是写入了depth value,那么 depthMap.r 记录了对应的深度值,可以直接用  float depthValue = texture(depthMap, TexCoords).r;

// configure depth map FBO
// -----------------------
const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
unsigned int depthMapFBO;
glGenFramebuffers(1, &depthMapFBO);
// create depth texture
unsigned int depthMap;
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// attach depth texture as FBO's depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

 

2. 只有传入gl_Position 才会去做透视除法.

When we output a clip-space vertex position to gl_Position in the vertex shader, OpenGL automatically does a perspective divide e.g. transform clip-space coordinates in the range [-w,w] to [-1,1] by dividing the x, y and z component by the vec- tor’s w component. As the clip-space FragPosLightSpace is not passed to the fragment shader viagl_Position we have to do this perspective divide ourselves:

float ShadowCalculation(vec4 fragPosLightSpace)
{
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
[...]
}

 

3. Shadow acne 的解决办法就是:

We can solve this issue with a small little hack called a shadow bias where we simply offset the depth of the surface (or the shadow map) by a small bias amount such that fragments are not incorrectly considered below the surface.

float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
float shadow = currentDepth - bias > closestDepth  ? 1.0 : 0.0;

4. Peter panning

To mostly fix peter panning we cull front faces. Note that you need to enable GL_CULL_FACE first.

glCullFace(GL_FRONT);

This effectively solves the peter panning issues, but only for solid objects that actually have an inside without openings. In our scene for example, this works perfectly fine on the cubes, but won’t work on the floor as culling the front face completely removes the floor from the equation. The floor is a single plane and would thus completely be culled. If one wants to solve peter panning with this trick care has to be taken to only cull the front faces of objects where it makes sense.

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值