Garis putih aneh di sekitar model

19

Saya sedang mengerjakan sebuah game di XNA 4 dan saya baru-baru ini beralih ke implementasi bayangan yang ditunda mengikuti panduan ini . Garis putih aneh muncul di model saya sekarang dan saya tidak yakin apa yang menyebabkan ini. Saya pikir mungkin itu kurang presisi pada target render normal atau target render kedalaman tetapi meningkatkannya menjadi 64 bit (Rgba64), bukannya 32 (Warna) tidak membantu. Saya juga berpikir mungkin ada masalah dengan perhitungan specular jadi saya mencoba mengatur specular ke 0 tetapi itu tidak membantu. Debugging piksel dalam PIX menunjukkan nilai difus sedang dihitung hampir putih untuk piksel itu. Ada ide? Saya menyertakan gambar masalah di bawah ini, lebih mudah untuk melihatnya dalam ukuran penuh.

Pixel Shader:

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);
}

Sunting : Maaf tentang JPG, pengunggah stackexchange melakukannya sendiri. Roy T: Saya benar-benar merujuk konversi XNA4 Anda dari tutorial untuk bagian-bagian yang berubah dari XNA3. Karena saya tidak membuat perubahan besar pada kode saya pikir mungkin bug ini ada dalam aslinya tetapi tidak mungkin untuk melihat dengan begitu banyak lampu semua bergerak di sekitar, jadi saya menghapus semua kecuali satu lampu dan bug muncul lagi (lihat dekat siku kadal)

Berikut adalah konten GBuffer untuk adegan saya:

Penyangga Warna: Penyangga Mendalam: Penyangga Normal: Penyedia Final:

Sunting2 :

Saya mulai curiga masalahnya adalah CombineFinal.fx ketika sampel peta warna. Ini adalah perhitungan untuk piksel berwarna yang benar tepat di sebelah piksel putih:

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

Dan ini adalah output dari piksel putih berwarna tidak langsung tepat di sebelahnya:

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

DifuseColor adalah satu-satunya perbedaan, dan warna ini diambil langsung dari peta warna. Mungkin ada sedikit kesalahan dalam perhitungan koordinat tekstur untuk sampel dari?

Pass pencahayaan:

Telanor
sumber
4
Tolong jangan jpeg kompres tangkapan layar yang menunjukkan kesalahan grafis yang halus. Orang ingin melihat masalah dalam reproduksi sempurna.
aaaaaaaaaaaa
Yah, kompresi jpeg benar-benar memungkinkan glitch cukup baik, saya pikir, satu pixel saja dan hanya ketika hal-hal tertentu disatukan kembali (perbedaan besar dalam Z-depth dan pencahayaannya (cukup) tinggi pada semua piksel). Selamat mencoba, rendering yang ditangguhkan cukup teknis.
Valmond
2
Tidak yakin apakah itu membantu, tetapi Anda menggunakan versi kode / tutorial yang sangat lama, kode / tutorial aktual Catalin Zima sekarang ada di: catalinzima.com/tutorials/deferred-rendering-in-xna dan XNA4.0 yang disetujui versi ada di sini: roy-t.nl/index.php/2010/12/28/…
Roy T.
Seperti biasa dengan debugging rendering yang ditangguhkan, dapatkah Anda memposting tangkapan layar dari semua buffer? Mungkin ada di buffer pencahayaan, tetapi bisa jadi itu sesuatu yang lain.
Roy T.
Insting saya adalah bahwa itu akan menjadi masalah dengan cara bagian dari algoritma menangani sudut 90 derajat, tapi saya harus bermain dengan ode setelah bekerja untuk melihat lebih jauh.
Jordaan Mylonas

Jawaban:

4

Saya memiliki garis putih atau "halo" di sekitar model saya juga, ketika saya mulai dengan penyaji saya sendiri. Masalahnya adalah bahwa nilai offset tekstur untuk overlay target render tidak diatur dengan benar. Beberapa tekstur perlu disetel ke +0,5 piksel untuk offset, bukan -0,5 piksel.

Hanya setelah mengutak-atik nilai dari beberapa tekstur offset yang garis hilang. Kemungkinan besar itu ada di salah satu shader pencahayaan.

Sunting: omong-omong saya juga belajar dari tutorial Catalin Zima yang merupakan cabang dari contoh Anda, jadi itu harus bekerja.

ChrisC
sumber
Yup, itu dia. Saya mengubahnya menjadi + halfPixel untuk semua sampling koordinat dalam shader cahaya dan lingkaran cahaya sudah hilang sekarang.
Telanor
0

Saya tidak yakin persis apa yang terjadi, tetapi beberapa hal untuk diperiksa:

  1. Pastikan penyaringan tekstur Anda dimatikan saat mengambil sampel G-buffer - tidak ada bilinear atau anisotropik atau apa pun.

  2. Saya melihat Anda menambahkan offset setengah piksel ke koordinat tekstur; periksa kembali apakah itu benar. Saya tidak cukup terbiasa dengan XNA untuk mengetahui apa yang harus diimbangi dengan benar, tetapi Anda harus dapat memeriksanya dengan menulis shader yang mengambil sampel salah satu buffer-G dan hanya menampilkan sampel. Kemudian, bolak-balik di antara ini dan menampilkan buffer-G langsung di layar. Jika Anda mendapatkan offset yang benar, Anda seharusnya tidak melihat perbedaan, bahkan satu piksel pun.

Nathan Reed
sumber
Aku pergi dan mengubah segala sesuatu yang berhubungan dengan GBuffer ke POINT (saya berasumsi bahwa menonaktifkan penyaringan?) Dan masih sama. Tentang poin kedua Anda, bukankah mengeluarkan GBuffer secara langsung sama persis: membuat shader yang hanya menampilkan data? Bisakah Anda menjelaskan lebih banyak tentang itu?
Telanor
Nah, bagaimana Anda membuat tangkapan layar G-buffer di atas? Saya kira Anda memanggil semacam fungsi API bawaan, untuk menyalin piksel satu-ke-satu dari G-buffer ke layar (back buffer)? (Saya tidak tahu XNA, jadi saya tidak tahu apa namanya) salinan satu-ke-satu ... dengan cara itu Anda bisa memastikan koordinat teksturnya benar dan Anda benar-benar mendapatkan sampel satu-ke-satu.
Nathan Reed