direct3d淡入淡出效果会留下伪影

本文关键字:伪影 淡入 淡出 direct3d | 更新日期: 2023-09-27 18:23:56

我有一个Direct3D程序,它通过阿尔法混合在屏幕上绘制一个黑色正方形,而不是清除每一帧来绘制轨迹。渲染后,它会:

renderstate.alphablendenable = true;
renderstate.blendoperation = add; 
renderstate.sourceblend = zero; 
renderstate.destinationblend = invblendfactor; 
renderstate.blendfactor = rgb(8,8,8);

然后它呈现正方形(请原谅伪代码)。除了没有完全清除屏幕之外,这个操作效果很好。它留下了永久的痕迹,我不明白为什么。适当的混合应该在足够多的帧后将其完全变黑,但这会留下灰色的痕迹。有人知道为什么或者Direct3D中有更好的淡入淡出方法吗?

direct3d淡入淡出效果会留下伪影

根据代码其余部分的结构,有很多方法可以实现这一点。例如,可以将所有内容渲染为纹理,并在黑色背景的顶部使用递减的alpha进行渲染,而不是相反。

如果你不介意使用着色器,一种快速且相对有效的方法是将像素着色器应用于你正在"淡入"的任何对象。

一个相当于你现在所做的着色器(在顶部渲染低阿尔法黑色)是这样的:

float4 FadeEffectShader(PixelInputType input) : SV_Target
{
   float4 color;    
    color = shaderTexture.Sample(SampleType, input.tex);
    color = color * 0.01;
    return color;
}

你最终会看到颜色沿着一条指数曲线逐渐消失,就本例而言,这条曲线永远不会等于零,你会留下一个优美的渐变,直到出现伪影的地方几乎变成黑色。你真正想要的更像是:

float4 FadeEffectShader(PixelInputType input) : SV_Target
{
    float4 color;   
    color = shaderTexture.Sample(SampleType, input.tex);
    color = color * 0.01;
    if(color.r<0.01) color.r = 0;
    if(color.g<0.01) color.g = 0;
    if(color.b<0.01) color.b = 0;
    return color;
}

值小于0.01的箝位将确保它们变为黑色,而不是闭合,但还不够接近黑色。