opengl中的完美(3D)纹理映射 [英] Perfect (3D) texture mapping in opengl

查看:29
本文介绍了opengl中的完美(3D)纹理映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 opengl 中创建一个简单的 3D 数组可视化.3D 数组包含颜色值.为了实现这一点,我可以画很多立方体,给它们纹理坐标以指向正确的纹素.嗯,我试过了,它有效.但是我需要更多,实现我想要的唯一方法是,如果我只是在平面打开时在另一个轴方向上的每个网格上绘制完整的 2D 平面,并且这样做是 6 个方向.例如:我在 Z 坐标 -15 到 +15 上从 -15 到 +15 绘制 XY 平面,并且也为后 XY 平面、YZ 平面、后 YZ 平面,...这样,我可以在每个角落放置 3D 纹理坐标,剩下的就交给插值了.

I am trying to create a simple 3D-array visualisation in opengl. The 3D-array contains color values. To achieve this, I could just draw lots of cubes, giving them texture-coordinates to point to the correct texel. Well, I tried it, and it works. But I need a lot more, and the only way to achieve what I want is if I just draw full 2D planes on every grid in the other axis direction as the plane is on and do this is 6 directions. So for example: I draw XY-plane from -15 to +15, on Z-coordinates -15 to +15, and do this also for back-XY-plane, YZ-plane, back-YZ-plane, ... This way, I can just put 3D-texture coordinates at every corner and interpolation should do the rest.

我将数组坐标作为纹理坐标,介于 0 到 32 之间,原因是,在着色器中,我可以将纹理坐标设置为底,然后将其除以 32 以获得每个像素的精确纹素在网格上.

I have taken array-coordinates as texture coordinates, between 0 and 32, the reason for this is, that in the shader, I can floor the texture-coordinate and then divide it by 32 to get the exact texel for every pixel on the grid.

但是唉...像素着色器一直在怀疑选择,一个像素映射到与下一个像素不同的纹素,而下一个像素再次正确映射.

But alas... the pixel shader is constantly doubting choices, one pixel maps to a different texel than the next pixel, while the next-next pixel maps correctly again.

我曾经通过在浮点数上添加 0.5 或 0.35 来解决这类问题,以确保浮点数在所有硬件平台上都正确舍入,但对我来说这仍然是一个 hack.此外,它不适用于 3D 纹理.

I used to solve these kind of problems by adding 0.5 or 0.35 to the floats to make sure that the floats are rounded correctly on all hardware platforms, but it still seems such a hack to me. Also, it doesn't work on the 3D texture.

谁能告诉我如何处理这个问题?

Can anyone tell me how to handle this?

推荐答案

谁能告诉我如何处理这个问题?

Can anyone tell me how to handle this?

您遇到了臭名昭著的围栏发布问题.简单来说,纹理坐标 0 和 1 不是像素中心,而是像素边界.看看这个简单的草图

You're running into the infamous fenceposting problem. Simply spoken, texture coordinates 0 and 1 are not pixel centers, but pixel borders. Have a look at this simple sketch

  | 0 | 1 | 2 | 3 |
  ^               ^
 0.0             1.0

  0   1   2   3   4
 --- --- --- --- ---
  4   4   4   4   4

所以要解决纹理的像素 i(比如 0)N(比如 4)像素宽,您必须使用纹理坐标

So to address pixel i (say 0) of a texture N (say 4) pixels wide you must use the texture coordinate

(i/N + (i+1)/N)/2 = i/2N + (i+1)/2N = (2i + 1) / 2N = (i + 0.5)/N

因此,添加 0.5 并不是 hack.但是在着色器中,您可以只使用 texelFetch 以绝对像素而不是采样坐标来处理纹理.但是你必须自己实现过滤.

So adding that 0.5 is not a hack. However in the shader you can just use texelFetch to address the texture in absolute pixels, instead of a sampling coordinate. However you must implement filtering yourself then.

这篇关于opengl中的完美(3D)纹理映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆