Я працюю над грою в XNA 4, і нещодавно я перейшов на реалізацію відкладеного затінення, слідуючи цьому посібнику . Зараз на моїх моделях з’являються дивні білі контури, і я не впевнений, що це спричиняє. Я подумав, що це може бути недостатньою точністю до нормальної цілі візуалізації або цілі глибини відображення, але збільшення їх до 64 біт (Rgba64) замість 32 (Color) не допомогло. Я також подумав, що це може бути якась проблема з дзеркальним розрахунком, тому я спробував встановити окуляр на 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 зробив це самостійно. Рой Т: Я насправді посилався на ваше перетворення XNA4 підручника для частин, які змінилися з XNA3. Оскільки я не вніс жодних великих змін у код, я подумав, що, можливо, ця помилка існувала в оригіналі, але просто неможливо побачити стільки вогнів, що рухаються навколо, тому я видалив усе, крім одного світла, і помилка з’явилася знову (дивіться біля ліктя ящірки)
Ось вміст GBuffer для моєї сцени:
Колірний буфер: Буфер глибини: Звичайний буфер: Остаточний рендер:
Edit2 :
Я починаю підозрювати, що проблема 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 - єдина відмінність, і цей колір взято безпосередньо з кольорової карти. Можливо, є невелика помилка в обчисленні координати текстури для вибірки?
Просвітлення: