openGL实现阴影映射(Shadow Mapping)
openGL系列文章目录
文章目录
- openGL系列文章目录
- 前言
- 阴影映射
- 阴影映射原理
- 二、使用步骤
- 显示效果
- 源码下载
- 参考
前言
阴影是光线被阻挡的结果;当一个光源的光线由于其他物体的阻挡不能够达到一个物体的表面的时候,那么这个物体就在阴影中了。阴影能够使场景看起来真实得多,并且可以让观察者获得物体之间的空间位置关系。场景和物体的深度感因此能够得到极大提升,下图展示了有阴影和没有阴影的情况下的不同:
图1
你可以看到,有阴影的时候你能更容易地区分出物体之间的位置关系,例如,当使用阴影的时候浮在地板上的立方体的事实更加清晰。阴影还是比较不好实现的,因为当前实时渲染领域还没找到一种完美的阴影算法。目前有几种近似阴影技术,但它们都有自己的弱点和不足,这点我们必须要考虑到。
视频游戏中较多使用的一种技术是阴影贴图(shadow mapping),效果不错,而且相对容易实现。阴影贴图并不难以理解,性能也不会太低,而且非常容易扩展成更高级的算法(比如Omnidirectional Shadow Maps和 Cascaded Shadow Maps)。
阴影映射
阴影映射原理
阴影映射背后的思路非常简单:我们以光的位置为视角进行渲染,我们能看到的东西都将被点亮,看不见的一定是在阴影之中了。假设有一个地板,在光源和它之间有一个大盒子。由于光源处向光线方向看去,可以看到这个盒子,但看不到地板的一部分,这部分就应该在阴阴影-阴影映射这里的所有蓝线代表光源可以看到的fragment。黑线代表被遮挡的fragment:它们应该渲染为带阴影的。如果我们绘制一条从光源出发,到达最右边盒子上的一个片元上的线段或射线,那么射线将先击中悬浮的盒子,随后才会到达最右侧的盒子。结果就是悬浮的盒子被照亮,而最右侧的盒子将处于阴影之中。我们希望得到射线第一次击中的那个物体,然后用这个最近点和射线上其他点进行对比。然后我们将测试一下看看射线上的其他点是否比最近点更远,如果是的话,这个点就在阴影中。对从光源发出的射线上的成千上万个点进行遍历是个极端消耗性能的举措,实时渲染上基本不可取。我们可以采取相似举措,不用投射出光的射线。我们所使用的是非常熟悉的东西:深度缓冲。
图2
在深度缓冲里的一个值是摄像机视角下,对应于一个片元的一个0到1之间的深度值。如果我们从光源的透视图来渲染场景,并把深度值的结果储存到纹理中会怎样?通过这种方式,我们就能对光源的透视图所见的最近的深度值进行采样。最终,深度值就会显示从光源的透视图下见到的第一个片元了。我们管储存在纹理中的所有这些深度值,叫做深度贴图(depth map)或阴影贴图。
左侧的图片展示了一个定向光源(所有光线都是平行的)在立方体下的表面投射的阴影。通过储存到深度贴图中的深度值,我们就能找到最近点,用以决定片元是否在阴影中。我们使用一个来自光源的视图和投影矩阵来渲染场景就能创建一个深度贴图。这个投影和视图矩阵结合在一起成为一个T变换,它可以将任何三维位置转变到光源的可见坐标空间。 在右边的图中我们显示出同样的平行光和观察者。我们渲染一个点P处的片元,需要决定它是否在阴影中。我们先得使用T把P变换到光源的坐标空间里。既然点P是从光的透视图中看到的,它的z坐标就对应于它的深度,例子中这个值是0.9。使用点P在光源的坐标空间的坐标,我们可以索引深度贴图,来获得从光的视角中最近的可见深度,结果是点C,最近的深度是0.4。因为索引深度贴图的结果是一个小于点P的深度,我们可以断定P被挡住了,它在阴影中了。定向光并没有位置,因为它被规定为无穷远。然而,为了实现阴影贴图,我们得从一个光的透视图渲染场景,这样就得在光的方向的某一点上渲染场景。深度映射由两个步骤组成:首先,我们渲染深度贴图,然后我们像往常一样渲染场景,使用生成的深度贴图来计算片元是否在阴影之中。听起来有点复杂,但随着我们一步一步地讲解这个技术,就能理解了。
图3
二、使用步骤
我们学会了如何为3D 场景添加光照。但是,我们并没有真的添加光线,而是模拟光照在物体上的效果——使用ADS 模型——并相应地调整这些物体的绘制方式。当我们用这种方法照亮同一个场景中的多个物体时,它的局限性就体现出来了。考虑图4所示的场景,其中包含了砖块纹理环面以及地平面(地平面是一个巨大立方体的顶部,使用了来自[LU16]的草地纹理)。一眼望去我们的场景好像没问题。但是,仔细观察会发现有什么重要的东西没有出现。具体来说,就是我们没有办法分辨出环面距离它下方纹理立方体的距离。环面究竟是浮在立方体上面呢,还是放置在立方体顶部呢?我们无法回答这个问题的原因正是因为场景中缺乏阴影。我们期望看到阴影,因为大脑需要通过阴影,才能针对我们所看到的物体以及他们的位置关系构建完整的心理模型。考虑图8.2 所示的同样的场景,不过添加了阴影。现在就很明显了,左图中环面放在地平面上;而右图中,环面则浮于其上。
图4
图5
显示效果
源码下载
源码下载地址
参考
1.《LearnOpengl CN》
2. 《计算机图形学编程 使用OpenGL和C++》
openGL实现阴影映射(Shadow Mapping)相关推荐
- 计算机图形学【GAMES-101】6、阴影映射(Shadow Mapping)
快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...
- 阴影(shadow mapping)(硬阴影)
着色是一种局部现象,只考虑着色点自己.光源.摄像机,如果我要算出它的着色,完全不考虑其它物体,甚至自己的其它部分对这个着色点的影响.而事实上如果有其它物体挡在 shading poin ...
- 【Shading】Shadow Mapping 阴影映射
课程来源:GAMES101-现代计算机图形学入门-闫令琪 Lecture12 GAMES101 现代计算机图形学入门 主讲老师:闫令琪,UCSB 课程主页:https://sites.cs.ucsb. ...
- 阴影映射(Shadow Map)的研究(三)
阴影映射(Shadow Map)的研究(三) 最近为了自己制作的项目可是吃了不少苦头,这其中关键的一点就是想要实现阴影映射(Shadow Map).为了实现目标,我参考了网络上很多相关的资料,也看了一 ...
- 【GAMES-202实时渲染】1、软阴影01(Shadow Mapping、Peter Panning、PCSS原理超详细)
Lecture3 Real-Time shadows1 1 Shadow Mapping回顾 2 Shadow Mapping缺点及解决方案 2.1 自遮挡现象 解决方案1 定义一个bias 解决方案 ...
- 【Unity Shader】Unity中阴影映射标准制作流程
前半部分的基于图片的实时阴影技术是百人计划的前半部分总结,后面的Unity中的实现过程是<入门精要>中的实现. 1 基于图片的实时阴影技术 这里的"基于图片"指阴影生成 ...
- [转载] [OpenGL] shadow mapping(实时阴影映射)
参考链接: Java中静态函数的阴影(方法隐藏) 转载原创:ZJU_fish1996 http://blog.csdn.net/zju_fish1996/article/details/51932 ...
- [OpenGL] shadow mapping(实时阴影映射)
source:原文地址 code:点击可以直接下载源代码 1978年,Lance Williams在其发表的论文<Casting curved shadows on curved surface ...
- OpenGL shadow mapping 阴影贴图的实例
OpenGL shadow mapping 阴影贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #i ...
最新文章
- wifi信号桥怎么设置_iPhone信号差怎么办?这样设置,信号满分,网速如飞
- 《Nature》发布毫米级软体机器人,可在没有任何物理干预情况下游走于人体
- element ui封装 tree下拉框
- posix thread线程
- 【youcans 的 OpenCV 例程 200 篇】104. 运动模糊退化模型
- java流对象_Java对象流的使用
- ATL中建立消息窗口
- 数组存放字符_字符串的 3种表示方法,不会用不是合格的程序员
- windows 11屏幕保护程序配置教程——设置无效解决方案
- 安装MongoDB出现Verify that you have sufficient privileges to start system services 十秒解决方案
- web前端期末大作业:旅游网页主题网站设计——桂林旅游网站的设计 (7页)HTML+CSS+JavaScript web网页设计与开发 静态网页的制作 web期末作业设计网页 web结课作业的源
- Python办公自动化 | Task 01 文件自动化处理邮件批量处理
- Android通过浏览器打开App并传递参数
- SCI (SSCI) 投稿全过程信件模板一览(Cover letter,催稿信,修改稿及回复,感谢信,询问校稿及校稿信) (转)
- Dom对象和java
- 小白如何在window电脑上安装Linux系统(虚拟机)超详细
- 使用ULIB+Altium Designer绘制元件原理图及封装
- Python环境配置与数据处理
- DropDownList ListBox GridView DataList Repeater FormView DetailsView 数据绑定控件详解
- 人的寿命和什么有关系?