我一直在研究一个着色器程序,而最奇怪的事情之一正在发生。我有一个名为 PositionLightPS 的方法,它本质上执行位置光(全向和聚光灯)的计算,并返回一个包含光强度和漫反射颜色的结构。
它曾经在该程序的先前版本中工作,但由于某种原因它停止工作......
让我解释一下为什么。但首先,这里是 PositionPS 方法的代码。我毫不怀疑这种方法的计算是正确的,但稍后会详细介绍。
struct LightFragment {
float4 diffuse;
float intensity;
};
LightFragment PositionLightPS(PositionLightVOut pin, float3 lightToPixelVec)
{
LightFragment result;
pin.normal = normalize(pin.normal);
float4 diffuse = shaderTexture.Sample( textureSampler, pin.tex0 );
float3 finalDiffuse = float3(0.0f, 0.0f, 0.0f);
float d = length(lightToPixelVec);
if( d > plRange )
{
result.diffuse = float4(finalDiffuse, 0);
result.intensity = 0;
return result;
}
lightToPixelVec /= d;
result.intensity = dot(lightToPixelVec, pin.normal);
if( result.intensity > 0.0f )
{
finalDiffuse = result.intensity * diffuse.xyz;
finalDiffuse.xyz *= clColour.xyz;
finalDiffuse.xyz *= clColour.w;
finalDiffuse /= plAttenuation[0] + (plAttenuation[1] * d) + (plAttenuation[2] * (d*d));
}
result.diffuse = float4(finalDiffuse, diffuse.a) * diffuseColour;
return result;
}
这是全向光像素着色器。
float4 OmniLightDiffusePS(PositionLightVOut pin) : SV_TARGET0
{
float3 lightToPixelVec = plPosition.xyz - pin.worldPos.xyz;
return = PositionLightPS(pin, lightToPixelVec).diffuse;
}
出于某种原因,这不起作用,尽管它已经存在了很长时间。但这不是我问题的重点。绝对奇怪的是,这两种方法会产生不同的结果。
float4 OmniLightDiffusePS(PositionLightVOut pin) : SV_TARGET0
{
//return float4(1,1,1,1);
float3 lightToPixelVec = plPosition.xyz - pin.worldPos.xyz;
LightFragment fragment = PositionLightPS(pin, lightToPixelVec);
return float4(1,1,1,1);
}
这将返回一个黑色像素
float4 OmniLightDiffusePS(PositionLightVOut pin) : SV_TARGET0
{
return float4(1,1,1,1);
float3 lightToPixelVec = plPosition.xyz - pin.worldPos.xyz;
LightFragment fragment = PositionLightPS(pin, lightToPixelVec);
//return float4(1,1,1,1);
}
这将返回一个白色像素
所以这意味着调用 PositionLightPS 方法会对返回的值产生影响……但是为什么呢?为什么会呢?怎么了?是内存错误吗?
(注:直接在OmniLightDiffuse方法中复制PositionLightPS方法代码即可解决问题,灯光显示正常。这说明PositionLightPS中的计算是正确的。那么问题来了,使用LightFragment结构体对shader程序有影响吗不知何故?)