android openGL ES详解——面剔除

Android 开发文档 - OpenGL 详解 Android 可通过开放图形库 (OpenGL®)(特别是 OpenGL ES API)来支持高性能 2D 和 3D 图形。 OpenGL ES 是 OpenGL 规范的一种形式,适用于嵌入式设备。 两个基本类 用于通过 OpenGL ES API 来创建和操控图形:GLSurfaceView 和 GLSurfaceView.Renderer。 GLSurfaceView 此类是一个 View,... 阅读详情

目录

一、什么是面剔除?

1.面剔除

2.隐藏面消除

二、立方体中的正背面

1.正背面的定义

2.顶点连接顺序分析

三、面剔除常用API

四、正背面剔除功能举例

五、总结

一、什么是面剔除?

1.面剔除

尝试在头脑中想象一下有一个3D立方体,你从任何一个方向去看它,最多可以同时看到多少个面。如果你的想象力不是过于丰富,你最终最多能数出来的面是3个。你可以从一个立方体的任意位置和方向上去看它,但是你永远不能看到多于3个面。所以我们为何还要去绘制那三个不会显示出来的3个面呢。如果我们可以以某种方式丢弃它们,我们会提高片段着色器超过50%的性能!

正背面剔除方案,是OpenGL中针对图形绘制的一种技巧,主要用于处理立体图形绘制时,只绘制观察者能看到的部分,看不到的部分就丢弃不绘制,这种做法可以将渲染性能提高50%左右。我们所说的是超过50%而不是50%,因为从一个角度只有2个或1个面能够被看到。这种情况下我们就能够提高50%以上性能了。

这的确是个好主意,但是有个问题需要解决:我们如何知道某个面在观察者的视野中不会出现呢?如果我们去想象任何封闭的几何平面,它们都有两面,一面面向用户,另一面背对用户。假如我们只渲染面向观察者的面会怎样?

这正是面剔除(Face culling)所要做的。OpenGL允许检查所有正面朝向(Front facing)观察者的面,并渲染它们,而丢弃所有背面朝向(Back facing)的面,这样就节约了我们很多片段着色器的命令(它们很昂贵!)。我们必须告诉OpenGL我们使用的哪个面是正面,哪个面是反面。OpenGL使用一种聪明的手段解决这个问题——分析顶点数据的连接顺序(Winding order)。

2.隐藏面消除

任何一个3D的物体,比如立方体,球,多边形多面立方体,等等,就像地球有昼夜一样,太阳光永远只能照射在地球的一个面上,在任何情况下我们都只能看到其中的一个面,那么对于看不到的背面在计算机里图形学里面如果不被渲染,那么性能会提高50%,即使渲染了也不看不到,而且性能下降,所以,完全没有必要。在绘制3D场景的时候,我们需要决定哪些部分是对观察者 可见的,或者哪些部分是对观察者不可⻅的.对于不可见的部分,应该及早丢弃.例如在⼀个不透明的墙壁后,就不应该渲染.这种对于看不到的面不去渲染的情况叫做“隐藏面消除”

二、立方体中的正背面

任何物体都有两面性,正面和背面,而观察者只能看到一个面.OpenGL可以通过分析顶点数据的顺序检测到面向观察者的面从而渲染他们,丢弃背面的渲染.这样可与节约片元着色器的性能.

1.正背面的定义

  • 正面:按照逆时针顶点连接顺序的三角形面
  • 反面:按照顺时针顶点连接顺序的三角形面

2.顶点连接顺序分析

  • 左侧三角形顶点顺序为: 1—> 2—> 3 ; 右侧三角形的顶点顺序为: 1—> 2—> 3 - 当观察者在右侧时,则右侧的三角形方向为逆时针方向则为正面,左侧的三角形为顺时针为背面
  • 当观察者在左侧时,则左侧的三角形方向为逆时针方向为正面,右侧的三角形为顺时针为背面
GLfloat vertices[] = {
    //顺时针
    vertices[0], // vertex 1
    vertices[1], // vertex 2
    vertices[2], // vertex 3
    // 逆时针
    vertices[0], // vertex 1
    vertices[2], // vertex 3
    vertices[1] // vertex 2
};

正面和背面是由三角形的顶点定义顺序和观察者的方向共同决定的,随着观察者的角度方向改变,正面背面也会跟着改变。观察者的角度很好理解,站在不同的角度方位看一个物体,能看到的一面是正面,看不到的是背面。实际的顶点连接顺序是在光栅化阶段(Rasterization stage)计算的,所以当顶点着色器已经运行后。顶点就能够在观察者的观察点被看到。把所有三角的顶点都定义为逆时针是一个很好的习惯。

三、面剔除常用API

  • 开启正背面剔除(默认是背面剔除)
void glEnable(GL_CULL_FACE)

从这儿以后,所有的不是正面朝向的面都会被丢弃(尝试飞入立方体看看,里面什么面都看不见了)。目前,在渲染片段上我们节约了超过50%的性能,但记住这只对像立方体这样的封闭形状有效。当我们绘制上个教程中那个草的时候,我们必须关闭面剔除,这是因为它的前、后面都必须是可见的。

  • 关闭正背面剔除(默认是背面剔除)
 void glDisable(GL_CULL_FACE)
  • 用户选择剔除哪个面(正面/背面)

OpenGL允许我们改变剔除面的类型。要是我们剔除正面而不是背面会怎样?我们可以调用glCullFace来做这件事:

void glCullFace(<#GLenum mode#>)

glCullFace函数有三个可用的选项:
GL_BACK:只剔除背面(默认值)。
GL_FRONT:只剔除正面。
GL_FRONT_AND_BACK:剔除背面和正面。
  • 用户指定顺时针或者逆时针为正面

另外,我们还可以告诉OpenGL使用顺时针而不是逆时针来表示正面,这通过glFrontFace来设置:

glFrontFace(GLenum mode)
glFrontFace(GL_CCW); // 逆时针为正面(默认值)
glFrontFace(GL_CW); // 顺时针为正面
  • 我们可以做个小实验,告诉OpenGL现在顺时针代表正面:
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
或者
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);

上述两段代码功能相同

具体实现代码如下

  //例如,剔除背⾯实现(1)
    glCullFace(GL_BACK);
    glFrontFace(GL_CW);
    //例如,剔除正⾯实现(2)
    glCullFace(GL_FRONT);
    //以下两行是默认的,可以不写
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);

剔除正、背面举例如下:

// 剔除背面方式1 - 正常情况下使用默认的情况即可
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

//剔除背面方式2
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glCullFace(GL_FRONT);

//剔除正面方式1
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);

//剔除正面方式2
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glCullFace(GL_BACK);

四、正背面剔除功能举例

  • 未开启背面剔除功能

绘制甜甜圈模型,旋转甜甜圈,会出现如下情况:

  • 开启正背面剔除功能

旋转甜甜圈又出现如下问题:

  • 上面这种情况出现的原因是什么呢?

在甜甜圈旋转的过程中,当前后两部分重叠时,对于我们而言,需要展示的是前面的部分,后面部分是隐藏面,但是OpenGL并不能清楚的区分哪个面在前哪个面在后,因此出现了缺口。

  • 那么如何解决这种问题呢?

利用深度测试解决。深度测试参考文章:android openGL ES详解——深度缓冲区_opengl 深度信息-优快云博客

五、总结

隐藏面消除总结:

  • 正背面消除:需要根据顶点数据顺序判断用户可见部分与隐藏面,隐藏面直接丢弃,不绘制,只绘制可见部分
  • 深度测试:可以一次性解决隐藏面消除问题,原理是不管有多少图层,只显示可见图层,剩余不可见的都丢弃

正如你所看到的那样,面剔除是OpenGL提高效率的一个强大工具,它使应用节省运算。你必须跟踪下来哪个物体可以使用面剔除,哪些不能。


 

参考文章

OpenGL_正面剔除,深度测试和Z冲突 - 简书

OpenGL--- (四)OpenGL渲染技巧:正背面剔除 - 简书

Open GL 渲染技巧-正背面剔除、深度测试、颜色混合 - 简书

OpenGL--- (四)OpenGL渲染技巧:正背面剔除 - 简书

OpenGL---(五)OpenGL渲染技巧:深度测试、多边形偏移、混合 - 简书

面剔除 - LearnOpenGL-CN

OpenGL学习脚印:背面剔除(Face Culling) 写在前面 在绘制封闭类型的几何对象时,开启背面剔除功能能够提高渲染性能。本节简要介绍下背面剔除。什么是背面剔除当我们观察场景中对象时,一般只能以一定角度来观察,那么对象的某些面我们是看不到的,例如你观察一个立方体,最多只能同时看到3个面,有时只能看到1个面,而我们绘制时如果不采取剔除背面的措施,则要绘制6个面,其中包括一些,我们根本看不到的面。对于立方体这个面较少的几何对象,性能开销不明显 阅读详情

相关推荐

opengles 背面剔除介绍(十二)

本文主要介绍 opengles3.0 中的背面剔除相关知识,对于绘制3d 图形, 经常会用到它,并且它能提升渲染效率软硬件环境:硬件:PC软件:ubuntu22.04 opengles3.0OpenGL ES也支持剔除功能,可以通过启用面剔除来提高渲染性能。面剔除是一种在渲染过程中忽略掉某些面的技术,从而减少不可见的面的绘制,节省处理时间和带宽。

lh0616的博客 768

什么是背面剔除,它何时在 Blender 中有用?

本质上,背面剔除是一种仅隐藏网格背面而网格正面保持可见的方法。当您处理对象时,可以在 3D 视口中使用此功能,但也可以在其材质设置中为材质启用,以便它也应用于材质视图和最终渲染。这就引出了一个问题——我们如何分辨脸部的哪一侧是正面,哪一侧是背面?对于默认平面,向上或朝向正局部 z 轴的面被视为正面,而底部被视为背面。在 Blender 的其余默认网格中,例如立方体、球体,甚至 Suzanne,所有指向对象内部的面都被视为背面。这意味着如果您启用了背面剔除并且从外部查看封闭的网格,您将能够看到它。

专注于3D渲染行业,分享3D渲染的经验和技巧 1万+

Android学习笔记:OpenGL绘图总结

很久不用OpenGL ES绘图,怕自己忘记了,于是重新复习一遍,顺便原理性的东西总结如下: 1,Android 3D坐标系统    如图: Android的三维坐标系统中:                    坐标原点位于中央,                    X轴从左向右延伸,原点左边的值为负数,右边为正数;                    Y轴从下向上延伸,原点

duancanmeng的专栏 5261

OpenGL:背面剔除

背面剔除、缠绕顺序

zhang_shuaifeng的博客 600

Android OpenGL ES 2.0开发环境搭建与3D渲染实践

OpenGL ES作为移动端3D图形渲染的行业标准,其可编程管线架构通过顶点着色器和片段着色器实现灵活渲染控制。在Android平台开发中,GLSurfaceView与EGL配置构成基础渲染环境,而MVP矩阵体系则处理3D空间变换。通过VBO优化顶点数据传递、纹理映射增强表面细节、Phong光照模型提升真实感,开发者能构建高性能图形应用。典型应用场景包括AR/VR、游戏开发和数据可视化,其中着色器编译、GPU资源管理和多版本API兼容是需要重点掌握的核心技术。

cucanqi9387的博客 487

Opengl ES系列学习--增加地形

本节我们在上一节的基础上继续添加地形图功能,我们要分析的目标就是《OpenGL ES应用开发实践指南 Android卷》书中第12章实现的最终的结果,代码下载请点击:Opengl ES Source Code,该Git库中的heightmapModule就是我们本节要分析的目标,先看下本节最终实现的结果。 可以看到,地形图中有高有低,是用绿色来表示的,最接近底部的颜...

红旺永福 745

OpenGL ES for Android(面剔除)

简介 首先我们绘制一个立方体,想象一下能看到几个面。一般情况下我们最多能看到三个面,极端的情况我们甚至只能看到一个面,这时候如果不绘制看不到的面,是不是非常节省资源,忽略掉看不到的面就叫面剔除。那么怎么判断一个面是否面向观察点呢,在OpenGL中用了这样一个技巧:分析顶点数据的环绕顺序(Winding Order)。 环绕顺序 绘制三角形时用到了三个顶点,这三个顶点的顺序就是我们提到的环绕顺序。三个点的顺序要么是顺时针,要么是逆时针的,而且当一个面在面向观察点时是顺时针时,那么它在背向观察点时肯定是逆

1 258

OpenGL ES干货系列(一)三角形

OpenGL ES干货系列(一)三角形阅读提示三角形的正反面三角形带三角形扇 阅读提示 本系列文章 并不是一个系统性介绍 OpenGL ES的合集,而是在学习中针对一些重点、难点、有趣点的干货汇总。如果你对OpenGL基本概念有一定了解,并且知道怎么绘制一个三角形(这就够了!),那么本系列文章将很适合你! 另外,本系列是我在学习过程中的总结,因此,难免会有错误或理解不到位的地方,欢迎批评指正! 对...

weixin_44549785的博客 465

学习OpenGL ES for Android(二十一)— 面剔除

首先我们绘制一个立方体,想象一下能看到几个面。一般情况下我们最多能看到三个面,极端的情况我们甚至只能看到一个面,这时候如果不绘制看不到的面,是不是非常节省资源,忽略掉看不到的面就叫面剔除。那么怎么判断一个面是否面向观察点呢,在OpenGL中用了这样一个技巧:分析顶点数据的环绕顺序(Winding Order)。 环绕顺序 绘制三角形时用到了三个顶点,这三个顶点的顺序就是我们提到的环绕顺序。三个...

chends 612

OpenGL面剔除(Face Culling)编程

通过启用面剔除功能并定义剔除规则,我们可以排除不可见的三角形面,从而减少不必要的渲染开销。然而,我已经在上面的回答中给出了使用面剔除功能的示例代码的框架。面剔除(Face Culling)是OpenGL中一种优化技术,它可以通过排除不可见的三角形面来提高渲染性能。当渲染一个复杂的三维场景时,只有可见的面需要被绘制,而背面或不可见的面可以被剔除掉,从而减少不必要的渲染开销。上述代码将指定逆时针方向的三角形面被认为是正面,而顺时针方向的三角形面被认为是背面。上述代码将启用面剔除功能,并默认剔除背面的三角形面。

CyberByte的博客 326

Android OpenGL ES圆形绘制示例:点绘圆圈、线绘圆环、面绘实心圆

一套开箱即用的Android图形开发示例,基于OpenGL ES实现三种形态的圆形渲染——用离散顶点点绘轮廓、用闭合线段线绘圆环、用三角扇形面绘实心圆饼。项目结构清晰,核心逻辑集中在Opengl目录,circle模块独立封装坐标生成与绘制逻辑,适配Android Studio标准构建流程,内置gradlew、build.gradle和gradle.properties,无需额外配置或第三方依赖即可编译运行。代码明确区分GL_POINTS、GL_LINE_LOOP和GL_TRIANGLE_FAN三种绘制模式,

salt的博客 203

OpenGL ES之一——概念扫盲

一.OpenGL OpenGL概念:Open Graphics Library(开放图形库)。 1.1OpenGL到底是什么 OpenGL是一个规范,解释如下: OpenGL到底是什么?一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khr...

gongxiaoou的博客 5601

Fluent温度超限调试:从能量方程到网格优化的实战指南

本文深入解析Fluent中温度超限问题的诊断与解决方法,从能量方程机制到网格优化策略,提供实战指南。通过分析温度与焓的换算关系,探讨典型场景如能量方程发散、局部网格质量差等,并给出五步调试法及高级命令应用,帮助工程师有效解决温度计算异常问题。

weixin_29045585的博客 530

Android OpenGL ES渲染框架设计与优化实践

OpenGL ES作为移动端图形渲染的行业标准,通过硬件加速实现高效图形处理。其核心原理是通过顶点着色器和片元着色器构建可编程渲染管线,在Android平台上广泛用于游戏开发、AR/VR等场景。针对原生API存在的开发效率问题,构建轻量级渲染框架能显著提升工程实践效率。通过封装纹理加载、Shader管理等基础模块,结合矩阵池技术等优化手段,不仅减少60%冗余运算,还能实现跨版本兼容。这类框架特别适合需要精细控制渲染流程的中大型应用开发,是掌握移动端图形编程的重要实践。

weixin_30235225的博客 349

【宠物识别系统】设计框架

能跑通的 Demo。收集 10,000 张同品种但不同个体的图片。训练ArcFace模型,验证准确率能否达到 99% 以上。搭建Milvus向量数据库。开发移动端 App/小程序。加入“图像质量检测”和“用户反馈纠错”功能。你是更偏向于做软件服务(如寻宠App、保险API),还是做软硬结合的产品(如智能喂食器)?这决定了我们下一步是深挖云端高并发架构,还是边缘端模型压缩。更偏向于软件,应用更广泛些,继续既然专注于纯软件/SaaS (Software as a Service) 方向。

百态·数智思维 | 聚焦大数据、量化与未来AI 1413

地平线RDKX3初始配置与USB无线网卡

地平线X3无线网卡配置

Richard_Mei的博客 4075

Android OpenGL ES 概述

Android 提供了 OpenGL 去进行 2D 和 3D 图形的高效绘制。OpenGL 是一个跨平台的图形 API,对于 3D 图形硬件有一套标准的软件接口。

JunkChen 2507

别光看手册!手把手教你用SGM2036 LDO设计一个稳定3.3V转1.8V的MCU供电电路(附PCB布局避坑指南)

本文详细介绍了如何使用SGM2036 LDO设计一个稳定的3.3V转1.8V的MCU供电电路,包括需求分析、芯片选型、外围器件计算、PCB布局避坑指南及实测验证。通过实际案例和计算示例,帮助工程师快速掌握LDO应用技巧,确保系统电源稳定可靠。

weixin_42548893的博客 505

Android游戏开发–使用OpenGL ES显示图形元素(原语)

这是android OpenGL ES系列的第2部分。 在上一篇文章中,我们研究了如何设置android项目以将提供的OpenGL视图与渲染器一起使用。 您可以使用该文章中的项目作为模板。 在开始展示事物之前,我们必须了解3D编程的一些基本概念,并熟悉术语。 我真的是基本几何。 3D图形发生在笛卡尔坐标系中 。 这意味着所使用的坐标系具有三个维度。 X , Y和Z。 传统上, ...

274

CCS配置MSPM0G3507(七) 编码器(TIMER-QEI)

1.选择时钟源 BUSCLK2.时钟分频配置为1分频3.分频系数配置为14.若勾选 Start ,则生成程序后会自动开启定时器的计数,否则需手动在程序中开启5.Load Value 设置为65535。

kaneki_lh的博客 1万+

YOLO11多个点组合创新:GC10-DET缺陷检测 | DCNv4结合SPPF+11Detect创新性结合

DCNv4结合SPPF+11Detect创新性结合,原始mAP50为0.633 提升至0.651

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1287

一步一步学android opengl es2.0编程,Android OpenGL ES 2.0 手把手教学(5)- 绘制模式

大家好,下面和大学一起学习绘制模式,在我的github上有一个项目OpenGLES2.0SamplesForAndroid,我会不断地编写学习样例,文章和代码同步更新,欢迎关注,链接:github.com/kenneycode/…在我们之前的例子中,我们都是以三个独立顶点为一个三角形的方式来进行渲染,如果大家有注意观察的话,会发现我们在调用glDrawArrays()方法的时候,第一个参数都是用G...

weixin_39541681的博客 213

AD(十四)调用已有的PCB元件封装库

软件:Altium Designer 16 需要资料:已有的PCB原理图文件(.PCBDOC)或者PCB库文件(.PCBLIB)(来源文中细说) 调用已有的PCB元件封装库(一)从已有的PCB原理图文件(*.PCBDOC)中调用1、PCB原理图文件来源2、打开已有的PCB原理图文件(*.PCBDOC)3、生成PCB封装库4、复制封装到工程文件下的PCB库文件(*.PCBLIB)5、重名问题(二)从已有的PCB库文件(*.PCBLIB)中调用1、PCB库文件(*.PCBLIB)的来源2、打开已有的PCB库 (

Curnane0_0的博客 5082

[android] OpenGL与OpenGL ES简介

简介 OpenGL OpenGL的全称是Open Graphics Library,即开放的图形库接口,它定义了一个跨编程语言,跨平台的编程接口的规范,它主要用于3D图形(2D也可以)编程。OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL。IRIS RL是一个工业标准的3D图形软件接口,功能虽然强大,但是移植性不好,于是SGI公司在IRIS GL的基础上开发了OpenGL。

努力奋斗 929

第四章节 Qt字符串QString详解

QString 的使用方式和 C++标准库的 std::string 字符串的非常相似。

m0_65635427的博客 889

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

HJ详解Android OpenGL ES 2.0

前言 (一) 绘制2D图形  1.1 如何定义三角形的坐标  1.2 OpenGL中的坐标系  1.3 GLSurfaceView  1.4 Render  1.5 绘制对象  1.5 长方形,圆形,任意形状  1.6 图形的正反面 (二) 2D贴图 2.1 纹理坐标系 2.2 纹理格式 2.3 纹理使用 前言 OpenGL 是2D和3D图形API,使用它我...

少年的此间 1389

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: android openGL ES详解——深度缓冲区
下一篇: android openGL ES详解——混合
闲暇部落
博客等级 码龄12年 2775粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲暇部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值