Phương pháp 1
Bạn không phải tạo một phiên bản màu trắng của mỗi sprite trong trò chơi của mình một cách thủ công - bạn cũng có thể tự động hóa quá trình khi tải. Nói cách khác, bạn có thể sử dụng Texture2D.GetData()
để truy cập các pixel của kết cấu của mình (và truy xuất chúng dưới dạng đơn giản Color[]
), lặp lại chúng thay thế bất kỳ pixel không trong suốt nào bằng màu trắng, sau đó lưu nó vào một kết cấu mới bằng cách sử dụng và Texture2D.SetData()
.
Cách 2
Tôi đã thử chơi xung quanh BlendState
nhưng không thể tìm ra cách hiển thị toàn bộ màu trắng, ít nhất là không nằm trong giới hạn của hồ sơ Reach. Nhưng nếu ai đó biết một cách cho tôi biết. Tuy nhiên, những gì tôi đã tìm thấy là một cách để làm điều đó bằng cách sử dụng bộ đệm stpson và AlphaTestEffect
lớp tích hợp. Ý tưởng như sau:
- Tạo một backbuffer có bộ đệm stpson.
- Xóa bộ đệm stprint về không.
- Vẽ các họa tiết bạn muốn tô màu trắng và bất cứ khi nào chúng vượt qua bài kiểm tra alpha, hãy đặt bộ đệm stpson tại vị trí đó thành 1.
- Vẽ một hình tứ giác màu trắng bao phủ toàn bộ màn hình, nhưng chỉ khi giá trị của bộ đệm stprint là 1.
Đây là mã tôi đã sử dụng:
(Bước 1) Trước tiên, hãy đảm bảo rằng backbuffer đang được tạo có chỗ cho bộ đệm stpson:
graphics = new GraphicsDeviceManager(this) { PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 };
(Bước 2) Tạo kết cấu trắng 1x1 sẽ được thu nhỏ để lấp đầy toàn bộ màn hình:
private Texture2D pixel;
pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new[] { Color.White });
(Bước 3) Và bây giờ là phần khó - kết xuất nó. Chà, không khó lắm, nhưng đòi hỏi hai DepthStencilState
đối tượng và một AlphaTestEffect
đối tượng. Bạn chỉ nên tạo những thứ này một lần.
// 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();
Và kết quả: