Je travaille sur un jeu dans XNA 4 et je suis récemment passé à une implémentation d'ombrage différé en suivant ce guide . Un étrange contour blanc apparaît maintenant sur mes modèles et je ne suis pas sûr de ce qui cause cela. Je pensais que c'était peut-être un manque de précision sur la cible de rendu normale ou la cible de rendu en profondeur, mais les augmenter à 64 bits (Rgba64) au lieu de 32 (Couleur) n'a pas aidé. J'ai également pensé que cela pourrait être un problème avec le calcul spéculaire, j'ai donc essayé de mettre le spéculaire à 0, mais cela n'a pas aidé non plus. Le débogage du pixel dans PIX montre que la valeur diffuse est calculée comme presque blanche pour ce pixel. Des idées? J'ai inclus une photo du problème ci-dessous, il est plus facile de le voir en taille réelle.
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);
}
Edit : Désolé pour le JPG, l'uploader de stackexchange l'a fait tout seul. Roy T: J'ai effectivement référencé votre conversion XNA4 du tutoriel pour les parties qui ont changé de XNA3. Comme je n'ai pas apporté de modifications majeures au code, j'ai pensé que ce bug existait peut-être dans l'original mais était tout simplement impossible à voir avec autant de lumières qui se déplaçaient, alors j'ai supprimé toutes les lampes sauf une et le bug est réapparu (regardez près du coude du lézard)
Voici le contenu de GBuffer pour ma scène:
Tampon de couleurs: Tampon de profondeur : Tampon normal: Rendu final:
Edit2 :
Je commence à soupçonner que le problème est CombineFinal.fx lorsqu'il échantillonne la carte de couleurs. Voici le calcul d'un pixel correctement coloré juste à côté d'un pixel blanc:
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
Et voici la sortie d'un pixel blanc mal coloré juste à côté:
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
La couleur diffuse est la seule différence, et cette couleur est prise directement à partir de la carte des couleurs. Peut-être y a-t-il une légère erreur dans le calcul de la coordonnée de texture à échantillonner?
Pass d'éclairage:
Réponses:
J'avais aussi ce contour blanc ou "halo" autour de mes modèles, quand j'ai commencé sur mon propre rendu différé. Le problème était que la valeur de décalage de texture pour superposer les cibles de rendu n'était pas configurée correctement. Certaines textures devaient être définies sur +0,5 pixels pour le décalage au lieu de -0,5 pixels.
Ce n'est qu'après avoir modifié les valeurs de certains décalages de texture que les contours ont disparu. C'est probablement dans l'un des shaders d'éclairage.
Edit: d'ailleurs, j'ai également appris du tutoriel de Catalin Zima qui est une branche de votre exemple, donc cela devrait fonctionner.
la source
Je ne sais pas exactement ce qui se passe, mais deux ou trois choses à vérifier:
Assurez-vous que le filtrage de texture est désactivé lors de l'échantillonnage des tampons G - pas bilinéaire ou anisotrope ou quoi que ce soit.
Je vois que vous ajoutez un décalage d'un demi-pixel aux coordonnées de la texture; revérifiez que c'est vrai. Je ne connais pas assez bien XNA pour savoir quel devrait être le bon décalage, mais vous devriez pouvoir le vérifier en écrivant un shader qui échantillonne l'un des G-buffers et sort juste l'échantillon. Basculez ensuite d'avant en arrière entre cela et affichez le G-buffer directement à l'écran. Si vous avez le bon décalage, vous ne devriez voir aucune différence, pas même un seul pixel.
la source