3.OpenGL渲染技巧

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3.OpenGL渲染技巧相关的知识,希望对你有一定的参考价值。

参考技术A 1.渲染过程产生的问题
看到了不透明墙壁后面的东西,不应该渲染墙壁后的东西(隐藏面消除)

2.油画渲染
距离观察者由远及近的绘制物体,可以解决。
但是这出现了新的问题,如果3个三角形互相叠加,油画算法将无法渲染。

3.正背面剔除
OpenGL可以检查朝向观察者的面并渲染它们,而丢弃背面。
OpenGL如何区分正背面?
通过分析顶点数据的顺序。

4.深度测试
深度:3D世界中像素点距离摄像机的距离。
深度缓冲区:一块内存区域、存储着每个像素点的深度值,值越大距离摄像机越远。
为何需要深度缓冲区?绘制顺序就不重要了。
深度测试:是否绘制物体表面,表面深度值和当前缓冲区深度值比较,大于则丢弃,否则更新像素颜色值和深度值。

5.多边形模型
6.多边形偏移
7.裁剪
8.颜色混合

1.谈谈图形图像渲染中的深度缓冲区?
一块内存区域、存储着每个像素点的深度值,值越大距离摄像机越远。
为何需要深度缓冲区?绘制顺序就不重要了。

2.阐述隐藏面消除解决方案?
正背面剔除、深度测试

3.阐述深度缓冲区带来的隐患、解决方案、预防方案?
原因:深度缓冲区的限制导致深度相差很小。
隐患:交错闪烁出现2个画面
解决方案:让深度值之间产生间隔,在执行深度测试前将立方体的深度值做一些细微的增加,区分重叠的2个图形深度值。
第一步:Polygon Offset方式解决。
glEnable(GL_POLYGON_OFFSET_FILL)
第二步:指定偏移量
void glPolygonOffset(Glfloat factor,Glfloat units);
第三步: 关闭Polygon Offset
glDisable(GL_POLYGON_OFFSET_FILL)

预防方案:
不要将2个物体靠的太近;将裁剪面设置的离观察者远一些;使用高位数的深度缓冲区。

1.深度测试

2.OpenGL 裁剪

3.OpenGL混合

通过OpenGL理解前端渲染原理

 

一、OpenGL

OpenGL,是一套绘制3D图形的API,当然它也可以用来绘制2D的物体。OpenGL有一大套可以用来操作模型和图片的函数,通常编写OpenGL库的人是显卡的制造者。我们买的显卡都支持特定版本的OpenGL。

下图是用OpenGL做的旋转的立方体。

技术图片

二、渲染原理

2.1 渲染管道

在OpenGL中,所有东西都在一个3D的空间里,而我们的屏幕和窗口都是2D的,所以OpenGL需要将3D的坐标转换成2D的坐标,做这件事的是OpenGL中的渲染管道(graphics pipeline)。

渲染管道可以分成两大部分:第一部分将3D坐标转换成2D坐标;第二部分把2D的坐标转换成实际的像素。

2.2 着色器

通常来说,渲染管道把一组3D坐标转换成屏幕上带有颜色的2D像素需要经过很多步。上一步的输出作为下一步的输入,所有步骤都是高度专一的,每步都有一个特定的函数,且可以很容易地并发执行。显卡有数千个处理核心来快速处理渲染管道中的数据,而这些是在每个步骤中通过运行在GPU上的多个小程序来处理的,这些小的程序被称之为程序着色器(shader)。

其中的一些着色器是可以配置的,开发者可以根据需求配置自己的着色器去替代已经存在的那些,这就让我们能够更自由和细粒度地控制渲染的过程。同时,因为它们运行在GPU上,又给我们保留了珍贵的GPU时间,在平时的开发中,我们也要充分利用GPU渲染来提高软件性能。

着色器通常使用GLSL来写,全称是OpenGL Shading Language。

2.3 举个例子

下图展示了一个抽象的渲染管线中的步骤,其中蓝色部分是我们可以注入自己的着色器。

技术图片

通过上图我们发现,要把顶点数据转换成全渲染的像素要经过很多步,接下来我们对每一个步骤和代码进行简单的解释。

我们在渲染管线中传入一组可以组成三角形的3D坐标数据,这组数据即顶点数据。顶点数据是顶点的集合,而一个顶点是一个3D坐标的集合。

渲染管线的第一步是顶点着色器(Vertex Shader)。我们这里传入的是一个简单的顶点,顶点着色器可以让我们做一些基础的处理操作,比如顶点的属性。

在初始装配阶段,也就是Shape Assembly阶段,从顶点着色器中输出的顶点会形成一个原始的形状。本例中,输出的顶点形成的是一个三角形。

从初始装配阶段到geometry shader阶段,我们可以通过发散其他顶点来形成新的图形,本例中形成了第二个三角形。

在Tessellation Shader阶段,可以把上一阶段给出的原型图再分割成若干个小的原型图。本例中,可以形成更多的三角形来创造一个更加平坦、顺滑的环境。这么说可能难以理解,我们结合下图来进一步阐述,这就是细分曲面着色器的作用。

技术图片

细分曲面着色器的下一阶段是光栅化阶段(Rasterzation stage),在这一阶段会对最终的原型和呈现在屏幕上的对应像素做一个映射,形成fragment,供下一阶段的fragment shader使用。

Fragment shader最主要的使命是计算出一个像素的最终颜色,在这个阶段我们可以使用OpenGL中一些高级的特效。通常fragment shader会包含3D界面的多个数据,包括灯光、阴影、颜色等等。

当所有对应的颜色都确定以后,最终的原型将会被传入最后一个步骤,我们称之为Alpha test and blending阶段。这个阶段会判断相应的深度,比如一个物体可能在另一个物体的后面,那它可能采用其他的颜色;或者如果该物体被遮挡,可能会被裁掉。

如上文所述,我们可以看到整个渲染管线的步骤和逻辑是十分复杂的,这其中包含了很多个可以改变的步骤,但我们一般只操作Vertex Shader 和 fragment shader,其他的着色器我们会直接采用默认的。在实际的OpenGL编程中,我们至少需要定义一个Vertex Shader和Fragment shader。(需要说明的是,OpenGL 3.1之前的版本包含了固定管线,从3.1版本开始,固定管线从核心中删掉了,因此我们必须使用着色器去工作)。

三、总结

本文为该系列文章的第一篇,先简单介绍OpenGL的一些原理,后续文章中会添加新的代码分析,包括着色器(Shader)、纹理(Textture)、变形(transformation)、坐标系统(Coordinate systems)、相机(Camera)等。

作者:崔晓迪

以上是关于3.OpenGL渲染技巧的主要内容,如果未能解决你的问题,请参考以下文章

Opengl_7_ *SwapBuffers

如何使用 OpenGL 3.3 格式的 QPainter?

ⓅChapter 1-Introduction

离屏帧缓冲区opengl上的glGetPixels

OpenGL 图片从文件渲染到屏幕的过程

QT5.3.1成功安装Failed to create OpenGL context错误解决方法