Shadow mapping学习记录

本文记录了使用OpenGL实现Shadow Mapping的过程,包括从平行光角度渲染depth map、解决光照异常、阴影缺失、视口设置错误、阴影过黑、Shadow Acne与Peter Panning问题,以及锯齿和软阴影实现。通过不断调整和优化,最终成功实现自然的阴影效果。
摘要由CSDN通过智能技术生成

跟着http://www.opengl-tutorial.org/cn/intermediate-tutorials/tutorial-16-shadow-mapping/学习了一下用OpenGL实现shadow mapping,下面记录实现过程中遇到的N个问题。

Shadow mapping主要是从light的视角渲染一个depth map到一个frame buffer中,再从camera的视角做shading,对每个shading point都到shadow map上查询一下是否被遮挡,如果被遮挡,就在shadow里

思路挺简单的,但是还是踩了N个坑:

1. 用 平行光,渲染出来的光照效果很奇怪

平行光的话,就是直接用uniform变量传给vs一个lightDir,然后用ViewMatrix变换到camera space里,再传给fs,然后在fs里normalize一下,就可以用于后续的计算了。和点光源的唯一区别就在于fs里点光源是用lightPos-vertexPos计算lightDir,而平行光可以直接传一个lightDir进来。

这个过程看起来蛮简单的,但是不知道为什么光照效果很奇怪,检查了很久代码,发现是这里写错了:

齐次坐标里,向量的形式是:(x, y, z, 0),点的形式是:(x, y, z, 1)

这里的lightDir应该是一个向量,所以不应该是 vec4(lightDir, 1) 而应该是 vec4(lightDir, 0)

改为:

之后就正常了:

2. 上面虽然光照正常了,但是没有阴影,这是为什么呢?

后来发现应该这样写才对:

从camera的视角做shading时,对每个shading point都要到light的shadow map上查询一下是否被遮挡

但是首先:

要自己做一下透视除法,这样才能把坐标变换到 [-1, 1]的裁剪空间中。为什么我们不用写这一句?因为平时我们变换到camera的clip space时,在vs里gl_position自动帮我们做了透视除法,但是现在我们要变换到light的clip space,就要自己写一下这句话,要不然坐标不在[-1,1]范围内。

然后其次:

要把坐标从[-1, 1]变换到[0,1],这样才能作为uv坐标在light的depth map里查找到相应的深度值

现在的结果就对了:

3. 但是这个阴影的位置怎么和教程里不太一样?

教程里是这样的:

感觉还是哪里不太对。。

我发现问题了,我的depth map的大小设置的是1024*1024:

但是渲染depth map的时候的viewport设置成了1024*768:

原来是viewport设置错了,把viewport改成1024*1024就正常了:

感到细节真的很重要!!!很多次都是栽在细节上了。。。

至此结果都是正确的了,只剩下一些改善

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值