HLSL学习摘记(I)

bg: 近两周在学习OGRE、DX、HLSL等等方面的东西。由于是第一次接触,仅凭着一点图形学的理论支持和一点点openGL的开发经验,以及半吊子英语阅读水平,在这些(中\英)学习资料中上蹿下跳;好似吃了千年大补丸,脑子里早已是晕晕乎乎,一团浆糊。于是决定将学到的知识归归类,整理一下写出来。内容由网络摘记和原创理解为主(因此,未必有参考价值,看官慎重对待之)。形式采用FAQ式的一问一答。这篇是关于HLSL的。

 

什么是Shader、HLSL ?

Shader是一种特殊的程序(可看作为一种脚本程序)。它相对独立于D3D主程序,并且被编译成显卡的GPU指令序列在显示芯片上跑。

HLSL(High-Level Shader Language,高级着色器语言)顾名思意,就是一种专门写Shader程序的编程语言。这是一种面向过程的高级语言。它除了读起来很不爽外(全是辅音字母,没法缩读--#),还是那个讨厌的IT大鳄微软所开发和拥有的语言。该语言只能供D3D使用,确切说是只能嵌套在D3D中跑,并且只有D3D能理解它(通过内置的编译器)。 微软这种垄断式的做法是为了对抗GLSL(GL Shader Language)。

再强调一遍:Shader是程序,HLSL是语言。这就是他们的本质。另外,Shader跑在显卡上,而不在主存中。

Shader和HLSL有什么用?

它们的作用主要体现在两方面:对于终端用户而言,Shader能表现出更加丰富的特效;对于图形开发者来说,Shader能让他们掌控更多的自由。这两方面其实是个因果关系:开发者能够更加自由地控制渲染流程的各个环节,他们就能编写出更加丰富逼真的特效。

“Shader能让开发者掌控更多的自由”,这句话是什么意思?如果不了解图形渲染的机制,这句话看上去依然非常抽象。下面略微介绍一下这方面的内容。

step1.主存中存放图形顶点信息的原始数据(有很多,如位置、法线、贴图坐标等)通过AGP专用总线传给显卡,同时,被看作“资源”的各种变换矩阵、灯光等也一并加载给显卡。

step2.显卡上的顶点处理单位(Vertex Processing Unit)会利用这些“资源”按照一定的算法(坐标变换、光照、贴图动画),对顶点原始信息进行加工。然后将结果输出给下一工序试用。这时候,各个顶点的坐标信息是屏幕空间坐标。

step3.从这里开始,进行光栅化(Raster)的工作。某一模块(我不清楚)接收处理过的顶点信息,然后以三角形为单位进行像素填充计算。计算的手段是通过“插值”得到的。包括决定哪些像素应该被填充,被填充的像素颜色、贴图坐标应该是什么,以及通过深度检测和模板检测决定该像素最终是否该被填充。

step4.显卡上的像素处理单元(Pixel Processing Unit)接收上一步得到的需要填充的像素,利用同样被看作“资源”的贴图信息,对每个像素进行贴图像素取值、贴图混合等工作。必要的话每像素光照也在这里完成。像素最终的处理结果被放进后备缓冲。

step5.后备缓冲与前台缓冲交换。然后被绘制在屏幕上。一帧画面就这样产生了。

由上可以看到,这一套管线是相对比较固定的。因此以往的显卡在顶点处理和像素处理过程中执行的是一套布在硬件上的固定的程序。那么有些事就比较难办到。如渲染一个水晶馒头。即便参数再多,其渲染所用到的光照公式也跑不出石膏这种东西。而现在的显卡允许你自己写这么一段程序来代替固定的顶点处理过程和像素处理过程(强调,只是这两个过程,跟插值什么的没关系)。因此,开发者就获得了操控这部份管线的自由,也因此可以编写出更加强大的画面来。

在D3D9以前,编写Shader还是类似汇编的方式,利用GPU自由的指令集,一条一条编写。但如同汇编用多了必然出现C一样,自D3D后,HLSL应运而生了。

Note:本文内容部分来自http://dev.gameres.com/Program/Visual/3D/Direct3DHLSL1.htm

原文地址:https://www.cnblogs.com/lookof/p/1550795.html