DirectX11游戏开发
文章平均质量分 69
DirectX是PC游戏开发的主流技术,DirectX11是DirectX当下的热门版本,意味着更高的特性性能,这让DirectX 11无形中新增了很多奇妙的潜力。本人将分享自己学到的DirectX11知识,与大家体会计算机实时渲染图形的魅力。
梦幻DUO
游戏开发爱好者
展开
-
DirectX11 使用Cube Mapping 立方体环境贴图实现天空、物体反射效果
这一章中,我们将学习使用立方体环境贴图(Cube Mapping)实现天空环境、模型反射效果。在《赛达尔传说:荒野之息》中,明朗或阴暗的天空都可以通过Cube Mapping来实现: (图为《赛达尔传说:荒野之息》游戏截图)一、使用Cube Map实现天空效果立方体环境贴图是一个数组纹理,用于模拟全包围的环境,类似带有6个面的正方体,因而称为 Cube Map。实际上打开dds文件后,只是一组原创 2017-08-20 18:29:06 · 6741 阅读 · 1 评论 -
DirectX11 Tessellation曲面细分实现动态增加模型细节
DirectX11新增了一个非常吸引人的新技术,就是曲面细分。曲面细分技术可以通过产生新的顶点模拟出更平滑的曲面。下图是《古墓丽影9中》没有开启曲面的效果,可以看到人物模型轮廓比较僵硬,这是因为原模型的三角形面数较低造成的: 开启了曲面细分后,看到人物模型轮廓已经相当平滑了,使得游戏画面更加真实: 那为什么不直接在原模型中增加模型面数呢? 原因有如下三点:动态LOD(levels of de原创 2017-08-14 15:40:45 · 5848 阅读 · 2 评论 -
DirectX11 使用Instancing技术提高重复模型的绘制效率
在游戏场景中,经常需要我们绘制大量相同的模型,比如英雄联盟中,战场上的小兵可以达到非常多的数量。(图为英雄联盟游戏截图)如果我们用以前的方法绘制,一个模型draw call一次,那么就会造成巨大的性能损耗。因为每次数据从内存传入显存都需要不少时间;而且每次draw call需要CPU和GPU进行周期同步,会导致CPU或GPU在等待;每次传入顶点数据后,都需要走一遍渲染管线,上下文也要进行切换等等。如原创 2017-08-17 11:37:57 · 4054 阅读 · 0 评论 -
DirectX11 使用计算着色器实现高斯模糊
高斯模糊,是一种使画面产生朦胧感的技术。在游戏中也可以可以经常看见使用高斯模糊的技术:(《赛达尔传说:荒野之息》中对游戏背景使用高斯模糊,就将我们的主角们与背景分离出来,形成了前景、背景两个层面)这节我们就来学习下如何使用DirectX11的计算着色器来实现高斯模糊。一、计算着色器(Compute Shader)如下图所示,计算着色器不属于渲染管线的一部分,但是计算着色器可以读写渲染管线。计算着色器原创 2017-08-13 22:43:34 · 3144 阅读 · 0 评论 -
DirectX11 使用几何着色器实现公告板效果
之前说过,可编程的着色器阶段有三个,依次是顶点着色器、几何着色器、像素着色器。之前说的都是顶点着色器和像素着色器,今天第一次详细介绍几何着色器,几何着色器是一个可选的阶段。一、使用几何着色器的好处 不像顶点着色器那样,输入一个顶点必须输出一个顶点。在几何着色器中,最大的好处是,你可以创建或销毁顶点,实现一些有趣的效果。例如在本例中,输入公告板的中心顶点,可以扩展出四个边框角顶点(两个三角形)。注意原创 2017-08-12 18:03:15 · 1969 阅读 · 0 评论 -
DirectX11 平面镜像的实现
平面镜像的实现在自然界中有许多物体的表面都非常光滑,可以像镜子一样反射周围的物体。本节介绍了如何在3D应用程序中模拟镜像效果。为简单起见,我们降低了任务难度,只在平面上实现镜像效果。例如,一辆光滑的汽车可以反射周围的物体;但是,车身是一个平滑曲面,而非平面。我们不选择这样的物体。我们将在光滑的大理石地板或挂在墙上的镜子中渲染物体的映像——换句话说,我们只实现平面上的镜像效果。要在程序中实现镜像效果,原创 2015-10-04 19:58:31 · 3273 阅读 · 2 评论 -
DirectX11 深度/模板状态
深度/模板状态1. 深度/模板描述当创建ID3D11DepthStencilState接口时,第一步是要填充一个D3D11_DEPTH_STENCIL_DESC实例:typedef struct D3D11_DEPTH_STENCIL_DESC{ BOOL DepthEnable;//默认True // 默认:D3D11_DEPTH_WRITE_MASK_ALL D3D11_D原创 2015-10-04 12:47:39 · 2957 阅读 · 0 评论 -
DirectX11 模板测试
模板测试1. 模板测试实现过程如前所述,我们可以使用模板缓冲区来阻止像素片段渲染到后台缓冲区的某些区域。判断一个特定像素是否可以写入后台缓冲区的操作称为模板测试(stencil test),其实现过程为:if( StencilRef & StencilReadMask ⊴ Value &StencilReadMask) accept pixelelse reject pixel原创 2015-10-04 12:21:09 · 2310 阅读 · 0 评论 -
DirectX11 模板
模板1. 什么是模板?前面的博文已经介绍过深度的概念,所以这里只解释模板的概念。模板缓冲区(stencil buffer)是一种用来实现特殊效果的离屏(off-screen)缓冲区。模板缓冲的大小与后台缓冲及深度缓冲的大小相同,也就是说,模板缓冲的第ij个像素对应于后台缓冲和深度缓冲第ij个像素。我们在4.1.5节的“注意”中提到,当指定一个模板缓冲时,它总是与深度缓冲共享相同的内存空间。尤如名字所原创 2015-10-04 12:14:40 · 1348 阅读 · 1 评论 -
DirectX11 雾
雾1. 为什么需要雾?当我们在游戏中模拟某些类型的天气状况时,可能会用到雾效(参见下图)。雾除了本身所具有的用途外,还具有一些附加效用。例如,雾可以用来掩盖渲染过程中出现的不自然的人工痕迹,避免蹿出问题的发生。蹿出(popping)是指由于摄像机的移动,使原本在远平面后面的物体突然进入平截头体内,从不可见变为可见;这看上去就像是突然“蹿”到场景里面一样。通过在一定距离内加入雾效,可以掩盖这一问题。注原创 2015-10-04 11:51:53 · 1765 阅读 · 1 评论 -
DirectX11 裁剪像素
裁剪像素1. 为什么需要裁剪像素?有时,我们希望完全丢弃某个源像素,使它不再接受后续处理。这一工作可以由HLSL的内置函数clip(x)来实现。该函数只能在像素着色器中使用,当x<0时丢弃当前像素,使之不再接受后续处理。该函数在渲染铁丝网纹理时非常有用。也就是说,它非常适合于渲染那些完全不透明或者完全透明的像素。 (带有alpha通道的铁丝网纹理。clip函数将丢弃那些带有黑色alpha值的像素,原创 2015-10-04 11:39:31 · 1893 阅读 · 0 评论 -
DirectX11 Alpha通道
Alpha通道1. 漫反射贴图控制Alpha通道在RGB混合中,源alpha分量可以用来控制透明度。混合方程中的源颜色来自于像素着色器。我们会在最后一章中看到,我们将漫反射材质的alpha值作为像素着色器的alpha输出。也就是说,漫反射贴图的alpha通道可以用来控制透明度。float4 PS(VertexOUT pin) : SV_Target{ … // 从漫反射材质和纹理中原创 2015-10-04 11:15:38 · 1560 阅读 · 0 评论 -
DirectX11 混合例子
混合例子1. 屏蔽颜色写入假设我们希望原始目标像素保持不变,即不被任何其他数值覆盖,也不与当前的光栅化源像素进行混合。当我们希望屏蔽后台缓冲区、只向深度/模板缓冲区写入数据时,该算法非常有用。要实现这一算法,可将源像素混合系数设为D3D11_BLEND_ZERO,目标混合系数设为D3D11_BLEND_ONE,混合运算符设为D3D11_BLEND_OP_ADD。使用一方案,混合方程可简化为:还有一种原创 2015-10-04 11:03:33 · 1402 阅读 · 0 评论 -
DirectX11 创建混合状态
创建混合状态1. 如何在DirectX11中创建混合状态?我们已经讨论了混合运算符和混合系数,但是还没有说该如何在Direct3D中使用些值。这些混合参数要通过ID3D11BlendState接口来控制。 我们可以通过填充一个D3D11_BLEND_DESC结构体并调用ID3D11Device::CreateBlendState方法来创建该接口:HRESULT ID3D11Device::Crea原创 2015-10-04 10:15:55 · 2233 阅读 · 0 评论 -
DirectX11 混合方程
混合方程1. 什么是混合?考虑下图。我们从地形和板条箱开始渲染场景,先绘制地形,再绘制板条箱,使地形和板条箱的像素依次存入后台缓冲区。然后使用混合(blending),将水体绘制到后台缓冲区,使水体像素和后台缓冲区中的地形、板条箱像素融为一体。通过一方式,我们可以透过水体看到地形和板条箱。本章我们主要讲解混合技术,它可以将当前的光栅化像素(也称为源像素)与后台缓冲区中的像素(也称为目标像素)混合(融原创 2015-10-04 09:17:40 · 1076 阅读 · 0 评论 -
DirectX11 压缩纹理格式
压缩纹理格式1. 为什么需要压缩纹理?一个虚拟场景可能会载入数百幅纹理,而些纹理会占用大量的GPU内存(记住,我们必须让所有的纹理驻留在GPU内存中,只有这样着色器才能快速地访问纹理)。使用这些格式的好处是它们可以压缩存储在GPU内存中,当使用时由GPU实时解压缩。将纹理存储为DDS压缩文件的另一个好处是可以减少磁盘空间的占用量。2. 压缩纹理I格式有哪些?了缓解GPU内存压力,Direct3D提供原创 2015-10-04 09:04:17 · 6101 阅读 · 1 评论 -
DirectX11 地形水波纹理示例Demo
地形纹理演示程序1. 地形纹理Demo介绍在本例中,我们要为地形和水体添加纹理。首先,我们要在地形上平铺一幅草地纹理。 由于地形网格很大,如果我们直接拉伸纹理,那么每个三角形只能得到很少的几个纹理元素。换句话说,这里无法为表面提供足够高的纹理分辨率;我们会受到倍增问题的影响。所以,我们要在地面网格上平铺草地纹理,进而获得较高的分辨率。其次,我们要通过一个时间函数对水体纹理进行平移,使水体显得更真实一原创 2015-10-04 00:05:28 · 1948 阅读 · 0 评论 -
DirectX11 对纹理进行变换
对纹理进行变换1. 纹理坐标变换有什么意义?如前所述,纹理坐标表示纹理平面上的2D点。因此,我们可以像使用其他坐标一样,对纹理坐标进行平移、旋转和缩放。下面是一些会对纹理进行变换的例子:1.沿着墙体拉伸一幅砖块纹理。该墙体顶点的纹理坐标在[0,1]区间内。我们将每个纹理坐标乘以4,使区间扩大为[0,4],让纹理在墙体上重复4×4次。2.在一片晴朗的蓝天上(即,在一个天空球上)拉伸一幅白云纹理。通过一原创 2015-10-03 23:25:17 · 1875 阅读 · 0 评论 -
DirectX11 寻址模式
寻址模式1. 寻址模式是什么?有哪几种?纹理必须与常量插值或线性插值一起使用以形成一个向量值函数T(u,v) = (r,g,b,a)。也就是,当给定一个纹理坐标(u,v)∈[0,1]2时,纹理函数T返回颜色(r,g,b,a)。Direct3D允许我们以4种不同的方式扩展该函数的值域(称为寻址模式):重复(wrap)、边框颜色(border color)、截取(clamp)和镜像(mirror)。2.原创 2015-10-03 23:12:07 · 1516 阅读 · 0 评论 -
DirectX11 板条箱示例Demo
板条箱Demo1. 指定贴图坐标GeometryGenerator::CreateBox产生箱子的贴图坐标,使得整个贴图图像都映射到箱子的每一面。为了简便起见,我们只显示前面、后面和顶面。注意这里我们省略了顶点结构的法线和切线向量的坐标。void GeometryGe ne rator::Cre ateBox(float width, float height, float depth, Mesh原创 2015-10-03 22:45:22 · 1996 阅读 · 0 评论 -
DirectX11 把纹理作为材质
把纹理作为材质1. 将纹理整合到我们的材质/光照系统?要将纹理整合到我们的材质/光照系统中,通常可以将环境光和漫反射光项调制到纹理颜色上,但不需要包括高光项(这常常被称为“后期添加调制,modulate with late add”)。// Modulate with late add.litColor = texColor*(ambient + diffuse) + spec;上述操作给每个像素原创 2015-10-03 20:51:35 · 1231 阅读 · 0 评论 -
DirectX11 纹理采样
纹理采样1. HLSL纹理采样表示我们知道,Texture2D对象用于在effect文件中表示纹理。不过,还有一种与纹理相关的SamplerState(采样器)对象。它用于描述如何使用过滤器访问纹理资源。下面是它的一些例子:// 在倍增、缩减、多级渐进纹理上使用线性过滤。SamplerState mySampler0{ Filter = MIN_MAG_MIP_LINEAR;};//原创 2015-10-03 20:42:51 · 2116 阅读 · 0 评论 -
DirectX11 过滤器
DirectX11 过滤器1. 倍增(magnification)现象纹理贴图元素应该被视为在一个连续图像上的离散颜色采样;不应该被视为矩形区域。那么问题是:当我们指定的纹理坐标(u,v)与任何一个纹理元素点都不对应时会产生什么结果?这一问题会发生在如下情景中:当观察点离场景中的一面墙很近时,墙会被放大,以至于会盖住整个屏幕。如果显示器的分辨率为1024×1024,墙体纹理的分辨率为256×256,原创 2015-10-03 20:27:51 · 1100 阅读 · 0 评论 -
DirectX11 创建和启用纹理
创建和启用纹理1. 创建纹理步骤纹理数据通常是存储在磁盘上的图像文件。我们需要将它读取出来,并载入到一个ID3D11Texture2D对象中(参见D3DX11CreateTextureFromFile)。不过,纹理资源是不能被直接绑定到渲染管线上的;我们需要为纹理创建一个着色器资源视图(ID3D11ShaderResourceView),然后将视图绑定到管线上。这个过程可分为两步:1.调用D3DX1原创 2015-10-03 19:36:09 · 6782 阅读 · 0 评论 -
DirectX11 纹理坐标
纹理坐标1. 纹理坐标是什么?Direct3D的纹理坐标系由表示图像水平方向的u轴和表示图像垂直方向的v轴组成。坐标(u,v)指定了纹理上的一个元素,我们将该元素称为纹理元素(texel,译者注:texel是texture element的缩写),其中0≤u,v≤1。注意,v轴的正方向是“垂直向下”的(参见图8.2)。另外,将规范化坐标区间设为[0,1],是因为这样可以使 Direct3D拥有一个独原创 2015-10-03 18:59:00 · 3023 阅读 · 0 评论 -
DirectX11 纹理和资源概述
纹理和资源概述 1. 为什么需要纹理? 我们的演示程序正在变得越来越有趣,但是顶点颜色无法体现真实世界物体所具有的细节。纹理贴图映射(texture mapping)是一种将图像数据映射到三角形表面的技术,它可以显著提高场景的细节和真实感。例如,我们可以创建一个立方体,然后将一 个板条箱纹理映射到立方体的每个面上,使它看上去更像是一个板条箱(参见下图)。 2. 纹理如何表示? 回顾我们自从原创 2015-10-03 18:26:38 · 1878 阅读 · 0 评论 -
DirectX11 光照演示示例Demo
光照演示示例Demo1. Demo介绍我们的光照演示程序中,我们实现了3种个不同的光源:1个平行光、1个点光、1个聚光灯。平行光的位置是固定的,点光绕着地形转圈,而聚光灯跟随相机移动,并指向相机的观察方向。光照演示程序只是对上一章的水波演示程序做了一些修改。2. effect文件//===========================================================原创 2015-10-03 13:19:05 · 1837 阅读 · 3 评论 -
DirectX11 光照实现
光照实现1. 光照结构体在LightHelper.h文件中,我们定义了一些的结构体来表示平行光、点光或聚光灯。 结构体成员组成如下: 1.Ambient:由光源发射的环境光的数量。 2.Diffuse:由光源发射的漫反射光的数量。 3.Specular:由光源发射的高光的数量。 4.Direction:灯光方向。 5.Position:灯光位置。原创 2015-10-03 12:17:22 · 1287 阅读 · 2 评论 -
DirectX11 HLSL打包(packing)格式和“pad”变量的必要性
“pad”变量的必要性和打包(packing)格式1. C++复制缓存定义了HLSL结构体后,我们就可以像以下代码一样初始化常量缓冲:cbuffer cbPerFrame{ DirectionalLight gDirLight; PointLight gPointLight; SpotLight gSpotLight; float3 gEyePosW;};在应用程原创 2015-10-03 11:42:23 · 1468 阅读 · 0 评论 -
DirectX11 聚光灯
聚光灯1. 什么是聚光灯?在现实生活中,最常见的聚光灯是手电筒。本质上,聚光灯由一个位置Q、一个方向向量d和一个圆锥体光照区域来描述(参见下图)。 (聚光灯由一个位置Q、一个方向向量d和一个半角角度为ϕmax的圆锥体照区域来描述。)当实现一个聚光灯时,我们开始所做的事情与点光相同。光照向量可以由以下公式描述: 其中,P是接收照的点的位置,Q是聚光灯的位置。从图中可以看到,当且仅当, −L与d之原创 2015-10-03 09:47:37 · 1327 阅读 · 0 评论 -
DirectX11 点光
点光1. 什么是点光?在现实生活中,最常见的点光源是灯泡;它可以向各个方向发射光线(参见下图)。对于任意一点P,都有一条从点光位置Q射向点P的线。通常,光照向量与点光的传播方向相反;也就是,该方向从点P指向点光源Q。本质上,点光和平行光之间的唯一区别是光照向量的计算方式——点光会随着点的位置而变化,而平行光会保持为一个常量。 (点光向各个方向发射光线;对于任意一点P,都有一条从点光源Q射向点P的线原创 2015-10-03 09:29:07 · 767 阅读 · 0 评论 -
DirectX11 平行光
平行光1. 什么是平行光?平行光(或方向光)用于模拟距离很远的光源,它产生的入射光是相互平行的(下图)。 平行光由一个描述线传播方向的向量来表示。因为它产生的线是平行的,所以所有光线都使用相同的方向向量。光照向量与平行光的传播方向相反。在现实生活中,最常见的平行光源是太阳(参见下图)。 2. 平行光的光照方程表示用于平行光的光照方程就是之前介绍过的三种光线组成的简单相加:原创 2015-10-03 09:15:45 · 950 阅读 · 0 评论 -
DirectX11 指定材质
指定材质1. 如何指定材质的值?表面上的材质有可能会发生变化;也就是说,表面上不同的点可能会有不同的材质值。例如,一个轿车模型的车身、窗户、灯和轮胎反射和吸收光线的能力是不一样的,所以轿车表面的材质值也应该不一样。 (将轿车网格分为5个材质属性组)要模拟材质值的不同,一种方法是在顶点级别上定义材质值。这些材质值会在三角形表面进行线性插值,使三角形网格的每个表面点都拥有材质值。但是,从第6章中的原创 2015-10-03 09:09:56 · 1174 阅读 · 0 评论 -
DirectX11 三种光照组成对比
三种光照模型对比1. 光源分类:在我们的模型中,光源可以发射3种不同类型的线:1.环境光(ambient light):模拟间接光照。2.漫反射光(diffuse light):模拟对粗糙表面的直接照。3.高光(specular light):模拟对光滑表面的直接光照。2. 材质分类:同样,物体表面有以下材质属性与其对应:1.环境材质:平面反射和吸收的环境光的总量。2.漫反射材质:平面反射和吸收的漫原创 2015-10-03 08:56:09 · 1224 阅读 · 0 评论 -
DirectX11 镜面光
镜面光 1. 什么是镜面光? 考虑下图所示的光滑表面。当灯照射在这样一个表面上时,光线会在一个由反射系数描述的圆锥体区域内形成锐利的反射;我们将这种反射称为镜面高光反射(specular reflection,或直译为镜面反射)。与漫反射不同,高光可能不会传入眼睛,因为它只在一个特定的方向上反射;高光的计算过程与观察点的位置相关。也就是说,当场景中的观察点位置发生变化时,我们看到的高光强度也会跟原创 2015-10-03 08:46:16 · 1163 阅读 · 0 评论 -
DirectX11 环境光
环境光 1. 什么是环境光? 前面提到,我们的光照模型不处理由场景中的其他物体反弹的间接光。不过,我们在现实生活中看到的很多光线都是间接光。例如,在一条通往房间的走廊里,我们不会直接看到房间里面的光源,但是光线会照射在墙壁上,通过墙壁把一部分线反弹到走廊中,间接地把走廊照亮。再比如,我们坐在一间屋子里,面前摆着桌子、茶壶和台灯。茶壶放在桌子上,并且只有一个侧面面向台灯;我们可以看到茶壶背面并不是原创 2015-10-02 23:42:53 · 865 阅读 · 0 评论 -
DirectX11 漫反射光
漫反射光 1. 漫反射光是什么? 考虑下图所示的粗糙表面。当光线照射在这样一个表面上时,会在不同的随机方向上散开;我们将这种反射称为漫反射(diffuse reflection)。在我们的光照模型中模拟了灯光与表面之间的这种相互作用,我们约定线会在表面的各个方向上均匀散开;所以,无论观察点(眼睛的位置)在哪里,我们总能看到漫反射光。也就是,我们不需要考虑观察点的位置(即,漫反射光的计算与观察点的原创 2015-10-02 23:18:04 · 1126 阅读 · 0 评论 -
DirectX11 兰伯特余弦定理(Lambert)
兰伯特余弦定理(Lambert) 1. 关于光照强烈度的思考 垂直照向平面的线比从侧面照向平面的线更加强烈(见下图)。 假设有一块很小的区域dA。当法线向量n与光照向量L平行时,区域dA受到的光线照射最多。随着n和L之间的夹角θ逐渐增大,区域dA受到的光线照射量会越来越少 (因为很多光线都无法照射到dA表面上了)。2. 推导兰伯特(Lambert)余弦定理 们可以从这个概念中推导出一个函原创 2015-10-02 23:03:06 · 5547 阅读 · 0 评论 -
DirectX11 法线向量
法线向量 1. 平面向量与表面向量的区别 平面法线(face normal)是描述多边形所朝方向的单位向量(即,它与多边形上的所有点相互垂直),如下图a所示。表面法线(surface normal)是与物体表面上的点的正切平面(tangent plane)相互垂直的单位向量,如下图b所示。表面法线确定了表面上的点“面对”的方向。当进行光照计算时,我们必须为三角形网格表面上的每个点求解表面法线,以原创 2015-10-02 22:53:16 · 2680 阅读 · 0 评论 -
DirectX11 光照与材质的相互作用
光照与材质的相互作用 1. 为什么需要光照? 下图展示了光照和阴影在表现物体的立体感和体积感时起到的重要作用。左边的球体没有灯照射,看上去就像是一个扁平的2D圆;而右边的球体有灯照射,看上去很立体。实际上,我们的视觉能力完全取决于光照及光照与材质之间的相互作用,所以,许多超写实场景的渲染工作都是通过精确的物理光照模型(lighting model)来实现的。(译者注:本章经常会提及“光照模型”个原创 2015-10-02 21:42:20 · 1029 阅读 · 0 评论