本系列文章主要翻译和参考自《Real-Time 3D Rendering with DirectX and HLSL》一书(感谢原书作者),同时会加上一点个人理解和拓展,文章中如有错误,欢迎指正。
这里是书中的代码和资源。
本文索引:
既然是写HLSL,自然离不开其开发公司——微软。微软为了编写DirectX和其着色器语言HLSL提供了很多方便、集成的相关工具,虽然是庞大了些,但毕竟同出一家,也是显得更方便一些。下面就为大家一一介绍下微软到底给我们提供了哪些方便的“捆绑”工具吧。
从Microsoft Visual Studio 2010开始,这个IDE已经发展了将近十几个大版本,功能越来越集成,体积也越来越庞大。这个IDE提供了对很多编程语言和硬件平台的支持,包括Windows Phone,Xbox 360,以及Xbox One。对我们来说,最值得高兴的应该是其提供了C++及HLSL语言的支持,并且还集成了Visual Stuidio Graphics(关于这个工具请参见本文后半部分)。
原书中使用的是VS2013版本,而目前已经出到了VS2015U2版本(想要了解DirectX11与VS2015U2的关系吗?请戳这里),本系列资料将使用最新的VS2015U2版本作为编程环境(其实是因为装了VS2015U2之后发现13不能用了,悲了个剧的……)。VS2013有很多版本,每个都有一些不同的特性,但Visual Studio Express 2013 for Windows Desktop已经是免费的啦,小伙伴们可以自行到官网下载。
目前想要开发微软相关应用的小伙伴可以发现,微软真是越来越霸道了,虽然也是方便了,想开发什么东西不要再去分别找各种安装包了,直接一个Windows SDK搞定。好吧……即使我不想开发Win Phone,这对强迫症患者真不是什么好消息。所以,当然啦,DirectX这种东西自然也被集成了进去,老老实实去下Windows SDK吧(当然和我一样用vs2015u2的童鞋就不用下了,也不用配置依赖库路径,VS已经都集成好了)。
以下是VS2015中已经集成好的依赖库设置:
仍然在使用VS2013的小伙伴可以参考原书对应部分~
刚开始了解这个东东的时候不禁开始感慨其高大上的设定,才了解到原来写shader也有框架这一说,作为一枚之前就是搞服务器的小菜鸟,刚开始接触3D编程一直以为就是一堆堆各种各样的接口,觉得貌似没有服务器那么有条理,什么都是规范好的,有框架,整洁又有序。现在突然冒出个框架,心里不禁有些激动。这篇文章是我转载在博客中介绍Effect框架比较全面的中文文章。以下是原书对Effect框架的一些说明:
如果你使用过之前的DirectX版本,那么对DirectX3D的扩展库(D3DX)应该会比较熟悉。这是老版本的DirectX中使用的一个集成库,但在Windows SDK中已经被遗弃(意味着DirectX中已经不能使用这个库)。但是D3DX的一些特性被保留了下来,包括特效文件格式(即我们编写shader的文件)的一些接口。还好,微软又提供了一套新的接口,其中含有D3DX库中的大部分特性,这套接口已经直接被包含在Effects 11 library中,然而,目前Effect11也被移除出Windows SDK,而这些特性也被转移到DirectX库中(目前的接口变化真是快,详细信息请查看本文参考链接中的文章……)。在原书编辑的时候,Effect框架已经更新到了11.09版本。 |
Effect11框架以源码的形式单独发布,使得用户可以在这个框架中加入或修改一些自定义内容。这也使得在使用这个库之前,你必须自己对其进行编译。目前,针对VS2013和VS2015版本,DEBUG和RELEASE,WIN32和X64平台的库已经发布。通过配置和编译之后就可以生成Effect11.lib静态库。原书的第三部分将会提供相关接口的使用范例。 |
这里是原书中提供的Effect框架在CodePlex上的网址。
这里是Effect框架的GIT地址。
DirectX Tool Kit(DirectXTK)是另一个D3DX的替代库,其中提供了可以在DirectX11中使用的C++类。下面的列表展示了该工具包中一些比较重要的库:
DirectXTK库的源代码也和Effect框架类似,提供了相应的工程文件,可以在其基础上做修改并编译出所需要的版本。原书的第三部分将会提供相关接口的使用范例。
纹理文件格式 |
纹理主要是一些覆盖在模型表面的2D位图。很多格式的文件都可以用来存储这些图片信息。以DirectXTK库为例,主要将这些文件格式分为两类: |
DDS:DirectDraw Surface(.dds) |
WIC:Windows Imaging Components(native: .bmp/.gif/.jpg/.png/.tiff/HD photo) |
DDS是微软提供的一种图片存储格式,这种格式可以让GPU直接解压。DDS的压缩比例因压缩时的参数设置而各有不同,但DDS的解压直接在GPU上进行使得其非常有用。从DDS的名字(DirectDraw Surface)就可以看出其在DirectX中运行的优势。 |
第二种图片类型,WIC,根本上来说和DDS有着很大的区别。WIC是使用图片的一种扩展框架。这种框架允许第三方添加一些对非本地文件格式的持续性支持接口以提供给开发者使用。只要使用者安装了对应格式的编码解码器就可以立即使用非本地文件格式的图片。 |
除此之外,你可能还想到了另一种图片格式,Targa(TGA),WIC中并没有提供对这种常见格式的本地化支持。[这里](https://www.leadtools.com/sdk/formats)是原书提供的关于WIC TGA编码解码器的网站链接。然而,目前最流行的TGA编码解码器并不是免费的。但你可以选择使用WIC支持TGA纹理的DirectXTex纹理处理库。这个开源代码库计划将加入到管线中以支持对DDS格式纹理的处理。这个库可以提供WIC支持并且也带有TGA读写器。 |
这里是原书中提供的DirectXTK在CodePlex上的网址。
对于玩家和游戏开发人员来说,NVIDIA几乎已经成了一个家喻户晓的名字。他致力于推进GPU发展进程,并且已经成为了图形硬件及软件领域的领头羊。在NVIDIA所做出的诸多贡献里,就包含有FX Composer,一个为编写shader提供的集成开发环境。这部分文章将开始介绍这个工具——也是在原书中应用非常广泛的工具。
首先,需要知道用HLSL编写shader就如同编写其他软件一样。你的shader代码是以文件的形式存储的,并且任何的文件编辑器都可以修改它。实际上,你可能完全不喜欢使用FX Composer来编写shader,而喜欢类似visual studio这样的工具。但使用目标编译、shader编写风格的FX Composer这类型的工具可能会为你提供更多的好处,尤其是实时展现在修改shader的过程中所反馈出来的视觉效果。并且使用FX Composer这类型的工具可以使你更专注于shader的编写而不用过早的投入到底层图形API接口的大坑中(例如DirectX和OpenGL)。不用担心你会过于关注那种不可移植的,只能在特定工具下使用的代码,你需要知道,你现在用FX Composer所编写的代码未来都可以直接在游戏引擎中使用,相关内容将会在原书的第三部分中介绍。
FX Composer是一个免费的工具,你可以直接从NVIDIA的官方开发者中心下载。整理本文的时候FX Composer的最新版本是2.5(和2年前一样,因为官方已经不在提供更新支持),下图是官方说明:
那么,我们还有必要研究这个工具吗?当然有。以下是作者在原书中给出的解释,直到现在仍然适用:
FX Composer——过时的shader编写工具? |
NVIDIA FX Composer已经不再提供更新开发支持,并且开始变得有些老旧。它仅支持DirectX 9和DirectX 10,并不支持DirectX 11。同样,AMD提供的shader编写工具——RenderMonkey,也不再支持DirectX 11,对这个工具的开发也已经停止。而且,在编写本书的时候据我所知,已经没有其他商业工具可以支持快速开发和可视化shader编写。这带来了很多问题,当然也同时伴随着很多机遇。 |
这种境况所带来的问题在于,这样的工具已经不再那么具有价值,尤其是对于最新的图形接口以及那些刚刚开始迈入图形编程领域开发者来说。没有了这样的shader编写工具,你必须在甚至都没有得以一窥那些最基本的渲染技术的情况下就必须广泛涉猎底层的API接口。而这些接口是在本书的第三部分才会介绍到的。甚至在第三部分的刚开始那几节内容主要是用来介绍怎么搭建一个C++渲染框架,而这个框架并不是用来完成渲染的(它只是提供了一些编程的基础框架使得你在编写真正的渲染功能的时候能够更有序和方便)。这样的障碍并不值得鼓励,尤其是在有shader编写工具可以使你在开始的时候就能够品尝劳动果实的时候。 |
shader编程工具的不再更新也使得那些更有野心的开发者拥有了更多机会,因为想要进入这个领域的鸿沟更大了。 |
所以,我还是选择继续使用NVIDIA的FX Composer作为本书第二部分的辅助工具,因为他提供了实时视觉效果预览,并且,这个工具只是缺乏对DirectX11的支持,因此它不会阻碍我们对渲染技术的介绍。刚开始我们不会直接介绍DirectX的某个具体新特性,我们编写出的材质也不会因为在最新的API版本中就不可使用。 |
下图是FX Composer工具的界面:
如你所见,这个工具的界面布局和visual studio的很像,拥有可以改变大小、可拖拽的面板。大部分面板的功能显而易见(例如,编辑器面板,属性面板以及输出面板)。我们需要解释的是另外一些不那么显而易见的功能。
在Assets面板下(如图3.4所示),你可以找到名为Effects和Materials的标签。每个Effect通过一个文件保存在你的shader代码中。一个Material就是一个effect的实例,通过调整shader中不同的参数来展现不同的效果。多个Material可以对应到一个effect上。
一个没有错误的material(意味着其对应的effect可以被正确编译)会出现在Material面板中,当中的球形将会展示出当前shader的渲染效果。如果其关联的effect没有被正确编译,也就是说这个material是有错的,面板中的球体将会以一个网状红色球体的形式表现出来(如图3.5所示)。Material面板下半部分展示了分配到这个material上的材质。
Render面板默认会出现在编辑器的右下角。这个面板将会呈现当你的shader应用在场景中的目标模型上的效果(如图3.6所示)。在这里,你可以使用编辑器预先自带的模型,点击主工具栏上的球,茶壶,圆环,平板按钮就可以改变模型,或者你可以自己倒入自定义的模型。想要倒入一个模型,只需要选择菜单栏中的”File->Import”按钮即可。在同一个场景中你可以任意引入很多个模型,只需要在render面板中将对应的material拖到模型上即可显示。
在render面板中,你可以通过鼠标和键盘改变3D场景中摄像机的位置和角度。如果你对Autodesk Maya(主流3D建模软件)很熟悉,他们的操作方式其实是很类似的。
你可以通过鼠标左键点击选择场景中的模型。
按下F键可以将摄像机的焦点调整为当前选中模型。
按住alt键和鼠标左键拖拽鼠标可以使摄像机围绕目标模型旋转。
按住Shift键和鼠标左键垂直方向上拖动鼠标可以放大或缩小摄像机视野。也可以使用鼠标滚轮变换摄像机视野。
按住ctrl键和鼠标左键拖拽鼠标可以平移摄像机。
在摄像机视野下,你可以操控场景中的物体。可以通过QWER键或者工具栏中的对应按钮完成操控。
Select Object模式对应键盘Q键,在该模式下可以选择但不改变模型。
Translate Object模式对应E键,在该模式下可以移动场景中的物体。在该模式下选中物体后会出现三个方向的坐标轴,可以通过拖拽某个方向上的坐标轴实现该方向上的移动,也可以直接拖拽三个坐标轴的相交点实现三个方向上的自由移动。
Rotate Object(E)和Scale Object(R)模式和Translate模式类似。
Render面板还包含一些其他的特性,包括背景色自定义修改,渲染参考网格,跟踪贯穿摄像机,屏幕捕捉。再次鼓励大家自己亲自尝试一下这些功能。
Texture面板(如下图所示)可以用来向项目中添加或移除纹理,分配纹理到材质,查看每个纹理的细节。要添加纹理,点击该面板左上角的加号按钮,你可以在属性面板中声明具体变量。双击Texture面板中的某个具体项就可以查看该材质的细节和各个通道。
注意: |
要分配纹理贴图到材质中需要为材质指定一个含有纹理变量的Effect,如果一个effect支持多个材质,拖拽某个材质到目标模型上就会出现对话框要求填入多个对应的材质变量。 原书中第五章”Chapter 5, Texture Mapping”将会详细讨论该主题。 |
如本文之前所提到的NVIDIA官方已经不在提供FX Composer更新支持,那么最新的shader辅助工具正是这一部分要介绍的NVIDIA Nsight Visual Studio Edition。
总的来说这个工具的推出使得NVIDIA将shader编写的强大功能又和visual studio 、eclipse等主流IDE集成在了一起,相当于一个插件。他支持shader的编写、编译、debug、性能分析和效果查看,并支持CUDA、C++、OpenGL、OpenCL、Direct Compute、DirectX。
这里是NVIDIA官方提供的NVIDIA Nsight Visual Studio Edition链接。
Visual Studio Graphics Debugger是嵌入在Visual Studio中允许你进行交互式debug自定义shader的工具。如果你对老版本的DirectX比较熟悉,也可以使用图形调试器PIX。Visual Studio Graphics Debugger取代了PIX并且保留了基础的工作流程。
注意: |
Visual Studio Graphics Debugger在visual studio2013 Express版本中已经不可使用。你需要下载免费版本的visual studio来运行这个工具。不过不用担心,原书中的所有例子都可以不使用这个工具。 |
这里是官方针对VS2015提供的graphic debugger说明。
如果你需要多发现几个Visual Studio中可以使用的图形调试器,那么你可以会需要如下两个工具:AMD的GPU PerfStudio 2和NVIDIA的Nsight Visual Studio Edition。这两个工具都是免费的。相对来说GPU PerfStudio 2可能是一个不错的选择,因为他是一个独立的工具并且不用受到你所选择IDE的限制。相关链接可以在本书提供的网址中找到。
在这篇文章中,我们对编写图形相关程序的工具做了一个大致的介绍。在这里推荐使用VS作为主要IDE,FX Composer作为初学shader的效果编辑、查看器。另外本文提到的三种shader debug可以根据自己的需要选择其一。
【1】去掉D3DX,从现在开始。(http://www.opengpu.org/forum.php?mod=viewthread&tid=8429&extra=&page=1)
这篇BBS中的帖子提到了D3D的一些演变和KlayGE shader框架,其中的回复也给了想要学习D3D的小伙伴一些参考,值得一看。
【2】关于Effect框架的移除。(http://stackoverflow.com/questions/31994455/reading-hlsl-semantics-annonations-with-directx-11-api/31994724#31994724)
这个链接的回答中,解释了现在Effect框架的处境,对的,现在的Effect框架已经不在DirectX包中做原生支持,而且类似开源包一样作为一个独立的包需要被引入。
【3】Effect官方文档介绍(https://msdn.microsoft.com/en-us/library/windows/desktop/ff476136(v=vs.85).aspx)
【4】微软开源一套DirectX工具集(http://www.infoq.com/cn/news/2015/04/mit-directx-github/)