2012-02-09 39 views
18

Khi tôi vẽ một hình ảnh kéo dài Texture2D, các pixel nhận được hiệu ứng giống như Blur.'Vùng lân cận gần nhất' zoom

Tôi muốn sử dụng đồ họa 'pixelated' trong trò chơi của mình và muốn biết cách tắt tính năng này theo hướng phóng to gần nhất đơn giản nhất.

tôi đã tạo ra hình ảnh này để minh hoạ: (x4 zoom)
enter image description here

Bằng cách nào tôi có thể thực hiện điều này?

+8

+1 cho sprite Star Control. – Rotem

Trả lời

15

Trong XNA 4, thay đổi SpriteBatch.Begin của bạn() để thiết lập trạng thái sampler để SamplerState.PointClamp

+5

Tôi đã sử dụng phương pháp theo cách này sau khi tra cứu các giá trị mặc định trên MSDN: 'spriteBatch.Begin (SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise);' và nó hoạt động tốt . Cảm ơn! – Acidic

5

Nếu bạn đang sử dụng một Shader để vẽ các hình ảnh, bạn có thể sửa đổi tình trạng sampler:

sampler2D mySampler = sampler_state 
{ 
    Texture=<SomeTexture>; 
    Filter=POINT; 
}; 

điểm lấy mẫu nên ngăn GPU từ nội suy khi lấy mẫu ảnh, mà có lẽ là yếu tố khiến antialias của bạn/hành vi mờ.

Nếu bạn chỉ sử dụng SpriteBatch để vẽ các hình ảnh, bạn có thể thiết lập các bộ lọc sử dụng:

Device.SamplerStates[0] = SamplerState.PointClamp; 

Ngoài ra, có vẻ như bạn có thể phải thiết lập các SpriteBatch sử dụng chế độ ngay. See this article on MSDN for more information hoặc this thread on the App Hub forums.

Dưới đây là một sớm thread SO rằng có thể sẽ rất hữu ích:

See this thread for more information.

Textures được lấy mẫu sử dụng tọa độ bình thường (0..1, 0..1) chứ không phải là tọa độ Texel. GPU sẽ tìm bốn ô gần nhất cho một tọa độ kết cấu đã cho, và nội suy giữa chúng dựa trên vị trí của điểm mẫu trong hình vuông đó.

Vì vậy, nếu tôi có kết cấu là 10 x 10 pixel và tôi cố đọc từ, (0,15, 0,15), GPU sẽ nội suy giữa các ô tại (1,1), (2, 1), (1,2) và (2,2). Trong trường hợp này, 0,05 sẽ làm cho điểm ảnh kết quả trên màn hình đơn giản là trung bình của bốn điểm ảnh xung quanh. Tuy nhiên, nếu kết cấu được lấy mẫu tại (0,19, 0,19), màu kết quả sẽ bị thiên vị nặng nề đối với texel tại (2,2).

Lấy mẫu điểm sẽ làm cho GPU luôn đọc màu chính xác từ kết cấu bên dưới thay vì trọng số trọng lượng xung quanh khu vực mẫu.

Dưới đây là một .Draw() phương pháp làm việc minh họa tất cả điều này:

protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.Black); 

     var largeRect = new Rectangle(50, 50, sprite.Width * 3, sprite.Height * 3); 

     /// start the batch, but in immediate mode to avoid antialiasing 
     spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); 

     /// set the filter to Point 
     GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; 

     /// draw the sprite 
     spriteBatch.Draw(sprite, largeRect, Color.White); 

     /// done! 
     spriteBatch.End(); 

     // TODO: Add your drawing code here 

     base.Draw(gameTime); 
    } 
+0

Tôi chỉ đơn giản sử dụng phương thức 'spriteBatch.Draw (...)'. Cả hai vẽ nó vào một hình chữ nhật lớn hơn và sử dụng kết quả thuộc tính 'scale' trong hiệu ứng này. – Acidic

+0

@Acidic được cập nhật. SpriteBatch cung cấp một thuộc tính để thiết lập phương thức lọc. –

+0

Cố gắng thay đổi giá trị của 'SamplerStates [0].Lọc' kết quả là một lỗi, nói rằng nó là một thuộc tính chỉ đọc. – Acidic

0

Bạn cần phải đảm bảo các tọa độ x, y của bạn là các giá trị số nguyên. Các tọa độ hoặc kích thước phân số dẫn đến việc chống răng cưa được áp dụng để mô phỏng bù trừ pixel "phân số".

Do đó làm mờ.

+0

vẽ bằng đối tượng 'Hình chữ nhật' vẫn tạo ra hiệu ứng không mong muốn. Câu hỏi vẫn được trả lời. :) – Acidic

Các vấn đề liên quan