モデルの周りの奇妙な白い輪郭


19

私はXNA 4でゲームに取り組んでおり、最近このガイドに従って遅延シェーディングの実装に切り替えました。奇妙な白い輪郭が私のモデルに今現れており、私はこれを引き起こしているものがわからない。通常のレンダーターゲットやデプスレンダーターゲットの精度が不足しているのではないかと思っていましたが、32(カラー)ではなく64ビット(Rgba64)に増やしても役に立ちませんでした。また、鏡面反射の計算に問題があるかもしれないと思ったので、鏡面反射光を0に設定しようとしましたが、それも助けにはなりませんでした。PIXでピクセルをデバッグすると、拡散値がそのピクセルに対してほぼ白として計算されていることがわかります。何か案は?以下に問題の写真を含めました。フルサイズで見た方が簡単です。

ピクセルシェーダー:

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    input.ScreenPosition.xy /= input.ScreenPosition.w;

    float2 texCoord = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1) - halfPixel;

    float4 normalData = tex2D(normalSampler, texCoord);

    //Transform normal back into [-1, 1] range
    float3 normal = normalize(2.0f * normalData.xyz - 1.0f);

    float specularPower = normalData.a;
    float specularHardness = tex2D(colorSampler, texCoord).a * 255;
    float depthVal = tex2D(depthSampler, texCoord).r;

    //Compute screen-space position
    float4 position = float4(input.ScreenPosition.xy, depthVal, 1.0f);

    //Transform to world space
    position = mul(position, InvertViewProjection);
    position /= position.w;

    //Surface-to-light vector
    float3 lightVector = lightPosition - position;

    float3 projectedTexCoords = position - lightPosition;
    projectedTexCoords = mul(projectedTexCoords, float3x3(
                            float3(-1, 0, 0),
                            float3(0, 1, 0),
                            float3(0, 0, 1)));

    float distanceToLight = length(lightVector) / lightRadius;
    float shadow = ShadowContribution(projectedTexCoords, distanceToLight);

    float attenuation = saturate(1.0f - distanceToLight);

    lightVector = normalize(lightVector);

    //Compute diffuse light
    float normalDotLight = max(0, dot(normal, lightVector));
    float3 diffuseLight = normalDotLight * Color.rgb;

    float3 reflectionVector = normalize(reflect(-lightVector, normal));
    float3 directionToCamera = normalize(cameraPosition - position);
    float specularLight = specularPower * pow(saturate(dot(reflectionVector, directionToCamera)), specularHardness);

    return shadow * attenuation * lightIntensity * float4(diffuseLight.rgb, specularLight);
}

編集:JPGについては申し訳ありませんが、stackexchangeのアップローダーはそれを単独で行いました。Roy T:XNA3から変更された部分について、チュートリアルのXNA4変換を実際に参照しました。コードに大きな変更を加えなかったので、このバグはオリジナルに存在する可能性があると考えましたが、非常に多くのライトが動き回っているのを見るのは不可能でした。トカゲの肘の近く)

私のシーンのGBufferの内容は次のとおりです。

カラーバッファー: 深度バッファー: 通常のバッファー: 最終レンダリング:

編集2

カラーマップをサンプリングするときに問題がCombineFinal.fxであると疑い始めています。これは、白いピクセルのすぐ隣にある適切な色のピクセルの計算です。

diffuseColor        : (0.435, 0.447, 0.412)
diffuseLight        : (1.000, 1.000, 0.902)
light               : (1.000, 1.000, 0.902, 0.000)
PixelShaderFunction : (0.435, 0.447, 0.371, 1.000)
specularLight       : 0.000

そして、これはその隣の不適切な色の白いピクセルからの出力です:

diffuseColor        : (0.824, 0.792, 0.741)
diffuseLight        : (1.000, 1.000, 0.902)
light               : (1.000, 1.000, 0.902, 0.000)
PixelShaderFunction : (0.824, 0.792, 0.669, 1.000)
specularLight       : 0.000

DiffuseColorが唯一の違いであり、この色はカラーマップから直接取得されます。おそらく、サンプリング元のテクスチャ座標の計算にわずかなエラーがありますか?

照明パス:


4
微妙なグラフィカルな不具合を示すスクリーンショットをjpeg圧縮しないでください。人々は問題を完全な再現で見たいと思うでしょう。
aaaaaaaaaaaa

まあ、jpeg圧縮は実際にグリッチを非常にうまく通過させます.1ピクセルのみで、特定のものが再結合されたときだけです(Z深度の大きな差分と照明はすべてのピクセルで(かなり)高い)。幸運なことに、遅延レンダリングは非常に技術的なものです。
ヴァルモンド

2
役立つかどうかはわかりませんが、非常に古いバージョンのコード/チュートリアルを使用しているため、Catalin Zimaの実際のコード/チュートリアルは次の場所にあります:catalinzima.com/tutorials/deferred-rendering-in-xnaおよび認定XNA4.0バージョンは次の場所にあります。roy-t.nl/index.php/2010/12/28/...
ロイ・T.

また、遅延レンダリングのデバッグと同様に、すべてのバッファからスクリーンショットを投稿できますか?おそらく照明バッファーにありますが、何か他のものである可能性があります。
ロイT.

私の本能は、アルゴリズムの一部が正確に90度の角度を処理する方法に問題があるということですが、さらに詳しく調べるには、作業後にodeで遊ぶ必要があります。
ヨルダンミロナス

回答:


4

自分の遅延レンダラーを開始したとき、モデルの周りにもこの白い輪郭または「ハロー」がありました。問題は、レンダーターゲットをオーバーレイするためのテクスチャオフセット値が正しく設定されていなかったことです。一部のテクスチャは、オフセットに対して-0.5ピクセルではなく+0.5ピクセルに設定する必要がありました。

アウトラインが消えたのは、テクスチャオフセットの一部の値を調整した後のみです。ほとんどの場合、照明シェーダーの1つにあります。

編集:ちなみに、あなたの例から分岐したCatalin Zimaのチュートリアルからも学んだので、うまくいくはずです。


うん、それでした。ライトシェーダーのすべての座標サンプリングで+ halfPixelに変更し、ハローが消えました。
テラノール

0

何が起こっているのか正確にはわかりませんが、いくつか確認してください:

  1. Gバッファのサンプリング時にテクスチャフィルタリングがオフになっていることを確認してください-バイリニアまたは異方性などはありません。

  2. テクスチャ座標に半ピクセルのオフセットを追加しているようです。それが正しいことを再確認してください。正しいオフセットが何であるかを知るほどXNAに精通していませんが、Gバッファーの1つをサンプリングしてサンプルを出力するシェーダーを作成することで、それを確認できるはずです。次に、これとGバッファを画面上に直接表示することを交互に切り替えます。正しいオフセットが得られれば、違いは見られず、1ピクセルも見られないはずです。


私は行って、GBufferに関連するすべてのものをPOINTに変更しました(フィルタリングが無効になっていると思いますか?)、それでも同じです。2番目のポイントについて、GBufferを直接出力することはまったく同じではありません。データを出力するだけのシェーダーを作成しますか?もう少し詳しく説明していただけますか?
テラノール

さて、どのようにして上記のGバッファのスクリーンショットを生成しましたか?何らかの組み込みAPI関数を呼び出して、Gバッファーから画面(バックバッファー)にピクセルを1対1でコピーすると仮定しますか?(私はXNAを知らないので、それが何と呼ばれるかわかりません。)私は言っている、組み込みの1対1コピー機能の出力を、行うために書かれたピクセルシェーダーの出力と比較します1対1のコピー...そのようにして、テクスチャ座標が正確に正確であり、実際に1対1のサンプリングを取得していることを確認できます。
ネイサンリード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.