6

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 を無効にしたことを確認したので、それが問題ではないことは確かです。これについて私にできることがあるかどうか誰か知っていますか?

4

2 に答える 2

1

Zバッファの問題のように見えます...コメントで見てきたことは知っていますが、

  1. あなたの錐台はどのように設定されていますか?

    znear,zfar?

  2. Zバッファに使用するビット深度は?

    これら 2 つのことを組み合わせると、深さの精度を推定できます。

    たとえばz = <0.1m - 10000.1m>、もちろん、通常の gl 16 bitfrustrum10000.0/65536=0.15 [m/step]には非線形の Z 値があるため、精度が高くなると近くなり、遠くになるとはるかに低くなります。

    モデルのステップと最小の詳細を比較すると、これが問題であるよりも大きな違いはありません。

これを修復するには、次のようにします。

  1. 錐台を変更する

    Near 値を拡大または Far 値を下げる

  2. z バッファごとにより多くの深度ビットを使用します (すべてのカードで機能するわけではありません)。

  3. 錐台をもっと使う

    レンダリング範囲が非常に広い場合、同じビューでより多くの錐台を使用しますが、

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

    もちろん、別の錐台を使用する前に z バッファをクリアする必要があります。ビューは、描画されたモデルの最大サイズでオーバーラップできます (その場合、すべてのビューのすべてのモデルは必要なく、範囲ビューでオブジェクトをレンダリングするだけです)。

    複数のレンダリング パスがあるため遅くなりますが、オーバーラップの場合、速度低下は範囲選択ifによるものであり、大したことではありません。

  4. リニア Z バッファ値を使用 ...

    GLSL内では、変換された Z 値を使用せず、代わりに自分で変換すると、すべての範囲で精度が同じになります。より離れた位置で指数関数的に低くなる代わりに

  5. モデルに LOD を使用する

    遠距離でのこの最小安全精度の下限ですが、モデルに LOD 範囲がない場合、自分で正しく計算することは非常に困難です

PS。カリングではありませんが、前面と背面の Z 値の精度が低いため、それらを誤って配置する可能性があります (前面を背面に変更したり、その逆を行ったりすることさえあります)。

于 2013-11-15T08:19:23.927 に答える
1

私が知る限り、深度バッファの値は線形ではないため、ポリゴンがカメラから離れているほど、特定の深度範囲に与えられるビットが少なくなり、z ファイティングが発生します。視錐台の遠方面を非常に遠くに選択すると、この問題はさらに悪化します(あなたが言ったように、地形サイズの2倍)。

そのため、錐台のサイズ (長さ) を小さくするか、Z バッファーの深さを大きくしてください。

于 2013-11-15T10:43:40.563 に答える