android openGL ES详解——面剔除

news2024/11/16 11:58:26

一、什么是面剔除?

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 深度信息-CSDN博客

五、总结

隐藏面消除总结:

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

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


 

参考文章

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

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

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

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

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

面剔除 - LearnOpenGL-CN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2090822.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

金融上云方案中,国产虚拟化产品选型的重点考虑因素、自动化运维建设步骤及如何进行保障数据中心安全需求的存储设计等问题及解决方法|金融行业数字化QA合集③

Q&#xff1a;金融机构应该从哪些方面考虑虚拟化产品选型&#xff1f; 我行是中小规模城商行&#xff0c;想实现虚拟化国产替换&#xff0c;针对国产虚拟化种类繁多的情况&#xff0c;我行应该从哪些方面考虑产品选型&#xff0c;确保所选择产品既能满足信创替换&#xff0c;又…

银河麒麟v10-sp3-x86系统安装k8s-1.30.4

X86-64和arm架构的区别 x86-64架构&#xff1a; 设计理念&#xff1a;x86-64架构起源于Intel的x86架构&#xff0c;并对其进行了64位扩展。这种架构的设计侧重于高性能和灵活性&#xff0c;适合处理复杂的计算任务。 性能特点&#xff1a;x86-64架构的处理器通常提供高性能的…

六个方面探讨企业为何迫切需要替换FTP

随着信息技术的迅猛发展和网络安全形势的日趋严峻&#xff0c;传统的FTP文件传输协议因其固有的局限性和安全隐患&#xff0c;逐渐难以满足现代企业的需求。因此&#xff0c;寻找并升级FTP替代方案成为众多企业需要解决的问题。本文将从六个方面探讨企业为何迫切需要替换FTP。 …

云轴科技ZStack产品升级,浙江分公司产品发布会成功举办

近日&#xff0c;以“智启未来&#xff0c;云端共赢”为主题的云轴科技ZStack浙江分公司针对浙江地区渠道合作伙伴的产品发布会在杭州顺利召开。ZStack总代理伟仕佳杰、神州数码、英迈等百余位合作伙伴代表出席会议&#xff0c;共同见证ZStack在云基础设施与AI软件基础设施领域…

易查分如何查询图片?

最近经常看到老师们各种分享和讨论一个问题&#xff0c;今天&#xff0c;我就和大家聊聊如何高效地在易查分平台上上传和管理图片&#xff0c;让查询结果更加直观。 首先准备你的图片&#xff0c;无论是获奖证书还是奖状&#xff0c;确保它们的格式正确&#xff0c;比如"2…

VMware虚拟机安装的Ubuntu,桥接方式静态ip,内网可以访问,ping外网不可用

1.环境说明 系统&#xff1a;Ubuntu 24.04 环境&#xff1a;VMware下桥接静态IP设置 2.问题&#xff1a;ping www.baidu.com报错 [~] ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolutio…

十、前后端分离通用权限系统(10)

&#x1f33b;&#x1f33b; 目录 一、功能说明二、部门管理三、岗位管理四、日志管理4.1、登录日志4.1.1、功能实现- 接口4.1.2、编写 AsyncLoginLogMapper4.1.3、功能实现- 接口实现4.1.4、导入获取ip地址的工具类 IpUtil4.1.5、在 TokenLoginFilter 调用方法实现4.1.6、修改…

【Matlab】时间序列模型(ARIMA)

文章目录 前言一、示例二、代码实现----Matlab全部数据的平稳性检验ADF检验图检验法 划分训练集平稳性检验确定 p&#xff0c;q结果分析和模型检验模型预测 前言 接上一篇博客&#xff0c;用 Matlab 完成代码编写。 【学习笔记】时间序列模型(ARIMA) 一、示例 已知一个上市公…

Linux云计算 |【第二阶段】SHELL-DAY4

主要内容&#xff1a; grep、egrep的使用&#xff0c;基本/扩展正则、sed的使用&#xff08;非交互、逐行处理、常用命令与选项&#xff09; 补充&#xff1a;grep [-E]选项&#xff0c;表示允许使用扩展的正则表达式&#xff08;同等于egrep&#xff09; 一、grep 与 egrep 的…

Kubernetes高可用部署

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

极限的性质【上】《用Manim可视化》

通过前面的极限的定义&#xff0c;现在是计算极限的时候了。然而&#xff0c;在此之前&#xff0c;我们需要一些极限的性质&#xff0c;这将使我们的工作变得简单一些。我们先来看看这些。 极限的性质&#xff1a; 1.常数对极限的影响 1.首先&#xff0c;我们假设和存在&…

Tengine框架之配置表的Luban转换与加载

对于一个游戏来说&#xff0c;配置表是必不可少的&#xff0c;而且文件数量还比较多&#xff0c;像活动、任务成就、图鉴、地图、皮肤、本地化语言、技能等等之类。配置表一般使用Excel格式&#xff0c;便于策划来配置。但游戏中一般使用txt/json/xml/二进制格式文件&#xff0…

碎碎念之Android中CPU架构arm-v8a、arm-v7a、x86

0 碎碎念 之前写博客都是为了复习基础知识&#xff0c;不过好像也忘得很快hh。 以后估计会写点感兴趣的自己碎碎念&#xff0c;缓解下emo的心情。&#xff08;不像之前的博客&#xff0c;这些博客不准备复现也不贴代码所以不一定对&#xff0c; 仅供个人参考 &#xff09; 现在…

Python酷库之旅-第三方库Pandas(111)

目录 一、用法精讲 486、pandas.DataFrame.count方法 486-1、语法 486-2、参数 486-3、功能 486-4、返回值 486-5、说明 486-6、用法 486-6-1、数据准备 486-6-2、代码示例 486-6-3、结果输出 487、pandas.DataFrame.cov方法 487-1、语法 487-2、参数 487-3、功…

鸿蒙项目签名配置

配置需要以下四个文件&#xff1a; 1. p12文件 2. csr文件 3. cer文件 打开AGC平台 点击申请调试证书 4. p7b文件 最后在项目中进行配置 配置项目的module.json5中

selenium使用指南

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 概述 selenium是网页应用中最流行的自动化测试工具&#xff0c;可以用来做自动化测试或者浏览器爬虫等。官网地址为&#xff1a;相对于另外一款web自动化测试工…

Linux安装Hadoop(单机版)详细教程

目录 一、JDK安装 1、下载JDK安装包 2、解压下载的JDK安装包 3、移动并重命名JDK包 4、配置Java环境变量 5、验证安装是否成功 二、Hadoop安装 1、下载Hadoop安装包 2、解压Hadoop安装包 3、配置Hadoop环境变量 4、修改配置文件 5、验证Hadoop是否安装成功 三&…

C# 开发环境搭建(Avalonia UI、Blazor Web UI、Web API 应用示例)

文章目录 C# 文档.NET SDK 下载安装 .NET SDK安装完验证VS Code 配置C# 开发插件settings.json WPF UI 框架Avalonia UI 框架创建 Avalonia 项目Avalonia 官方示例Avalonia 桌面 UI 库 Blazor Web UI 框架创建应用项目结构 ASP.NET Core 控制器创建 Web APIdotnet 命令dotnet n…

探索Unity与C#的无限潜能:从新手到高手的编程之旅

在数字创意与技术创新交织的今天&#xff0c;Unity游戏引擎凭借其强大的跨平台能力和灵活的编程接口&#xff0c;成为了无数开发者心中的首选。而C#&#xff0c;作为Unity的官方脚本语言&#xff0c;更是以其面向对象的特性和丰富的库支持&#xff0c;为游戏开发注入了无限可能…

克隆技术在代码溯源和复用及变更分析中的应用

摘要&#xff1a; 克隆技术已在软件代码溯源分析领域得到广泛应用&#xff0c;而轩宇软件成分分析系统基于溯源分析和同源分析技术&#xff0c;通过先进的特征向量提取、相似性匹配、高效检索引擎等多项技术&#xff0c;帮助企业高效识别代码来源、评估自主可控率&#xff0c;…