【问题标题】:Cube's edges in OpenGLOpenGL中立方体的边缘
【发布时间】:2016-06-06 16:59:27
【问题描述】:

我在 OpenGL 中绘制了一个立方体以将其用作天空盒。 我正在使用单个纹理图像,并使用 UV 坐标将 6 个面定位在正确的位置。 我使用以下代码发送纹理:

//------------------------------------Luminance--------------------------------------------------------------
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_width);
glBindTexture(GL_TEXTURE_2D, texturePointer[0]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_width, m_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_uYdata);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


//--------------------------------------U component------------------------------------------------------------
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_uvWidth);
glBindTexture(GL_TEXTURE_2D, texturePointer[1]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_uvWidth, m_uvHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_uUdata);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

//------------------------------------- V component-------------------------------------------------------------
glBindTexture(GL_TEXTURE_2D, texturePointer[2]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_uvWidth, m_uvHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_uVdata);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

我无法去除立方体面之间的白边,见下图:

GL_NEAREST去掉问题但是图片质量比较低, 如何使用GL_LINEAR 并移除此效果?

编辑:

立方体是使用以下教程创建的: Model loading

考虑到纹理是由六个面缝合成列。 实际的 Blender 对象是:

# Blender v2.77 (sub 0) OBJ File: 'demo_cube.blend'
# www.blender.org
o Cube
v  1.000000  -1.000000 -1.000000
v  1.0000000 -1.000000 1.000000
v -1.000000  -1.000000 1.000000
v -1.000000  -1.000000 -1.000000
v  1.000000   1.000000 -1.000000
v  1.0000000  1.000000 1.000000
v -1.000000   1.000000 1.000000
v -1.000000   1.000000 -1.000000
vt 0.833333333 0.0000
vt 0.666666666 1.0000
vt 0.833333333 1.0000
vt 0.833333333 0.0000
vt 1.000000000 1.0000
vt 1.000000000 0.0000
vt 0.333333333 1.0000
vt 0.500000000 0.0000
vt 0.333333333 0.0000
vt 0.500000000 1.0000
vt 0.666666666 0.0000
vt 0.500000000 0.0000
vt 0.000000000 0.0000
vt 0.166666666 1.0000
vt 0.166666666 0.0000
vt 0.333333333 0.0000
vt 0.166666666 1.0000
vt 0.333333333 1.0000
vt 0.666666666 0.0000
vt 0.833333333 1.0000
vt 0.500000000 1.0000
vt 0.666666666 1.0000
vt 0.000000000 1.0000
vt 0.166666666 0.0000
s off
f 2/1 4/2 1/3
f 8/4 6/5 5/6
f 5/7 2/8 1/9
f 6/10 3/11 2/12
f 3/13 8/14 4/15
f 1/16 8/17 5/18
f 2/1 3/19 4/2
f 8/4 7/20 6/5
f 5/7 6/21 2/8
f 6/10 7/22 3/11
f 3/13 7/23 8/14
f 1/16 4/24 8/17
//44 and 47

片段着色器是:

#version 330 core

in vec2 oTexCoord;

uniform sampler2D yChannel;
uniform sampler2D uChannel;
uniform sampler2D vChannel;



out vec4 color;


const vec3 offset = vec3(0.0625, 0.5, 0.5);
const mat3 coef = mat3(
        1.164,  0.0,          1.793,
        1.164, -0.213, -0.533,
        1.164,  2.112,   0.0
    );

void main()
{ 
    vec2 nTexCoord = vec2(oTexCoord.x, 1.0 - oTexCoord.y);

    vec4 Tcolor = vec4(1.0);

    if(oTexCoord.y <1  && oTexCoord.y > 0.0) {
        if(oTexCoord.x < 1  && oTexCoord.x > 0.0) {

            vec3 yuv = vec3(
                    texture(yChannel, nTexCoord).r,
                    texture(uChannel, nTexCoord).r,
                    texture(vChannel, nTexCoord).r
                ) - offset;
            vec3 rgb = yuv * coef;

            Tcolor = vec4(rgb, 1.0);            
        }
    }

    color = Tcolor;

}

【问题讨论】:

  • 您是否检查过您的纹理没有任何带有白色/透明像素或类似像素的 1 像素边框?
  • 这种渲染错误与人脸几何在边缘没有正确对齐有关。我不清楚您所说的“我正在使用单个纹理图像,并且我使用 UV 坐标将 6 个面定位在正确的位置”是什么意思。 - 如果您的意思是使用纹理定位顶点,这可能与图像格式精度有关。
  • 由于GL_NEAREST 消除了这些问题,这可能不是几何体对齐不正确的结果。然而,给定的方法似乎很奇怪。我不明白你为什么将 uvs 存储在纹理中。也许您可以进一步解释您的方法或添加您的着色器代码。
  • @Mr_Pouet :我检查了纹理,似乎没有任何白色/透明边框,我对不同的纹理内容有同样的问题。
  • @William Kappler:我已经编辑了问题,然后你可以看到相关的几何图形。可能是,可能是格式精度的问题,但到目前为止我做了一些尝试,问题还是一样。

标签: c++ opengl


【解决方案1】:

我想你想使用cubemapsGL_ARB_seamless_cube_map

虽然生成的 (s t ) 坐标不太可能明显位于确定的立方体贴图面之外,但通常情况下,线性采样期间所需的各个元素的位置不在确定的面内,并且它们的因此,坐标将被选定的夹紧和环绕规则修改。 这通常会在采样纹理中产生接缝或其他不连续性。

此扩展允许实现从相邻的立方体贴图面中抽取样本,从而提供创建无缝立方体贴图的能力。

(emph。我的)。

要使用它,首先检查您是否确实拥有该扩展程序(这取决于您的平台以及最终帮助您访问 OpenGL 的工具包),然后只需编写

glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

启用它(全局)。

【讨论】:

  • OP 没有使用立方体贴图,所以这无济于事。
  • 那么 OP 也应该使用立方体贴图并启用无缝过滤。
  • 不幸的是,我不能使用立方体贴图,因为函数 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,......) 太慢了,而且我的应用程序会实时更改纹理。如果目的是每秒多次将纹理发送到 GPU,则使用映射到 UV 坐标的单个纹理是一个不错的选择。
  • 说实话,我不太明白为什么上传 2D 纹理会比上传立方体贴图面更快……分析器怎么说?
  • 基本上,在这种方法之前,我已经创建了立方体 usign Cubemap,由于对函数 glTexImage2D() 的多次访问(6 次 3 颜色通道),它真的很慢。然后我决定只使用一个纹理,每个颜色通道只使用一次 glTexImage2D() 。我为两个立方体使用了相同的纹理,值得注意的是第二种方法的性能要好得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
相关资源
最近更新 更多