Strano contorno bianco attorno al modello


19

Sto lavorando a un gioco in XNA 4 e di recente sono passato a un'implementazione differita dell'ombreggiatura seguendo questa guida . Una strana sagoma bianca sta comparendo sui miei modelli ora e non sono sicuro di cosa stia causando. Ho pensato che forse fosse una mancanza di precisione sul target di rendering normale o sul target di rendering di profondità, ma aumentarli a 64 bit (Rgba64) anziché 32 (Color) non ha aiutato. Ho anche pensato che potesse essere un problema con il calcolo speculare, quindi ho provato a impostare lo speculare su 0, ma non ha aiutato neanche. Il debug del pixel in PIX mostra che il valore diffuso viene calcolato come quasi bianco per quel pixel. Qualche idea? Ho incluso una foto del problema qui sotto, è più facile vederlo a grandezza naturale.

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

Modifica : mi dispiace per il JPG, l'autore del caricamento di stackexchange lo ha fatto da solo. Roy T: In realtà ho fatto riferimento alla tua conversione XNA4 del tutorial per le parti che sono cambiate da XNA3. Dal momento che non ho apportato grandi modifiche al codice, ho pensato che forse questo bug esistesse nell'originale, ma era impossibile vederlo con così tante luci che si muovevano, quindi ho rimosso tutte le luci tranne una e il bug è apparso di nuovo (guarda vicino al gomito della lucertola)

Ecco i contenuti di GBuffer per la mia scena:

Buffer di colore: Buffer di profondità : Buffer normale: Rendering finale:

Modifica2 :

Sto iniziando a sospettare che il problema sia CombineFinal.fx quando campiona la mappa dei colori. Questo è il calcolo per un pixel adeguatamente colorato proprio accanto a un pixel bianco:

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

E questo è l'output di un pixel bianco di colore improprio direttamente accanto ad esso:

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 è l'unica differenza e questo colore viene preso direttamente dalla mappa dei colori. Forse c'è un leggero errore nel calcolo delle coordinate della trama da campionare?

Pass illuminazione:


4
Si prega di non comprimere jpeg uno screenshot che mostra un sottile problema grafico. Le persone vorranno vedere il problema in perfetta riproduzione.
aaaaaaaaaaaa l'

Bene, la compressione jpeg in realtà lascia passare il glitch abbastanza bene penso, solo un pixel e solo quando certe cose vengono riunite (grande differenza nella profondità Z e l'illuminazione è (abbastanza) alta su tutti i pixel). Buona fortuna, il rendering posticipato è piuttosto tecnico.
Valmond,

2
Non sono sicuro che sia d'aiuto, ma stai usando una versione molto vecchia del codice / tutorial, il codice / tutorial effettivo di Catalin Zima è ora disponibile su: catalinzima.com/tutorials/deferred-rendering-in-xna e un XNA4.0 sanzionato la versione si trova qui: roy-t.nl/index.php/2010/12/28/…
Roy T.

Inoltre, come sempre con il debug del rendering differito, potresti pubblicare schermate da tutti i buffer? Probabilmente è nel buffer di illuminazione, ma potrebbe essere qualcos'altro.
Roy T.

Il mio istinto è che sarà un problema con il modo in cui parte dell'algoritmo gestisce un angolo esattamente di 90 gradi, ma dovrò giocare con l'ode dopo il lavoro per approfondire.
Jordaan Mylonas,

Risposte:


4

Avevo questo contorno bianco o "alone" anche attorno ai miei modelli, quando ho iniziato con il mio renderer differito. Il problema era che il valore di offset della trama per la sovrapposizione delle destinazioni di rendering non era impostato correttamente. Alcune trame dovevano essere impostate su +0,5 pixel per l'offset anziché su -0,5 pixel.

Solo dopo aver modificato i valori di alcuni offset della trama, i contorni erano spariti. Molto probabilmente è in uno degli shader di illuminazione.

Modifica: tra l'altro ho anche imparato dal tutorial di Catalin Zima che è un ramo del tuo esempio, quindi dovrebbe funzionare.


Sì, era quello. L'ho cambiato in + halfPixel per tutto il campionamento delle coordinate nello shader di luce e l'alone non c'è più.
Telanor,

0

Non sono sicuro esattamente cosa stia succedendo, ma un paio di cose da ricontrollare:

  1. Assicurati di aver disattivato il filtro delle trame durante il campionamento dei buffer G - niente bilineare o anisotropico o altro.

  2. Vedo che stai aggiungendo un offset di mezzo pixel alle coordinate della trama; ricontrolla che sia giusto. Non ho abbastanza familiarità con XNA per sapere quale dovrebbe essere l'offset giusto, ma dovresti essere in grado di verificarlo scrivendo uno shader che campiona uno dei buffer G e genera semplicemente il campione. Quindi scorrere avanti e indietro tra questo e visualizzare il buffer G direttamente sullo schermo. Se hai l'offset corretto, non dovresti vedere differenze, nemmeno un singolo pixel.


Sono andato e ho cambiato tutto ciò che riguarda GBuffer in POINT (suppongo che disabiliti il ​​filtro?) Ed è sempre lo stesso. Riguardo al tuo secondo punto, l'output del GBuffer non sarebbe esattamente lo stesso: creare uno shader che emette semplicemente i dati? Puoi approfondire un po 'di più?
Telanor,

Bene, come hai generato gli screenshot del buffer G sopra? Presumo che tu chiami una sorta di funzione API integrata, per copiare i pixel uno a uno dal buffer G allo schermo (back buffer)? (Non conosco XNA, quindi non so come si chiamerebbe.) Sto dicendo, confronta l'output della funzione di copia one-to-one integrata con l'output di un pixel shader scritto per fare una copia uno a uno ... in questo modo puoi essere sicuro che le coordinate della trama siano esattamente corrette e stai davvero ottenendo un campionamento uno a uno.
Nathan Reed,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.