c++ - 从 texture() 切换到 texelFetch()

标签 c++ opengl glsl shader fragment-shader

目前我使用函数 texture(...) 读取 3D 纹理,如下所示:

vec3 值 = texture(texture_3D, coord).rgb

我现在要做的是:

vec3 值 = texelFetch(texture_3D, coord, 0).xyz

但是,我不知道如何转换我的坐标以使其与 texelFetch 一起使用。我的纹理大小为 256x256x256

而我现在的坐标计算如下:

vec3 min_box = vec3(-0.5);
vec3 max_box = vec3(0.5);

vec3 coord = worldToVolume(world_pos, min_box, max_box)

vec3 worldToVolume(world_pos, min_box, max_box) {
     return (world_pos - min_box) / (max_box - min_box)
}

有什么想法吗?如果您需要更多信息,请询问,我会提供。

最佳答案

这两个函数对完全不同的参数执行完全不同的任务。

texture 需要 [0,1] 中的归一化浮点纹理坐标(即 0 为左/下,1 为右/上)并执行适当的包装(因此坐标不一定必须在 [0,1] 中)并根据您设置的任何采样模式进行过滤(因此您不一定获得确切的纹素颜色)。

另一方面,

texelFetch 期望 [0,width-1] 中的整数纹素索引(分别是 y 和 z 的高度/深度)并且不执行任何类型的过滤或包装,访问指定 mipmap 级别中指定索引处的确切纹素值。

所以 texelFetch(texture_3D, ivec3(coord * vec3(256.0), 0) 应该等同于 texture(texture_3D, coord) with 过滤模式 GL_NEAREST 和环绕模式 GL_CLAMP_TO_EDGE。但是,还要记住在坐标恰好为 1.0 或在纹素边界上时可能出现的舍入问题,也许 texelFetch(texture_3D, ivec3(coord * vec3(255.0) + vec3(0.5), 0) 在这方面可能更安全。

但是,与简单地使用 GL_NEAREST 过滤器保持当前纹理访问相比,以这种方式更改它似乎是一个相当无用的方法。如果您已经有整数纹素坐标并且已经知道纹理大小,它会更有用。仅以这种方式模拟最近的过滤不会真正给您带来任何好处。它基本上是两种概念上不同的方法,一种使用与大小无关的浮点坐标过滤纹理,另一种使用整数索引访问 3D 数组。这取决于您周围的代码,哪种方法更适合您的用例。

关于c++ - 从 texture() 切换到 texelFetch(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45613310/

相关文章:

c++ - Linux 上的编译器 (GCC) 交叉编译(到 Windows)——如何在非源目录中构建它?

c++ - 当非限定名称查找涉及 using-directives 时 [basic.scope.hiding]p2 的解释

java - 使用着色器时纹理不渲染?

opengl - 如何处理离散光线追踪的错误索引计算?

c++ - Vim 中文件的一部分的快照 : hide comments and blank lines

c++ - 调试 DirectX 代码

c++ - glGetObjectParameteriv 不在 GLEW 中

opengl - 是否还有 OpenGL 1.2 的教程?

c++ - 在 GLSL C++ 中将射线与三角形相交

opengl - fwidth glsl 函数实际用于什么?