Эффект затухания Direct3D оставляет артефакты

У меня есть программа Direct3D, которая рисует следы, вместо того чтобы очищать каждый кадр, она рисует черный квадрат на экране с альфа-смешиванием. После рендеринга идет:

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

затем он отображает квадраты (пожалуйста, простите за псевдокод). это работает хорошо, за исключением того, что это не полностью очищает экран. он оставляет постоянные следы, я не могу понять, почему. Правильное смешивание должно после достаточного количества кадров полностью превратить его в черный, но это оставляет серые следы. кто-нибудь знает, почему или лучший метод затухания в Direct3D?


person HypnoToad    schedule 19.07.2013    source источник


Ответы (1)


Есть много способов подойти к этому в зависимости от того, как структурирована остальная часть вашего кода. Например, вы можете визуализировать все в текстуру и визуализировать ее с уменьшающейся альфой поверх черного фона, а не наоборот.

Если вы не возражаете против использования шейдеров, одним из быстрых и относительно эффективных способов будет применение пиксельного шейдера к тому, что вы «выцветаете».

Шейдерный эквивалент того, что вы делаете в данный момент (рендеринг черного цвета с низким альфа-каналом поверх), будет следующим:

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 гарантирует, что они станут черными, а не близкими, но недостаточно близкими к черному.

person nathanchere    schedule 19.07.2013
comment
спасибо, я думал, что есть способ сделать это без теней, но я думаю, что нет. Я до сих пор не понимаю, почему альфа-смешивание не работает должным образом. Думаю, мне придется использовать шейдер. благодаря. - person HypnoToad; 22.07.2013