unity shader学习1

 

1,渲染流水线:将摄像机,光源,纹理,模型,shader渲染成或者说生成一张二维纹理。比如电脑屏幕是一个平面,平面里有一张图片,这张图片因为图片上的每个点的颜色都不同,明暗阴影,所以看起来像是3d的。
渲染管线主要分为三个阶段:应用程序阶段、几何阶段、光栅阶段。

应用程序阶段:准备顶点坐标、法向量、纹理坐标、纹理等数据
这个阶段主要是和CPU、内存打交道,在把该计算的都计算完以后,在这个阶段的末端,这些计算好的数据(顶点坐标、法向量、纹理坐标、纹理)就会通过数据总线传给图形硬件,作为我们进一步处理的源数据。

几何阶段:顶点着色器(坐标变换等),几何着色器,裁剪,屏幕映射
几何阶段的主要工作就是“变换三维顶点坐标”和“光照计算“,通过顶点着色器,几何着色器,裁剪,屏幕映射,最终目的就是让GPU可以将这些三维数据绘制到二维屏幕上。

光栅化阶段:三角形设定,三角形遍历,像素(片段)着色器,合并
顶点和图元已经对应到像素,之后的流程就是如何处理像素,即给像素赋予颜色值。 在更新帧缓存之前,执行最后一系列针对每个片段的操作,其目的是计算出每个像素的颜色值。在这个阶段,可能存在遮挡剔除,融合,过滤等操作。该阶段之后,像素的颜色值被写入帧缓存中。

合并过程:像素,模板测试,深度测试,混合,如何写入颜色缓冲区。
unity的渲染流水线中,深度测试是在像素(片段)着色器之前的,可以提早将不需要的像素舍弃。这种技术叫Early-Z技术。但是如果提前的话,比如透明度测试,会出问题,8.3节会讲。
屏幕上显示的就是颜色缓存区的颜色值。使用双重缓冲,保证我们看到的图像是连续的。场景的渲染发生在幕后,即后置缓冲中。前置缓存区是我们现在看到的内容,后置缓冲完成之后,交换前后缓冲的内容,保证我们看到的图像是连续的。
如图所示:
2.3.8 3附图

2,OpenGL与DX
显卡驱动相当于显卡的操作系统,DX是接口,调用这些接口就可以和GPU沟通。程序调用DX接口,DX接口向显卡驱动发送命令,显卡驱动再与GPU沟通。显卡驱动将DX的函数翻译成GPU能够听懂的语言,同时把纹理格式转化成GPU支持的格式,并存储在显存中。

固定管线渲染:只提供一些配置操作,运行在较旧的GPU上,基本上已经退出历史舞台,OpenGL3.2就已经不支持了,可以通过可编程管线模拟固定编程管线。

draw call:CPU调用图像编程接口,DX中的一个函数,发送一个渲染命名,告诉GPU开始渲染。通过调用draw call告诉GPU开始一个渲染过程。
操作系统提供一个命令缓冲区,CPU把需要渲染的命令放入,GPU取命令,相互独立。命令有很多种,draw call就是一种,当draw call很多时,drawcall都需要很多准备工作,所以导致GPU闲置。
这里drawcall影响绘制的原因主要是因为每次绘制时,CPU都需要调用drawcall而每个drawcall都需要很多准备工作,检测渲染状态、提交渲染数据、提交渲染状态。而GPU本身具有很强大的计算能力,可以很快就处理完渲染任务。当DrawCall过多,CPU就会很多额外开销用于准备工作,CPU本身负载,而这时GPU可能闲置了。


减少draw call:
1,避免使用大量的很小的网格。有必要可以合并网格,合并的条件至少是:同材质、同shader。最好,同贴图,网格顶点格式也一致。
2,避免使用过多的材质,尽量在不同网格之间使用同一个材质。
3,批处理:对静态物体使用批处理。在cpu的内存中合并网格是有消耗的,静态物体只需一次,动态物体每帧都要重新合并。批处理的物体使用的是同一种渲染状态,应该是:同材质、同shader就行。

 

矩阵:

2个向量做点积可以求到一个向量在另一个向量上的投影,这个是默认的,以此为基础可以得到(可能有点蒙,只能记住,因为这是定理):2个单位向量的点积等于向量夹角的余弦值,也就是2个向量的点积等于2个向量的模乘上余弦值,向量的模(3,4)=3*3+4*4=25开根号=5。arcos()反余弦可以得到夹角的值。

2个向量的叉积的模等于2个向量的模乘上正弦值。2个向量的叉积任然是一个矢量,新的矢量垂直于当前矢量构成的平面,根据左右手坐标系你可以判断方向。你可以根据公式求出新的的矢量之后,再由新的矢量求模。等效于2个向量的模乘上正弦值。

正交矩阵:一个方阵的逆矩阵=转置矩阵,因为逆矩阵比较难求,而转置矩阵好求。转置矩阵*方阵=单位矩阵。一般是这样的才可以满足:
010            000
010            111
010 (方阵)   000  (转置矩阵)   
一个正交矩阵的行和列之间分别构成了一组标准正交基。标准正交基:就相当于模为1的坐标轴,他们相互垂直,正交基:就相当于模不为1的坐标轴,基矢量:就相当于坐标轴。

一个矢量(1,2,3),把他当成行矩阵还是列矩阵处理是不同的。unity中一般都是当成列矩阵,且是从右往左计算,比如:矩阵1*矩阵2*矢量=矩阵1*(矩阵2*矢量)
 

 

 

 

其他:
unity内部会把所有的Pass名称转换成大写,所以pass名称要大写。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值