ShadowMap DX9

 ShadowMap基本的思想很简单,首先从聚光灯角度对场景建立并保存场景深度。然后在正常渲染场景中,比较每个渲染点到灯的距离值(或者说到灯的深度值)是否比对应的已经建立在场景深度中的值要大,也就是说要远,如果远证明从当前视点观察的此点在灯角度中看不见,所以该渲染点处于阴影中,否则,不然。

 

首先分析一下ShadowMap的优劣:

优点:
ShadowMap只适合较近距离的阴影投射,由于32位浮点数的精度有限,所以在较远距离下,会将在阴影边界附近出现错误现象。一种是隐隐约约的阴影(即阴影中带有很多亮斑)。一种是阴影偏移并缩小。上述是比较严峻的劣势,另外的一些就是常说的锯齿,这些还算可以忍受。一般可以采用多重采样要减轻这个状况。再就是如果要使用点光源的话,需要都整个场景建立深度值,这样就需要立方体纹理,也就是CubeMapping。

缺点:
虽然有如此多的缺点,但其优点确也是很值得关注的。在近景下十分不错,而且ShadowMap的资源需求小,仅仅一张纹理。特别是其不会随着场景复杂而附加计算负担这点。能给恒定帧率提供保证。

 

在ShadowMap中给我纠正的一个最大误解就是,如何计算场景物体的点到灯的距离。不是我原本想想的那样,在ps(Pixel Shader)中一个一个的求平方再开平方根求距离(其实这根本就是错的,因为我们用的是深度值,并不是距离)。而是采用和建立的ShadowMap一样的方法,就是将场景变换到灯的投影空间,然后用z处于w,得到范围在0-1的z值也就是深度值。具体后面会提到。

 

ShadowMap案例中的大体思想知道后,欠缺的仅仅是一些编程接口的了解和使用。由于程序思路很清晰就不说程序的逻辑过程的!(不过看DX9对应的sample中代码,觉得不够条理,这个MS的员工写代码的时候可能在打盹) 

 

还是主要谈一下经验和重点,基本上也是编程中遇到的需要注意的地方。

 

个人经验:

ShadowMap中的阴影纹理啊
通过重新编写sample,我获得如下经验:

  1. 在阴影纹理创建中特别需要注意的是,包含阴影纹理的表面不能采用mip链。因为我们只需要一个表面,不需要那些mip链中的小表面。如果采用mip链后果将是很可怕的。因为采用后就会就导致使用mip链进行过滤得出深度值。而经过过滤的深度值是没有意义的。其实我查这个bug,查了5个小时,最后才发现是创建纹理时错误地把0传递给参数mipLeve,而0给mipLeve将会给表面创建mip链。而这是完全多余和错误的。
  2. 添加判断的偏移量是必须的,因为float的误差,添加很小的量给建立的场景缓存是需要的,这样最大程度减轻一个错误症状,它就是把不在阴影区错误的弄成阴影区的症状。
  3. 设置给灯的投影矩阵必须采用宽高比为1的矩阵,因为一般阴影纹理都采用正方形纹理。(此点后来证明不必要,只要第四点满足就可以)
  4. 两次建立的灯投影矩阵必须一样。这两次分别是给场景建立深度值是采用的矩阵,另一个是在正常渲染中,为了得到渲染点相对于灯的深度值所采用的灯的投影矩阵。特别是建立两次矩阵是采用的的近裁截面和远裁截面必须一致,否则两次得到的深度值之间没有可比性,因为投影空间中渲染点的深度值是通过用近裁截面和远裁截面之间的距离压缩得来的的。
  5. 投影空间中,x,y的范围是(-1~1),需要将其投射都纹理空间(0~1)并且需要注意纹理空间和投影空间y的反向。

其实上面提到的投影矩阵应该说是灯的是视矩阵和灯的投影矩阵的乘积。单独说投影矩阵只是为了不累赘。

另外一些知识点:

创建ShadowMap纹理时,采用F32的浮点数据类型,对应的格式是D3DFMT_R32,用D3DFMT_R32是将4字节解读为单独的红色通道,并且是浮点数表示的。虽然在ps中需要返回的颜色变量还是float4,但是只需要指定其x分量即可。同样在tex2D中我们也只需要查看其中的x分量就可以。

 

很开心!

时间: 2024-08-05 05:47:51

ShadowMap DX9的相关文章

vc6 0-请教一下安装了DX9,VC6.0不显示函数的问题

问题描述 请教一下安装了DX9,VC6.0不显示函数的问题 请教一下各位大神,我在电脑上安装了DX9 sdk之后,在目录中把include和lib都包含进去了,但是在写的过程中像打"lpD3DDevice->"后没有显示函数的列表,也没有参数提示,这是声明的"LPDIRECT3DDEVICE9"的. 但是声明的"LPDIRECT3DDEVICE"设备后,"lpD3DDevice->"就有函数显示了. 请问一下怎么让

错误信息-编译DX9程序出现奇怪的错误,请大牛帮忙解决,谢谢

问题描述 编译DX9程序出现奇怪的错误,请大牛帮忙解决,谢谢 1>g:directx 2007included3dx9math.h(787) : error C2143: syntax error : missing ',' before '*' 1>g:directx 2007included3dx9math.h(792) : error C2143: syntax error : missing ',' before '*' 1>g:directx 2007included3dx9m

ParallaxOcclusionMapping( POM ) DX9

ParallaxOcclusionMapping(后面成为POM)是一个不错的高级技术,在我看来它是至今让我印象最深刻的技术.与其说是视差,不如说准确的视线与高度图交点算法.在<Real-time Rendering>中也见过他的前身-ParallaxMapping,但是POM的精确度更高,对于斜视效果也很不错,这将让它在未来的重要技术中占有一席之地.闲话少说,还是重在实质技术.   在DX9的samples中,由ATI提高的POM案例,确实是一个不错的实践机会.看过2006的Dynamic

opengl-OpenGL编程指南第八版 例子04 shadowmap,运行错误

问题描述 OpenGL编程指南第八版 例子04 shadowmap,运行错误 下载了opengl第八版官方的demo,shadowmap那个不能运行. 刚开始发现是加载模型的问题,所以我把模型替换成了简单的球,但是结果是错误的. 对比书上原文,找到fragment shader中错误部分并改成和书上一样,结果还是错误的. 有没有大神运行除了正确结果,求助啊!!

HDRPipeline DX9

 HDR这个词汇在我看过的书或资料中多次出现,从<Real-time Rendering>到SDK里面的偶尔出现,一直对其是一种莫名的感觉,HDR是什么,High Dynamic Range,范围很广,为什么要HDR呢?因为了更好的画面.这些很浅显的认识让我一直云里雾里.终于在DX9的sample中有这么个简单的HDR教学实例,确实让我了解很多.在网上看到3d本身渲染的未经过HDR处理的图片和经过HDR处理过的图片比较起来,HDR所带来的图片确实让我折服.因为HDR处理后的图片让人感到身临其境

ShadowVolume DX9

 之前写过ShadowVolume,但是那是老版本(DX8)的DXSDK中的sample.而老版本并不是一个很好的解决方案.而DX9中的ShadowVolume还算是比较可取的方案.在这里主要对DX9中的ShadowVolume中的重点难点进行梳理.详细的细节,必须参考sample中的代码.   DX9中的shadowVolume最大的特点是建立了阴影体网格,而不是之前DX8中的动态生成轮廓边集合.建立阴影体网格最大的好处就是通过GPU来分担原来由CPU负责的轮廓边识别.而且由于新的阴影体积总体

DX9.0与opengl2.0的转换

问题描述 用DX9.0及HLSL写的地形渲染算法对应转换为opengl2.0来实现,有没有高手从事过相关方面的开发经验或相关资料,望不吝赐教... 解决方案 解决方案二:求解啊....解决方案三:使用ANGLE,你可以搜索ANGLE项目.

SkinnedMesh DX9

本想学习PRT技术,但是觉得这个技术太高级,而且就中国现在的技术来看,还未到这个程度.但是PRT技术一定要学,一定要掌握,才能不致于落后国际水平太多.这几天学习了一下骨骼动画.以前记得参加齐鲁软件大赛的时候,用Ogre很简单的就实现了骨骼动画.现在终于可以自己在DX基础上亲手完成这个3d游戏中最重要的技术.   骨骼动画中有许多我们需要注意的.简单屡一下骨骼动画中需要知道的基本知识点. 首先我们需要一个骨架.这些骨架中的骨骼有父子关系,有兄弟关系.父关节的运动是会带动子关节的.就像我们的上臂动会

MultiAnim DX9

这个案例比SkinnedMesh多的我觉得只是与骨骼动画更多的接口的认识.   MultiAnim主要的知识是: 在D3D中,一个动画控制接口有多个轨道,每个轨道上都独立的控制.我们可以控制轨道是否启用,速度,权重,优先级别.然后同个优先级别的每个轨道的动画会按对应的权重进行混合,最后不同优先级别再度混合.   这种独立有条理的结构同时也可以实现一个动画平滑过渡到另一个动画.   这些在我上传的d3dx_skinnedmesh.pdf都提及到了,而且系统全面.这里只总结MultiAnim中给我更