The Cg Tutorial 翻译

第一章,简介

这一章讲了四节:

1、“什么是CG?”介绍Cg编程语言。

2、“顶点,片段以及图像管线”讲了现代图形硬件的数据流和解释了Cg语言怎样参与这些数据流。

3、“Cg的历史性发展”讲了一些Cg发展的背景

4、“Cg的环境”讲了应用程序怎样着手使用Cg语言,通过实时Cg语言和3D API

1.1 什么是Cg

则会本书教了你怎样用一种叫做Cg的编程语言。Cg语言使你控制形状,外形,和使用可编程图形硬件进行对象的描绘成为可能。它结合了令人难以置信的速度和今天处理器的图形功能通过编程控制。计算机图形工作者,不管是艺术家还是程序员,都拥有了前所未有的的实时图形产生的控制能力。

Cg语言提供了开发人员一个完善的开发平台,而且这个平台是非常容易在多个平台上去创建特效和实时电影级效果。通过提供一个新级别的抽象,Cg代替了开发者直接控制图形硬件的汇编语言,从而更容易的锁定OpenGl,DirectX,Windows,Linux,Macintosh OS XXbox这些家用机平台。Cg语言是开发出来与微软公司密切合作,成为OpenGl,DirectX,HlSL这些语言的有利竞争者。

Cg的意思的“C for graphics”。C语言是一种比较流行通用的语言,在70年代就出现了。由于它的流行以及简洁的设计,随后就出现了不少以C为基础的编程语言。比如说,C++JAVA继承了它的语法以及结构。如果你熟悉C或者任何一种相似的语言,那么学习Cg语言会更加轻松。

另一方面,如果你对C语言甚至编程语言都不熟悉,但是你热爱计算机图形学而且想去学习一些新知识,无论如何,这本书都值得一读。Cg编程是比较简短而且容易明白的。

许多章节都有在理解Cg以及使用Cg方面有用的上下文知识。换句话说,你会发现通过实践会更加容易去学习Cg语言。任何时候你都可以没有拘束地跳到下一章,如果你认为这样学习会比较舒服的话。

1.1.1          图形硬件的编程语言

Cg不同于C,C++的地方是,它非常特别。没有人会用Cg去写一个电子表格或文字处理程序。相反,Cg定位在控制图形的形状,颜色等等渲染方面。明白地说,这种语言是一种被称为着色语言。然而,Cg可以做着色意外的更多的事情。例如,Cg编程可以表现物理模拟,混合,和其他非着色的事情。

可以把Cg编程看成一份详细的食谱,怎样使用图形硬件去渲染物体。例如,你可以写Cg程序去作出表面上的崎岖或者作出字符动画。后面,在1.3节里面,你将会学到更多的着色语言的历史和Cg是这段历史的哪一部分。

1.1.2          Cg的数据流模型

除了被专门用于图形之外,Cg和其他着色语言是不同于传统编程语言的,因为他们是基于数据流的计算模型。在这种模型里,计算是发生在对流水线的数据进行响应的。

当渲染图像时,Cg编程是操作在那些经过了处理的顶点和像素块上的。想象Cg编程就像一个黑盒子,里面的顶点或者像素块在盒子的一边,经过一系列的处理之后,他们就留到另一边。然而,这个盒子不是真的一个黑盒子,因为它是由你决定的,用Cg语言编程,可以精确地描述里面发生了什么事。

每一次顶点经过处理或者光栅化产生像素块(fragment),在渲染3D场景的时候,Cg就会处理你相应的顶点或者像素块(fragment)。1.3小节揭示了Cg更多的数据流模型。

当今相当多的个人电脑以及家用机上都有图形处理单元(GPU),它是实行图形处理像转换和光栅化3D模型那样的任务的。你的Cg会确实执行在计算机的Gpu中。

1.1.3          GPU的专业化和CPU的推广

不管个人电脑还是家用家平台都不一定要有GPU,但它们一定要有CPU去运行操作系统和应用程序。因为CPU是以通用计算作为设计的。CPU运行的应用程序是用通用计算语言编写的,比如C++JAVA

因为GPU是专业化的设计,所以在图形方面速度比CPU更快,比如渲染场景。新的GPU可以每秒钟处理成千上万的顶点,光栅化亿万个甚至上百亿个像素段(fragments)。未来的GPU甚至会更加快。这就是GPU在处理顶点和像素段上的压倒性的优势。但是GPU不能执行想CPU那样通用的程序。

专业化,高性能的GPU就是Cg存在的原因。通用的编程语言对于专业化地处理顶点和像素段来说实在太不适用了。相反,Cg语言就是设计出来去做这种事。Cg也提供了一个抽象的执行模型。你将会学习到这个独一无二的GPU执行模型在1.2节。

1.1.4          Cg的原理

去支持假象的互动,3D应用程序需要保持动画帧率在每秒15帧甚至更高的画面。一般的,我们会考虑60或者更高的帧率去实现实时互动,计算机的画面可能会有上百万的像素需要重绘。对于3D场景,GPU经常处理每一个像素在显示器上,计算物体间的阻挡关系,或者去改善每个像素的质量。这意味着实时3D程序可以要求每秒钟上亿万的像素更新。随着像素处理的需要,3D模型由那些顶点组成,这些顶点连接成为被多边形、线段和点的之后这些顶点、多边形、点会被光栅化成为像素,但在这些操作之前,顶点还是要经过转化(即平移、旋转等等)。这会导致每秒钟处理几千万的顶点转化。

更多的,这些图形处理发生在不包括画面需要更新的时候。实际上是我们需要CPU以及GPU的图形方面的功能。它们都需要去渲染场景并且以足够生动的帧率和质量,以满足开发者需求。这就是说,开发人员可以用C++Cg去开发3D程序。

1.1.5          与传统语言共存

不管Cg是否替代了现存的任何通用计算语言。Cg是一个辅助语言,设计出来就是专门为了高效利用GPU。程序员用像C或者C++这样的传统语言写的程序可以使用Cg runtime加载Cg程序去让GPU执行任务。Cg runtime是一个加载、编译、操作程序让GPU去执行的标准。应用程序提供Cg程序去指示GPU怎样实现可编程渲染效果,如果不这样做,这段程序可能会在CPU去完成。Cg语言实现了并行处理的专业风格。当你的CPU正在执行传统的程序,程序会让顶点和像素块在GPU上处理,如果这个程序是用Cg写的话。

如果实时渲染语言是有这么多好处,那么为什么不早点发明Cg语言呢?答案是计算机图形硬件的发展。在2001年之前,大部分的计算机图形硬件都非常昂贵,而且处理能力有限,3D程序都是固定管线的。“所谓固定管线”就是渲染的过程都是固定的,这是硬件决定的。幸运的是,这种状况现在改变了。

图形硬件和顶点和像素块(Fragment)的处理的设计都已经升级了,如今的渲染管线是可编程的,但是没有为硬件提供可编程的语言。Cg使得GPU编程变得容易,就像C语言使得在CPU上程序变得容易一样。

Cg语言存在之前,寻址到GPU来编程的可能途径就只有低级的汇编语言。隐藏这些的蹭的方法就只有想DirectXOpenGl的这些方法,使得GPU上开发变得实在非常痛苦。随着GPU技术的发展,使得汇编有可能需要更长更复杂,对于高级语言的要求变得更明朗了。扩展低级语言之后,就可以用高级语言的形式,把代码下放给编译器了。下面是一个复杂的汇编语言的一小部分。显然,这些代码是非常去理解的,尤其是那些硬件寄存器的具体功能。

Example 1-1. A Snippet of Assembly Language Code
. . .
DEFINE LUMINANCE = {0.299, 0.587, 0.114, 0.0};
TEX  H0, f[TEX0], TEX4, 2D;
TEX  H1, f[TEX2], TEX5, CUBE;
DP3X H1.xyz, H1, LUMINANCE;
MULX H0.w, H0.w, LUMINANCE.w;
MULX H1.w, H1.x, H1.x;
MOVH H2, f[TEX3].wxyz;
MULX H1.w, H1.x, H1.w;
DP3X H0.xyz, H2.xzyw, H0;
MULX H0.xyz, H0, H1.w;
TEX H1, f[TEX0], TEX1, 2D;
TEX H3, f[TEX0], TEX3, 2D;
MULX H0.xyz, H0, H3;
MADX H1.w, H1.w, 0.5, 0.5;
MULX H1.xyz, H1, {0.15, 0.15, 1.0, 0.0};
MOVX H0.w, H1.w;
TEX H1, H1, TEX7, CUBE;
TEX H3, f[TEX3], TEX2, 1D;
MULX H3.w, H0.w, H2.w;
MULX H3.xyz, H3, H3.w;
. . .

 

相反的,良好的Cg语言是更加方便、清晰、可读、debug以及重用。Cg为你提供了诸如C语言的高级语言的优势,同时提供了低级别的汇编代码的性能。

1.1.6          Cg的其他方面

Cg是一种语言用来“in the small”式编程。这就使得Cg比起其他现代通用语言,比如C++来说更加简单。Cg是专门去转化(transforming)顶点和像素段,它目前不包括大规模软件工程所需要的复杂的许多功能。不像C++javaCg不支持类和其他用于面向对象的功能。现阶段的Cg甚至不提供指针和内存分配功能(未来或许会加入)。Cg也不支持文件I/O操作。更广泛的讲,这些限制并不是真正意义上的限制,反而是当今最高性能的图形处理器功能指示。随着技术的进步而允许在GPU上进行更通用的计算,你可以希望Cg适当增加。因为Cg是非常接近C的,未来Cg的更新可能会从CC++里增加语言功能。

Cg自带的支持向量和矩阵,因为这些数据类型是图形数学运算的基础。Cg有一个函数库,叫做Standard Library,是非常适合这些图形运算需要的。例如,Cg标准库包含了反射函数去计算反射向量。

Cg程序执行是相对隔离的。这是说处理顶点或者像素段的时候不会对其他同时处理的顶点或者像素段处理有影响。在Cg程序中这些运算是没有副作用的。顶点和片段之间没有相互依存关系,使得Cg语言非常适合高速的平行运算。

1.1.7          Cg程序运行环境的限制

当你用为现代CPU设计的编程语言在现代操作系统上写程序时,你都会希望你的程序或多或少的能够正确,然后通过编译、正确地执行。这是因为CPU,是以通用计算为目的而设计的。

但是,GPU的情况确不尽相同,不是所有东西都可以写在GPU上的。Cg包括有特有的硬件概念,比如配置文件(profiles),必须由你指定,当你编译程序的时候。每个”profile”对应于一个特定的GPU架构组合和图形API。你的程序不仅要正确还要符合硬件的限制要求。例如,一个给定的profile像素块可能限制你不能超过四张贴图去访问像素块。

随着GPU的发展,有更多的profiles将会支持Cg语言相对的更强大的GPU架构。随着GPU的功能更全面,profiles将来会变得没那么重要。但现在Cg程序员需要限制自己的程序去确保通过编译和执行在现有的GPU上,因此现今写的程序的配置文件将不改变未来编制使用的配置文件(profile)

这种情况也许应该遏制,但是现实中的这本书中的Cg程序可以成千上万的GPU中,而且产生的引人入胜的渲染效果。另一个限制程序的规模和范围的理由是,这样做,你的程序会更加有效率。实时图形需要平衡场景复杂度、动画帧频、还有改善着色之间的关系。因此,经常会通过这样的Cg程序去使得渲染效果最大化。

必须常记在心的是配置文件的限制是GPU的限制,而不是Cg

1.2         顶点,像素块和图形管线

为了更了解Cg,你需要先明白GPU渲染图像是怎么一回事。这一节会解释图形硬件的演进和现代图形渲染管线。

1.2.1          计算机图形硬件的演进

计算机图形硬件正在让人难以置信的快速进步着。三股力量驱动着这个快速革新的步伐,如下如,首先,是半导体工业按照着摩尔定律,每18个月翻一番。第二股力量是大量计算的需求。第三股是持续的愿望。就是这三股力量的推动,成为发展Cg语言的动力。

 

1.2.2          4个世代的计算机图形硬件

90年代中期,世界上最快的图形硬件是由许多芯片组成的,它们一起负责渲染和显示输出。随着时间的推移和半导体技术的提高,硬件工程师把复杂的多芯片设计功能纳入一个图形芯片上。这种发展造成了巨大的一体化和经济规模。你会为GPU的晶体管数量感到惊讶。晶体管数量可以用于粗略估计计算机硬件的集成程度。比如说,INTEL2.4GHZPentium 45500万个晶体管;Nvidia则用了1亿2500万个晶体管集成在GeForceGpu中。

 

省略都是Nvidia的广告:)

都翻译重点吧,闲话有点多….

 

……

未来的GPU会进一步推广当前GPU可编程方面,Cg则是这方面容易使用的工具。

 

1.2.3          图形硬件管线

管线是一个序列的阶段,运行在一个固定的秩序当中。每一个阶段的输入都会来自前一个阶段的输出,而每一个阶段的输出则会成为下一个阶段的输入,就像装配车间的流水线。

下面展示的就是今天的GPU的图形硬件管线。3D应用程序发送顶点序列给GPUGPU把顶点序列构造成几何图元,几何图元有点、线、列等等多边形。

 

下面是几何图元的各种构造方式。

 

每个顶点不仅仅有位置,还有其他属性,例如颜色,发色颜色,纹理坐标,法线向量。法线向量确定了顶点所在面的朝向,经常用来计算光照。

 

顶点转化(Transformation)

 

顶点转化是图形硬件管线的第一个阶段。顶点转化执行了顶点上的一系列的数学运算。这些运算包括转化顶点位置到屏幕对应的坐标,用于光栅化,产生贴图坐标用于贴图,还有光照顶点产生的颜色。我们后面会解释这里的任务。

 

图元的绘制和光栅化

 

经过转化的顶点流入下一个阶段,这个阶段叫做基本图元组合和光栅化。首先,图元的绘制步骤会根据给定的构造信息把顶点构造成为几何图元。这个过程会构造一系列三角形、线、点。这些图元可能需要裁剪,还有一些图元的别面不需要被看见的时候会不光栅化这些面,这个叫做背面消隐。

多边形经过裁剪跟背面消隐之后就必须进行光栅化。光栅化是一个决定一系列像素被几何图元覆盖的过程。多边形、线段、点都是要根据每种基本类型指定的规则进行光栅化的。光栅化的结果是相应的像素填满了相应的区域。光栅化的结果是一系列的像素占据了相应的图元指示的像素块(Fragments)。图元的顶点数量跟光栅化的时候被产生的像素块(fragments)的数量没有关系。例如,一个三角只是有三个顶点指定,但是它可以占据整个屏幕,由此产生成千上万个像素块。

之前,我们讲过可以把像素块想象成为一堆像素,如果你不知道像素块(fragment)是什么。但是,现在需要明确像素块与像素的区别,那就是像素只是图片元素的一部分,保存在帧缓冲里的一个特殊的区域,拥有颜色,深度以及与位置相关的其他值这些属性。而像素块是一种状态,这种状态是用来指定更新指定的像素。

使用像素块(fragment)这个术语,是因为光栅化分解了每个几何图元(primitive),比如三角形,每个图元所覆盖的像素会成为每个像素大小的像素块。像素块有一个相关的像素位置、深度、一系列的插值参数。这些不同的插值参数来自顶点的转化(transform)构造出基本的图元,之后再产生出像素块。你可以认为像素块(fragment)是潜在的像素,这些像素块在帧缓冲中更新像素。

 

插值(Interpolation),纹理和颜色

 

一旦图元光栅化成为一个零集或者许多像素块,那些插值、纹理和着色阶段会作为像素片段必要的参数,执行一系列的贴图和数学运算,最后决定像素块的最终颜色。除了确定最终的像素块颜色之外,这个阶段可能会决定深度或者丢弃的像素块,这样就可以避免更新帧缓冲中相应的像素。可能会允许这个阶段丢弃像素块,这个阶段为每个接收到的输入,输出01的彩色像素块。

 

光栅化

 

 

 To Be Continued..........

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值