Состояние устройства AlphaBlend в XNA 4.0

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

Визуализировать вывод

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

Я пробовал так много разных комбинаций настройки 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
        };

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

поплавок альфа = 1.0F; if (HasAlphaTexture) alpha = tex2D(AlphaSampler, IN.UV).xyz;

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

вернуть float4 (результат.xyz, альфа);

Карты, которые я использую для этого, выглядят следующим образом: Карта прозрачностиРассеянная/Цветная карта


person helloserve    schedule 10.06.2011    source источник


Ответы (1)


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

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

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

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

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

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

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

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

person Andrew Russell    schedule 10.06.2011
comment
Спасибо, Эндрю. Очень признателен. - person helloserve; 11.06.2011