使用3D纹理时结果不正确 [英] Incorrect result when using 3D textures

查看:78
本文介绍了使用3D纹理时结果不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用现代的OpenGL 4.3内核.

I'm using modern OpenGL 4.3 core.

我刚刚意识到1024p x 1024p切片集太小了,无法满足我的需求.因此,我将其替换为1024p x 1024p x 4p 3D纹理. (我知道,这不是最好的解决方案,我最好使用2D纹理数组.我只是想知道为什么当前的解决方案不起作用.)

I just realized that 1024p x 1024p tileset is too small for my needs. So, I replaced it with 1024p x 1024p x 4p 3D texture. (I know, it's not the best solution, and I better to use 2D texture array. I'm just wondering why my current solution doesn't work.)

xy纹理坐标可以正常工作,与以前相同. z也可以,但是有点不正确.我希望第一层具有z == 0.0,第二层-z == 0.3333333,第三层-z == 0.66666666和第四层-z == 1.0.

x and y texture coordinates work fine, same as before. z also work, but a bit incorrectly. I would expect the 1st layer to have z == 0.0, 2nd layer - z == 0.3333333, 3rd layer - z == 0.66666666 and 4rd one - z == 1.0.

第1层和第4层按预期工作.但是0.333333330.66666666给我错误的结果:
0.33333333->第一层与第二层混合
0.66666666->第三层与第四层混合
(我正在使用线性过滤,这就是它们混合在一起的原因.)

The 1st and 4th layers work as expected. But 0.33333333 and 0.66666666 give me incorrect results:
0.33333333 -> 1st layer mixed with 2nd layer
0.66666666 -> 3rd layer mixed with 4th layer
(I'm using linear filtering, that's why they mix together.)

我尝试为第二层和第三层选择正确的z值:
z == 0.38
时,第二个显示正常 z == 0.62
时,第3个显示正常 (这些数字是近似值.)

I tried to pick the right z values for 2nd and 3rd layers:
2nd displays fine when z == 0.38
3rd displays fine when z == 0.62
(These numbers are approximate, of course.)

有什么想法为什么会发生以及如何解决?

Any ideas why this happen and how I can fix this?


这就是我创建纹理的方式:


This is how I create the texture:

glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &maintex);
glBindTexture(GL_TEXTURE_3D, maintex);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, TEXSIZE, TEXSIZE, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, textemp);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

这是我的着色器:

const char *vertex = 1+R"(
#version 430
uniform layout(location = 3) vec2 fac;
in layout(location = 0) vec2 vpos; // vertex coords
in layout(location = 1) vec3 tpos; // texture coords
in layout(location = 2) vec4 c_off;  // color offset    = vec4(0,0,0,0) by default
in layout(location = 3) vec4 c_mult; // color multiplicator    = vec4(1,1,1,1) by default
// These two are used to do some sort of gamma correction 

out vec3 var_tpos;
out vec4 var_c_off;
out vec4 var_c_mult;
void main()
{
    var_tpos = tpos;
    var_c_off = c_off;
    var_c_mult = c_mult;
    gl_Position = vec4(vpos.x * fac.x - 1, vpos.y * fac.y + 1, 0, 1);
})";


const char *fragment = 1+R"(
#version 430
uniform layout(location = 0) sampler3D tex;
in vec3 var_tpos;
in vec4 var_c_off;
in vec4 var_c_mult;
out vec4 color;
void main()
{
    color = texture(tex, vec3(var_tpos.x / 1024, var_tpos.y / 1024, var_tpos.z));
    color.x *= var_c_mult.x;
    color.y *= var_c_mult.y;
    color.z *= var_c_mult.z;
    color.w *= var_c_mult.w;
    color   += var_c_off;
})";

推荐答案

这是因为0是左侧texel的最左侧"部分,而1是最右侧texel的最右侧点.假设我们有4个纹理像素,则坐标如下:

That's because 0 is the "leftmost" part of the left texel and 1 is the rightmost point in the rightmost texel. Assume we have 4 texels, than the coordinates are as follows:

0       1/4      1/2      3/4       1
|  tx1   |  tx2   |  tx3   |  tx4   |

由于您需要精确击中体素的中心,因此必须使用比预期高1/2体素的地址(+ 0.25/2 = +0.125),因此体素中心如底部所述下图的线.

since you need to hit exactly the center of a voxel, you have to use addresses that are 1/2 voxel higher then you expected (+0.25/2 = +0.125), thus the voxel centers are as described in the bottom line of the following diagram.

|  tx1   |  tx2   |  tx3   |  tx4   |
    |        |        |        |
  0.125    0.375     0.625    0.875

这篇关于使用3D纹理时结果不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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