DirectX 11 学习笔记-Part2-4【Cubemap/贴图置换/阴影/屏幕空间环境光遮蔽】【原理篇】

本文深入探讨DirectX 11中的Cubemap技术,包括环境贴图、动态Cubemap和模拟反射。同时讲解了法线贴图、贴图置换、Shadow Mapping及其PCF过滤。此外,还介绍了环境光遮罩的原理,包括屏幕空间环境光遮罩的实现和优化方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码已上传至GitHub,这部分对应的项目为NormalDisplacementSsao。运行项目时可以使用数字键1-3切换渲染的shader,另外按下z键可以看到SSAO生成的遮罩贴图。

这部分内容较多,所以以介绍原理为主。另外在阅读源码时,为了剔除枝干让整体的代码更加一目了然,我用了模板和SFINAE(主要在SceneObject.h),如果看不懂的话也没有关系,不重要,关键是了解这些技术的主要流程。

首先我会对每个技术的原理做简要介绍。如果有时间和心情的话会结合代码分析。

目录

Cubemap

定义

环境贴图

模拟反射

动态Cubemap

法线贴图

贴图置换

Shadow Mapping

渲染阴影贴图

阴影贴图采样

PCF Filtering

环境光遮罩

通过光线追踪估算周围闭塞程度

屏幕空间环境光遮罩

环境光遮罩纹理

遮罩程度的估测


Cubemap

这部分代码可以参看DemoCubeMap这个项目。

定义

Cube mapping 保存6个纹理,可以把它们具象化为一个立方体的六个面。立方体是轴对称的,每一个面都可以正好对应到空间坐标的一个轴方向(±X, ±Y, ±Z,),因此Direct3D提供了D3D11_TEXTURECUBE_FACE用于描述六个面

typedef enum D3D11_TEXTURECUBE_FACE
{
    D3D11_TEXTURECUBE_FACE_POSITIVE_X = 0,
    D3D11_TEXTURECUBE_FACE_NEGATIVE_X = 1,
    D3D11_TEXTURECUBE_FACE_POSITIVE_Y = 2,
    D3D11_TEXTURECUBE_FACE_NEGATIVE_Y = 3,
    D3D11_TEXTURECUBE_FACE_POSITIVE_Z = 4,
    D3D11_TEXTURECUBE_FACE_NEGATIVE_Z = 5
} D3D11_TEXTURECUBE_FACE;

与2D纹理不同,我们无法再通过一个2d纹理坐标来确定Cube mapping中的一个图素。我们需要定义一个3D的纹理坐标,定义上,它是一个从原点出发的方向向量,cube map和这个方向相交的点就是这个3d坐标对应的图素。之前讨论过的texture filtering同样适用于cube map。

在HLSL中,TextureCube 代表了一个Cubemap。

TextureCube gCubeMap;
SamplerState gTriLinearSam
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
…
// in pixel shader
float3 v = float3(x,y,z); // some lookup vector
float4 color = gCubeMap.Sample(gTriLinearSam, v);

环境贴图

Cubemap的主要应用之一是环境贴图,即天空盒。

首先我们创建好Cubemap纹理,然后我们需要一系列顶点组成一个球形。由于天空可以认为是非常远的,所以实际上球形的精度并不是很重要。

绘制时,始终认为Camera是原点,因此直接使用球体的本地坐标作为世界坐标来使用。

我们可以认为天空盒的位置是最远的像素,因此直接将w设置为1。但此时必须要修改深度测试时的测试函数,默认是Less,我们需要改为Less_Equal否则w=1的像素会被舍弃,天空盒就无法绘制出来了。

模拟反射

通过环境贴图可以模拟反射,将周围的环境显示在光滑的物体表面。

主要过程是通过眼睛的位置和物体表面的法线,确定反射的方向,根据方向对cube map进行采样,从而把反射出来的图象绘制在物体上。

动态Cubemap

游戏中有许多动态的物体,因此需要通过动态生成环境贴图来模拟反射。一个做法是在反射的物体位置,向周围六个方向,渲染出Cubemap的六个面,这样就能绘制出动态的环境贴图。

法线贴图

物体的表面不总是光滑的,但如果将物体表面的每一个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值