【问题标题】:OpengL ES / Angle : rendering to single channel float textureOpengL ES / Angle:渲染到单通道浮动纹理
【发布时间】:2017-04-14 14:54:12
【问题描述】:

我正在尝试使用着色器对大型矩阵/图像进行简单操作。我通过渲染到帧缓冲区对象中的单通道浮动纹理编写了一些使用常规 OpenGL 运行的代码,效果很好。

我现在需要让它在不同的平台上运行(UWP + Angle、Android...),所以我正在尝试将代码移植到 OpenGL ES 2.0;我可以使它适用于常规 RGBA 图像,但不适用于浮动图像。

什么有效(输出缓冲区“data_out”包含渲染结果)

format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
internal_format = GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
    width,
    height,
    0, format, type,
    Data

(...)
glDrawElements(GL_TRIANGLES, (2) * 3, GL_UNSIGNED_SHORT, 0);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data_out);

什么不起作用:

format = GL_RED_EXT;
type = GL_FLOAT;
internal_format = GL_RED_EXT;
glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
    width,
    height,
    0, format, type,
    Data);
(...)
glReadPixels(0, 0, width, height, GL_RED_EXT, GL_FLOAT, data_out);

我对 data_out 的期望:

27.0000000  float
22.7840576  float
11.4528332  float
-3.45501971 float
-17.2838974 float
-25.7151508 float
-26.1157665 float
(...)

我得到了什么:

-25.7161427 float
-25.7161427 float
-25.7161427 float
-25.7161427 float
-25.7161427 float
-17.2863979 float
-17.2863979 float
(...)

我在网上找不到很多类似的问题,除了以下讨论: https://groups.google.com/forum/#!topic/webgl-dev-list/ms21hnWk0tg ,似乎是在总结“做不到”,却是2012年写的。

那么真的没有办法使用 OpenGL ES 2.0 渲染到单通道浮动纹理吗?因为那将是我项目的主要问题。

更新 - 所以我尝试了下面评论中提到的往返 RGBA 编码的浮点数。

inline float4 EncodeFloatRGBA( float v ) {
float4 enc = float4(1.0, 255.0, 65025.0, 160581375.0) * v;
enc = frac(enc);
enc -= enc.yzww * float4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);
return enc;
}
inline float DecodeFloatRGBA( float4 rgba ) {
return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
}
void main()
{
float raw_value = DecodeFloatRGBA(texture2D( myTextureSampler, UV ));
gl_FragColor = EncodeFloatRGBA(raw_value);
}

推送一个填充了任意值 (5.23) 的纹理并使用 glReadPixels 检索显示,我只得到 4 个字节中的 3 个字节,alpha 被固定为 0

输入值(每字节字节)

[0] 41 ')'  unsigned char
[1] 92 '\\' unsigned char
[2] 167 '§' unsigned char
[3] 64 '@'  unsigned char

输出值(每字节字节)

[0] 41 ')'  unsigned char
[1] 92 '\\' unsigned char
[2] 167 '§' unsigned char
[3] 0 '\0'  unsigned char

【问题讨论】:

    标签: floating-point shader opengl-es-2.0 render-to-texture


    【解决方案1】:

    对于浮点格式支持,您需要扩展名:https://www.khronos.org/registry/OpenGL/extensions/OES/OES_texture_float.txt

    对于单通道渲染格式,您需要扩展名:https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_rg.txt

    跨 8888 或 4444 渲染目标的多个通道对浮点数进行编码并不是一种不寻常的方法。这里有一个例子和几个链接:http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/

    【讨论】:

    • 谢谢。我使用以下命令检查了扩展: const GLubyte* msg = glGetString(GL_EXTENSIONS); ,我确实在列表中看到了 GL_OES_texture_float 和 GL_EXT_texture_rg。按照我的理解,我可以处理这样的纹理,但不能渲染它们。我将研究将浮点数编码/解码为 RGBA 格式,尽管我认为它会影响性能。
    • 你是对的。 khronos.org/registry/OpenGL/extensions/EXT/… 为 GLES 2 添加了半个浮点数,但除了需要 GLES 3 的 khronos.org/registry/OpenGL/extensions/EXT/… 之外,我找不到全浮点数。
    • 于是我在一个简单的直通测试中实现了上面提到的编码/解码功能(aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final),结果与源不同,因为alpha通道设置为零。进一步看,我发现这个stackoverflow.com/questions/6893302/… 带有评论“请注意,你也不能存储 alpha(以这种方式),因为 highp 浮点数是 24 位长,而不是通常使用的 32 位”。所以第一个版本的代码不应该工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多