Metode 1
Anda tidak harus membuat versi putih solid dari setiap sprite di game Anda secara manual - Anda bisa mengotomatiskan proses pada waktu pengambilan. Dengan kata lain, Anda dapat menggunakan Texture2D.GetData()
untuk mengakses piksel tekstur Anda (dan mengambilnya sebagai sederhana Color[]
), iterate di atasnya menggantikan setiap piksel non-transparan dengan putih solid, dan kemudian simpan ke tekstur baru menggunakan dan Texture2D.SetData()
.
Metode 2
Saya mencoba bermain-main dengan BlendState
tetapi tidak bisa menemukan cara untuk membuat semuanya putih, setidaknya tidak dalam batasan profil Jangkauan. Tetapi jika seseorang tahu caranya, beri tahu saya. Apa yang saya temukan, bagaimanapun, adalah cara untuk melakukannya dengan menggunakan buffer stensil dan AlphaTestEffect
kelas bawaan. Idenya adalah sebagai berikut:
- Buat backbuffer yang memiliki buffer stensil.
- Bersihkan buffer stensil ke nol.
- Gambarkan sprite yang ingin Anda warnai menjadi putih dan setiap kali mereka lulus uji alpha, atur buffer stensil ke lokasi itu menjadi 1.
- Gambarlah quad putih yang menutupi seluruh layar, tetapi hanya di mana nilai buffer stensil adalah 1.
Berikut kode yang saya gunakan:
(Langkah 1) Pertama-tama pastikan backbuffer sedang dibuat dengan ruang untuk buffer stensil:
graphics = new GraphicsDeviceManager(this) { PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 };
(Langkah 2) Buat tekstur putih 1x1 yang akan diskalakan untuk mengisi seluruh layar:
private Texture2D pixel;
pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new[] { Color.White });
(Langkah 3) Dan sekarang bagian yang sulit - render. Yah, tidak terlalu sulit, tetapi membutuhkan dua DepthStencilState
objek dan satu AlphaTestEffect
objek. Anda harus membuat ini hanya sekali.
// Clear stencil buffer
GraphicsDevice.Clear(ClearOptions.Stencil, Color.Black, 0f, 0);
// Prepare the alpha test effect object (create it only once on initilization)
AlphaTestEffect alphaTestEffect = new AlphaTestEffect(GraphicsDevice)
{
DiffuseColor = Color.White.ToVector3(),
AlphaFunction = CompareFunction.Greater,
ReferenceAlpha = 0, World = Matrix.Identity,
View = Matrix.Identity,
Projection = Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1)
};
// Prepare the first DepthStencilState (create only once, or put it in a static class)
DepthStencilState beforeDepthStencilState = new DepthStencilState
{
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1
};
// Draw your sprites using the structures above
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, beforeDepthStencilState, null, alphaTestEffect);
spriteBatch.Draw(sprite, new Vector2(300, 150), Color.White);
spriteBatch.End();
// Prepare the second DepthStencilState (create only once, or put it in a static class)
DepthStencilState afterDepthStencilState = new DepthStencilState
{
StencilEnable = true,
StencilFunction = CompareFunction.Equal,
ReferenceStencil = 1
};
// Draw a full screen white quad with the structure above
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, afterDepthStencilState, null);
spriteBatch.Draw(pixel, GraphicsDevice.Viewport.Bounds, Color.White);
spriteBatch.End();
Dan hasilnya: