Shader、Draw Call和渲染管线(Rendering Pipeline)
翻阅了很多资料,也做了不少笔记,决定还是对渲染进行一个总结,以巩固所学的东西。
《Real-Time Rendering, Third Edition》 (PDF的配图链接)将一个渲染流程分为三个阶段:
即 应用阶段(PApplication Stage)、几何阶段(Geometry Stage)、光栅化阶段(Rasterizer Stage)
我借用《Unity Shader入门精要》的网页贴图来说明
颜色表示了不同阶段的可配置性或可编程性:绿色表示该流水线阶段是完全可编程控制的,黄色表示该流水线阶段可以配置但不是可编程的,蓝色表示该流水线阶段是由GPU固定实现的,开发者没有任何控制权。实线表示该shader必须由开发者编程实现,虚线表示该Shader是可选的。
顶点着色器(Vertex Shader)、片元着色器(Fragment Shader)是我们编写 Shader最常用的二个。另外二个曲面细分着色器(Tessellation Shader)、几何着色器(Geometry Shader)都是可选着色器。
既然提到了着色器(Shader),那什么是Shader呢?
A shader is a piece of code, that is executed on the GPU. The engine feeds it with 3d model vertices, textures and other information, and gets back from it pixel colours.
-- from What is a Shader?
翻译过来:Shader 就是运行在GPU上的一段代码,引擎提供给它3D的模型顶点、纹理和其它信息,并获取返回的像素颜色。
那Draw Call又是什么呢?
A draw call is a command to render one mesh. It is given by the CPU. It is received by the GPU. The command only points to a mesh which shall be rendered and doesn’t contain any material information since these are already defined via the render state. The mesh resides at this point in the memory of your graphic card (VRAM).
-- from renderhell-book1
有兴趣可以观看下面这个视频,很形象和生动。
视频地址:
https://data.simonschreibt.de/gat049/cpu_calls_gpu.webm
https://data.simonschreibt.de/gat049/commandbuffer_communication_chunk.webm
实际上,Draw Call就是一个命令,它的发起方是CPU,接收方是GPU。这个命令仅仅会指向一个需要被渲染的图元(primitives)列表,而不会再包含任何材质信息(这些信息已经在渲染状态中被定义了),此时网格是驻留在显存(Video Random Access Memory)中的。
当给定了一个Draw Call时,GPU就会根据渲染状态(例如材质、纹理、着色器等)和所有输入的顶点数据来进行计算,最终输出成屏幕上所显示的那些像素。
只看文字不免过于抽象,我之前在网上看到一张图,描述的挺不错。
而实际的工作比这个要复杂很多,包括:坐标转换、透视、裁剪等一系列操作。
所上图所示,需要历经:坐标转换(模型空间 –> 齐次裁剪空间),逐顶点光照,透视除法(归一化的设备坐标 —— Normalized Device Coordinates, NDC),裁剪,屏幕映射。
这里再多解释一下,何为齐次裁剪空间。齐次裁剪空间是一个中心点是坐标原点的立方体,xyz取值范围是[-1, 1]。使用一个4x4的齐次变换矩阵将点从摄像机坐标空间变换到齐次裁剪空间,将顶点的深度值z保存在顶点经过变换得到的齐次坐标的w分量中。最后,把顶点在齐次空间中的坐标通过将x,y,z分量除以w分量的方式,将齐次坐标转为NDC。
为什么需要使用NDC呢?为了适配屏幕的多分辨率问题。
归一化坐标中,两个轴其中一个轴的范围是由0至1(但不能两个都是0~1),而且能轻易缩放至不同分辨率下的像素单位。假设把y轴的范围设置为0.0 ~ 1.0,当使用4:3长宽比时,x轴的范围就是0.0至1.333(=4/3),而16:9时x轴的范围则是0.0 ~ 1.777(=16/9),这样就不会出现拉伸了。
接下来就进入光栅化阶段了。
接收顶点信息,进行适当的转换后,对顶点进行插值处理,然后对三角形进行遍历,检查每个网格是否被三角形覆盖,如果被覆盖就会生成一个片元。之后交给片元着色器(在DirectX中,也称为像素着色器 Pixel Shader)。
经过片元着色器(Fragment Shader)处理后,得到一个或者多个颜色值(如下图所示)。
之后进入逐片元操作(Per-Fragment Operations),会经过模板测试(Stencil Test)、深度测试(Depth Test)、混合(Blend)等一系列操作,最后得到的结果(一系列颜色值)存放到帧缓冲区,供GPU进行屏幕的更新。
大体的渲染过程就如上所述。中间忽略了不少信息,如坐标转换(主要使用矩阵、四元数,矩阵就是映射),还有投影(正交/平行投影、透视投影),以及光照模型(各种贴图和法线、切线等)。整个过程中裁剪不仅仅只发生在应用阶段,背面剔除、遮挡剔除(光栅化阶段)都使用了裁剪。也没有提及为什么是减少Draw Call,以及如何优化。
先大体理解整个脉络,中间每一个点都可以单独写很多内容,但是总的流程是这样的。对整个渲染流程,时刻要在脑海中有一个比较清晰的认识和了解,不然很容易被各种转换和模型给搞晕,不知道当前处于什么阶段,输入是什么,输出又是什么,接下来要怎么走。
Shader、Draw Call和渲染管线(Rendering Pipeline)的更多相关文章
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- Real-Rime Rendering (1) - 渲染管线(Rendering Pipeline)
提要 渲染管线是实时渲染中最重要的部分,它的最主要的任务就是在给定一个虚拟的场景,包括相机,object,灯光,纹理等等,生成一副2D的图像. 最基础的渲染管线如下图所示: 主要的阶段包括三个:App ...
- 高屋建瓴 cocos2d-x-3.0架构设计 Cocos2d (v.3.0) rendering pipeline roadmap(原文)
Cocos2d (v.3.0) rendering pipeline roadmap Why (the vision) The way currently Cocos2d does rendering ...
- Rendering pipeline overview(读书笔记1 --- Real-Time rendering)
1. Rendering pipeline的作用就是在给定的虚拟相机.三维物体.光源.着色方程式.纹理等的条件下产生(渲染)二维图像 2. pipeline包含很多个stage,其效率由最慢的stag ...
- OpenGL渲染管线(rendering pipeline)
OpenGL中的渲染管线包括:顶点着色器(vertex shader).细分着色器(里面包含两种:细分控制着色器和细分控制着色器)(tessellation shader).几何着色器.光栅化及片元着 ...
- graphic rendering pipeline
整理下管线 此时一定要有这张图 注意表中的数据流向 强调几个细节 之前对次序理解有点乱 rasterizer之前 管线里是只有逐顶点信息的 IA里面会setup primitive 通过Primit ...
- Geometry Stage in Rendering pipeline (读书笔记2 --- Real-Time rendering)
Geometry Stage一般包含下面几个阶段 1. Model & View Transform(模型和视图变换) --- 模型空间--> 世界空间 模型变换:每个模型经过模型变换来 ...
- 现代OpenGL渲染管线介绍
原文摘选自 现代OpenGL渲染管线介绍 此文对最新的OpenGL做一个简单的介绍,如有理解错误,敬请指正.英文原文: https://glumpy.github.io/modern-gl.html ...
- [OpenGL红宝书]第一章 OpenGL概述
第一章 OpenGL概述 标签(空格分隔): OpenGL 第一章 OpenGL概述 1 什么是OpenGL 2 初识OpenGL程序 3 OpenGL语法 4 OpenGL渲染管线 41 准备向Op ...
随机推荐
- JMeter执行压测输出HTML图形化报表(一)
一.应用场景 1.无需交互界面或受环境限制(linux text model) 2.远程或分布式执行 3.持续集成,通过shell脚本或批处理命令均可执行,生成的测试结果可被报表生成模块直接使用,便于 ...
- springboot创建错误
1.Unknown system variable 'query_cache_size' 解决:https://www.cnblogs.com/nicknailo/articles/9074804.h ...
- windows搭建RocketMQ服务
写在前面: 1.基于rocketmq 4.2.0版本 2.64位 win10 系统 3.JDK 1.8 (注意,jdk路径一定不要有空格,不然执行相应的cmd命令时会报错) 4.其它需要的软件,mav ...
- iframe获取元素
原生js在网页中,父元素获取iframe中的元素: window.onload=function () { 例如: console.log(window.frames["iframe的nam ...
- 51Nod1675 序列变换 数论 莫比乌斯反演
原文http://www.cnblogs.com/zhouzhendong/p/8665675.html 题目传送门 - 51Nod1675 题意 给定序列$a,b$,让你求满足$\gcd(x,y)= ...
- eclipse里面svn比较之前版本的代码
team——显示资源历史记录比较
- NN:实现BP神经网络的回归拟合,基于近红外光谱的汽油辛烷值含量预测结果对比—Jason niu
load spectra_data.mat plot(NIR') title('Near infrared spectrum curve—Jason niu') temp = randperm(siz ...
- Cinema CodeForces - 670C (离散+排序)
Moscow is hosting a major international conference, which is attended by n scientists from different ...
- Codeforces 853B Jury Meeting (差分+前缀和)
<题目链接> 题目大意: 有$ n(n<=1e5)$个城市和一个首都(0号城市),现在每个城市有一个人,总共有$ m (m<=1e5)$次航班,每个航班要么从首都起飞,要么飞到 ...
- HDU2255 奔小康赚大钱 (最大权完美匹配) 模板题【KM算法】
<题目链接> 奔小康赚大钱 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊 ...