Я хотел бы сделать простую вещь: отрендерить 2d текстуру в цель 2d рендеринга с альфа-наложением каналов.
Итак, я создаю свою цель рендеринга:
renderTarget = new RenderTarget2D(m_graphicsDevice, 200, 200);
затем я создаю свою текстуру:
texture = new Texture2D(_device, 1, 1, false, SurfaceFormat.Color);
Color clr = Color.Red;
// set half transparency on my texture
clr.A = 128;
Color[] bitmap = new Color[1] {clr};
texture.SetData(bitmap);
затем я очищаю свою цель рендеринга белым и дважды рисую текстуру в цели рендеринга с хорошим масштабом и с помощью операции умножения на цвете и альфа-канале.
graphicsDevice.SetRenderTarget(renderTarget);
graphicsDevice.Clear(Color.White);
BlendState myState = new BlendState();
// multiplicative blending on color
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.SourceColor;
// multiplicative blending on alpha
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;
spriteBatch.Begin(SpriteSortMode.Immediate, myState);
// draw my texture twice, with an overlaping part
spriteBatch.Draw(texture, new Vector2(0, 0), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Vector2(50, 50), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.End();
graphicsDevice.SetRenderTarget(null);
и я рисую эту цель рендеринга на экране с зеленым фоном и состоянием рендеринга без предварительного умножения, чтобы значение альфа в текстуре применялось как прозрачность.
graphicsDevice.Clear(Color.Green);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
spriteBatch.Draw(renderTarget, Vector2.zero, Color.White);
spriteBatch.End();
результат такой, как ожидалось:
в цели рендеринга только для пикселей, принадлежащих одной текстуре:
- red chanel = texture red chanel (1) * render target red chanel (1) = 1
- зеленый и синий chanel = текстура chanel (0) * render target chanel = 0
- альфа канал = текстура альфа (0,5) * цель рендеринга альфа (1) = 0,5
- и эта текстура, нарисованная над зеленым фоном, дает коричневый цвет благодаря альфа-прозрачности, установленной на 0,5 (1/2 красного + 1/2 зеленого)
в цели рендеринга для перекрывающихся пикселей (таким образом, вышеуказанное вычисление применяется дважды)
- red chanel = texture red chanel (1) * texture red chanel (1) * render target red chanel (1) = 1
- зеленый и синий канал = канал текстуры (0) * канал текстуры (0) * целевой канал рендеринга = 0
- альфа-канал = альфа текстуры (0,5) * альфа текстуры (0,5) * альфа целевой рендеринга (1) = 0,25
- и эта текстура, нарисованная над зеленым фоном, дает почти зеленый цвет благодаря альфа-значению 0,25 (1/4 красного + 3/4 зеленого)
теперь, если я изменю состояние рендеринга, чтобы просто позволить применить альфа-канал текстуры и не допустить умножения цветов:
BlendState myState = new BlendState();
// texture color is ignored, dest color remain unchanged
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.One;
// alpha chanel are still multiplied
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;
что я должен получить:
в цели рендеринга только для пикселей, принадлежащих одной текстуре:
- red chanel = 0 * texture red chanel (1) + 1 * render target red chanel (1) = 1
- зеленый и синий chanel = 0 * текстура chanel (0) + 1 * render target chanel (1) = 1
- альфа канал = текстура альфа (0,5) * цель рендеринга альфа (1) = 0,5
- и эта текстура, нарисованная над зеленым фоном, должна дать светло-зеленый цвет (1/2 белого + 1/2 зеленого).
в цели рендеринга для перекрывающихся пикселей (таким образом, вышеуказанное вычисление применяется дважды)
- red chanel = 1
- зеленый и синий Шанель = 1
- альфа-канал = альфа текстуры (0,5) * альфа текстуры (0,5) * альфа целевой рендеринга (1) = 0,25
- и эта текстура, нарисованная над зеленым фоном, должна давать более интенсивный зеленый цвет (0,25 * белый + 0,75 * зеленый).
и я получаю простую белую текстуру ...
почему вычисление альфа-смешения в моей цели рендеринга перестает работать, если я не смешиваю цвета? Моя цель - проводить вычисления только на альфа-канале, без получения цвета текстуры. Как я могу это сделать ?
Благодарность