阴影映射(Shadow Map)的研究(二)

阴影映射(Shadow Map)的研究(二)

上一篇文章介绍了我对Z缓存的较为详细的研究。这里之所以对Ze求导函数,是因为的我们需要寻找它的变化曲线,从而找到极值点,这样就能够确定Ze相对于zw的疏密分布情况。幸运的是,我们找到的导函数是双曲函数,并且我们关心的的右侧是单调递增的。

蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/44946763。欢迎同行前来探讨。

引出上一篇文章的结论,当

时,导函数取得最大值。但是在Zw∈[0,2n-1]上导函数是单调递增的,原函数Ze在Zw∈[0,2n-1]上是单调递减的。这就导致了16、24或者32位的深度数据用了很大一部分的范围来区分视角空间近处很小一部分的Z值,远处的Z值只用很小一部分的数据范围来区分,所以越是远处的数据,就越容易造成z-fighting。那么我想将尽量让远一些的地方分配较大范围的Z值该怎么办呢?

根据导函数和原函数在上篇文章得出来的解析式以及图像,我们需要让相同的[0,Ze]用更丰富的[0,zw]来表示,那么就需要将函数的图像向右平移。如下图所示:

于是我们要将极值点(不可导)

向右平移。通过设定:

解不等式,最后得到

不等式右边是一个常量,那么要求左边near尽量大或者far尽量小或者二者兼施,这样才能保证更多的精度用于更远的摄像机空间位置。

我们产生的阴影映射要避免精度过低,或者z-fighting现象,需要光照和摄像机空间的near和far需要遵守上面的规律。这里我拿我的例子程序来作对比:

可以看到,近远裁面的正确设置对减少z-fighting起到的作用是非常显著的。

时间: 2024-10-23 12:38:44

阴影映射(Shadow Map)的研究(二)的相关文章

阴影映射(Shadow Map)的研究(三)

阴影映射(Shadow Map)的研究(三) 最近为了自己制作的项目可是吃了不少苦头,这其中关键的一点就是想要实现阴影映射(Shadow Map).为了实现目标,我参考了网络上很多相关的资料,也看了一些案例,最终花了我一个月的时间将这个效果实现了. 阴影映射这样的效果,其实在即将发布的Qt 3D中已经有相关的介绍,KDAB中有一篇文章<Shadow Mappingin Qt3D 2.0>就在Qt 3D的框架上实现了阴影映射.不过当时这个效果是假定目标机器支持OpenGL 3.0规范的,目前大部

阴影映射(Shadow Map)的研究(四)

阴影映射(Shadow Map)的研究(四) 上一篇文章粗略地介绍了要实现OpenGL ES 2.0的阴影映射所需的知识难点,现在简略地说明一下:1.FBO:2.着色器:3.float的分拆以及组合.上篇文章虽然说已经成功地移植了来自Java编写的Android下阴影映射的效果,但这边采用的很大程度上是OpenGL原生代码编写的内容,接下来的目标是采用自Qt 5起就逐渐采用的Qt对OpenGL的封装类,用面向对象的思维来处理OpenGL对象,这样让代码更加优雅. 1.FBO 首先说一下FBO.在

阴影映射(Shadow Map)的研究(五)

阴影映射(Shadow Map)的研究(五) 我成功地将别人的例子加以改进,使用QOpenGLWidget作为渲染窗口,将阴影映射渲染了出来.目前可以确定的是,使用OpenGL ES 2.0作为渲染的接口要求,能够让目前绝大多数机器都能够顺利兼容,但是囿于渲染窗口,可能在某些平台上表现不好.如果移植到Qt Quick 2,这样能够支持的平台就更多了.现在我将这些接口统统使用Qt的方式实现了,移植到Qt Quick 2也很简单. 这里主要参考的是OpenGLUnderQML这个例子,自定义了一个Q

阴影映射(Shadow Map)的研究(六)

阴影映射(Shadow Map)的研究(六) 成功地将阴影映射与Qt Quick 2整合之后,接下来可以将阴影映射的效果变得更漂亮一些.如果你成功地运行过我制作的演示程序,那么就会发现,阴影映射的效果并不是那么理想,可能有噪点(粉刺)的出现.这个是和阴影的产生相关,主要还是由于阴影映射这个算法它要求产生的阴影精度是有限的.很多改进的算法都是围绕着如何让阴影更加自然进行研究的.这里我也尝试模仿了一个稍微简单的算法:PCF算法. PCF算法的理念也比较简单,简言之就是让产生的阴影更加模糊.它主要在阴

Shadow Map阴影贴图技术之探 【转】

这两天勉勉强强把一个shadowmap的demo做出来了.参考资料多,苦头可不少.Shadow Map技术是目前与Shadow Volume技术并行的传统阴影渲染技术,而且在游戏领域可谓占很大优势.本篇是第一辑.——ZwqXin.comShadow Map的原理很简单,但是实现起来到处是雷.当然这只是我的体会.恩,不过就是“从光源处看场景,那些看不见的区域全部都该是阴影”.很容易看出,与针对 特定模型的Shadow Volume不同,Shadow Map是针对场景的.这就是说,对一个光源应用一次

[OpenGL] shadow mapping(实时阴影映射)

source:原文地址 code:点击可以直接下载源代码 1978年,Lance Williams在其发表的论文<Casting curved shadows on curved surfaces>中提出了Shadow mapping算法,从那以后,该算法在离线渲染和实时渲染两个领域都得到了广泛的应用.皮尔斯动画工作室的Renderman渲染器.以及一些知名电影如<玩具总动员>都使用了shadow mapping技术. 在众多图形应用的阴影技术中,shadow mapping只是产

Shadow Map阴影贴图技术之探

这两天勉勉强强把一个shadowmap的demo做出来了.参考资料多,苦头可不少.Shadow Map技术是目前与Shadow Volume技术并行的传统阴影渲染技术,而且在游戏领域可谓占很大优势.本篇是第一辑.--ZwqXin.comShadow Map的原理很简单,但是实现起来到处是雷.当然这只是我的体会.恩,不过就是"从光源处看场景,那些看不见的区域全部都该是阴影".很容易看出,与针对特定模型的Shadow Volume不同,Shadow Map是针对场景的.这就是说,对一个光源

OpenGL 阴影之Shadow Mapping和Shadow Volumes

先说下开发环境.VS2013,C++空项目,引用glut,glew.glut包含基本窗口操作,免去我们自己新建win32窗口一些操作.glew使我们能使用最新opengl的API,因winodw本身只包含opengl 1.1版本的API,根本是不能用的. 其中矩阵计算采用gitHub项目openvr中的三份文件, Vectors.h ,Matrices.h, Matrices.cpp,分别是矢量与点类,矩阵类,我们需要的一些操作,矢量的叉乘和点乘,矩阵转置,矩阵的逆,矩阵与矢量相剩等. 这里主要

Shadow Map 实现极其细节

这里不介绍算法原理,只说说在实现过程中遇到的问题,以及背后的原因.开发环境:opengl 2.0  glsl 1.0. 第一个问题:产生深度纹理. 在opengl中每一次离屏渲染需要向opengl提供一个renderframe,一个renderframe包含一个texture和一个renderbuffer.texture是一个存储特定数据的内存区,可以存储颜色,深度以及模版.renderbuffer目前不太清楚. 具体代码如下: glGenFramebuffers(1, &frameBuff)