Opengl es GLSL:使用2D纹理模拟3D纹理

Opengl es GLSL:使用2D纹理模拟3D纹理,opengl-es,glsl,textures,3d-texture,Opengl Es,Glsl,Textures,3d Texture,我想出了一些代码,使用包含瓷砖的大2D纹理模拟3D纹理查找。3D纹理为128x128x64,大2D纹理为1024x1024,分为64块128x128 片段着色器中的查找代码如下所示: #extension GL_EXT_gpu_shader4 : enable varying float LightIntensity; varying vec3 pos; uniform sampler2D noisef; vec4 flat_texture3D() { vec3 p = pos;

我想出了一些代码,使用包含瓷砖的大2D纹理模拟3D纹理查找。3D纹理为128x128x64,大2D纹理为1024x1024,分为64块128x128

片段着色器中的查找代码如下所示:

#extension GL_EXT_gpu_shader4 : enable

varying float LightIntensity;
varying vec3 pos;

uniform sampler2D noisef;
vec4 flat_texture3D()
{
    vec3 p = pos;
    vec2 inimg = p.xy;

    int d = int(p.z*128.0);
    float ix = (d % 8); 
    float iy = (d / 8);
    vec2 oc = inimg + vec2(ix, iy);
    oc *= 0.125;

    return texture2D(noisef, oc);
}

void main (void)
{
    vec4 noisevec = flat_texture3D();
    gl_FragColor = noisevec;
}
平铺逻辑似乎工作正常,这段代码只有一个问题。看起来是这样的:

#extension GL_EXT_gpu_shader4 : enable

varying float LightIntensity;
varying vec3 pos;

uniform sampler2D noisef;
vec4 flat_texture3D()
{
    vec3 p = pos;
    vec2 inimg = p.xy;

    int d = int(p.z*128.0);
    float ix = (d % 8); 
    float iy = (d / 8);
    vec2 oc = inimg + vec2(ix, iy);
    oc *= 0.125;

    return texture2D(noisef, oc);
}

void main (void)
{
    vec4 noisevec = flat_texture3D();
    gl_FragColor = noisevec;
}

在体素层之间有奇怪的1到2像素宽的条纹。 当
d
改变时,条纹正好出现在边界处。

我已经做了两天了,仍然不知道这里发生了什么。

这看起来像是纹理过滤器的问题。想想看:当你靠近边界时,双线性滤波器会考虑相邻的纹理,在你的情况下:从另一个“深度层”。 为了避免这种情况,可以钳制纹理坐标,以便它们永远不会超出平铺最外层纹理中心定义的矩形(类似于GL_钳制_到_边,但基于每个平铺)。但是您应该知道,使用mipmapping时问题会变得更严重。您还应该知道,当前无法像真实3D纹理那样在z方向进行过滤。当然,您可以在着色器中手动模拟


但真的:为什么不使用3D纹理呢?硬件可以用更少的开销为您完成所有这一切…

您使用的是线性采样还是最近采样?#extension GL#U EXT#U gpu#shader4:enable“这让我很困惑。如果你能做到这一点,为什么你不能创建一个真实的3D纹理呢?没有支持DX10且不允许3D纹理的硬件。@Tim,线性位它似乎没有什么区别。@Nicolas我需要它作为
%
操作符,无论如何,它是针对iOS的,它似乎不支持这个扩展,所以我想我需要找到另一种方法来实现这一点……事实证明,mipmap确实是个问题。谢谢