我正在使用片段着色器对我从OBJ文件加载的对象进行Lambert和Fog着色,但我对多边形有一个小问题。当我将相机位置移离物体时,我的网格中的一些多边形被“剔除”。
示例:
老实说,我不知道为什么会发生这种情况,为什么只有当我离开这个物体时才会发生这种情况。这是我的着色器:
顶点着色器
# version 400
out struct vData {
vec4 pos;
vec4 texcoord;
vec3 normal;
} fdata;
void main() {
fdata.texcoord = gl_MultiTexCoord0;
fdata.normal = normalize(gl_NormalMatrix * gl_Normal);
fdata.pos = gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * fdata.pos;
}
片段着色器
# version 400
layout(binding=0) uniform sampler2D mainTexture;
uniform vec4 lightColor;
uniform vec4 lightPos;
in struct vData {
vec4 pos;
vec4 texcoord;
vec3 normal;
} fdata;
vec4 ComputeLambert(const in vec3 lightdir, const in vec4 lightColor, const in vec3 normal, const in vec4 diffuse) {
float nDotL = dot(normal, lightdir);
return diffuse * lightColor * max(nDotL, 0.0);
}
float ComputeFogFactor(const in vec4 coord, const in float density) {
const float LOG2 = 1.442695;
float z = coord.z / coord.w;
float fogFactor = exp2( -density * density * z * z * LOG2 );
return clamp(fogFactor, 0.0, 1.0);
}
void main() {
vec3 mypos = fdata.pos.xyz / fdata.pos.w;
vec3 lightdir = lightPos.xyz / lightPos.w;
vec3 direction = normalize(lightdir - mypos);
vec4 diffuse = texture2D(mainTexture, fdata.texcoord.st);
diffuse = ComputeLambert(direction,lightColor, fdata.normal, diffuse);
float fogFactor = ComputeFogFactor(gl_FragCoord,gl_Fog.density);
vec4 finalcolor = mix(gl_Fog.color, diffuse, fogFactor);
//vec4 finalcolor = vec4(1.0,1.0,1.0,1.0);
finalcolor.a = 1.0;
gl_FragColor = finalcolor;
}
我确保在我的绘图电话之前禁用Face Culling,所以我很确定这不是问题。有人知道我能做些什么吗?
答案 0 :(得分:1)
看起来像Z-buffer问题......我知道你已经通过评论来看看它,但是:
你的截头日是怎样的?
znear,zfar
?
您使用的Z缓冲区的深度是什么?
当你将这两个东西组合在一起时,你可以估计深度的准确性。
例如z = <0.1m - 10000.1m>
和16 bit
需要10000.0/65536=0.15 [m/step]
当然正常的gl frustrum具有非线性Z值,所以更准确度接近且远远不够
当您比较模型的步长和最小细节时,它们与您的问题没有多大区别。
要修复此问题,您可以执行以下操作:
更改frustrum
放大近值或降低远值
每个z缓冲区使用更多深度位(不适用于所有卡)
使用更多的frustrums
对于非常大的渲染范围,我使用更多具有相同视图的截头,但
view1 z = < 0.1, 10.0 >
view2 z = < 10.0, 100.0 >
view3 z = <100.0,10000.0 >
当然你需要在使用另一个截头之前清除z缓冲区。视图可以通过绘制模型的最大大小重叠(然后您不需要所有视图中的所有模型只按范围视图渲染对象)。
由于多次渲染过程较慢,但在重叠的情况下,减速只能通过范围选择if
进行,这不是什么大问题。
使用线性Z缓冲区值...
GLSL 内的不使用变换的Z值,而是将其转换为自我,这使得精度在所有范围内都相同。而不是在更远的位置指数地降低
将LOD用于模型
远距离的最低安全精度,但如果你的模型没有LOD范围,那么很难自己正确计算
PS。它没有剔除,但正面和背面的z值准确度较低,可能导致错位(甚至改变前后,反之亦然)
答案 1 :(得分:0)
据我所知,深度缓冲区值不是线性的,因此多边形离相机越远,在某个深度范围内给出的位越少,导致z-fighting。当您选择远视平面的远平面时,这个问题变得更加严重(正如您所说:地形大小的两倍)。
因此,尝试减小平截头体尺寸(长度)和/或增加z缓冲深度