Directx 9中shadowmap 的解析

 

1.  ShadowMap原理

   首先准备一张纹理贴图,和一个深度模版。

准备深度模版的作用是为了进行深度测试,使得纹理贴图只用记录每个像素深度最小的值。

1.将世界坐标系下的顶点转换到光源视点下,再投影,最后渲染一遍场景,得到一张带深度缓冲区的纹理贴图(以纹理贴图为渲染目标),但是纹理贴图中的记录的不是颜色值,而是深度值,由于使用了深度测试模版所以该贴图里得到的深度值是每个像素点的最小深度值(即最接近光源的深度值)此时得到了shadowmap

2:将相机视点下的顶点转换到光源视点下投影,逐像素的用当前像素的深度值与纹理贴图中对应的像素点进行比较深度值(把投影后的x,y坐标计算u,v坐标 便可找到对应的点),来判断是否会产生阴影。最后在视点下绘制

2.  例子分析:

 在OnCreateDevice() 函数中建立.fx文件与应用程序之间的关联,g_pEffect是指向该效果的指针

OnResetDevice()中创建阴影图所需要的纹理贴图以及深度模版,并设定深度模版的行为是自动处理深度模版测试

OnFrameRender()中将我们创建的g_pShadowMap作为渲染目标,g_pDSShadow作为深度模版,并保留原来的渲染目标与深度模版

下面开始分析OnFrameRender()中的代码

  

g-bFreeLight是用来判断当前的光源是否为自由光(在例子有2个光源,一个是自由光 一个是汽车的车头灯)。如果g_bFreeLighttrue 那么就把光源相机的视点矩阵赋值给mLightView; g_LCamera是一个放在光源处的模拟相机(生成阴影图需要以光源处的视野来做投影,也就相当于将相机放在光源位置,朝着光源的照射方向)。

如果bFreeLightflase则将汽车的世界矩阵传递给mLightView,把汽车的位置传递给vPos,方向传递给vDir(这个方向是在局部坐标系下的 汽车的朝向)mLightView的第4个分量设置为是由于vDirw分量是1,但是vDir是向量 所以为了保证Transform()的正确性 将其设为0

我们利用处理过的mLightView变换Dir,使其变成在世界坐标系下的汽车朝向。

在这里将vDir.w=0.0f, 是为了保证下面的单位化向量的正确性,因为将w置为0之后,Dir其实被变成了一个三维空间的点.(x,yz,0)单位化以后 是和(x,y,z)一样的。

我们将使用VPosVDir 作为D3DXMatrixLookAtLH()中的相机位置 和 相机观察点 这2个参数。

但是此时的vPosVDir还无法直接传进去,因为此时vPos只是 汽车的位置,而不是车头灯光的位置,所以应该将vPos往车头方向移动一些。

vDir始终是在vPos的基础上 朝vDir的方向移动一些,这样保证了灯光与车的朝向一致

此时以车灯为视点的观察矩阵已经求好了,下面调用RenderScene()渲染场景(也就是绘制阴影图)

下面分析RenderScene()中的代码

RenderScene()中定义g_pEffect中的一些变量的值,然后调用了SetTechnique()使用不同的technique.绘制阴影图调用的techniquetechnique RenderShadow

vershadow中,首先将pos先转到世界坐标系再转换到光源视点的坐标系(g_mWorldView,再将其投影(g_mProj)

Depth记录z值。

在PixShadow中,用Depth.x/Depth.y也就是oPos.z/oPos.w.在渲染的过程中,由于我们启用了自动的深度模版测试,所以每个像素的z值都是该像素的最小z.

至此 已经拥有了一张阴影图g_pShadowMap

继续回到OnFrameRender();

下面进行第二次渲染首先将原来的渲染目标和深度模版都替换回去

 

g_bCameraPerspectivetrue时,从相机视角的坐标系下渲染场景,为false时,从光源视角下的坐标系渲染场景,并且把我们刚才得到的shadowmapfx文件里的g_txShadow进行关联

mViewToLightProj 首先是将pmview求逆, (得确保这个定点在世界坐标系下)再换到光源视点坐标下下,再进行投影的变换矩阵,设置完g_mViewToLightProj之后  再调用了一次RenderScene();

与上一次调用相比,参数二变成了false ,参数四由光源视点矩阵,变成了pmView(pmView有可能是mLightView 也有可能是正常相机的视点),参数五由光源的投影矩阵变成了正常相机的投影矩阵

在RenderScene()中,调用了g_pEffect->SetTechnique( "RenderScene" )

这个technique包含2个渲染器VertScene()PixScene()

Mul(iPos,g_mWorldView) 是将顶点转换到世界坐标系下,再转换到pmView表示坐标系下.

Mul(vPos,g_mProj) 投影

Mul(iNormal,(float3x3)g_mWorldView);将法线转换到世界坐标系下,再转换到pmView表示坐标系下.

Text = iTex 复制纹理

vPosLiht = mul(vPos,g_mViewToLightProj) 首先会将vPos转换到世界坐标系下(因为取反了pmView)再转换到光源的视野坐标系,再投影.

vLight是 点到光源向量的单位向量

Dot(vLight,g_vLightDir)cos(点到光源的向量与光源的方向向量的夹角).

如果这个值大于g_fCosTheta(是光源的角度的一半)则说明在灯光中。ShadwoTexC是纹理贴图坐标,通过这个坐标可以从我们绘制好的阴影图中采样

float2 ShadowTexC = 0.5 * vPosLight.xy / vPosLight.w + float2( 0.5, 0.5 );这一步将在投影空间下的坐标变成0~1的范围

 ShadowTexC.y = 1.0f - ShadowTexC.y; 由于在贴图空间内,坐标轴y是向下的,与投影坐标系内正好相反,所以要把投影坐标系里的y值反向。到此ShadowTexC已经变成了贴图空间的坐标.

 

Texelpos是纹理空间中对应的像素坐标,lerpsTexelpos的小数部分。屏幕中的像素点是不存在小数的,所以在这里产生了一个误差,无法找到正确的深度值做为对比对象

例子中使用了2X2插值的办法来弥补这个误差,取临近4个点,做差值,得到LightAmount,用这个LightAmount来控制光线。

Diffuse由漫反射光和环境光组成,其中漫反射光为 saturate( dot( -vLight, normalize( vNormal ) ) ) * LightAmount *( 1 - g_vLightAmbient ).

( 1 - g_vLightAmbient ).为光源的亮度,dot( -vLight, normalize( vNormal ) ) 计算的是光源视点下的顶点法线与点到光源的单位向量的夹角。

如果该像素不在灯光的照射中,那么Diffuse就是环境光*材质,之后返回纹理*Diffuse

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DirectX 9 SDK安装包是用于开发DirectX 9应用程序和游戏的软件开发工具包。它包含了一系列的库、工具和文档,可以帮助开发人员创建基于DirectX 9技术的应用程序。 DirectX是一套由微软公司开发的多媒体编程接口,它提供了一系列的功能,包括图形渲染、音频处理、输入设备管理等。DirectX 9是DirectX的一个版本,它于2002年发布,具有广泛的兼容性和功能。 SDK安装包包含了一些重要的组件,比如Direct3D、DirectSound、DirectInput等。Direct3D是用于3D图形渲染的组件,它支持各种渲染效果和技术。DirectSound用于音频处理,可以实现3D音效和音乐播放等功能。DirectInput则用于处理输入设备,比如键盘、鼠标和游戏手柄等。 使用DirectX 9 SDK安装包,开发人员可以利用其提供的库和工具,快速开发出高性能的DirectX 9应用程序和游戏。它提供了丰富的文档和示例代码,帮助开发人员了解和学习DirectX 9的使用方法和技术。此外,SDK还提供一些辅助工具,比如调试器和性能分析器,方便开发人员进行代码调试和性能优化。 总之,DirectX 9 SDK安装包是一款强大的软件开发工具包,适用于开发DirectX 9应用程序和游戏。它提供了丰富的功能和工具,帮助开发人员快速开发出高性能、丰富多彩的应用程序。 ### 回答2: DirectX 9 SDK是一个用于开发游戏和多媒体应用程序的软件开发工具包。它提供了一系列的工具和资源,帮助开发者创建与DirectX 9兼容的应用程序。 安装DirectX 9 SDK需要以下几个步骤: 首先,下载DirectX 9 SDK安装包。可以从Microsoft官方网站或其他可靠的软件下载网站获取最新的安装包。确保选择适合自己操作系统的版本。 然后,双击下载的安装包进行安装。安装程序会打开一个向导,根据提示逐步进行安装。可以选择安装目录和其他选项,也可以接受默认设置直接点击下一步。 安装过程可能会提示安装一些必要的系统组件,如.NET Framework等。按照提示同意安装这些组件,以确保DirectX 9 SDK正常工作。 安装完成后,可以在开始菜单找到DirectX 9 SDK的相关工具和示例程序。这些工具包括DirectX 9的开发文档、开发工具、示例代码等,可以帮助开发者更好地理解和使用DirectX 9。 值得注意的是,DirectX 9 SDK已不再接受更新和支持,因此它可能不适用于最新的操作系统和硬件。如果需要开发DirectX应用程序,建议使用更新的DirectX版本或其他替代工具包。 总之,安装DirectX 9 SDK是一个相对简单的过程,只需下载安装包,按照安装向导进行操作即可。安装后,开发者可以使用DirectX 9 SDK提供的工具和资源进行游戏和多媒体应用程序的开发。 ### 回答3: DirectX 9 SDK 是微软开发的一个软件开发工具包,用于帮助开发者创建游戏、多媒体应用程序和图形应用程序。它包含了一系列的API(应用程序接口),用于处理图形、声音、输入设备和网络通信等问题。 安装DirectX 9 SDK 时,首先需要下载安装包。安装包一般提供在微软官方网站上,可以通过搜索引擎查找到官方下载链接。 下载完成后,双击安装包进行安装。安装过程,用户需要同意软件许可协议,并选择安装路径。 安装完成后,可以在安装路径找到 DirectX 9 SDK 的安装目录。在该目录下,可以找到一些开发工具、示例代码和文档等资源。 开发者可以利用这些资源来学习和开发相关应用程序。例如,他们可以使用示例代码作为参考来编写自己的程序,或者阅读文档了解API的使用方法和功能。 DirectX 9 SDK 还提供了一些工具来测试和调试应用程序。开发者可以使用这些工具来检测和修复错误,以确保应用程序的稳定运行。 总之,DirectX 9 SDK 是一个强大的开发工具包,可以帮助开发者创建高性能的游戏、多媒体和图形应用程序。通过安装和使用这个SDK,开发者可以更加方便地进行应用程序的开发和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值