Java OpenGL纹理重复工件

Java OpenGL纹理重复工件,java,opengl,glsl,textures,opengl-4,Java,Opengl,Glsl,Textures,Opengl 4,我正在使用OpenGL(4.5内核,LWJGL 3.0.0 build 90),我注意到使用GL\u REPEATwrap模式的纹理上出现了一些重复次数较多的瑕疵: 这是什么原因造成的,我如何修复它(如果可以的话)? 在这里,平面的大小为100x100,UV为10000x1000。这个屏幕截图非常接近它(从远处看,纹理非常小,我们只看到一个平坦的灰色),近平面为0.0001,远平面为10。 我不确定问题是否出在深度缓冲区中,因为OpenGL默认的深度缓冲区在较近的距离具有非常高的精度 (编辑

我正在使用OpenGL(4.5内核,LWJGL 3.0.0 build 90),我注意到使用
GL\u REPEAT
wrap模式的纹理上出现了一些重复次数较多的瑕疵:

这是什么原因造成的,我如何修复它(如果可以的话)?
在这里,平面的大小为100x100,UV为10000x1000。这个屏幕截图非常接近它(从远处看,纹理非常小,我们只看到一个平坦的灰色),近平面为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);
}
片段着色器:

#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缓冲区中是无用的,因为你可以在以后从深度缓冲区计算它。我只是暂时这么做,但这只是暂时的。 此外,如果我的着色器中有任何内容被弃用或是不好的做法,那么如果你告诉我该怎么做就好了!谢谢

附加信息(我认为大多数都是无用的):
  • 摄像机:视场=70°,比值=16/9,近距离=0.0001,远距离=10
  • OpenGL:Major=4,Minor=5,Profile=Core
  • 纹理:InternalFormat=
    GL\u RGBA
    ,过滤器=各向异性,三线性
  • 硬件:GPU=NVIDIA GeForce GTX 970,CPU=Interl(R)Core(TM)i7-4790K CPU@4.00GHz,内存=16.00GB RAM(可用15.94GB),屏幕=1920 x 1080@144Hz
  • 驱动程序:GeForce游戏就绪驱动程序V368.69(发布日期:2016年7月6日)

  • 这很可能是由于在光栅化(插值、透视校正)过程中创建的浮点不精确性造成的,并且由于片段着色器中用于获取正确纹理的规格化而恶化


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

    您是否尝试过用最小的可能场景重现问题?像一个2x2平面在正向着色?是的,它产生相同的结果。此外,离平面越近,瑕疵越明显。但我认为这可能只是mipmap的一个问题?我敢打赌,原因是:大量重复意味着浮点值的指数更高,因此尾数中剩余的分数位更少,即使在标准化和插值之前,纹理坐标的精度也是如此<代码>10000这似乎是更符合逻辑的原因。请回答这个问题,以便我可以验证它!谢谢您回答了另一件我不理解的事情:OpenGL如何知道使用哪个mipmap级别:D!有关导数的实际计算,请参见和。是否可以使用导数函数删除这些伪影?据我所知,问题只是一个浮点精度错误(无法修复),使用更多的几何体和更小的UV范围,因此不精确性更小。