Java OpenGL纹理重复工件
我正在使用OpenGL(4.5内核,LWJGL 3.0.0 build 90),我注意到使用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默认的深度缓冲区在较近的距离具有非常高的精度 (编辑
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缓冲区中是无用的,因为你可以在以后从深度缓冲区计算它。我只是暂时这么做,但这只是暂时的。
此外,如果我的着色器中有任何内容被弃用或是不好的做法,那么如果你告诉我该怎么做就好了!谢谢
附加信息(我认为大多数都是无用的):
GL\u RGBA
,过滤器=各向异性,三线性这很可能是由于在光栅化(插值、透视校正)过程中创建的浮点不精确性造成的,并且由于片段着色器中用于获取正确纹理的规格化而恶化
但mipmaps也有一个问题:为了计算使用哪个级别,将检索相邻像素的UV,以了解纹理是否在屏幕上拉伸或压缩。由于不精确,相邻像素共享相同的UV,因此它们之间的差异(或“偏导数”)为空。这使得
texture()
函数对这些相同像素的最低mipmap级别进行采样,从而产生不连续性。您是否尝试过用最小的可能场景重现问题?像一个2x2平面在正向着色?是的,它产生相同的结果。此外,离平面越近,瑕疵越明显。但我认为这可能只是mipmap的一个问题?我敢打赌,原因是:大量重复意味着浮点值的指数更高,因此尾数中剩余的分数位更少,即使在标准化和插值之前,纹理坐标的精度也是如此<代码>10000这似乎是更符合逻辑的原因。请回答这个问题,以便我可以验证它!谢谢您回答了另一件我不理解的事情:OpenGL如何知道使用哪个mipmap级别:D!有关导数的实际计算,请参见和。是否可以使用导数函数删除这些伪影?据我所知,问题只是一个浮点精度错误(无法修复),使用更多的几何体和更小的UV范围,因此不精确性更小。