位置: 编程技术 - 正文
推荐整理分享OpenGL阴影贴图详解(opengl消隐),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:opengl绘图背景透明,opengl 加载模型 贴图,opengl3d贴图,opengl2.1光影,opengl3d贴图,opengl 加载模型 贴图,opengl3d贴图,opengl背景贴图,内容如对您有帮助,希望把文章链接给更多的朋友!
既然模拟出了光照,那么也少不了阴影,阴影的产生是因为距离光线较近的物体遮挡了距离较远的物体,导致被遮挡的物体接受的光照少于遮挡物的,因此阴影的产生与否与物体到光源的位置有关系,静态物体的阴影可以用光照贴图来模拟,而动态阴影要用阴影锥或者阴影贴图实现,阴影锥会引入许多额外的顶点为管线带来负担,目前比较流行的阴影模拟方法是用阴影贴图,它的好处在于只是用纹理存储物体的深度信息而并不会引入额外顶点.
要实现阴影贴图有以下几个步骤:
首先开辟一块纹理缓存以便之后保存世界的深度信息:
我这边开了两张深度纹理shadowMapTextureLeft与shadowMapTextureRight.
然后新建渲染目标对象fbo,fbo类于帧缓冲区,只不过把渲染的片段保存于其他的缓存而不是屏幕上的帧缓冲区:
这边的glDrawBuffer(GL_NONE);与glReadBuffer(GL_NONE);是为了屏蔽颜色的输入输出,因为这个fbo用于写入深度信息.
缓冲区准备工作完成.
接着设置光源:
然后设置渲染阴影贴图的投影矩阵:
这边我用的是方向光源,所以设置的平行投影.
然后设置渲染阴影贴图的视图矩阵,将视点放在光源位置,将方向定位光向量:
好了,现在准备工作都完成了,开始渲染阴影贴图:
给fbo挂上深度纹理,接下来渲染的内容都将保存到深度纹理当中,把遮挡物的正面剔除,因为遮挡物反面也会产生正确的阴影.
然后还原渲染目标,清除一下帧缓冲区内容
接着进行一遍普通渲染,重置投影与视图矩阵:
传入深度纹理进行一次普通渲染:
普通渲染的时候使用阴影贴图比较着色器,进行阴影渲染.
有一点要说明一下,阴影贴图中的片段深度信息都是在纹理坐标系内的点,那么进行正常渲染的时候我们传入渲染阴影贴图时候用的视图矩阵与投影矩阵,然后进行以下变换:
模型空间->世界空间->阴影视图空间->阴影投影空间->规范化设备空间->阴影贴图纹理空间
那么接下来向着色器传递以下矩阵:
所以顶点着色器可以这么写:
然后在片段着色器当中将传入的shadowVertLeft和shadowVertRight都除以它们的w坐标就能得到正常渲染的片元在阴影贴图坐标系内的坐标了,之后把这个坐标的深度(也就是z)与阴影贴图内的深度用shadow2D做比较,这边我偷了个懒,用shadow2DProj做,使用proj函数可以实现齐次除法,也就是顶点除以w.
片段着色器这么写:
片段的z坐标要加上一个偏移量,原因如图所示:
最后返回的factor即为阴影,把它与环境颜色相乘就能够输出片段了.
最终效果如下:
还能够在渲染阴影贴图的那一步使用着色器对深度纹理进行过滤产生半影区,这边我使用了pcf法对阴影进行处理.
codeblocks配置GLUT 原文地址:
SDL2源代码分析7:显示(SDL_RenderPresent()) =====================================================SDL源代码分析系列文章列表:SDL2源代码分析1:初始化(SDL_Init())SDL2源代码分析2:窗口(SDL_Window)SDL2源代码
在Xcode中使用GLUT开发OpenGL应用程序 Xcode是MacOSX中自带的开发环境。GLUT提供了跨越平台的OpenGL实用工具。本文讲述如何在Xcode3.2中使用GLUT来开发OpenGL应用程序。在Xcode的启动面板中,选Create
标签: opengl消隐
本文链接地址:https://www.jiuchutong.com/biancheng/373124.html 转载请保留说明!上一篇:学习Nehe Lesson2 && Lesson3(学习雷锋好榜样)
下一篇:codeblocks配置GLUT(codeblocks配置文件在哪)
友情链接: 武汉网站建设