Shader入门笔记(一)

前言:

参加实习也好一阵子了,目前还没有遇到图形学的开发问题。为了更深入真正的游戏开发世界,也为了做项目接下来的与shader编程有关的功能而准备,准备开一系列帖子,做一下shader编程的笔记。
前段时间读《Unity入门精要》(冯乐乐著)总是读了忘忘了读,这系列笔记将主要依据这本书的知识体系记录一下本人学到的UnityShader知识。

正篇:

一 渲染流水线:

渲染流水线的任务是从一系列顶点数据和纹理信息出发,把这些信息转换成人眼可见的图像,这个工作通常是GPU和CPU共同完成的。

渲染流水线的三个阶段:
渲染流水线可以被分为三个阶段:应用阶段,几何阶段,光栅化阶段。

三个阶段都做了什么:

应用阶段(CPU):可以对应我们Unity开发的时候对场景数据的操作,这个阶段完全由开发者决定。

应用阶段中,开发者主要有三个任务:
1.准备好场景数据,比如摄像机的位置,视锥体,场景中包含了哪些模型,使用了哪些光源等等。
2.为了提高渲染性能,做一个粗粒度剔除culling工作,将不可见的物体剔除出去。
3.设置好每个模型的渲染状态,包括它的材质(漫反射颜色,高光反射颜色),使用的纹理和shader等。

应用阶段的末期会输出渲染图元,通常是点,线,三角面等。

几何阶段(GPU):几何阶段用于处理所有和我们要绘制的几何相关的事情,决定绘制的图元是什么,怎样绘制,在哪里绘制等。

几何阶段中,开发者的任务:
1.几何阶段和每个渲染图元打交道,进行逐点,逐多边形的操作。
2.几何阶段的另一个重要任务就是把顶点坐标变换到屏幕空间中,然后交由光栅器处理。
通过对渲染图元的多步处理后,将会输出屏幕空间的二位顶点坐标,每个顶点的深度值,着色等相关信息并传递给下一阶段。*

光栅化阶段(GPU):用上个阶段传递的数据产生屏幕上的像素,并渲染出最终图像。
1.决定每个渲染图元中的哪些像素应该被绘制在屏幕上。
2.对上一个阶段得到的逐顶点数据(纹理坐标,顶点颜色)进行插值,然后进行逐像素处理。

二 CPU和GPU之间的通信:

渲染流水线的起点是CPU,应用阶段大致分为三个阶段:
1.把数据加载到显存中
2.设置渲染状态
3.调用Draw Call

把数据加载到显存中渲染所需的数据从硬盘中加载到系统内存RAM中,然后网格和纹理,位置信息,法线坐标等数据又被加载到显卡上的显存。
通常情况下,把数据加载到显存后,RAM中数据就可以移除了。但是对于一些数据来说,cpu需要访问他们,(比如网格信息,cpu需要访问他们来进行碰撞检测)我们不希望这些被移除。

设置渲染状态:
定义场景中的网格是怎么被渲染的,用顶点着色器还是片元着色器,光源属性,材质等。

调用Draw Call:
DrawCall 是CPU向GPU发起的一个命令,这个命令仅仅只想一个需要被渲染的图元列表。给定了Draw Call,GPU就会根据渲染状态和所有输入的顶点数据进行计算(GPU渲染流水线)

三 GPU流水线:

几何阶段和光栅阶段可以分成更小的若干阶段,每个阶段GPU提供了不同的可配置性或者可编程性。

在这里插入图片描述
顶点着色器:完全可编程,通常用于实现顶点的空间变换,顶点着色等功能。
曲面细分着色器:是可选的着色器,用于细分图元。
几何着色器:可选着色器,用于执行主图元的着色操作或者被用于产生更多的图元
裁剪:不可编程,将不再摄像机视野内的顶点裁剪掉。
屏幕映射:可配置,可编程,负责每个图元的坐标转换到屏幕坐标上。
—————————————————————————————
三角形设置:三角形遍历:这两个阶段是固定函数。
片元着色器:完全可编程,用于实现逐片元着色操作。
逐片元操作:不可编程,但配置性很高。修改颜色,深度缓冲,进行混合等。
—————————————————————————————

顶点着色器

cpu输入的每个顶点都会调用一次顶点着色器。顶点着色器本身不创建或者销毁任何顶点,无法得到顶点之间的关系。
顶点着色器的需要完成的工作有:坐标变换和逐顶点光照。
1.坐标变换:顶点着色器可以在这一步改变顶点额位置(比如改变顶点位置来模拟水面 )。
2.一个最基本的顶点着色器必须完成的一个工作是:把顶点坐标从模型空间转换到齐次裁剪空间

裁剪

摄像机的视野范围很有可能不会覆盖所有场景的物体,哪些不在摄像机视野范围内的物体不需要被处理。

与NDC中单位立方体相交的图元会被裁剪,新的顶点会生成,原来在外部的顶点会被舍弃。

屏幕映射

屏幕映射的任务是将每个图元的x,y坐标转换到屏幕坐标系下,屏幕坐标系是一个二维坐标系,和屏幕分辨率有很大关系。

屏幕坐标系和z坐标一起构成了窗口坐标系,这些值会被传递到光栅化阶段。

三角形设置:这个阶段计算光栅化一个三角网格所需的信息。上一阶段我们得到三角形网格每条边的两个顶点,我们要计算每条边上的像素坐标,就要得到三角形的表示方式。这个计算三角形网格表示数据的过程叫做三角形设置。

三角形遍历:这个阶段会检查每个像素是否被一个三角网络覆盖。如果被覆盖,则生成一个片元。这样找到那些像素被三角形网格覆盖的过程叫三角形遍历,也成为扫描变换。

三角形遍历的结果是一个片元序列。一个片元不是像素,而是这个像素的屏幕坐标,深度信息,和其它从集合阶段输出的顶点信息(纹理坐标,法线等)等很多状态的集合

片元着色器:片元着色器的输入是顶点着色器中输出的数据插值得到的,输出是一个或多个颜色。

这一阶段完成很多哦重要的渲染技术,最重要的技术之一就是纹理采样:使用顶点着色器阶段输出的每个顶点对应的纹理坐标,经过光栅化对三角网格的三个顶点纹理坐标进行插值以后,可以得到覆盖该片元的纹理坐标。

片元着色器尽仅可以影响单个片元,不可以将自己的任何结果直接发送给他的邻居们。有一个例外是片元着色器可以访问导数信息。

逐片元操作:也被称为输出合并阶段。
这个阶段的主要任务有:
1.决定每个偏远的可见性:深度测试,模板测试等;
2.如果一个片元通过了所有的测试,就把这个片元的颜色值和已经存储在颜色缓冲区里的颜色进行合并,最后写入颜色缓冲区中。

模板测试:在模板缓冲区中找到该片元的模板值和参考值比较,通过开发者指定的比较函数来决定是否舍弃。不管一个片元是否通过模板测试,都可以根据测试结果来修改模板缓冲区。

深度测试:该片元在深度缓冲区的值通过由开发者指定的比较函数和参考值比较。如果一个片元没有通过深度测试,就没有权力改变深度缓冲区里的值。如果片元通过了测试,还可以指定是否要用这个片元的深度覆盖掉原有的深度值。
合并:决定覆盖颜色缓冲区的像素值还是进行其他操作。混合操作:如果关闭混合,直接用该片元的颜色值替换掉颜色缓冲区的像素值。如果开启混合,得到片元源颜色和存在与颜色缓冲区的目标颜色进行混合操作,更新颜色缓冲区的值。

Unity的流水线中,深度测试实在片元着色器之前(Early-Z)

为了避免我们看到正在光栅化的图像,GPU采用双重缓冲策略,场景被渲染到后置缓冲后再与前置缓冲交换。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值