XNA ड्रा या एक कण प्रणाली लिखें। भाग II: शेड्स

सभी खेल डेवलपर्स और सिर्फ खेल देव में रुचि रखने वाले लोगों को नमस्कार।

यह आपको पिक्सेल शेड्स के बारे में बताने का समय है और पोस्ट-प्रेकिंग कैसे करना है। यह XNA में आलेखीय तरीकों पर लेख का दूसरा भाग है, पिछले लेख में - हमने स्प्रिटबैच के ड्रा और स्टार्ट तरीकों की जांच की। एक उदाहरण के लिए: हम एक पिक्सेल shader जोड़कर अपने कण प्रणाली में सुधार करेंगे जो अंतरिक्ष को विकृत करेगा।







इस भाग में:

शेडर



बात करते हैं शादियों की। दो प्रकार के शेड हैं (शेडर मॉडल 2.0 में, जिसका हम उपयोग करते हैं): वर्टेक्स और पिक्सेल।

पॉलीहेड्रा के शीर्ष पर मैप किए गए डेटा पर वर्टेकर शेड संचालित होता है। इस तरह के डेटा, विशेष रूप से, अंतरिक्ष में शीर्ष के निर्देशांक, बनावट निर्देशांक, स्पर्शरेखा सदिश, द्विघात वेक्टर, सामान्य वेक्टर शामिल हैं। वर्टेक्स शेडर का उपयोग प्रजातियों के लिए किया जा सकता है और वर्टिकल के ट्रांसफॉर्मेशन, टेक्सचर कोर्डिनेशन की पीढ़ी, लाइटिंग की गणना आदि के लिए इस्तेमाल किया जा सकता है।

त्रिकोण के रेखांकन के चरण में प्रत्येक टुकड़े के लिए पिक्सेल शेड निष्पादित किए जाते हैं। एक टुकड़ा (या पिक्सेल) एक बिंदु है, जिसके साथ खिड़की के निर्देशांक हैं, उस पर श्रृंखला की कार्रवाई करने के बाद रैस्टराइज़र द्वारा प्राप्त किया गया है। सीधे शब्दों में कहें, फ्रेम बफर में परिणामी बिंदु, इन बिंदुओं का संयोजन तब छवि बनाता है। पिक्सेल शेड अंतिम चरण तक टुकड़े पर काम करते हैं, अर्थात। गहराई से परीक्षण, अल्फा और स्टैंसिल। पिक्सेल shader वर्टेक्स shader से प्रक्षेपित डेटा (रंग, बनावट निर्देशांक) प्राप्त करता है।



यदि पिक्सेल shader के बारे में बहुत संक्षेप में कहा जाए, तो यह तैयार छवि प्रोसेसर है।

विस्थापन shader के मामले में, वर्टिकल शेड्स की आवश्यकता नहीं है, आइए पिक्सेल शेड्स पर विचार करें

पोस्ट प्रोसेसिंग


एक आलसी संक्षिप्त व्यक्ति होने के लिए, पोस्ट-प्रोसेसिंग शेड्स को निष्पादित किया जाता है जब खेल की पूरी तस्वीर पहले से ही खींची जाती है: अलग-अलग स्प्राइट्स पर नहीं बल्कि पूरी तस्वीर पर छायांकन तुरंत लगाया जाता है।

- क्योंकि spriteBatch.Bgin के पास एक पैरामीटर, प्रभाव है, इसलिए अभी एक shader को लागू करना आसान नहीं है, हम इसे कैसे आकर्षित करते हैं?
मैं उत्तर देता हूं: यह ठीक है कि इस तरह के एक shader को सिंगल स्प्राइट्स पर लागू किया जाता है, परिणामस्वरूप, विस्थापन shader कुटिल रूप से कार्य करेगा।

पोस्ट-प्रोसेस प्रोसेसिंग बनाने के लिए, आपको पहले स्क्रीन पर क्या खींचना चाहिए - एक अलग बनावट पर आकर्षित करना चाहिए, और फिर पोस्ट-प्रोसेस शेडर का उपयोग करके इस बहुत बनावट को ड्रा करना चाहिए। इस प्रकार, shader एकल स्प्राइट पर नहीं, बल्कि पूरे चित्र पर कार्य करता है।

-Stop, लेकिन एक अलग बनावट पर आकर्षित करने के लिए कैसे?
जवाब है: RenderTarget2D से मिलें

RenderTarget2D



और फिर, मेरे दोस्त को नमस्कार - संक्षिप्तता। RenderTarget2D - अनिवार्य रूप से एक बनावट जो आप आकर्षित कर सकते हैं।

हम उस स्थान पर जाते हैं जहां हम आमतौर पर दृश्य खींचते हैं, सफाई से पहले, हम सम्मिलित करते हैं:

GraphicsDevice.SetRenderTarget(renderTarget); 


अब सब कुछ स्क्रीन पर नहीं, बल्कि RenderTarget2D पर खींचा जाएगा।
स्क्रीन पर वापस जाने के लिए, हम निर्माण का उपयोग करते हैं:

 GraphicsDevice.SetRenderTarget(null); 


ड्राइंग करने से पहले RenderTarget साफ़ करना याद रखें।

डिस्मेंमेनैट-मैप के साथ डिस्टर्बिंग शेडर



इस तरह के पिक्सेल शेडर का विचार बहुत सरल है: इनपुट एक बनावट है जिसे "तुला" होने की आवश्यकता है, दूसरा इनपुट एक नक्शा है कि कैसे झुकना है।

हम व्यवहार में कैसे - के बारे में एक नक्शा उत्पन्न करेंगे।

वैसे, नक्शे के बारे में। मानचित्र दृश्य की बनावट के समान आकार की छवि है, सिवाय, शायद, कि हम खींची गई छवि को नहीं देखेंगे।

मानचित्र के समान और छायाकार कैसे काम करता है:

छवि प्रसंस्करण की प्रक्रिया में - हमें वर्तमान पिक्सेल स्थिति मिलती है, हम रंग प्राप्त करते हैं। हम कार्ड के लिए भी ऐसा ही करते हैं। यानी अंततः, हम संशोधन के लिए उपलब्ध होंगे: पिक्सेल रंग, पिक्सेल स्थिति, छवि में संबंधित पिक्सेल स्थिति के नक्शे पर पिक्सेल रंग।

हम मानचित्र के रंगों का उपयोग करके जानकारी को बताएंगे कि किस तरह से पिक्सेल को मोड़ना है।

उदाहरण के लिए, आर-चैनल (लाल) 0f से 1f तक मान प्राप्त करता है। अगर हमें मानचित्र पर विकृतियां R = 0.5f दिखाई देती हैं, तो हम बस छवि पिक्सेल की स्थिति को 10f * 0.5f पिक्सेल द्वारा स्थानांतरित कर देते हैं। 10f वह बल है जिसके साथ हम चलते हैं।

तदनुसार, आर-चैनल एक्स समन्वय के अनुरूप होगा, और जी-चैनल वाई के लिए।

यदि आपको चित्रों की आवश्यकता है, तो उन्हें प्राप्त करें:

मूल छवि:


नक्शा:


अंतिम तस्वीर:


इसलिए, हमने सिद्धांत को हल कर दिया है, अब इसे कोड के साथ लागू करने का प्रयास करते हैं।

कार्य योजना:


अभ्यास: कण प्रणाली को संशोधित करना



हम पिछले लेख से स्रोत कोड को अंतिम रूप दे रहे हैं।
तुरंत कुछ चित्र जोड़ें ताकि विकृतियां ध्यान देने योग्य हों, उदाहरण के लिए यह एक:



ParticleController की प्रतिलिपि बनाएँ और इसे ShaderController कहें , इसमें हमें केवल कण बनाने की प्रक्रिया को बदलने की आवश्यकता है, और विशेष रूप से:

 public void EngineRocketShader(Vector2 position) // ,      { for (int a = 0; a < 2; a++) //  2     { Vector2 velocity = AngleToV2((float)(Math.PI * 2d * random.NextDouble()), 1.6f); float angle = (float)(Math.PI * 2d * random.NextDouble()); float angleVel = 0; Vector4 color = new Vector4((float)random.NextDouble(), (float)random.NextDouble(), 1f, (float)random.NextDouble()); //   R  G  A . float size = 1f; int ttl = 80; float sizeVel = 0; float alphaVel = 0.01f; GenerateNewParticle(smoke, position, velocity, angle, angleVel, color, size, ttl, sizeVel, alphaVel); } } 


हम पोस्ट-प्रोसेसिंग को लागू करते हैं, नए चर बनाते हैं:

 RenderTarget2D shader_map; //    RenderTarget2D renderTarget; //     


हम उन्हें आरंभ करते हैं:

 shader_map = new RenderTarget2D(GraphicsDevice, 800, 600); renderTarget = new RenderTarget2D(GraphicsDevice, 800, 600); 


हम मुख्य वर्ग की ड्रा विधि में जाते हैं और लिखते हैं:

 protected override void Draw(GameTime gameTime) { GraphicsDevice.SetRenderTarget(renderTarget); //   renderTarget GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(); spriteBatch.Draw(background, new Rectangle(0, 0, 800, 600), Color.White); spriteBatch.End(); part.Draw(spriteBatch); GraphicsDevice.SetRenderTarget(shader_map); //     GraphicsDevice.Clear(Color.Black); shad.Draw(spriteBatch); GraphicsDevice.SetRenderTarget(null); //    GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(); spriteBatch.Draw(renderTarget, new Rectangle(0, 0, 800, 600), Color.White); spriteBatch.End(); base.Draw(gameTime); } 


पोस्ट-प्रोसेसिंग तैयार है, अब एक shader बनाएं।

एक नया प्रभाव (fx) फ़ाइल बनाएँ ( यह एचएलएसएल में लिखी गई एक shader फ़ाइल है ), इसे वहाँ दर्ज करें, कुछ इस तरह से:

 texture displacementMap; //   sampler TextureSampler : register(s0); //   ,     sampler DisplacementSampler : samplerState{ //  TextureAddress Texture = displacementMap; MinFilter = Linear; MagFilter = Linear; AddressU = Clamp; AddressV = Clamp; }; float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { /* PIXEL DISTORTION BY DISPLACEMENT MAP */ float3 displacement = tex2D(DisplacementSampler, texCoord); //  R,G,B   // Offset the main texture coordinates. texCoord.x += displacement.r * 0.1; //    texCoord.y += displacement.g * 0.1; //    float4 output = tex2D(TextureSampler, texCoord); //      return color * output; } technique DistortionPosteffect { pass Pass1 { PixelShader = compile ps_2_0 main(); //   } } 


शेडर बनाया गया है, आप इसे उसी तरह से एक नियमित बनावट के रूप में लोड कर सकते हैं, सिवाय इसके कि प्रकार Texture2D नहीं है, लेकिन प्रभाव

अब हमारे ड्रॉ को अपडेट करें:

 effect1.Parameters["displacementMap"].SetValue(shader_map); //    spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, effect1); //     spriteBatch.Draw(renderTarget, new Rectangle(0, 0, 800, 600), Color.White); spriteBatch.End(); 


हम शुरू करते हैं, हम सुंदर, यथार्थवादी पशु विकृतियों की प्रशंसा करते हैं (यह एक डेमो को देखने के लिए बेहतर है) :


वास्तव में, कण प्रणाली का यह कार्यान्वयन (शेड्स नहीं है, लेकिन पहले पाठ में क्या था) एक पूरे के रूप में प्रदर्शन के लिए पूरी तरह से अच्छा नहीं है। अन्य विधियां हैं जिन्हें समझना अधिक कठिन है, मैं उनके बारे में बाद में बात करूंगा।

मैं स्रोत कोड और डेमो लागू करता हूं (इस बार, यह XNA 4.0 और हार्डवेयर समर्थन DirectX9, sh 2.0 के साथ किसी भी कंप्यूटर पर चलेगा)

हो सकता है कि इस सप्ताह, यह नहीं पता होगा कि कब - मैं अपडेट विधि के बारे में बात करूंगा और बॉक्स 2 डी का उपयोग करके भौतिकी को कैसे लागू किया जाए।

गुड लक और एक बार फिर छुट्टी प्रोग्रामर के साथ 0xFF + 1 दोपहर! ;)

Source: https://habr.com/ru/post/In128349/


All Articles