*2.3 着色器的渲染流程
定点数据->定点作色器(接收定点数据,单独处理每个顶点)-》细分作色器(描述物体的形状,在管线中生成新的几何体处理(平顺)模型生成最终状态)->几何作色器-》图元设置-》剪切(剪切视口之外的绘制)-》光栅化(输入图元的数学描述,转化为与屏幕对饮的位置像图片元,简称光栅化)->片元作色器(片元颜色以及深度值,然后船体到片元测试和混合模块)--》效果
*2.4 着色器的渲染
- 定点卓色器()
2 细分着色器()
3 几何着色器
4 片元做色器
- 什么是管线?(一环套一环 类似流水线)
- 什么是可编程的管线(开放的2给着色器给开发者编程Shader(语言GLSL))
- 什么是固定管线(封装好的API)
在渲染过程中可能产生的问题
在绘制3D场景的时候,我们需要解决那些部分是对观察者课件的,或者纳西部分是对管材这不课件的。对应不课件的部分,应该及早丢弃,例如在一个不透明的青碧后,就不应该渲染。这种情况叫做“影藏面消除”(Hidden surface elimination).
2.5.1 油画法
-
油画算法
1 先绘制场景中的离观察者较远的物体,在绘制较进的物体。(基本没人用,有渲染的性能问题。同一个地方会绘制多次。解决不了图片交叉的问题)
2 例如下图先绘制红色部分在绘制黄色部分,左后绘制灰色部分,即可解决隐藏面消除的问题
2.5.2
正背面剔除法(Face Culling)
背景
尝试相依一个3D图形,你从任何一个方向去观察,罪错可以看多几个面?
答案是,最多3个面,从一个立方体的任意位置和方向上看,你不可能看到多于3个面。
那么思考?我们为何要多于的去绘制那根本看不到的3个面?
如果我们能以一种方式去丢弃这部分数据,OpenGL在渲染的性能即可提高超过50%。解决问题
如何知道一个面在观察者的视野中不会出现。
任何平面都有2个面,正面、背面。一位置一个时刻只能看到一面。
OpenGL 可以做到检查所有正面朝向观察者的面,并渲染他们。从而丢弃背面朝向的面。这样可以节约片元着色器的性能。
如果告诉OpenGL 你绘制的图形,那个面试正面,那个面是背面? 答案:通过分心定点数据的顺序了解深度
什么是深度
深度其实就是该像素点在3D事件中距离摄像机的距离。Z值。
什么是深度缓冲区
深度缓冲区,就是一块内存区域,转么存储着每个像素点(绘制在屏幕上的)深度值。深度值(Z值)越大,则离摄像机就越远。
为什么需要深度缓冲区
在不适用深度测试的时候,如果我们先绘制一个距离比较近的问题,在绘制距离比较远的物体,则距离远的位图因为偶绘制,会把距离近的问题覆盖掉。有了深度换缓冲区后,绘制物体的顺序就不那么重要的,实际上,只要存在深度缓冲区,OpenGL都会把像素的深度值写入到缓冲区中,除非调用glDepethMask(GL_FALSE).来禁止写入。深度测试
深度缓冲区(DepthBuffer)和颜色缓冲区(ColorBuffer)是对应的。颜色缓冲区存储像素的颜色信息,而深度缓冲区存储的深度信息。在决定是否绘制一个物体表面时,首先要将表面对应的像素的深度值与当前深度缓冲区中的值进行比较。如果大于深度缓冲区中的值,则丢弃这部分,否则利用这个像素对应的深度值和颜色值。粉笔跟新深度缓冲区和颜色缓冲区,这个过程称为“深度测试”。
3.1 ZFighting闪烁问题的原因
以为开启深度测试后,OpenGL就不会再去控制模型别遮挡的部分,这样实现的显示更加真实。但是由于深度缓冲区精度的限制,对应深度相差非常小的情况下。(例如在同一平面上进行2次制),OpenGL就可能出现不能争取判断两者的深度值,会导致深度测试IDE结果不可预测,显示出来的现象事时交错闪烁,的亲2个画面,交错出现。
解决方法
一 请用Pplygon Offset方式解决
解决方法:然深度值之间产生剑客,如果2个图形之间有间隔,是不是一味这就不会产生干涉。可以理解为在执行深度测试前将立方体的深度值做一些细微的增加。于是就能将重叠的2个图形深度值之间有所区别
启用Pllygon Offset方式
glEnable(GL_POLYGON_OFFSET_FILL)
参数列表
GL_POLYGON_OFFSET_POINT 对应光栅化模式:GL_POINT
GL_POLYGON_OFFSET_LINE 对应光栅化模式:GL_LINE
GL_POLYGON_OFFSET_FILL 对应光栅化模式:GL_FILL
第二步
制定偏移量
通过glPolygonOffset来指定glPolygonOffset 需要两个参数:factor,units
每个Ffagment的深度都会增加如下所示的偏移量。
Offset = (mfactor)+(runits)
m:多变性的深度的斜率的最大值,理解一个多边形越是与近裁剪面平行,m就越接近于0.
r : 能产生于窗口左边系的深度值种可分辨的差异最小值。r是由具体OpenGL平台指定的一个常量。
一个大于0的offset 会把模型推到离你(摄像机)更远的位置,响应一个小于0的Offsect 会把模型拉近
一般而言,只需要将-1 和0 这样简单赋值给glPolygonOffset基本可以满足需求。
void glPolygonOffset(Glfloat factor,Flfloat units);
应用到片上总偏移计算方程式
Depth Offset = (DZfactor)+(funits);
DZ 深度值(Z值)
r:是的深度缓冲区产生变化的最小值。
负值:将使得z值距离我们更近,而正值,将使的Z值距离我们更远。
第三部:关闭Polygon Offset
glDisable(GL_POLYGON OFFSET_FILL)
ZFighting闪烁问题预防
1.不要将2个物体靠的太近,避免渲染时三角形叠在一起。这中方式要求对场景中物体出入一个少量的偏移,那么久可能避免ZFighting现象。例如上面的立方体和平面下移0.001f就可以解决这个问题。当然手动去插入这个小的偏移是要付出代价的。
尽肯恩将近裁剪面设置的离观察者远一些。上面我们看到,在近裁剪平面附近,深度的精确度是很高的,因此尽可能让近才见面远一些的话,会使整个裁剪范围内的精度变高一些。但是这种方式会是离观察者较近的物体被裁剪掉,因此需要调试好裁剪面参数。
使用更高位数的深度缓冲区,通常使用的深度缓冲区是24位的,现在一些硬件使用32位的缓冲区,是精度得到提高。
四 混合
我们把OpenGL 渲染时会把颜色值存在颜色缓冲区中,每个片段的深度值也是放在深度缓冲区。但深度缓冲区被关闭时,新的颜色将简单的付给原来颜色缓存区存在的颜色值,当深度缓冲区再次打开时,新的颜色片段只是当他们比原来的值更接近邻居的裁剪平面才会替换原来的颜色片段。
glEnable(GL_BIEND);
4.1 组合颜色
目标颜色:已经存储在颜色缓存的颜色值。
缘来颜色:作为当前渲染命令结果进入颜色缓存区的颜色值。
当前混合功能被启动时,源颜色和目标颜色的组合方式是混合方程式控制的。在默认情况下,混合方程式如下:
Cf = (Cs*S)+(Cd *D);
Cf:最终计算参数的颜色。
Cs:源颜色
Cd:目标颜色
S:混合因子
D 目标混合因子