पहला कदम ग्राफिक्स कार्ड को बताने के लिए है कि हमें स्टैंसिल बफर की आवश्यकता है। ऐसा करने के लिए जब आप GraphicsDeviceManager बनाते हैं तो हम PrethredDepthStencilFormat को DepthFormat.Depth24Stencil8 पर सेट करते हैं ताकि वास्तव में लिखने के लिए एक स्टैंसिल हो।
graphics = new GraphicsDeviceManager(this) {
PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8
};
AlphaTestEffect का उपयोग निर्देशांक प्रणाली को सेट करने और अल्फा परीक्षण के साथ पिक्सेल को फ़िल्टर करने के लिए किया जाता है। हम किसी भी फ़िल्टर को सेट करने और समन्वय प्रणाली को व्यू पोर्ट पर सेट नहीं करने जा रहे हैं।
var m = Matrix.CreateOrthographicOffCenter(0,
graphics.GraphicsDevice.PresentationParameters.BackBufferWidth,
graphics.GraphicsDevice.PresentationParameters.BackBufferHeight,
0, 0, 1
);
var a = new AlphaTestEffect(graphics.GraphicsDevice) {
Projection = m
};
अगला हमें दो डेप्थस्टैंसिलस्टेट्स स्थापित करने की आवश्यकता है। ये बताता है कि जब स्प्राइट बैच स्टैंसिल से मिलता है और जब स्प्राइट बैक बैकरफ़र को प्रदान करता है, तो यह बताता है। हम मुख्य रूप से दो चर स्टैंसिलफंक्शन और स्टैंसिलपास में रुचि रखते हैं।
- स्ट्रीन्सफंक्शन तय करता है कि स्प्राइटबैच व्यक्तिगत पिक्सेल कब खींचेगा और कब उन्हें अनदेखा किया जाएगा।
- StencilPass तय करता है जब खींचे गए पिक्सेल स्टेंसिल को प्रभावित करते हैं।
पहले डेप्थलस्टेनस्टेट के लिए हमने स्टैंसिलफंक्शन को कंपेरिजन के लिए सेट किया। यह स्टैंसिलटेस्ट सफल होने का कारण बनता है और जब स्टैंसिलटेस्ट स्प्राइटबैच उस पिक्सेल को प्रस्तुत करता है। StencilPass को StencilOperation पर सेट किया गया है। बदलें का अर्थ है कि जब स्टैंसिलटेस्ट सफल होता है तो पिक्सेल रेफ़रबैंसर के मान के साथ स्टैंसिलबफ़र को लिख देगा।
var s1 = new DepthStencilState {
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
सारांश में स्टैंसिलटेस्ट हमेशा गुजरता है, छवि को सामान्य रूप से स्क्रीन करने के लिए तैयार किया जाता है, और स्क्रीन पर आरेखित पिक्सेल के लिए स्टैंसिलबफर में 1 का मान संग्रहीत किया जाता है।
दूसरा डेप्थ स्टैंसिलस्टेट थोड़ा अधिक जटिल है। इस बार हम केवल स्क्रीन पर आकर्षित करना चाहते हैं जब StencilBuffer में मान है। इसे प्राप्त करने के लिए हमने स्टैंसिलफंक्शन को कंपेरिजन.सेक्शुअल और रेफ़रस्टैंसिल से 1. पर सेट किया। इसका मतलब है कि जब स्टैंसिल बफर में मान 1 है तो स्टैंसिलटेस्ट सफल होगा। स्टैंसिलपास को स्टैंसिलपरेशन पर सेट करना। अपडेट न करने के लिए स्टैंसिलबफर रखें। यह हमें एक ही मास्क का उपयोग करके कई बार आकर्षित करने की अनुमति देता है।
var s2 = new DepthStencilState {
StencilEnable = true,
StencilFunction = CompareFunction.LessEqual,
StencilPass = StencilOperation.Keep,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
सारांश में स्टैंसिलटेस्ट तभी गुजरता है जब स्टैंसिलबफर 1 (मास्क से अल्फा पिक्सल) से कम हो और स्टैंसिलबफर को प्रभावित न करे।
अब जबकि हमारे पास अपना डेप्थस्टैंसिलस्टेट्स स्थापित हो गया है। हम वास्तव में एक मुखौटा का उपयोग करके आकर्षित कर सकते हैं। बस पहले डेप्थिलस्टेनस्टेट का उपयोग करके मुखौटा खींचें। यह BackBuffer और StencilBuffer दोनों को प्रभावित करेगा। अब जबकि स्टैंसिल बफ़र का मान 0 है जहाँ आप मास्क की पारदर्शिता थी और 1 जहाँ इसका रंग था हम बाद की छवियों को मास्क करने के लिए स्टैंसिलबफ़र का उपयोग कर सकते हैं।
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, s1, null, a);
spriteBatch.Draw(huh, Vector2.Zero, Color.White); //The mask
spriteBatch.End();
दूसरा SpriteBatch दूसरे DepthStencilStates का उपयोग करता है। कोई फर्क नहीं पड़ता कि आप क्या आकर्षित करते हैं, केवल पिक्सल जहां स्टैंसिलबफर 1 पर सेट है वह स्टैंसिल परीक्षण पास करेगा और स्क्रीन पर आ जाएगा।
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, s2, null, a);
spriteBatch.Draw(color, Vector2.Zero, Color.White); //The background
spriteBatch.End();
नीचे ड्रा विधि में कोड की संपूर्णता है, गेम कंस्ट्रक्टर में PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 सेट करना न भूलें।
GraphicsDevice.Clear(ClearOptions.Target
| ClearOptions.Stencil, Color.Transparent, 0, 0);
var m = Matrix.CreateOrthographicOffCenter(0,
graphics.GraphicsDevice.PresentationParameters.BackBufferWidth,
graphics.GraphicsDevice.PresentationParameters.BackBufferHeight,
0, 0, 1
);
var a = new AlphaTestEffect(graphics.GraphicsDevice) {
Projection = m
};
var s1 = new DepthStencilState {
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
var s2 = new DepthStencilState {
StencilEnable = true,
StencilFunction = CompareFunction.LessEqual,
StencilPass = StencilOperation.Keep,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, s1, null, a);
spriteBatch.Draw(huh, Vector2.Zero, Color.White); //The mask
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, s2, null, a);
spriteBatch.Draw(color, Vector2.Zero, Color.White); //The background
spriteBatch.End();