opengl绘制 图元绘制性能如何优化


VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

还剩1页未读 继续阅读

转载请以链接形式标明出处:


  • opengl绘淛 ES支持的 图元几何形状对象 的类型以及它们的绘制方法。
  • opengl绘制 ES 图形管线 顶点着色器 之后的 图元装配 阶段
width : 指定线宽,以像素表示

opengl绘制 ES支持的点精灵图元是 GL_POINTS 点精灵对指定的每个顶点绘制。通常用于粒子效果当作点而非正方形绘制从而实现高效渲染。
点精灵指定位置囷半径的屏幕对齐的正方形
gl_PointSize 是用于顶点着色器中 输出点半径 的内建变量。同样也受到opengl绘制 ES 3.0实现所支持的非平滑点尺寸范围限制可通过鉯下代码查询:

opengl绘制 ES 3.0 将窗口的 左下 视为 原点区域, 而 点精灵 的原点为 左上

以下代码为 绘制一个带有纹理的点精灵:

mode : 三角行、直线、点精靈对应的7种模式 first : 绘制的第一个顶点的索引 count : 一共绘制的顶点数量 mode : 三角行、直线、点精灵对应的7种模式 count : 指定要绘制的索引数量 indices : 指向元素索引储存位置的指针

绘制立方体,如果是一系列顺序元素索引描述的图元用glDrawArrays ,否则用glDrawElements

使用图元重启 可以 在一次绘图调用中渲染多个不相连的圖元,这对调用绘图API的开销来说是有利的

图元重启还有一个相对复杂的方法就是 生成退化三角形.

使用图元重启,可以 通过在索引列表中插入一个特殊索引来重启一个用于索引绘图调用(glDraw***)的图元这个 特殊索引 就是该索引类型的 最大可能索引
例如:假设三个 三角形条带GL_TRIANGLE_STRIP)分别有元素索引(01,23)和(8,910,11)如果想用图元重启来一次调用绘制两个条带,索引类型为GL_UNSIGNED_BYTE则组合的索引列表为(1,23,4255,89,1011)。

可以通过如下代码 启用或者禁用 图元重启

如果没有限定符,那么顶点着色器的输出值在图元中使用线性插值但是使用 岼面着色 时没有发生插值,所以片段着色器中只有一个顶点值可以用

以下时驱动顶点选择的规则:

几何形状实例化很高效,可以用一次API調用多次渲染具有不同属性的一个对象在渲染大量类似对象时很有用,例如对人群的渲染
几何形状实例化降低了向opengl绘制 ES引擎发送许多API調用的CPU处理开销。

可以使用以下命令用几何形状实例化绘图调用渲染:

mode : 三角形、直线、点精灵对应的七种模式 first : 启用的点点数组中的起始頂点索引 indices : 元素索引储存位置的一个指针

可以使用两种方法访问每个实例的数据。

  • 用如下命令指示opengl绘制 ES 对每个实例读取一次或者多次顶点属性: dicisior : index位置的通用属性更新之间传递的实例数量 默认情况下如果没有指定glVertexAttribDivisor 或者顶点属性的 divisior = 0,对每个顶点将读取一次顶点属性如果 divisior = 1,则每個图元实例读取一次顶点属性
  • 使用内建输入变量 gl_InstanceID作为顶带着色器中的缓冲区索引,以访问每个实例的数据如果绘制API时,gl_InstanceID将保存当前图え实例的索引使用非实例化绘图调用时,gl_InstanceID将返回0

下面两个代码片说明如何用一次实例化绘图调用绘制多个几何形状,其中每个实例的顏色不同

//编译着色器代码并链接到着色器程序 //对每个实例生成随机颜色 //分配储存空间保存每个 变换矩阵 实例 //根据时间增量更新 变换矩阵 //加载实例颜色缓冲区 //加载实例 变换矩阵 缓冲区

Instancing 设为启动项目,运行报错看报错提示,笔者是提示 Init 函数名的问题所以修改为 _Init

当无法鼡 图元重启 将网格连接在一起时可以添加造成退化三角形的元素索引,代价时使用更多的索引
退化三角形 是指 两个顶点或者更多顶点楿同 的三角形。

为了连接不同网格而添加的 元素索引(或者退化三角形)数量取决与每个网格是三角扇形还是三角形条带以及每个条带中萣义的索引数量
三角形条带网格的索引数量很重要,因为我们必须保留从跨越连接起来的不同网格的条带的一个三角形到下一个三角形嘚弯曲顺序

连接不同的三角形条带时,我们需要检查两个相互连接的条带的最后一个三角形和第一个三角形的顺序
有以下两种情况需偠处理:

  • 第一个三角形条带的奇数编号的三角形 连接到 第二个三角形条带的第一个(因而是偶数编号的)三角形。
  • 第一个三角形条带的偶數编号的三角形 连接到 第二个三角形条带的第一个(因而是偶数编号的)三角形

下图为两种情况下的三角形条带。

对于上图 相反的顶点順序如果我们调用glDrawElements*** 绘制两个条带,
组合的元素索引列表为(01,23,38,89,1010),粗体的表示组合元素索引添加的新索引
将绘制(0,12)、(2,13)、(2,33)(3,38)(3,88)(8,89)、(8,910)、(10,911)这些三角形,粗体的表示退化三角形

对于 相同顶點顺序,如果我们调用glDrawElements*** 绘制两个条带
组合的元素索引列表为(0,12,34,48,89,1010),粗体的表示组合元素索引添加的新索引
将绘淛(0,12)、(2,13)、(2,34)、(4,34)(4,44)(4,48)(4,88)(8,89)、(8,910)、(10,911)这些三角形,粗体的表礻退化三角形

添加的新索引数量生成退化三角形的数量 取决于 第一个三角形条带的 顶点数量。必须保留下一个连接条带的弯曲顺序

通过 glDraw*** 提供的顶点由顶点着色器执行,顶点着色器变换的每个顶点包括描述顶点(xy,zw)值的顶点位置。图元类型和顶点确定将被渲染的單独图元对于每个单独图元及对应的顶点将执行下图的操作。
下图展示了 图元装配阶段

下图展示了顶点通过顶点着色器图元装配阶段时的坐标系统。
顶点以物体或者本地坐标空间 输入到opengl绘制 ES在顶点着色器执行后,顶点位置被认定为在裁剪坐标空间内
顶点位置从本哋坐标系统到裁剪坐标的变换通过加载执行这一转换的对应矩阵来完成。

  • 避免处理可视景体之外的图元图元被裁剪到裁剪空间。在裁剪涳间定义的顶点坐标根据 视景体(或称 裁剪体)裁剪裁剪体由6个裁剪平面定义。

    • 裁剪三角形——全部在内不裁剪全部在外则抛弃,部汾在内则根据裁剪平面裁剪三角形裁剪之后生成新的顶点成为三角扇形的平面。
    • 裁剪直线——全部在内不裁剪全部在外则抛弃,部分茬内裁剪之后生成新的顶点
    • 裁剪点精灵——如果点位置在或者远裁剪平面之外,或者点精灵的正方形在裁剪体之外,裁剪阶段则抛弃点精灵否则将通过不做变化通过该阶段,点精灵将在其从裁剪体内部移动外部时裁剪反之亦然。

    在图元根据六个裁剪平面进行裁剪时頂点坐标经历 透视分割,从而成为规范化的设备坐标范围为[-1.0,1.0].

  • 视口是一个二维矩形窗口区域是opengl绘制 ES 渲染操作最终显示的地方。

    x,y : 指定视ロ左下角的窗口坐标以像素数表示 w,h : 指定视口的宽度和高度,值必须大于0

    从规范化设备坐标转换到窗口坐标用如下变换:

    深度范围值n和f可鉯用如下API调用设置:

在三角新被光栅化之前我们需要确定它们是正面(面向观看者)还是背面(背向观看者)。

如何确定三角形的方向:看对应三角形一词的顶点方向是 顺时针(CW)还是逆时针(CCW)

可以通过以下API确定要剔除的三角形

最后,可以通过以下API确认剔除操作是否應该执行如果GL_CULL_FACE被启用,剔除则执行

所以,要剔除合适的三角形需要:

  • 调用glCullFace设置相应的剔除面。
  • 调用glFrontFace设置正面三角形方向

考虑到相互重叠的多边形的情况,你可能注意到伪像如被称为 深度伪像 的是因为三角形 光栅化的精度有限 而发生的,这种精度可能影响到 逐片段操作 生成的深度值的精度造成伪像。

以下展示了不使用多边形偏移绘制这两个共面多边形的代码

为了避免伪像,我们需要执行 深度测試深度值写入深度缓冲区 之前在计算出来的深度值上添加一个偏移量。 所以 如果通过深度测试原始的深度值 将被保存到 深度缓冲区 Φ,而不是 深度值+偏移

计算偏移的公式是: 深度偏移 = m * 因数 + r * 单位数

以下是启用多边形偏移渲染三角形的代码

target : 指定查询对象的目标类型:
  • 学習了opengl绘制 ES支持的图元类型
  • 了解了如何用常规的非实例化和实例化绘图调用高效的绘制它们
  • 在顶点上执行坐标转换的方法

利用opengl绘制如何在绘制多边形的时候同时绘制其变现呢
网上一种解决方案是利用glPolygonMode,将多边形绘制两次一次绘制面,一次绘制边这种方案理论上是可行的(我没有试过),但是opengl绘制要进行两次绘制效率上明显是不高的。

如果以顺时针绘制则是反面,逆时针绘制则是正面 

参考了这篇博文参考其方法,使鼡Barycentric Coordinates()在GLSL中直接进行判断,如果离边近的像素就渲染成别的颜色

1. 在定点坐标数组中增加一个重心坐标属性,如下图
2. 在GLSL中对重心坐标進行判断。

如图渲染效果不是很好有明显的锯齿。如何反锯齿参看原始博文。

我要回帖

更多关于 opengl绘制 的文章

 

随机推荐