#Unity shader学前准备之CG语言(2)

##shader Language        shader language,称为着色语言,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 被定位为高级语言,如,GLSL 的全称是“High Level Shading Language”,Cg 语言的全称为“C for Graphic”,并且这两种 shader language 的语法设计非常类似于 C 语言。不过高级语言的一个重要特性是“独立于硬件”,在这 一方面 shader language 暂时还做不到,shader language完全依赖于GPU构架,这一特征在现阶段是非常明显的!任意一种 shader language 都必须基于图形硬 件,所以 GPU编程技术的发展本质上还是图形硬件的发展。在 shader language存在之前,展示基于图形硬件的编程能力只能靠低级的汇编语言。(注,其实是存在软渲染这种渲染器的,完全不依赖硬件,甚至无法利用GPU资源,软渲染器大多是专业渲染器,比如著名的vray,在影视,动画,CG行业比较常见,但随着GPGPU发展,可以利用GPU计算能力的专业渲染器在,但GPGPU的渲染器已经和即时渲染的渲染器有区别)
       shader language也并非GLSL,HLSL,CG三种,事实上,渲染语言有很多种,下面列举几个相对常见的。

Offline rendering

  • RenderMan Shading Language
  • Houdini VEX Shading Language
  • Gelato Shading Language
  • Open Shading Language

Real-time rendering

  • ARB assembly language
  • OpenGL shading language
  • Cg programming language
  • DirectX High-Level Shader Language
  • Adobe Pixel Bender and Adobe Graphics Assembly Language
  • PlayStation Shader Language
  • iOS Metal Shading Language

##shader Language原理        使用 shader language 编写的程序称之为 shader program(着色程序)。着色程 序分为两类:vertex shader program(顶点着色程序)和 fragment shader program (片断着色程序)。(注意:unity3D中还有一个surface shader,非常好用而且常用,但surface归根结底是unity造出来的,底层还是定点渲染和片段渲染,可以看这篇博文
       顶点和片段处理器被分离成可编程单元,可编程顶点处理器是一个硬件单元,可以运行顶点程序,而可编程片段处理器则是一个可以运行片段程序的单元。顶点和片段处理器都拥有非常强大的并行计算能力,并且非常擅长于矩阵(不高于4阶)计算,片段处理器还可以高速查询纹理信息(目前顶点处理器还不行,这是顶点处理器的一个发展方向)。如上所述,顶点程序运行在顶点处理器上,片段程序运行在片段处理器上, 哪么它们究竟控制了 GPU 渲染的哪个过程。

可编程图形渲染管线

可编程图形渲染管线

       对比上一章中的GPU渲染管线,可以看出,顶点着色器控制顶点坐标 转换过程;片段着色器控制像素颜色计算过程。这样就区分出顶点着色程序和片段着色程序的各自分工:Vertex program 负责顶点坐标变换;Fragment program负责像素颜色计算;前者的输出是后者的输入。
可编程图形硬件输入\输出

可编程图形硬件输入\输出

       上图展示了现阶段可编程图形硬件的输入\输出。输入寄存器存放输入的图 元信息;输出寄存器存放处理后的图元信息;纹理buffer存放纹理数据,目前大多数的可编程图形硬件只支持片段处理器处理纹理;从外部宿主程序输的常量放在常量寄存器中;临时寄存器存放着色程序在执行过程中产生的临时数据。 顶点着色器和像素着色器的数据处理流程

顶点着色器和像素着色器的数据处理流程出

##Cg语言概述        Cg(C for Graphcis)语言,是 NVIDIA 与 Microsoft合作研发,旨在为开发人员提供一套方便、跨平台(良好的兼容性),控制可编程图形硬件的高级语言。 Cg 语言的语法结构与 C 语言非常类似,使用 Cg 编写的着色程序默认的文件后 缀是*. Cg。Cg语言一直状态良好,但是还是停止开发了,这只有一个可能,那就是东家NVIDIA玩腻了,截肢2012年,Cg发行了最终版,Cg3.1,NVIDIA在官网发表了声明,推荐开发者使用GLSL和HLSL,Cg的支持将在日后逐步放弃(12年NV发布了开普勒,彻底击败老对手AMD,并之后牢牢把握了桌面独立GPU市场霸主的地位)。

CG官网

虽然Cg被NV判了死刑,但有一位NV的工程师,做了Cg的开源版本,nvFX,并上传到了github上。

       Cg语言并没有什么好的开发环境,下面是官网提供的两个开发建议:

http://prideout.net/blog/?p=1 discusses on how LUA can be used for effect management;

https://code.google.com/p/glfx/ offers another way to manage effects on top of GLSL language.

本人将采用unity3D作为CG学习的工具。

       打开unity3D,在project->creat->shader,新建一个shader文件。新建的shader文件如下图所示。 新建的shader

       其中的CGPROGRAMENDCG之间是CG程序的代码。不同的硬件,能使用的shader也不相同,一个U3D的shader文件可以写若干个SubShader,若是第一个SubShader硬件无法支持,会自动选择下一个,如果都不行,还有FallBack "Diffuse"这个最坏的方案。可见,U3D的shader还是非常人性化。

       然后,在project->creat->material,新建一个材质,然后把shader文件拖动到material上,就得到了该shader对应的材质,然后GameObject->3D Object->plane,新建一个平面,然后把材质拖到这个平面上,就能看到效果。因为没有对该shader做出任何修改,就是U3D的默认材质效果。