OpenGL纹理重复工件

nas*_*sso 5 java opengl textures glsl opengl-4

我正在使用OpenGL(4.5核心,使用LWJGL 3.0.0 build 90),我注意到纹理上的一些工件使用GL_REPEAT了具有大量重复的包装模式:

纹理瑕疵

是什么导致这种情况,我该如何解决(如果可以的话)?


这里,平面的大小是100x100,UV是10000x10000.这个截图是真的很接近它(从更远的,质地是如此之小,我们只看到一台灰色),近平面是在0.0001和10远平面,我不知道问题出在自OpenGL默认值以来,深度缓冲区在更近距离处具有非常高的精度.

(编辑:我在考虑纹理坐标上的浮点错误,但我不确定)

这是我的着色器(我使用延迟渲染,纹理采样在几何传递中,所以我只给出几何传递着色器).

顶点着色器:

#version 450 core

uniform mat4 projViewModel;
uniform mat4 viewModel;
uniform mat3 normalView;

in vec3 normal_model;
in vec3 position_model;
in vec2 uv;
in vec2 uv2;

out vec3 pass_position_view;
out vec3 pass_normal_view;
out vec2 pass_uv;
out vec2 pass_uv2;

void main(){
    pass_position_view = (viewModel * vec4(position_model, 1.0)).xyz;
    pass_normal_view = normalView * normal_model;
    pass_uv = uv;
    pass_uv2 = uv2;

    gl_Position = projViewModel * vec4(position_model, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

#version 450 core

struct Material {
    sampler2D diffuseTexture;
    sampler2D specularTexture;

    vec3 diffuseColor;

    float uvScaling;
    float shininess;
    float specularIntensity;

    bool hasDiffuseTexture;
    bool hasSpecularTexture;
    bool faceSideNormalCorrection;
};

uniform Material material;

in vec3 pass_position_view;
in vec3 pass_normal_view;
in vec2 pass_uv;
in vec2 pass_uv2;

layout(location = 0) out vec4 out_diffuse;
layout(location = 1) out vec4 out_position;
layout(location = 2) out vec4 out_normal;

void main(){
    vec4 diffuseTextureColor = vec4(1.0);

    if(material.hasDiffuseTexture){
        diffuseTextureColor = texture(material.diffuseTexture, pass_uv * material.uvScaling);
    }

    float specularTextureIntensity = 1.0;

    if(material.hasSpecularTexture){
        specularTextureIntensity = texture(material.specularTexture, pass_uv * material.uvScaling).x;
    }

    vec3 fragNormal = pass_normal_view;
    if(material.faceSideNormalCorrection && !gl_FrontFacing){
        fragNormal = -fragNormal;
    }

    out_diffuse = vec4(diffuseTextureColor.rgb * material.diffuseColor, material.shininess);
    out_position = vec4(pass_position_view, 1.0); // Must be 1.0 on the alpha -> 0.0 = sky
    out_normal = vec4(fragNormal, material.specularIntensity * specularTextureIntensity);
}
Run Code Online (Sandbox Code Playgroud)

是的,我知道,眼睛空间位置在G缓冲区中是无用的,因为您可以稍后从深度缓冲区计算它.我现在就这样做了,但这是暂时的.此外,如果我的着色器中的任何内容被弃用或者不好的做法,如果你告诉我该怎么做,那将会很酷!谢谢 !

附加信息(我认为大多数都没用):

  1. 相机: FOV = 70°,比率 = 16/9, = 0.0001, = 10
  2. OpenGL: Major = 4,Minor = 5,Profile = Core
  3. 纹理: InternalFormat = GL_RGBA,Filters =各向异性,三线性
  4. 硬件: GPU = NVIDIA GeForce GTX 970,CPU = Interl(R)Core(TM)i7-4790K CPU @ 4.00GHz,内存 = 16.00 GB RAM(15.94 GB可用),屏幕 = 1920 x 1080 @ 144Hz
  5. 驱动程序: GeForce Game Ready驱动程序V368.69(发布日期:2016年7月6日)

ple*_*ron 3

这很可能是由于光栅化(插值、透视校正)过程中产生的浮点不精确性,并且由于片段着色器中获取正确纹理像素的标准化而恶化。

但这也是 mipmap 的一个问题:为了计算使用哪个级别,需要检索相邻像素的 UV 以了解纹理在屏幕上是否被拉伸或压缩。由于不精确,相邻像素共享相同的 UV,因此它们之间的差异(或“偏导数”)为零。这使得texture()函数采样在这些相同像素上具有最低的 mipmap 级别,从而产生不连续性。