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: