OpenGL纹理重复工件

时间:2016-07-13 17:16:57

标签: java opengl glsl textures opengl-4

我正在使用OpenGL(4.5核心,LWJGL 3.0.0 build 90),我注意到使用GL_REPEAT包裹模式的纹理上的一些文物,重复次数很多:

Texture artifacts

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

此处,平面尺寸为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);
}

片段着色器:

#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);
}

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

Additionnal infos(我认为大部分都没用):

  1. 相机: FOV = 70°,比率 = 16/9, = 0.0001, = 10
  2. OpenGL: 主要 = 4,次要 = 5,个人资料 =核心
  3. 纹理 InternalFormat = GL_RGBA过滤器 =各向异性,三线
  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日)

1 个答案:

答案 0 :(得分:1)

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

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