计算渲染目标上的像素
Count pixels on the render target
使用 OpenGL ES 2.0 和 Galaxy S4 phone,我有一个渲染目标 1024x1024 RGBA8888,其中每帧都会渲染一些纹理。我需要计算在渲染目标上渲染了多少红色 RGBA(1, 0, 0, 1) 像素(每秒两次)。
主要问题是从 GPU 获取纹理非常耗费性能(~300-400 毫秒),并且冻结不适用于我的应用程序。
我知道原子计数器的 OES_shader_image_atomic 扩展(只是在片段着色器工作时增加一些值),但它仅在 OpenGL ES 3.1(及更高版本)中可用,我必须坚持使用 ES 2.0。
有没有我遗漏的通用解决方案?
您可以尝试将有问题的纹理 "reduce" 缩小到一个小得多的纹理,然后读回 CPU 那个纹理(在性能方面应该更便宜)。例如,您可以将纹理拆分为 N × N 的正方形(其中 N 最好是二的幂),然后将 "whole screen" 四边形渲染为 1024/N × 1024/N 纹理,并使用片段着色器求和相应方块中的红色像素数:
sampler2D texture;
void main(void) {
vec2 offset = N * gl_FragCoord.xy;
int cnt = 0;
for (float x = 0.; x < float(N); x += 1) {
for(float y = 0.; y < float(N); y += 1) {
if (texture2D(texture, (offset + vec2(x, y)) / 1024.) == vec4(1, 0, 0, 1)) {
cnt += 1;
}
}
}
gl_FragColor = vec4((cnt % 256) / 255., ((cnt / 256) % 256) / 255., /* ... */);
}
还要记住 readPixels
同步等待 GPU 完成所有先前发出的纹理绘制。所以有两个纹理可能是有益的,
在每一帧上,一个被渲染到,另一个被读取。下一帧你交换它们。这会在一定程度上延迟获得所需数据,但应该会消除一些冻结。
使用 OpenGL ES 2.0 和 Galaxy S4 phone,我有一个渲染目标 1024x1024 RGBA8888,其中每帧都会渲染一些纹理。我需要计算在渲染目标上渲染了多少红色 RGBA(1, 0, 0, 1) 像素(每秒两次)。
主要问题是从 GPU 获取纹理非常耗费性能(~300-400 毫秒),并且冻结不适用于我的应用程序。
我知道原子计数器的 OES_shader_image_atomic 扩展(只是在片段着色器工作时增加一些值),但它仅在 OpenGL ES 3.1(及更高版本)中可用,我必须坚持使用 ES 2.0。
有没有我遗漏的通用解决方案?
您可以尝试将有问题的纹理 "reduce" 缩小到一个小得多的纹理,然后读回 CPU 那个纹理(在性能方面应该更便宜)。例如,您可以将纹理拆分为 N × N 的正方形(其中 N 最好是二的幂),然后将 "whole screen" 四边形渲染为 1024/N × 1024/N 纹理,并使用片段着色器求和相应方块中的红色像素数:
sampler2D texture;
void main(void) {
vec2 offset = N * gl_FragCoord.xy;
int cnt = 0;
for (float x = 0.; x < float(N); x += 1) {
for(float y = 0.; y < float(N); y += 1) {
if (texture2D(texture, (offset + vec2(x, y)) / 1024.) == vec4(1, 0, 0, 1)) {
cnt += 1;
}
}
}
gl_FragColor = vec4((cnt % 256) / 255., ((cnt / 256) % 256) / 255., /* ... */);
}
还要记住 readPixels
同步等待 GPU 完成所有先前发出的纹理绘制。所以有两个纹理可能是有益的,
在每一帧上,一个被渲染到,另一个被读取。下一帧你交换它们。这会在一定程度上延迟获得所需数据,但应该会消除一些冻结。