c – 当我的相机远离物体时,为什么OpenGL会剔除我的多边形?

我在从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,所以我很确定这不是问题.有人知道我能做些什么吗?

最佳答案
看起来像Z-buffer问题…我知道你通过评论来看看它但是:

>你的冬天怎么样?

znear,zfar?
>你用于Z缓冲区的位深度是多少?

当您将这两个东西组合在一起时,您可以估计深度精度.

例如,z =< 0.1m-10000.1m>和16位取10000.0 / 65536 = 0.15 [m /步]当然正常的gl frustrum具有非线性Z值,所以精度更接近,远远小得多

当您比较模型的步长和最小细节时,它们与您的问题没有多大区别.

要修复它,您可以这样做:

>改变截头

放大近值或降低远值
>每个z缓冲区使用更多深度位(不适用于所有卡)
>使用更多的frustrums

对于非常大的渲染范围,我使用更多具有相同视图的截头,但是

view1  z = <  0.1,   10.0 >
view2  z = < 10.0,  100.0 >
view3  z = <100.0,10000.0 >

当然你需要在使用另一个截头之前清除z缓冲区.视图可以通过绘制模型的最大大小重叠(然后您不需要所有视图中的所有模型只按范围视图渲染对象).

它由于多次渲染过程而变慢,但在重叠的情况下,减速仅通过范围选择ifs并不是什么大问题.
>使用线性Z缓冲区值…

在GLSL内部不使用变换后的Z值,而是将其转换为自我,这使得精度在所有范围内都相同.而不是在更远的位置指数地降低
>将LOD用于模型

这个较低的最小安全精度在远处范围但如果你的模型没有LOD范围,那么很难自己正确地计算它

PS.它没有剔除,但正面和背面的z值准确度很低,可能导致它们错位(甚至改变前后,反之亦然)

转载注明原文:c – 当我的相机远离物体时,为什么OpenGL会剔除我的多边形? - 代码日志