问题标签 [opengl-es-3.1]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1148 浏览

android - Android opengl 着色器程序将图像从相机复制到 SSBO 以进行 TF-lite GPU 推理

Tensorflow lite gpu 委托文档提供了一种在 Android[3] 中使用 Opengl 和 SSBO 运行 tflite 推理的更快方法。该文档提供了示例代码,用于创建和绑定 SSBO 与 GPU 中已有的图像。我们如何从 android live camera 复制或转换图像并使用 OpenGL 着色器代码将其复制到 SSBO?当我们只是将 CPU 内存转储到 SSBO 时,与正常的 gpu 委托执行相比,性能会变得更差。那么将相机图像传递给SSBO以使tflite推理更快的正确或最有效的方法是什么?

在下面的代码中,我们尝试将相机帧转换为位图,然后将其转换为纹理,最后将其复制到 SSBO。然而,这种方法比普通的 GPU 委托执行管道(其中数据从 CPU 复制到 GPU 的开销)要慢得多。目的是通过使图像数据在 GPU 内存中可用,然后将其传递给模型来减少 CPU 到 GPU 的图像数据复制。我们能够使用标准 GPU 委托推理机制在 40-50 毫秒内运行模型[1];而使用上述 SSBO 方法(未优化)需要 90-100 毫秒。以上时间是指interpreter.run()tensorflow lite中运行方法的时间。此外,看起来这种 SSBO 机制仅适用于 OpenGL ES 3.1 或更高版本。

理想的用例(由 tensorflow 建议)如下[2]:

  1. 您以表面纹理的形式获得相机输入。
  2. 创建一个 OpenGL 着色器存储缓冲区对象 (SSBO)。
  3. 用于GPUDelegate.bindGlBufferToTensor()将该 SSBO 与输入张量相关联。

  4. 编写一个小的着色器程序来有效地将 [1] 的表面纹理转储到 [2] 的 SSBO 中。

  5. 运行推理。

我们能够将相机帧作为原始字节获取或将其转换为纹理,甚至将其渲染到 GLSurface View。但是我们无法实现 tensorflow 所建议的加速。

  1. https://github.com/tensorflow/tensorflow/issues/26297
  2. https://github.com/tensorflow/tensorflow/issues/25657#issuecomment-466489248
  3. https://www.tensorflow.org/lite/performance/gpu_advanced#android_2

安卓代码:

计算着色器:-

0 投票
1 回答
397 浏览

android - 在使用 OpenGL-ES 的不同 Android 手机上,使用 alpha 混合的颜色是不同的

我在使用 OpenGL ES 3.1 的 Android 上遇到问题。我编写了一个应用程序,显示液体从屏幕顶部落下。这种液体由许多有点透明的粒子组成,但使用 alpha 混合的颜色在另一部手机上显示不同。

每一滴的颜色定义如下:

每个粒子颜色都存储在缓冲区中:

并将这个缓冲区传递给要绘制的 OpenGL 实体:

通过调用此函数来关闭渲染:

片段着色器只绘制它接收到的颜色:

它在一部手机(Nexus 5X)上运行良好: 正确渲染

但是在另一部手机(Galaxy S10)上,使用完全相同的代码,颜色就不一样了: 不正确的渲染

有没有人知道解决这个问题的方法?我也想在第二部手机上显示正确的颜色。

0 投票
0 回答
216 浏览

opengl-es - 将 glsl 模与 uint 一起使用

在我的计算机着色器中,我尝试根据图像矩形内的 gl_GlobalInvocation 变量计算每个本地调用的纹理坐标。对于高达 262144 的 gl_GlobalInvocation.x 的较大值,我会得到奇怪的结果。(gl_WorkGroupSize=1024 (1024,1,1), gl_NumWorkGroups=256 (256,1,1), width <= 512, height <= 512) 也许是因为 glsl 模无法处理 OpenGL ES 3.1 中的 uint 数据类型。

是否有替代方法来计算 uint 范围的坐标?

0 投票
1 回答
141 浏览

c - 为什么我的三角形在 Raspberry Pi 上的 OpenGL ES 3 中是白色的

我有一个非常简单的 OpenGL ES 程序示例,我试图在 Raspberry Pi 4 上的 RaspiOS Desktop(又名 Raspbian)上运行该程序。

我的目标很简单——在屏幕中央画一个红色三角形。但是,三角形显示为白色而不是红色。

我已经搜索并尝试了所有方法,但找不到任何帮助。在这一点上,我感到非常沮丧,因为这应该是第一个介绍 OpenGL ES 世界的教程,而我已经陷入困境,无法继续更复杂的示例。

无论如何,这是完整的例子

在运行它之前,您需要:

  1. sudo raspi-config
  2. 转到高级选项 > GL 驱动程序
  3. 启用 GL(假 KMS)
  4. 重启

然后你可以像这样编译和运行它:

起初我以为可能是驱动程序中的一些错误或其他东西。但是后来我找到了这个示例并尝试运行它,它绘制了一些具有多种颜色的图形,这很好。

我会很感激任何帮助。这几天我一直在尝试调试它。

0 投票
0 回答
41 浏览

android - 无法使用特定索引(Android11、Pixel3)进行 imageLoad()

我遇到了一个问题,我无法在“imageBuffer”的特定地址读取值。

一个数组有粒子位置,第一个和第二个元素有一个数组的长度,如果我尝试使用数组长度的第一个元素,它总是为零,以下返回。

int total_particle = int(imageLoad(particle_pos_in, 0).x);

这是 imageBuffer 的输入。

计算我可以读取第一个索引的着色器。

您可以假设 TOTAL_PARTICLE 为 100K,因此有1000 个工作组,每个工作组有 100 次调用。

也许我应该确保我访问的地址,但这个地址永远不会写在这里,也不会写在其他调用中。

注意

  1. 如果我使用 1 个大小的工作组(x=1,y=1 和 z=1),它工作正常

  2. 而不是第一个元素,使用统一的 vec4 可以正常工作。

  3. 上面的代码适用于大多数设备(10+ Android 设备),但是,Android11 的设备(Pixel3)(Android10 很好)。

  4. 这是一个测试代码,我有很多计算着色器程序,但只有使用 const integer index 访问 imageBuffer 才会在设备上出现问题。

0 投票
0 回答
92 浏览

android - Android 如何将相机流拆分为具有不同 fps/分辨率/water_marks 的多个流以进行预览/录制/实时流/AI

我正在开发一个具有预览/本地录制/实时流/AI 功能的项目。

所有这些功能都可能随时被激活/停用。

并且每个流在特定的帧速率下都有自己的分辨率,并带有自定义的水印。

所以我正在为此寻找解决方案,

如果解决方案能够在用户体验和效率上取得平衡,那就太好了。

我学到的潜在解决方案。

----

[Android 相机 API2]

通过将不同的目标输出表面激活为相机重复请求。

优点:

  1. 易于拆分为不同的分辨率。

缺点:

  1. 替换重复请求将引入帧间隙和明显的抖动。
  2. 无法控制每个输出表面的 fps,并且可能会减慢整个请求的 fps。(yuv 数据提取的输出表面和 ImageReader 太多)
  3. 支持有限的输出表面。(通常 3 个)
  4. 不知道如何对每个流进行帧后处理,例如添加水印。

[Android Camera API2 + libyuv]

将一个 ImageReader 添加到 Camera API2 并将 ImageReader 的数据复制到多个流中,并使用 libyuv 为每个流进行缩放/水印。

优点:

  1. 每个流的 FPS 可控。
  2. 即时添加/删除流。

缺点:

  1. 使用 libyuv 进行 sacle/water-mark 的 CPU 负载较高。
  2. 用于处理和传输过多数据缓冲区的高 CPU。
  3. 如果涉及 4K 分辨率,则会出现散热问题。

【安卓相机API2+OpenGLES】

  1. 生成纹理对象。
  2. 创建一个 TextureSurface(纹理对象)。
  3. 将 TextureSurface 馈送到 Camera API2。
  4. 当 FrameAvailable 时更新 TexImage。

通过以下方式添加流:

  1. 使用共享的 GlContext 创建一个线程。
  2. 为输出表面创建 EGLSurface。(SurfaceView/MediaCodec/ImageReader..)
  3. 设置一个周期性定时器(fps 控制)来绘制帧。
  4. 当铃声响起。
  5. BindTexture 并绘制到当前的 EGLSurface。
  6. 将位图混合为水印。
  7. 如果流需要 YUV420 输出,我可以rgbaToYuv通过片段着色器实现,然后 glReadPixels()。

通过以下方式删除流:

  1. 释放相关资源。
  2. 终止此线程。

优点:

  1. 动态添加/删除流而不影响其他流。
  2. 简单的fps控制
  3. 轻松添加水印

缺点:

  1. 可能是 GPU 加载过多?

我真的不确定。我对OpenGLES的东西不是很熟悉。

所以请发表评论。

您如何看待上述解决方案?

哪一个更好?

和任何其他方法?

如果我缺乏理解,请原谅我。

0 投票
1 回答
154 浏览

opengl-es - glsl 可以支持的最大整数(无符号整数)值是多少?

可以在着色器中使用的整数和无符号整数的最大值是多少?

0 投票
0 回答
89 浏览

c++ - glTexImage2D 纹理不能以正确的格式读取

我正在开发一个涉及 OpenGLES (3.1) 的跨平台项目。Windows虽然代码在我和Ubuntu机器上完美执行。在 Raspberry PI 4 上运行相同的代码会导致一个奇怪的问题,在使用glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, 0)调用成功初始化纹理后,稍后在请求相同 FrameBuffer 的可用读取类型的代码中glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, ...)返回 GL_GRBA。对于上下文创建,我将 GLFW 与 GLAD 一起使用。下面是纹理初始化的完整代码:

  • read_format值等于GL_RGBA哪个应该GL_RGB
  • read_type值等于GL_UNSIGNED_BYTE预期

因此,在渲染调用尝试读取纹理到本地back_buf数组后,使用:glReadPixels(0, 0, 16, 256, GL_RGB, GL_UNSIGNED_BYTE, back_buf)导致GL_INVALID_OPERATIONwith glReadPixels(invalid format GL_RGB and/or GL_UNSIGNED_BYTE). 将读取类型从更改GL_RGBGL_RGBA修复错误,但我的程序无法使用生成的数据格式(我严格寻找 GL_RGB 格式)。

我的问题是我做错了什么还是 Raspberry PI 4 OpenGLES 驱动程序有问题?

0 投票
0 回答
26 浏览

unreal-engine4 - glTexStorage3D() 创建的 Texture3D 在 Compute Shader 调度后出现奇数值?

首先,由 glTexStorage3D() 创建一个 Texture3D。[安卓(Open GL ES 3.1)]

每一帧,事件的顺序是:

  1. 将此 Texture3D 用于计算着色器写入(glMemoryBarrier(ALL_BITS) 确实发生了)
  2. 使用 thie Texture3D 进行片段着色器读取

然后,在第 1 帧和第 2 帧之间,在第 1 帧结束时,这个 Texture3D 仍然包含正确的值。但是在第 2 帧中,这个 Texture3D 出现了一些绝对不是我写的随机值!

框架1

框架2

我真的找不到原因......也许是gles不可变存储的问题?

0 投票
0 回答
17 浏览

opengl-es-3.1 - 使用 OpenGL ES 3.1 调整图像大小

我想使用 OpenGL ES 3.1 调整图像大小。作为输入,我有一个 void 指针和输出,我也想要一个 void 指针。

有人知道我该怎么做吗?有没有人有这方面的例子?

谢谢 !