0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

三维场景转化为一幅二维图像的过程

Dbwd_Imgtec 来源:未知 作者:李倩 2018-07-13 17:10 次阅读

三维图形渲染管线就是将三维场景转化为一幅二维图像的过程。

图像中物体所处位置及外形由其几何数据和摄像机的位置共同决定,物体外表是受到其材质属性、光源、纹理及着色模型所影响。

管线过程由3个大的阶段组成:

Application(应用程序阶段):运行在CPU上,能被开发者完全控制,该过程所做操作包括:

① 准备场景数据

加载模型:Mesh、Material、Shader、Texture(硬盘 --> 内存 --> 显存)

摄像机(位置、朝向、视锥体)

光源(位置、类型等参数信息

② 裁剪和剔除 :视锥裁剪、背面剔除、遮挡剔除 (Occlusion Culling)

③ 计算模型视图矩阵

④ 设置渲染状态(RenderState)

渲染管线内部维护着一些状态值。在我们调用渲染API函数进行绘制之前我们需要设置这些状态值。

这些状态值指导GPU如何渲染我们传递到显存的模型和纹理数据。我们称这些状态值为“渲染状态(Render States) ”。

渲染状态包括Shader、Texture、Material、Light内部定义的各种状态等

最后,发起DrawCall调用

Geometry(几何阶段):负责与每个渲染图元打交道,进行逐顶点、逐多边形的操作。

其重要任务是把顶点坐标变换到带有深度的屏幕空间中,再交给光栅器进行处理。

可进一步分割成:模型视图变换,顶点着色,[曲面细分],[几何着色],投影,裁剪及屏幕映射

模型变换:将模型从模型空间变换到世界空间

视图变换:将各个模型从世界空间变换到眼空间(摄像机处于原点)

通常会把这两个变换矩阵结合成modelview矩阵,并将这个过程称之为模型视图变换

顶点着色器:主要功能是修改顶点属性。如:通过传入模型视图矩阵(MVP)进行顶点空间变换(位置属性)、逐顶点光照(颜色属性)、纹理坐标变换(uv属性)等

顶点着色器的处理单元是顶点,也就是说,输入进来的每个顶点都会调用一次顶点着色器。

顶点着色器只能对输入顶点的相关属性进行修改、创建和忽略,不可以创建或销毁任何顶点,而且无法得到顶点与顶点间的关系。

输入一般是一个变换矩阵和一个相对坐标;输出为眼空间中的坐标及每个顶点所附带的其他属性,如颜色、纹理坐标

曲面细分着色器:用于细分图元,分为3个阶段。

Control Shader,负责把控后续阶段的初始化操作,例如细化程度(可编程

处理Control阶段的输出,细化Patch数据(不可编程)

Evaluation Shader的输入为Patch数据;输出数据为顶点着色器所应输出的数据,但是是批量的(可编程)

几何着色器:输入是1个图元,输出是N个图元(N>=0)

通过Shader程序可以指定Geometry Shader对顶点信息进行增减。还有,因为实际增减的是图元顶点,所以对各种的线段、多边形、粒子等图元也可以进行增减。

利用Geometry Shader的各种方法被创造出来,因为可以自由的生成多边形,那么就可以在地面上生长出草的多边形,或者让3D角色生长出毛发等是最基本的使用方法。

在游戏中,还可以把不需要做逻辑交互处理的例如火花等特效的表现,使用Geometry Shader来生成。

注:Geometry Shader通常是在display driver中实现的,也就是说其实是由CPU负责计算,当重新返回GPU的VS时,对流水线的影响很大,所以Geometry Shader的实际效能并不高,甚至是非常低

投影:分为透视投影与正交投影;在眼空间将模型从三维空间投影到二维平面(D3D投影平面为z=1.0,OpenGL为z=-1.0;为了便于理解,可将其定义为视景体近裁截面)

注:上图为眼空间,D3D为左手系,OpenGL为右手系

投影完成后,会得到归一化的设备坐标(Normalized Device Coordinates,NDC),方便下一步进行硬件裁剪

归一化x、y分量到[-1.0, 1.0]

归一化z深度值(D3D:[0.0, 1.0] OpenGL:[-1.0, 1.0])注:近裁截面为最小深度、远裁截面为最大深度;

裁剪:将那些不在摄像机视野内的顶点裁剪掉,并剔除某些三角图元面片

屏幕映射:将每个图元的x、y坐标从NDC转换到屏幕空间

注:D3D将屏幕左上角作为原点,x轴向右,y轴向下;OpenGL将屏幕左下角作为原点,x轴向右,y轴向上

Rasterizer(光栅化):对上个阶段得到的图元各顶点进行插值(z深度值、法线方向、纹理坐标、颜色等)来产生屏幕上的像素,并渲染出最终的图像。

光栅化的任务主要是决定每个渲染图元中的哪些像素应该被绘制在屏幕上

三角形设置:对三个顶点插值计算三角形边上的像素

三角形遍历:扫描三角形边上的像素来插值计算整个三角形内的像素

片元着色器:逐片元的进行着色计算(即逐像素光照)。该阶段可以完成很多重要的渲染技术 如:纹理采样

逐像素、逐顶点光照差异性主要体现在对于非精细模型,在执行逐顶点光照时,由于点距较大,在进行颜色线性插值的过程中,无法精细平滑过渡,导致效果变差。

另外逐像素光照可以在渲染时添加并不存在的表面细节。如通过bump贴图或normal贴图,在原本平坦的表面表现出近似的凹凸效果。

当然,逐像素的计算量要比逐顶点要大

逐片元操作:有时也被称为光栅操作(raster operations ,ROP)或混合操作(blend operations),通过设置来淘汰一些不合格的片元以及如何合并问题

如果一个片元通过了所有的测试,新生成的片元才能和颜色缓冲区中已存在的像素颜色进行Alpha混合,并写入颜色缓冲区

• Alpha测试:

注1:并非所有显卡都支持Alpha测试特性,使用前需要检查显卡是否有该能力

注2:由于大量片元会在该阶段舍弃,Alpha测试可提高含大量透明物件场景的性能

• 模板测试:

注1:若建立模板缓冲区为8bits,则模板值的范围为:[0, 255]的整数;其初始值为清理模板缓冲区的所设置的值

注2:若在模板测试时,关闭了深度测试,则深度测试始终通过

• 深度测试:

注1:深度值范围(D3D:[0.0, 1.0] OpenGL:[-1.0, 1.0]),建立深度缓冲区位数越多,则深度值的精度就会越高;其初始值为清理深度缓冲区的所设置的值

注2:关闭了深度测试,意味着该片元始终通过深度测试

• Alpha混合:

FrameBuffer(帧缓冲)

帧缓冲器(frame buffer):在显卡中硬件实现,用于存放渲染的最终结果。分为:单缓冲、双缓冲(double buffering)、三重缓冲(Triple Buffering)

单缓冲:各个物体的渲染会直接画在屏幕上,效率比较低,由于能看到中间绘制过程,会导致屏幕不断闪烁。一般只用于显示非动态的图像

双缓冲(double buffering):绘制是在一个后备缓冲器(backbuffer)中以离屏的方式进行的。一旦在后备缓冲器中完成绘制,

通过交换指令(D3为Present、OpenGL为SwapBuffer)就可将后备缓冲器中的内容与已经在屏幕上显示过的前台缓冲器(frontbuffer)中的内容进行交换,使得一个完整的帧显示在屏幕上。

完成交换后,后备缓冲器变为前台缓冲区,而前台缓冲区变为后备缓冲区,为下一帧的绘制工作提前做好准备。

我们将前后缓冲区功能互换的行为成为提交(Presenting)。

由于只是将前台缓冲区的指针和后备缓冲区的指针做一个简单的交换,提交是一个运行速度很快的操作。

// OpenGL单缓冲glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glFlush(); //单缓冲的刷新模式;// OpenGL双缓冲glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutSwapBuffers(); //双缓冲的刷新模式;

三重缓冲(triple buffering):一个前台缓冲区,两个后备缓冲区。

在开启了VSync垂直同步时,若游戏的FPS低于显示器刷新频率,三重缓冲可缓解卡顿现象,然而由于存在2个后备缓冲区,三重缓冲会导致画面有一帧的延迟。(见下文说明)

显示器

以CRT显示器为例(液晶显示器原理类似),CRT的电子枪从左到右,从上到下进行逐行扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描。

为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号

当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;

而当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。

显示器通常以固定频率(如60HZ)进行刷新,这个刷新率就是 VSync 信号产生的频率。

将显卡与显示器的刷新频率通过一个称为VSync的信号同步起来,保证显示器上显示的是一帧完整的画面,来解决Tearing(撕裂)现象(多帧画面同时绘制在显示器上)。

假设游戏的FPS是100,显示器的刷新频率是75Hz,显卡将比显示器快1/3;这意味着,在1个显示器刷新周期内,显卡将写入4/3的帧数据,也就是说,下一帧的1/3覆盖在前一帧之上;

当然,随着系统运行,1/3这个比例会发生变化,1/3,2/3,1,1/3,循环;这种帧与帧之间的不完全覆盖重合现象就是撕裂现象。

D3DPRESENT_PARAMETERS md3dPP;md3dPP.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // 开启垂直同步

当开启了垂直同步,若游戏FPS高于显示器刷新频率时,显卡会将一部分时间浪费在等待上,显卡必须等待VSync信号的到来才能将绘制好的画面推送给显示器,这也使得游戏的最大FPS下降为显示器的刷新频率

这避免了显卡做一些无用的工作,降低显卡的功耗;然而,VSync技术也有缺点,会导致玩家输入的响应出现延迟;另外,若游戏的FPS低于显示器刷新频率,那么系统的FPS将迅速下降为显示器刷新频率的分数倍上,加剧画面卡顿(Shutter)

Triple Buffering(三重缓冲)可以缓解这一问题,示意图如下:

然而,从上图可以看出由于存在2个后备缓冲区,三重缓冲会导致画面有一帧的延迟。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10412

    浏览量

    206467
  • 摄像机
    +关注

    关注

    3

    文章

    1418

    浏览量

    58962
  • 三维
    +关注

    关注

    1

    文章

    466

    浏览量

    28765

原文标题:三维图形渲染管线

文章出处:【微信号:Imgtec,微信公众号:Imagination Tech】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    二维三维Gauss随机粗糙面的Monte Carlo仿真

    二维的推导方法扩展到三维,建立了三维Gauss随机粗糙面模型。【关键词】:高功率微波;;Monte Carlo方法;;随机粗糙面;;仿真【DOI】:CNKI:SUN
    发表于 05-28 13:41

    二维数组转换为RGB图像问题

    大家好,我现在是通过建立个512×512的二维数组生成一幅黑白图像,但是现在我又要通过这个二维数组生成
    发表于 09-17 14:21

    三维动画制作过程之间的联系

    ,动画始终缭绕这风格进行发展变化,从二维走到三维,动画师们始终在尽力坚持动画的个性。绝大多数的三维动画都属于这作风作品。(3)采取
    发表于 11-15 14:28

    proE4.0野火版如何三维图转换成二维的图?

    我是新人,希望大家来帮助我下,我刚刚自学proE4.0野火版,工作需要现在将原有三维立体图转换成二维图,请问大家有人知道过程吗。我想要具体步骤。谢谢
    发表于 05-09 15:45

    二维傅里叶变换后怎样求波数?

    我有一幅海浪的遥感图像图像分辨率为2.5m,裁出其中个512像元*512像元的区域,对其做二维傅里叶变换,想求该区域海浪的波数K。(有文
    发表于 10-20 18:43

    三维逆向工程的成果及应用案例

    `三维逆向工程的成果及应用案例何为逆向工程?为适应现代先进制造技术的发展,需将实物样件或手工模型转化为Sence数据,以便利用快速成形系统、计算机辅助系统等对其进行处理,并进行修改和优化。逆向工程
    发表于 03-02 15:12

    三维触控技术突破“向箔”的束缚

    `| 突破向箔的束缚:三维触控然而,人们对触摸屏交互方法的探索并没有到此为止。这里不妨再梳理下手机与用户交互方式的进化过程。最初,用户只能通过按手机上若干位置固定的按键来操作手机,
    发表于 12-19 15:53

    LM1875 PCB 3二维图 附加个空气净化器三维

    LM1875PCB3二维图附加个空气净化器三维
    发表于 01-17 14:22

    二维数组怎么转化为

    二维数组怎么转化为
    发表于 05-04 17:04

    如何用labview程序将二维图片转化为比特序列?

    如何用labview程序将二维图片转化为比特序列?
    发表于 05-16 11:13

    在LABVIEW中怎么将二维数组转化为数组

    `在LABVIEW中怎么将二维数组转化为数组并且如何将数据显示到波形图中... 并且如何将数据显示到波形图中在“数组”中有“重排数组
    发表于 02-14 16:56

    三维设计应用案例

    CAD是目前工业制造产品设计的重要软件之,广泛应用于机械、建筑等领域。而常用的CAD软件,也就是所谓的三维制图软件,较二维的图纸和二维的绘图软件,
    发表于 07-03 07:06

    Labview 如何把二维数组转化为2D,簇3的类型

    想将R,G,B灰度图合成位RGB彩色图,要用到IMAQ ColorValueToInteger,输入端类型要2D,簇3的类型,但是R,G,B都是二维数组,不知道该怎么转化
    发表于 07-25 15:44

    安徽三维动画制作和二维动画有哪些区别呢?(

    三维动画制作中,“”这个字,是个几何学和空间理论的基本概念。构成空间的每个要素,如长度、宽度、高度,被称之为
    发表于 01-22 10:02

    安徽三维动画制作和二维动画有哪些区别呢?(

    二维动画制作制作和三维动画制作除了按照在制作过程中摄像机或者虚拟摄像机是否可以任意进行旋转的区别外,主流的二维动画制作(不包括平面材料动画制作)和
    发表于 01-25 10:34