【OpenGL】阴影映射实现实时阴影

本文介绍了使用OpenGL实现阴影映射以实现实时阴影的技术,包括创建阴影贴图、渲染场景到阴影贴图以及正常渲染场景的步骤。通过深度缓冲和帧缓冲对象,将场景转换到光源空间进行比较,从而确定片元是否处于阴影中。文章还讨论了阴影贴图的优缺点,并展示了使用偏移量和点采样改善阴影质量的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完整代码已上传:https://github.com/kaiwu119/BallFreeFallAnimation

阴影是光线被物体遮挡而产生的,当光线照射不到物体表面时,这个物体就处于阴影中了, 阴影的存在可以让场景更加真实,而且更容易分辨出物体的相对位置。现在有很多阴影的实现方法,但是都不是那么容易实现的,而阴影映射是比较容易实现的,这次主要介绍阴影映射实现实时阴影,下面先看效果图

还是比较懒,素材选用了之前的自由落体小程序,但是对之前的效果进行了修改,可以很明显的看出现在渲染出的效果更好。

我们从上面的图看出小球的影子是实时跟着小球移动的,附加了阴影之后这个小球是不是更具有真实感了呢。

阴影映射

先说一下阴影贴图的好处:不需要了解场景中的物体,对于每个灯光而言,只需要一张纹理来保存阴影信息。

缺点是 易走样。后面会讲到。

阴影映射是实现阴影的一种方法,这种方法思路非常简单,简单来说:光源发出的一条射线中与光线触碰到的第一个物体,那么这个就是光亮点,也是在这个射线中距离光源的最近点,然后我们把这个最近点和射线上的其余点进行比较,只要比最近点远那就是处于阴影中。但是我们遍历所有的射线显然效率是很低的,于是我们引入了一种类似的举措,但是效率上更可观——深度缓冲。在深度缓冲中,里面的一个值对应于在摄像机的视角下的一个片元的深度值(取值为0~1),那么我们就可以简单的获取这些最近点的深度值了,我们只需要把摄像机架在光源的位置对屏幕进行渲染,然后把获取到的深度值保存到一张纹理中,这个纹理就叫做深度贴图,或是阴影贴图。之后我们正常渲染的时候,我们就可以让每一个片元的深度值和阴影贴图相对应的深度值比较,我们就能知道这个片元是否处于阴影之中。

那么如何比较呢?因为我们的阴影贴图是在光源的位置上获取的,那么我们同样也要将所有的片元转换到光源空间中,然后再进行比较。

技术路线是:

  1.  创建阴影贴图
  2.  渲染场景到阴影贴图
  3.  正常渲染场景(使用阴影贴图)

下面我们分别具体阐述方法和代码:

 

1. 创建阴影贴图

    glGenFramebuffers(1, depthMapFBO); //生成一个帧缓冲对象

    glGenTextures(1, depthMap);
    glBindTexture(GL_TEXTURE_2D, *depthMap);//绑定深度图
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值