学习shader之前必须知道的东西之计算机图形学(一)渲染管线

引言
shader到底是干什么用的?shader的工作原理是什么?

其实当我们对这个问题还很懵懂的时候,就已经开始急不可耐的要四处搜寻有关shader的资料,恨不得立刻上手写一个出来。但看了一些资料甚至看了不少cg的语法之后,我们还是很迷茫,UNITY_MATRIX_MVP到底是个什么矩阵?它和v.vertex相乘出来的又是什么玩意?当这些问题困扰我们很久之后,我们才发现,原来我们是站在浮沙上筑高台,根基都没有打牢当然不可能盖得起高楼大厦了。

那根基是什么呢?大牛曰,计算机图形学。

shader中文名叫着色器,顾名思义,它的作用可以先简单理解为给屏幕上的物体画上颜色。而什么东西负责给屏幕上画颜色?当然是GPU,所以我们写shader的目的就是告诉GPU往屏幕哪里画、怎么画。说到这其实大家应该很明白了,如果我们连GPU的工作原理都不知道,何谈指挥它?

说到计算机图形学,包括我在内很多同学都非常害怕它,因为里面包含了各种艰深的理论、变换,大量的公式什么的。其实我们大可不必一开始就吓倒自己,先从基本概念开始,慢慢来,总有一天我们也会成为大牛~!

最后,这篇文章不算是原创,最多算是摘要+读后感,很多概念性文字都是我从书里搬过来后再加上自己的理解,算是和大家一起学习,有理解不当之处还请多多指教。

废话不多说,让我们来进入第一章的学习,GPU的渲染管线。



正文

所谓GPU的渲染管线,听起来好像很高深的样子,其实我们可以把它理解为一个流程,就是我们告诉GPU一堆数据,最后得出来一副二维图像,而这些数据就包括了”视点、三维物体、光源、照明模型、纹理”等元素。

在各种图形学的书中,渲染管线主要分为三个阶段:应用程序阶段、几何阶段、光栅阶段。

1,应用程序阶段。

这个阶段相对比较好理解,就比如我们在Unity里开发了一个游戏,其实很多底层的东西Unity都帮我们实现好了,例如碰撞检测、视锥剪裁等等,这个阶段主要是和CPU、内存打交道,在把该计算的都计算完以后,在这个阶段的末端,这些计算好的数据(顶点坐标、法向量、纹理坐标、纹理)就会通过数据总线传给图形硬件,作为我们进一步处理的源数据。

2,几何阶段。

主要负责顶点坐标变换、光照、裁剪、投影以及屏幕映射,改阶段基于GPU进行运算,在该阶段的末端得到了经过变换和投影之后的顶点坐标、颜色、以及纹理坐标。简而言之,几何阶段的主要工作就是“变换三维顶点坐标”和“光照计算”。

问题随之而来,为什么要变换顶点坐标?我是这么理解的,比如你有一个三维游戏场景,场景中的每个模型都可以用一个向量来确定它的位置,但如何让计算机根据这些坐标把模型正确的、有层次的画在屏幕上?这就是我们需要变换三维顶点坐标的原因,最终目的就是让GPU可以将这些三维数据绘制到二维屏幕上。

根据顶点坐标变换的先后顺序,主要有如下几个坐标空间:Object space,模型坐标空间;World space,世界坐标空间;Eye space,观察坐标空间;Clip and Project space,屏幕坐标空间。下图就是GPU的整个处理流程,深色区域就是顶点坐标空间的变换流程,大家了解一下即可,我们需要关注的是每个坐标空间的具体含义和坐标空间之间转换的方法。

2.1,从object space到world space

object space有两层核心含义,第一,object
space中的坐标值就是模型文件中的顶点值,这些值是在建立模型时得到的,例如一个.max文件,里面包含的数据就是object
space的坐标。第二,object space的坐标与其他物体没有任何参照关系,这是object space和world
space区分的关键。world
space坐标的实际意义就有有一个坐标原点,物体跟坐标原点相比较才能知道自己的确切位置。例如在unity中,我们将一个模型导入到场景中以后,它的transform就是世界坐标。

2.2,从world space到eye space

所谓eye space,就是以摄像机为原点,由视线方向、视角和远近平面,共同组成的一个梯形体,如下图,称之为视锥(viewing
frustum)。近平面,是梯形体较小的矩形面,也是靠近摄像机的平面,远平面就是梯形体较大的矩形,作为投影平面。在这个梯形体的内的数据是可见的,超出的部分会被视点去除,也叫视锥剪裁。

例如在游戏中的漫游功能,屏幕的内容随摄像机的移动而变化,这是因为GPU将物体的顶点坐标从world space转换到了eye space。

2.3,从eye space到project and clip space

eye space坐标转换到project and clip
space坐标的过程其实就是一个投影、剪裁、映射的过程。因为在不规则的视锥体内剪裁是一件非常困难的事,所以前人们将剪裁安排到一个单位立方体中进行,这个立方体被称为规范立方体(CCV),CVV的近平面(对应视锥体的近平面)的x、y坐标对应屏幕像素坐标(左下角0、0),z代表画面像素深度。所以这个转换过程事实上由三步组成:

(1),用透视变换矩阵把顶点从视锥体变换到CVV中;

(2),在CVV内进行剪裁;

(3),屏幕映射:将经过前两步得到的坐标映射到屏幕坐标系上。

2.4,primitive assembly(图元装配)和triangle setup(三角形处理)

到目前为止我们得到了一堆顶点的数据,这一步就是根据这些顶点的原始连接关系还原出网格结构。网格由顶点和索引组成,这个阶段就是根据索引将顶点链接到一起,组成线、面单元,然后进行剪裁,如果一个三角形超出屏幕以外,例如两个顶点在屏幕内,一个顶点在屏幕外,这时我们在屏幕上看到的就是一个四边形,然后把这个四边形切成两个小的三角形。

现在我们得到了一堆在屏幕坐标上的三角形面片,这些面片是用于光栅化的。

3,光栅化阶段。

经过上面的步骤之后,我们得到了每个点的屏幕坐标值,和我们需要绘制的图元,但此时还有两个问题:

(1)屏幕坐标是浮点数,但像素是用整数来表示的,如何确定屏幕坐标值所对应的像素?

(2)如何根据已确定位置的点,在屏幕上画出线段或者三角形?

对于问题1,绘制的位置只能接近两指定端点间的实际线段位置,例如,一条线段的位置是(10.48, 20.51),转换为像素位置就是(10,21)。

问题2,涉及到具体的画线和填充算法,有兴趣的话可以研究。

这个过程结束后,顶点和图元已经对应到像素,之后的流程就是如何处理像素,即给像素赋予颜色值。

给像素赋予颜色的阶段称为Pixel Operation,是在更新帧缓存之前,执行最后一系列针对每个片段的操作,其目的是计算出每个像素的颜色值。在这个阶段,被遮挡的面通过一个被称为深度测试的过程消除。

pixel operation包含下面这些流程:

(1)消除遮挡面;

(2)Texture operation,纹理操作,根据像素的纹理坐标,查询对应的纹理值;

(3)Blending,通常称为alpha blending,根据目前已经画好的颜色,与正在计算的颜色的alpha值混合,形成新的颜色。

(4)Filtering,将正在计算的颜色经过某种滤镜后输出。

该阶段之后,像素的颜色值被写入帧缓存中。

时间: 2024-10-25 00:00:49

学习shader之前必须知道的东西之计算机图形学(一)渲染管线的相关文章

这两天学习perl,总结的一些东西!

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

计算机图形学的学习资源

计算机图形学(Computer Graphics,简称CG)是一个令人着迷的领域,本文整理了一些图形学相关的学习资源. Wikipedia的介绍,及其后面附的"参考文献"和"外部链接"总是值得一看的: Computer graphics:主要介绍图形学的历史: Computer graphics (computer science):介绍图形学学科,后面附了知名研究者,以及著名大学的图形学小组: 3D computer graphics:这是图形学中最重要的部分:

初次学习shader

Shader "Custom/Diffuse Texture" { //在shader中的位置 Properties { //着色器的属性 _MainTex ("Base (RGB)", 2D) = "white" {}//每一条属性的定义的语法是这样的:_Name("Display Name", type) = defaultValue[{options}] 注释:① } SubShader { //表面着色器 Tags {

用别人的钱和时间进行学习(可以学到很多东西,创业成功多了把握,而且缓解财务压力),善于利用已有资源,别着急,只要不断工作、不断学习然后保持耐心即可

我还是个小孩的时候,曾经在堂兄的礼品店干过. 那些漫长炎热的夏天实在是太无聊了,所以我甚至都没开口让他给我工钱. 不过有一天我突然想到了一个好点子.我可以跑到山里面,到当地果园摘一些无花果,然后卖给游客. 我把这个计划告诉了堂兄. “这是个糟糕的想法,”他听了直摇头:“每个人都会问你的果是从哪儿来的.然后你就成小偷了.” 这是我的第一个商业点子——不过它还没有来得及开始就夭折了. 很多人相信成功的创业注定需要冒险. 要么你是个守着柠檬汁小摊的 8 岁小孩,要么就是没有合适的东西. 就像 Remi

Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐标系下进行的. 一个二维的笛卡尔坐标系包含了两个部分的信息: 一个特殊的位置,即原点,它是整个坐标系的中心. 两条过原点的互相垂直的矢量,即X轴和Y轴.这些坐标轴也被称为是该坐标的矢量. OpenGL 和 DirectX 使用了不同的二维笛卡尔坐标系.如下图所示: 2)三维笛卡尔坐标系 在三维笛卡尔坐标系中,

【系统学习Shader与后处理】第2篇:uv控制之water

我们每要实现一个效果,就如这个系列开头所说,先分析效果需要用什么模式来实现. 我们发现,水流动的效果跟uv有关,所以我们需要去控制uv. 控制uv一般有三种方式: 1.time 2.采样其他图 3.C#输入参数 然后根据这些参数,用某个公式实现 这个shader,使用了time + 采样其他图 +C#输入参数 使用time,是为了达成两个目的, 第一个目的是time参数平滑递增, 第二个目的是uv本身的特点,是随着超出uv的范围后,又会回到uv起始位置. 所以使用了time,我们就可以让水流动起

学习MySQL我们应该知道哪些东西?

1.如何快速掌握MySQL? ⑴培养兴趣 兴趣是最好的老师,不论学习什么知识,兴趣都可以极大地提高学习效率.当然学习MySQL 5.6也不例外. ⑵夯实基础 计算机领域的技术非常强调基础,刚开始学习可能还认识不到这一点,随着技术应用的深 入,只有有着扎实的基础功底,才能在技术的道路上走得更快.更远.对于 MySQL的学习来说, SQL语句是其中最为基础的部分,很多操作都是通过SQL语句来实现的.所以在学习的过程中, 读者要多编写SQL语句,对于同一个功能,使用不 同的实现语句来完成,从而深刻理解

第三章 学习Shader所需的数学基础(5)

1. Unity Shader的内置变量(数学篇) 使用Unity写shader的一个好处在于,它提供了很多内置参数,这使得我们不在需要自己手动算一些值.本文给出Unity内置的用于空间变换和摄像机以及屏幕参数的内置变量.这些内置变量可以在UnityShaderVariables.cginc文件中找到定义和说明. 1.1 变换矩阵 首先是用于坐标空间变换的矩阵.表中给出了Unity5.2版本提供的所有内置变换矩阵.下面的所有矩阵都是float4×4类型的. 上表给出了这些矩阵的常用用法.但读者可

《Unity Shader 与 计算机图形学》第二章

提示:本篇将会非常长~ 本系列文章分为 硬件 编程入门 工程实践 上一篇 主要介绍了GPU的特征工作原理 以及渲染的底层流程 其实对于新架构而言还有所不同 Shader描述了如何渲染物体的信息,包括: Texture Setup.纹理设置 Material Property.材质设置 Render State.渲染状态 Blend Setup.混合设置 Pixel Shader.像素着色 Vertex Shader.定点着色 Render Target Setup 渲染目标设置 Shader并不