Состояние устройства AlphaBlend в XNA 4.0 - PullRequest
0 голосов
/ 10 июня 2011

У меня проблема с настройкой правильной работы BlendState на графическом устройстве и корректным отображением альфа-наложения.

Render Output

В некоторых случаях вы можете видеть листья через другие листья, в других - нет. И багажник тоже всегда скрыт.

Я пробовал так много разных комбинаций настройки BlendState. На данный момент это выглядит так:

        GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        //GraphicsDevice.BlendState = BlendState.AlphaBlend;
        GraphicsDevice.BlendState = new BlendState()
        {
            AlphaBlendFunction = BlendFunction.Add,
            AlphaDestinationBlend = Blend.InverseSourceAlpha,
            AlphaSourceBlend = Blend.One,
            BlendFactor = new Color(1.0F, 1.0F, 1.0F, 1.0F),
            ColorBlendFunction = BlendFunction.Add,
            ColorDestinationBlend = Blend.InverseSourceAlpha,
            ColorSourceBlend = Blend.One,
            ColorWriteChannels = ColorWriteChannels.All,
            ColorWriteChannels1 = ColorWriteChannels.All,
            ColorWriteChannels2 = ColorWriteChannels.All,
            ColorWriteChannels3 = ColorWriteChannels.All,
            MultiSampleMask = -1
        };

Код шейдера выглядит следующим образом:

float alpha = 1,0F; if (HasAlphaTexture) alpha = tex2D (AlphaSampler, IN.UV) .xyz;

// ... // определить значения цвета и т. д. ///...

return float4 (result.xyz, alpha);

Карты, которые я использую для этого, выглядят следующим образом: Opacity Map Diffuse/Color Map

1 Ответ

4 голосов
/ 10 июня 2011

Прежде всего вы хотите либо отсортировать свою геометрию, либо использовать альфа-тестирование, потому что вы не можете комбинировать рендеринг на основе Z-буфера (он же: глубинный буфер) с прозрачностью.Нет никакого способа «смешать» значение Z-буфера - поэтому он всегда использует самое верхнее значение, блокируя все позади, даже когда цвет, который вы отображаете, прозрачен.

Взгляните эта статья для объяснения ( и это слово для качества ).Это решит вашу проблему с геометрией, которая иногда не будет отображаться за некоторой прозрачной геометрией.

Проблема с вашим состоянием смешивания состоит в том, что вы используете предварительно умноженное смешивание с данными, которые не были предварительно умножены.

См. Эту статью для объяснения предварительно умноженной альфа .Это было по умолчанию в XNA 4.0 .

При предварительном умножении вы масштабируете свои значения цвета (RGB) на свое альфа-значение (то есть: вы умножаете их)прежде чем смешивать их (т. е. pre ).

Таким образом, есть два возможных решения: вы можете использовать BlendState.NonPremultiplied.Но предварительное умножение имеет свои преимущества (как объяснено в этой статье), поэтому лучшим решением будет выполнить умножение в вашем шейдере следующим образом:

return float4(result.xyz * alpha, alpha);

Конечно, предпочтительнее просто использовать одну текстуру сальфа-канал, если это вообще возможно.Если вы не можете объединить альфа-канал с помощью своих инструментов рисования, вы можете использовать XNA Content Pipeline, чтобы объединить две текстуры и выполнить предварительное умножение во время сборки.По умолчанию импортер текстуры Content Pipeline выполняет предварительное умножение по умолчанию.

...