OpenGL 纹理中的 NAN

问题描述 投票:0回答:3

我在桌面应用程序(Windows/Linux、GLSL 4.2)中使用包含 float 32 数据(GL_RGBA32F 格式)的 1D、2D 和 3D OpenGL 纹理。

这些纹理包含预先计算的物理数据的结果,并且可能包含一些预计算失败的 NAN 值(这在我的应用程序中是“正常”,某些情况无法计算,这种情况很少见,但“正常”)

我需要在着色器中检测这些值。

GLSL 采样器中处理 NAN 值有任何标准吗?

更具体地说:

  • 确定写入纹理中的 NAN 值可以通过“textureXXX”GLSL 方法读取为 NAN 吗?

  • 如果使用非 NEAREST 过滤调用“textureXXX”方法,并且插值之一是 NAN,我应该得到 NAN 值作为结果吗?

谢谢。

编辑:

正如答案所说,OpenGL 规范中对 NaN 支持没有任何要求。

所以我会:

  • 用“特殊”值替换 NaN 值,以防纹理中的 NaN 值在 GLSL 中不被读取为 NaN

  • 自己实现mipmap

  • 根据“特殊”值测试所有值

这是额外的工作,但似乎有必要确保在不同平台/不同硬件上支持我的无效值。

opengl glsl nan
3个回答
2
投票

根据我对规范的解释,答案都是“否”。我为此找到的最确凿的证据位于最新 GLSL 规范的第 4.7.1 节“范围和精度”(例如 GLSL 4.20 规范的第 65 页):

对 NaN 进行操作的运算和内置函数不需要返回 NaN 作为结果。

texture()
GLSL 调用是内置函数,因此我相信此规则适用于它们,并且您不能指望它们为包含 NaN 值的纹理返回 NaN。


2
投票

OpenGL 4.5 兼容性规范的第 2.3.4.1 节表示“允许实现, 但不是必需的,以支持 InfNaN 的浮点计算。”

我在规范的纹理缩小部分没有发现任何提及 NaN 值的内容(OpenGL 4.5 兼容性规范中的 8.14.2)。然而,片段缩小中使用的方程似乎相当明确,所以我想实现将尊重其中的 NaN 值。但是,如果您害怕,您可以使用原始纹理访问函数自行实现 mipmapping。 正如 Reto Koradi 所指出的,纹理函数可能不会为过滤后的纹理返回 NaN 值。


0
投票

WebGL 纹理中的 NaN

具有 NaN 值的纹理适用于在 intel iMac 上运行的 WebGL。我想它也适用于其他平台。在从 JS 制作(浮动)纹理之前,您需要在 WebGL1 中使用 OES_texture_float 扩展。

在着色器 GLSL 中,您可以像这样检测 NaN...

vec4 data = texture2D(samplerData, tc);
bool bNaN = (data.r != data.r);

此外,在创建 WebGL 纹理之前,您可能需要在 JS 中将所有(浮动)纹理值缩放到 0 到 1 之间。然后您可以使用统一值在 GLSL 着色器中按比例缩小它们。

© www.soinside.com 2019 - 2024. All rights reserved.