XNA 4'te bir oyun üzerinde çalışıyorum ve son zamanlarda bu kılavuzu izleyerek ertelenmiş bir gölgeleme uygulamasına geçtim . Modellerimde garip bir beyaz anahat görünüyor ve buna neyin neden olduğundan emin değilim. Belki normal render hedefi veya derinlik render hedefi üzerinde bir hassasiyet eksikliği olduğunu düşündüm ama 32 (Renk) yerine 64 bit'e (Rgba64) yükseltmek yardımcı olmadı. Ben de speküler hesaplama ile ilgili bir sorun olabileceğini düşündüm bu yüzden 0 speküler ayarlamaya çalıştım ama bu da yardımcı olmadı. PIX'te pikselde hata ayıklama, dağınık değerin o piksel için neredeyse beyaz olarak hesaplandığını gösterir. Herhangi bir fikir? Aşağıdaki sorunun bir resmini ekledim, tam boyutta görmek daha kolay.
Piksel gölgelendirici:
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);
}
Düzenleme : JPG için üzgünüm, stackexchange'in yükleyicisi bunu kendi başına yaptı. Roy T: Aslında XNA3'ten değiştirilen parçalar için öğreticinin XNA4 dönüşümüne başvurdum. Kodda herhangi bir büyük değişiklik yapmadığım için belki de bu hatanın orijinalinde var olduğunu düşündüm, ancak etrafta hareket eden birçok ışıkla görmek imkansızdı, bu yüzden bir ışık hariç hepsini kaldırdım ve hata tekrar ortaya çıktı (bak kertenkelenin dirseğine yakın)
İşte sahnem için GBuffer içerikleri:
Renk Tamponu: Derinlik Tamponu: Normal Tampon: Son İşleme:
Edit2 :
Renk eşlemini örneklediğinde sorunun CombineFinal.fx olduğundan şüphelenmeye başlıyorum. Bu, beyaz bir pikselin hemen yanında uygun şekilde renkli bir pikselin hesaplanmasıdır:
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
Ve bu, hemen yanındaki yanlış renklendirilmiş beyaz bir pikselin çıktısıdır:
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 tek farktır ve bu renk doğrudan renk haritasından alınır. Belki de numuneden doku koordinatının hesaplanmasında küçük bir hata var mı?
Aydınlatma Geçişi: