当前位置: 首页 > 知识库问答 >
问题:

OpenGL:使用mipmap(OpenTK)时模糊的纹理

季阳朔
2023-03-14

我在C#for OpenGL 3.1中使用OpenTK包装器。我正在渲染一个场景,在这个场景中,相同的纹理用于近处和远处的对象。当我不使用MipMap时,纹理非常清晰(即使纹理对象非常小),但闪烁(如果我正确理解该术语)是可见的——当纹理对象移动到很远的地方时,纹理的像素似乎会闪烁。所以我尝试使用mipmaps。在更改为TextureMiniFilter后,请更改为LinearMipmapLinear并调用GL。GenerateMipmap(GenerateMipmapTarget.Texture2D)闪烁效果消失,但纹理非常模糊,以下是用于比较的图像:

看起来自动生成mipmap需要一些调整,但我找不到任何方法告诉OpenTK应该构建多少mipmap,或者应该使用什么方法来缩小原始图像的比例。这是用于加载纹理的代码:

var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.BindTexture(TextureTarget.Texture2D, textures[idx]);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);  
bmp.UnlockBits(data);

在使用mipmap时,可以做些什么来提高纹理清晰度?

更新:

手动生成mipmap后,效果完全相同。

解决方案:我遵循datenWolf的答案并使用了各向异性纹理过滤-这消除了问题。我用代码启用了它:

        float maxAniso;
        GL.GetFloat((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt, out maxAniso);
        GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, maxAniso);

支持的扩展列表可以通过以下方式获得:

var extensions = GL.GetString(StringName.Extensions).Split(' ');

共有1个答案

班承恩
2023-03-14

这里有两个主要的可能的罪魁祸首:在OpenGL实现的glGenerateMipmap中可能有一个低质量的降尺度过滤器。纹理坐标中的轻微各向异性可能会导致更模糊的过滤。

补救措施:

>

  • 实现您自己的图像降尺度并单独传递每个mipmap级别(glTexImage2D级别参数),并且不依赖glGenerateMipmap

    使用各向异性纹理过滤

  •  类似资料:
    • 我很难让mipmaps正常工作。我使用的是OpenGL 1.1,我没有glu,所以我使用以下纹理初始化代码: 变量: 是保存纹理mipmap像素数组列表的数组。mipmap处理正确(我单独测试了它们)是将原始图像缩小为1x1像素纹理的mipmaps数(原始纹理为256x256-因此在代码中此时为8)<代码>宽度和高度是原始纹理(256x256)的尺寸。 结果是它甚至没有使用纹理。一切都呈现出平坦的

    • 所以最近我开始阅读OpenGL维基文章。这就是我在这里描述OpenGL纹理的方式。不过,有几点尚不清楚。 以下陈述是真的、假的还是视情况而定? 将两个纹理绑定到同一个纹理单元是不可能的。 将两个采样器绑定到同一个纹理单元是不可能的。 将一个纹理绑定到两个不同的纹理单元是不可能的。 将一个采样器绑定到两个不同的纹理单元是不可能的。 应用程序有责任明确将什么采样器类型传递给什么统一变量。 着色器程序有

    • 在 OpenGL 中使用混合时,我有一个(希望)小问题。目前,我使用 LWJGL 和光滑的Util 来加载纹理。纹理本身是一个 2048x2048 png 图形,我在其中存储大小为 128x128 的图块,以便每行/列有 16 个 sprite。由于 glTexCoord2f() 使用规范化的坐标,我编写了一个小函数来缩放整个图像,以便仅显示我想要的子画面。它看起来像这样: (Recangle4d

    • 我有以下片段着色器: 如果我运行我的程序,我得到opengl错误1282,这是无效操作。如果我不使用texture(),那么我就写texCoord=vec4(...)它工作得很完美。我总是把tid(纹理ID)作为0(没有纹理)传入,所以这个部分甚至不应该运行。我已经将纹理统一设置为某个占位符,但据我所知,这应该无关紧要。那么什么会导致无效操作呢?

    • 我正在绘制一个纹理四边形,但使用的纹理是以前绑定的纹理,即使我试图绑定一个新纹理。 在GuiHandler中创建纹理。Java语言 渲染代码 有人知道为什么使用先前绑定的纹理而不是正确的纹理吗?P、 我正在使用LWJGL

    • 我创建了一个类来保存我的模型信息。我必须正确渲染模型并正确包装纹理,但是由于某种原因,如果我有多个模型,它会将我所有的模型纹理化为仅1个纹理,正如您在这张图片中看到的:http://imgur.com/d0glIwF 知道为什么会这样吗? 这是我的代码: 提前谢谢你。