我正在使用XNA 4开发游戏,最近我按照本指南切换到了延迟着色实现。现在,我的模型上出现了一个奇怪的白色轮廓,我不确定是什么原因引起的。我认为可能是普通渲染目标或深度渲染目标缺乏精确度,但将它们提高到64位(Rgba64)而不是32位(彩色)没有帮助。我还认为镜面反射计算可能存在一些问题,因此我尝试将镜面反射设置为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的上传器是自己完成的。Roy T:对于从XNA3更改的部分,我确实参考了本教程的XNA4转换。由于我没有对代码进行任何大的更改,因此我以为可能是该错误存在于原始代码中,但是由于周围有太多的灯光移动而无法看到,所以我只移除了一个灯光,然后再次出现了该错误(看一下在蜥蜴的肘部附近)
这是我的场景的GBuffer内容:
颜色缓冲区: 深度缓冲区: 普通缓冲区: 最终渲染:
编辑2:
我开始怀疑问题是在对颜色图进行采样时的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是唯一的区别,该颜色直接从颜色图中获取。也许在计算要采样的纹理坐标时会出现一点错误?
照明通行证: