找回密码
 立即注册
查看: 234|回复: 0

GPU编程和CG语言学习第三节(自我学习)

[复制链接]
发表于 2022-7-18 09:31 | 显示全部楼层 |阅读模式
CG/HLSL语言的广泛应用
(知乎手机端需要移动滑块进行阅读,如有不便,还请见谅!)
<hr/>第 3 章 Shader Language
     shader language,称为着色语言,shade 在英语是阴影、颜色深浅的意思,
Wikipedia 上对 shader language 的解释为“The job of a surface shading procedure is
to choose a color for each pixel on a surface, incorporating any variations in color of
the surface itself and the effects of lights that shine on the surface(Marc Olano)”,
翻译:(着色器语言,称为着色语言,阴影在英语是阴影、颜色深浅的意思,维基百科上对着色器语言的解释为
“表面阴影过程的工作是选择每个像素的颜色,将表面本身的颜色变化和灯光的影响表面(马克奥拉诺)”
,即着色语言基于物体本身属性和光照条件,计算每个像素的颜色值。)即,shader language 基于物体
本身属性和光照条件,计算每个像素的颜色值。
     实际上这种解释具有明显的时代局限性,在 GPU 编程发展的早期,shader
language 的提出目标是加强对图形处理算法的控制,所以对该语言的定义亦针对
于此。但随着技术的进步,目前的 shader language 早已经用于通用计算研究。
     shader language 被定位为高级语言,如,HLSL 的全称是“High Level Shading
Language”,Cg 语言的全称为“C for Graphic”,并且这两种 shader language 的语
法设计非常类似于 C 语言。不过高级语言的一个重要特性是“独立于硬件”,在这
一方面 shader language 暂时还做不到,shader language 完全依赖于 GPU 构架,
这一特征在现阶段是非常明显的!任意一种 shader language 都必须基于图形硬
件,所以 GPU 编程技术的发展本质上还是图形硬件的发展。在 shader language
存在之前,展示基于图形硬件的编程能力只能靠低级的汇编语言。
    目前,shader language 的发展方向是设计出在便捷性方面可以和 C++\JAVA
相比的高级语言,“赋予程序员灵活而方便的编程方式”,并“尽可能的控制渲染
过程”同时“利用图形硬件的并行性,提高算法的效率”。Shader language 目前主
要有 3 种语言:基于 OpenGL 的 GLSL,基于 Direct3D 的 HLSL,还有 NVIDIA
公司的 Cg 语言。
   本章的目的是阐述 shader language 的基本原理和运行流程,首先从硬件的角
度对 Programmable Vertex Processor(可编程顶点处理器,又称为顶点着色器)
和 Programmable Fragment Processor(可编程片断处理器,又称为片断着色器)
的作用进行阐述,然后在此基础上对 vertex program 和 fragment program 进行具
体论述,最后对 GLSL、HLSL 和 Cg 进行比较。(CG 则是真正意义上的跨平台它会根据平台的不同,编译成相应的中间语言。CG 语言
平台性很大原因取决于与微软的合作 这也导致 CG 语言的语法和 HLSL 非常相像,CG 语言可以
无缝移植 HLSL,但缺点是可无法完全发挥出 OpenGL 的最新特性。)
<hr/>3.1 Shader Language 原理
    使用 shader language 编写的程序称之为 shader program(着色程序)。着色程
序分为两类:vertex shader program(顶点着色程序)和 fragment shader program
(片断着色程序)。为了清楚的解释顶点着色和片断着色的含义,我们首先从阐
述 GPU 上的两个组件:Programmable Vertex Processor(可编程顶点处理器,又
称为顶点着色器)和 Programmable Fragment Processor(可编程片断处理器,又
称为片断着色器)。
   顶点和片段处理器被分离成可编程单元,可编程顶点处理
器是一个硬件单元,可以运行顶点程序,而可编程片段处理器则是一个可以运行
片段程序的单元。
   顶点和片段处理器都拥有非常强大的并行计算能力,并且非常擅长于矩阵
(不高于 4 阶)计算,片段处理器还可以高速查询纹理信息(目前顶点处理器还
不行,这是顶点处理器的一个发展方向)。

    对比上一章图3中的 GPU 渲染管线,可以看出,顶点着色器控制顶点坐标
转换过程;片段着色器控制像素颜色计算过程。这样就区分出顶点着色程序和片
段着色程序的各自分工:Vertex program 负责顶点坐标变换;Fragment program
负责像素颜色计算;前者的输出是后者的输入。  
    图9展示了现阶段可编程图形硬件的输入\输出。输入寄存器存放输入的图
元信息;输出寄存器存放处理后的图元信息;纹理 buffer 存放纹理数据,目前
大多数的可编程图形硬件只支持片段处理器处理纹理;从外部宿主程序输入的常
量放在常量寄存器中;临时寄存器存放着色程序在执行过程中产生的临时数据。


<hr/>3.2 Vertex Shader Program
    Vertex shader program(顶点着色程序)和 Fragment shader program(片断着
色程序)分别被 Programmable Vertex Processor(可编程顶点处理器)和
Programmable Fragment Processo(可编程片断处理器)所执行。
    顶点着色程序从 GPU 前端模块(寄存器)中提取图元信息(顶点位置、法
向量、纹理坐标等),并完成顶点坐标空间转换、法向量空间转换、光照计算等
操作,最后将计算好的数据传送到指定寄存器中;然后片断着色程序从中获取需
要的数据,通常为“纹理坐标、光照信息等”,并根据这些信息以及从应用程序传
递的纹理信息(如果有的话)进行每个片断的颜色计算,最后将处理后的数据送
光栅操作模块。
    图 10 展示了在顶点着色器和像素着色器的数据处理流程。在应用程序中设
定的图元信息(顶点位置坐标、颜色、纹理坐标等)传递到 vertex buffer 中;纹
理信息传递到 texture buffer 中。其中虚线表示目前还没有实现的数据传递。当前
的顶点程序还不能处理纹理信息,纹理信息只能在片断程序中读入。
    图 10 展示了在顶点着色器和像素着色器的数据处理流程。在应用程序中设
定的图元信息(顶点位置坐标、颜色、纹理坐标等)传递到 vertex buffer 中;纹
理信息传递到 texture buffer 中。其中虚线表示目前还没有实现的数据传递。当前
的顶点程序还不能处理纹理信息,纹理信息只能在片断程序中读入。
    顶点着色程序与片断着色程序通常是同时存在,相互配合,前者的输出作为
后者的输入。不过,也可以只有顶点着色程序。如果只有顶点着色程序,那么只
对输入的顶点进行操作,而顶点内部的点则按照硬件默认的方式自动插值。例如,
输入一个三角面片,顶点着色程序对其进行 phong 光照计算,只计算三个顶点的
光照颜色,而三角面片内部点的颜色按照硬件默认的算法(Gourand 明暗处理或
者快速 phong 明暗处理)进行插值,如果图形硬件比较先进,默认的处理算法较
好(快速 phong 明暗处理),则效果也会较好;如果图形硬件使用 Gourand 明暗
处理算法,则会出现马赫带效应(条带化)。
    而片断着色程序是对每个片断进行独立的颜色计算,并且算法由自己编写,
不但可控性好,而且可以达到更好的效果。
由于 GPU 对数据进行并行处理,所以每个数据都会执行一次 shader 程序程
序。即,每个顶点数据都会执行一次顶点程序;每个片段都会执行一次片段程序。


<hr/>3.3 Fragment Shader Program
    片断着色程序对每个片断进行独立的颜色计算,最后输出颜色值的就是该片 41
段最终显示的颜色。可以这样说,顶点着色程序主要进行几何方面的运算,而片
段着色程序主要针对最终的颜色值进行计算。  
片段着色程序还有一个突出的特点是:拥有检索纹理的能力。对于 GPU 而言,
纹理等价于数组,这意味着,如果要做通用计算,例如数组排序、字符串检索等,
就必须使用到片段着色程序。让顶点着色器也拥有检索纹理的能力,是目前的一
个研究方向。  
    附:什么是片断?片断和像素有什么不一样?
    所谓片断就是所有的三维顶点在光栅化之后的数据集合,这些数据还没有
经过深度值比较,而屏幕显示的像素都是经过深度比较的。 <hr/>3.4 CG VS GLSL VS HLSL
(摘取Unity Shader入门精要——冯乐乐)
    我们上面讲到了很多可编程的着色器阶段, 如顶点着色器、 片元着色器等。 这些着色器的可
编程性在千,我们可以使用 一种特定的语言来编写程序,就好比我们可以用C#来写游戏逻辑一样。
在可编程管线出现之前, 为了编写着色器代码,开发者们学习汇编语言。为了给开发者们打
开更方便的大门, 就出现了更高级的着色语言C Shading Language)。 着色语言是
专门用于编写着色器的, 常见的着色语言有DirectX的HLSL (High Level Shading
Language)、 OpenGL的GLSL (OpenGL Shading Language)以及NVIDIA的CG CC for Graphic)。
HLSL、GLSL、CG都是“ 高级(High-Level)"语言, 但这种高级是相对于汇编语言来说的,
而不是像C#相对千C的高级那 样。这些语言会被编译成与机器无关的汇编语言,
也被称为中间语言(Intermediate Language, IL)。 这些中间语言再交给显卡
驱动来翻译成兵正的机器语言, 即GPU可以理解的语言。  
    GLSL的优点在千它的跨平台性它可以在Windows、Linux、 Mac甚至移动平台等多种平台
上工作,但这种跨平台性是由千OpenGL没有提供着色器编译器,而是由显卡驱动来完成着色器  
的编译工作。也就是说, 只要显卡驱动支待对GLSL的编译它就可以运行。这种做法的好处在千,  
由于供应商完全了解自己的硬件构造,他们知道怎样做可以发挥出最大的作用。换句话说,GLSL
是依赖硬件,而非操作系统层级的。但这也意味着GLSL的编译结果将取决于硬件供应商。要知  
道, 世界上有很多硬件供应商-NVIDIA、ATI等,他们对GLSL的编译实现不尽相同,这可能  
会造成编译结果不一致的情况, 因为这完全取决于供应商的做法。
   而对于HLSL. 是由微软控制着色器的编译,就算使用了不同的硬件,同一个着色器的编译
结果也是一样的(前提是版本相同)。但也因此支持HLSL的平台相对比较有限,几乎完全是微软  
自己的产品, 如Windows、 Xbox 360等。 这是因为在其他平台上没有可以编译HLSL的编译器。 <hr/>3.5 本章小结.
(学会了CG语言相当于掌握了HLSL语言,正所谓一石二鸟!虚幻自定义材质可用HLSL编写,对于开发者来说是不错的选择,Unity shaderlab进行了封装,学习CG语言同时掌控两个游戏引擎的shader代码编写,何不乐哉?)
<hr/>Tips:
大部分的内容我都是直接摘取的,一些硬件版本的介绍我省略了,但不妨碍大家对着色器语言的理解。我个人也不排斥学习GLSL,原著中所写:语言无高低,用法有高下。着色程序中的算法才是精髓所在!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-25 16:56 , Processed in 0.091269 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表