Skip to content

3D ब्रश तकनीकें और इन-गेम वर्ल्ड स्कल्प्टिंग

हम चाहते हैं कि खिलाड़ी दुनिया को स्कल्प्ट कर सकें। केवल ग्रिड पर प्रीफैब न रखें। केवल ब्लॉक चालू-बंद न करें। बल्कि टेरेन को सच में नया आकार दें: नदियाँ तराशें, पहाड़ उठाएँ, चट्टानी ढलानों को चिकना करें और गुफाएँ खोदें। वैसा ही काम जो ZBrush और Blender का स्कल्प्ट मोड कलाकारों के लिए करता है, लेकिन एक मल्टीप्लेयर ब्राउज़र गेम के भीतर 60fps पर चलता हुआ।

यह एक कठिन इंजीनियरिंग समस्या है, जिसमें डेटा रिप्रेज़ेंटेशन, मेश एक्सट्रैक्शन, GPU कंप्यूट, ब्रश गणित और नेटवर्क सिंक्रोनाइज़ेशन शामिल हैं। इस गाइड में हमने अपनी सभी जानकारियाँ दर्ज की हैं।

टेरेन रिप्रेज़ेंटेशन की दो दुनियाएँ

हर स्कल्प्टिंग सिस्टम इस चुनाव से शुरू होता है कि टेरेन डेटा को किस तरह स्टोर किया जाए। यही चुनाव तय करता है कि किस तरह के संपादन संभव होंगे, वे कितनी तेज़ी से चलेंगे और उन्हें कितनी मेमोरी की आवश्यकता होगी।

हाइटमैप

हाइटमैप प्रत्येक ग्रिड बिंदु के लिए ऊँचाई का एक मान स्टोर करता है। आप इसे एक ग्रेस्केल छवि की तरह समझ सकते हैं, जिसमें चमक ऊँचाई के बराबर होती है। हमारा मौजूदा world/client टेरेन ठीक इसी तरह काम करता है: noise.ts FBM वैल्यू नॉइज़ के ज़रिए ऊँचाई उत्पन्न करता है और प्रत्येक Chunk एक Float32Array हाइटमैप स्टोर करता है, जिसे PlaneGeometry पर प्रोजेक्ट किया जाता है।

हाइटमैप तेज़ होते हैं। सैंपलिंग में बाइलिनियर इंटरपोलेशन के साथ केवल एक ऐरे लुकअप लगता है। LOD आसान है क्योंकि आपको केवल ग्रिड रिज़ॉल्यूशन घटाना होता है। स्प्लैट-आधारित टेक्सचर ब्लेंडिंग सीधे UV ग्रिड पर मैप होती है। फ़िज़िक्स कोलिज़न केवल ऊँचाई की क्वेरी तक सीमित हो जाते हैं।

इसकी सीमा टोपोलॉजी है। हाइटमैप प्रत्येक (x, z) निर्देशांक के लिए केवल एक ऊँचाई दर्शा सकता है। गुफाएँ नहीं। ओवरहैंग नहीं। मेहराब नहीं। सुरंगें नहीं। अगर कोई खिलाड़ी ऐसी चट्टान स्कल्प्ट करता है जो मुड़कर अपने ही ऊपर आ जाती है, तो हाइटमैप उसे स्टोर नहीं कर सकता। ऐसे टेरेन के लिए यह ठीक है जिसमें मुख्यतः लहरदार पहाड़ियाँ और पर्वत हों। लेकिन फ़्रीफ़ॉर्म स्कल्प्टिंग के लिए, जहाँ खिलाड़ी ज़मीन के भीतर खुदाई कर सकते हैं, यह उपयोगी नहीं है।

वॉल्यूमेट्रिक (3D स्केलर फ़ील्ड)

वैकल्पिक तरीका 3D स्पेस के प्रत्येक बिंदु पर एक मान स्टोर करना है। यदि ठोस सामग्री के भीतर मान ऋणात्मक और बाहर धनात्मक हो, या इसका उल्टा हो, तो आपके पास Signed Distance Field (SDF) होता है। यदि मान केवल घनत्व हो—किसी सीमा से ऊपर ठोस और नीचे खाली—तो आपके पास डेंसिटी फ़ील्ड होता है।

वॉल्यूमेट्रिक रिप्रेज़ेंटेशन किसी भी टोपोलॉजी को संभाल सकते हैं। गुफाएँ, ओवरहैंग, तैरते द्वीप और पहाड़ों के आर-पार सुरंगें। इसके बदले अधिक मेमोरी और जटिलता की कीमत चुकानी पड़ती है। 32-बिट फ़्लोट वाला 256^3 ग्रिड 64 MB लेता है। 512^3 ग्रिड 512 MB लेता है। और यह केवल एक चंक के लिए है। इसे व्यावहारिक बनाने के लिए आपको स्पार्स डेटा स्ट्रक्चर—जैसे ऑक्ट्री और ब्रिक मैप—की आवश्यकता होती है।

मेश एक्सट्रैक्शन चरण भी आसान नहीं है। आप केवल वर्टेक्स की Y पोज़िशन सेट करके काम पूरा नहीं कर सकते। आपको ऐसा एल्गोरिदम चाहिए जो स्केलर फ़ील्ड को पढ़े और उस सतह का अनुमानित ट्रायंगल मेश बनाए जहाँ फ़ील्ड शून्य को पार करता है।

मेश एक्सट्रैक्शन: मार्चिंग क्यूब्स, सरफेस नेट्स और ड्युअल कॉन्टूरिंग

मार्चिंग क्यूब्स

Marching Cubes सबसे पुराना और सबसे व्यापक रूप से लागू किया गया आइसोसरफेस एक्सट्रैक्शन एल्गोरिदम है। Lorensen और Cline ने इसे 1987 में प्रकाशित किया था। यह वॉक्सेल ग्रिड के प्रत्येक क्यूब की जाँच करता है, जहाँ हर कोने पर एक स्केलर मान होता है। यदि कुछ कोने सतह के भीतर—ऋणात्मक—और कुछ बाहर—धनात्मक—हों, तो उस क्यूब के भीतर ट्रायंगल मेश का एक पैच रखा जाता है।

प्रत्येक क्यूब में 8 कोने होते हैं और हर कोना भीतर या बाहर हो सकता है, जिससे 256 संभावित कॉन्फ़िगरेशन (2^8) बनते हैं। सममिति के ज़रिए ये घटकर 15 विशिष्ट मामलों में आ जाते हैं। एक लुकअप टेबल प्रत्येक मामले को ट्रायंगल के एक सेट से मैप करती है। किनारों पर जहाँ चिह्न बदलता है, वहाँ लीनियर इंटरपोलेशन से एज इंटरसेक्शन बिंदु निकाले जाते हैं।

हाल के GPU इम्प्लीमेंटेशन ने Marching Cubes को रियल-टाइम स्कल्प्टिंग के लिए पर्याप्त तेज़ बना दिया है। UE5 पर 2025 का एक इम्प्लीमेंटेशन प्रत्येक GPU थ्रेड को एक क्यूब देता है, जिससे हज़ारों क्यूब एक साथ प्रोसेस होते हैं। मुख्य बात यह है कि प्रत्येक क्यूब का ट्रायंगुलेशन उसके पड़ोसी क्यूब से स्वतंत्र होता है, इसलिए एल्गोरिदम को बेहद आसानी से पैरेलल किया जा सकता है।

MCHex (arxiv 2511.02064, 2025) Marching Cubes को गारंटीकृत धनात्मक Jacobian मानों वाली एडैप्टिव हेक्साहेड्रल मेश जनरेशन तक विस्तारित करता है, जिससे सिमुलेशन मेश के लिए बाउंड्री का अनुमान बेहतर होता है।

rupMC CPU/GPU हेटेरोजीनियस आर्किटेक्चर का उपयोग करके सीरियल इम्प्लीमेंटेशन की तुलना में दर्जनों गुना तेज़ और पैरेलल DMC वेरिएंट की तुलना में 4x तेज़ प्रदर्शन प्राप्त करता है।

मुख्य सीमा यह है कि Marching Cubes को तीखे फ़ीचर संभालने में कठिनाई होती है। 90 डिग्री का किनारा गोल होकर चिकने वक्र में बदल जाता है। टेरेन स्कल्प्टिंग के लिए यह आम तौर पर स्वीकार्य है—प्राकृतिक भूभाग अधिकांशतः चिकना होता है—लेकिन आर्किटेक्चरल फ़ीचर के लिए यह समस्या है।

सरफेस नेट्स

Surface Nets एल्गोरिदम का एक नया परिवार है, जो डिस्क्रीट स्केलर फ़ील्ड से अधिक चिकने मेश बनाता है। क्यूब के किनारों पर वर्टेक्स रखने के बजाय—जैसा Marching Cubes करता है—Surface Nets सतह वाले प्रत्येक क्यूब में एक वर्टेक्स रखता है, फिर आस-पास के वर्टेक्स को जोड़कर क्वाड बनाता है।

परिणाम स्वाभाविक रूप से अधिक चिकना होता है। 2024 के एक शोधपत्र (arxiv 2401.14906) ने उच्च-प्रदर्शन वाला पैरेलल Surface Nets इम्प्लीमेंटेशन प्रस्तुत किया, जो सीक्वेंशियल एल्गोरिदम की तुलना में दस से सौ गुना तेज़ चलता है। fast-surface-nets Rust क्रेट छोटी लुकअप टेबल और SIMD एक्सेलेरेशन का उपयोग करके एक 2.5 GHz कोर पर लगभग 2 करोड़ ट्रायंगल प्रति सेकंड उत्पन्न करता है।

bevy-sculpter (v0.18.0, जनवरी 2026) अपनी मुख्य मेशिंग रणनीति के रूप में Surface Nets का उपयोग करता है। यह क्रेट चार ब्रश प्रकारों के साथ SDF-आधारित वॉल्यूमेट्रिक स्कल्प्टिंग देता है: हार्ड CSG (तुरंत जोड़ना/हटाना), स्मूथ कंटीन्यूअस (दबाकर रखे गए इनपुट के लिए), ब्लर (सतह को चिकना करना) और फ़्लैटन (लक्ष्य ऊँचाई पर सेट करना)। संपादन के बाद सही signed distance field गुणों को बहाल करने के लिए इसमें Fast Sweeping Method के ज़रिए SDF रीडिस्टेंसिंग भी शामिल है।

Surface Nets, Marching Cubes—सरल और तेज़, लेकिन बाइनरी डेटा पर एलियस्ड मेश बनाता है—और Dual Contouring—फ़ीचर सुरक्षित रखता है, लेकिन जटिल है—के बीच एक अच्छा संतुलन है।

ड्युअल कॉन्टूरिंग

Dual Contouring उन तीखे फ़ीचर को सुरक्षित रखता है जिन्हें Marching Cubes और Surface Nets नहीं रख पाते। यह प्रत्येक कोने पर केवल फ़ील्ड का चिह्न ही नहीं, बल्कि एज इंटरसेक्शन पर ग्रेडिएंट—नॉर्मल—का भी उपयोग करता है। QEF (Quadratic Error Function) मिनिमाइज़ेशन प्रत्येक सेल के भीतर वर्टेक्स को ऐसी पोज़िशन पर रखता है जो एज इंटरसेक्शन की सभी सीमाओं को सर्वोत्तम रूप से संतुष्ट करती है।

परिणाम यह है कि एक्सट्रैक्ट किए गए मेश में तीखे किनारे और कोने सुरक्षित रहते हैं। लंबवत सतहों वाला क्यूब, क्यूब ही बना रहता है।

इसके बदले जटिलता बढ़ती है। QEF सॉल्व में इंटर-सेल निर्भरताएँ होती हैं, जो GPU पैरेललाइज़ेशन को कठिन बनाती हैं। यह नॉन-मैनिफ़ोल्ड मेश—ऐसे किनारे जिन्हें दो से अधिक पॉलिगॉन साझा करते हैं—बना सकता है। और इसका इम्प्लीमेंटेशन Marching Cubes से अधिक जटिल है, हालाँकि Johannes Jendersie के अनुसार एक काम करने वाला Dual Contouring इम्प्लीमेंटेशन लगभग 200 पंक्तियों का होता है, जबकि मज़बूत Marching Cubes इम्प्लीमेंटेशन 500 से अधिक पंक्तियों का होता है।

Cubical Marching Squares (CMS) को बीच के विकल्प के रूप में प्रस्तावित किया गया है: यह इंटरसेल-इंडिपेंडेंट—अर्थात GPU-अनुकूल—है और फिर भी कुछ हद तक फ़ीचर सुरक्षित रखता है।

किसका उपयोग करें

ब्राउज़र में खिलाड़ियों के लिए टेरेन स्कल्प्टिंग हेतु:

Surface Nets सबसे मज़बूत उम्मीदवार है। यह बाइनरी डेटा पर Marching Cubes में दिखने वाले एलियसिंग आर्टिफ़ैक्ट के बिना चिकने मेश—प्राकृतिक दिखने वाला टेरेन—बनाता है। यह रियल-टाइम री-मेशिंग के लिए पर्याप्त तेज़ है। और इसे लागू करना Dual Contouring से आसान है।

Marching Cubes तब भी एक ठोस विकल्प है जब GPU पैरेललिज़्म प्राथमिकता हो—हर क्यूब स्वतंत्र है—या आपको व्यापक लाइब्रेरी समर्थन चाहिए। Reinder Nijhoff का WebGPU SDF Editor (जनवरी 2026) अपने एक्सट्रैक्शन पाइपलाइन में Marching Cubes और Surface Nets दोनों को लागू करता है और पूरी तरह GPU पर चलता है।

Dual Contouring को उन मामलों के लिए रखना बेहतर है जहाँ प्रदर्शन से अधिक आर्किटेक्चरल सटीकता मायने रखती हो। ब्राउज़र संदर्भ में रियल-टाइम टेरेन स्कल्प्टिंग के लिए यह आदर्श नहीं है।

Transvoxel एल्गोरिदम: LOD स्टिचिंग का समाधान

जब वॉक्सेल टेरेन को अलग-अलग रिज़ॉल्यूशन में मेश किया जाता है—खिलाड़ी के पास LOD0 और दूर LOD2—तो सीमाओं पर दरारें बनती हैं। हाइटमैप के लिए यह सरल समस्या है: कम रिज़ॉल्यूशन वाले पड़ोसी से मेल कराने के लिए एज वर्टेक्स को इंटरपोलेट करें। हमारा मौजूदा chunk.ts, stitchEdge() में ठीक यही करता है।

वॉल्यूमेट्रिक टेरेन के लिए यह समस्या कहीं अधिक कठिन है। LOD0 पर किसी गुफा का मुख बाउंड्री पर 30 ट्रायंगल बना सकता है। LOD1 पर वही क्षेत्र पूरी तरह अलग टोपोलॉजी वाले 8 ट्रायंगल बना सकता है। उनके बीच लीनियर इंटरपोलेशन करने का कोई आसान तरीका नहीं है।

Eric Lengyel का Transvoxel Algorithm (2009) इसे "ट्रांज़िशन सेल" से हल करता है। दो LOD स्तरों की सीमा पर एल्गोरिदम 8 क्यूब कोनों के बजाय 9 हाई-रिज़ॉल्यूशन सैंपल पर विचार करता है, जिससे 512 संभावित कॉन्फ़िगरेशन बनते हैं जो 73 समतुल्यता वर्गों में आते हैं। प्रत्येक वर्ग एक पूर्वनिर्धारित ट्रायंगल पैटर्न से मैप होता है, जो दोनों रिज़ॉल्यूशन के बीच की खाली जगह को पूरी तरह भर देता है।

एल्गोरिदम स्थानीय वॉक्सेल डेटा पर काम करता है, इसलिए बदले गए क्षेत्र को दोबारा ट्रायंगुलेट करना तेज़ होता है। रियल-टाइम स्कल्प्टिंग के लिए यह अत्यंत महत्वपूर्ण है: जब कोई खिलाड़ी LOD सीमा के पास टेरेन संपादित करता है, तो केवल ट्रांज़िशन सेल को दोबारा बनाना पड़ता है।

इसका एक Rust इम्प्लीमेंटेशन transvoxel क्रेट के रूप में उपलब्ध है। मूल लुकअप टेबल transvoxel.org पर उपलब्ध हैं।

ब्रश का गणित

स्कल्प्टिंग ब्रश एक ऐसा फ़ंक्शन है जो लक्ष्य बिंदु के चारों ओर एक निश्चित त्रिज्या के भीतर स्केलर फ़ील्ड के मानों को बदलता है। Blender से Unreal Engine और रनटाइम गेम सिस्टम तक, सभी इम्प्लीमेंटेशन में इसका गणित आश्चर्यजनक रूप से समान है।

फ़ॉलऑफ़ फ़ंक्शन

ब्रश फ़ॉलऑफ़ तय करता है कि संपादन की शक्ति केंद्र से किनारे की ओर कितनी घटेगी। Blender 5.1 इन मानक प्रोफ़ाइल को परिभाषित करता है:

स्मूथ: f(d) = 3d^2 - 2d^3 (Hermite इंटरपोलेशन, हमारे noise.ts जैसा ही smoothstep)

स्फ़ीयर: केंद्र पर अधिक प्रभाव और सीमा के पास तेज़ फ़ॉलऑफ़। इसका अनुमान f(d) = sqrt(1 - d^2) से लगाया जाता है।

शार्प: f(d) = (1 - d)^n, जहाँ n > 2 है। यह एक बारीक नोक बनाता है।

लीनियर: f(d) = 1 - d, जहाँ d केंद्र से नॉर्मलाइज़ की गई दूरी है—केंद्र पर 0 और किनारे पर 1।

कॉन्स्टेंट: d < 1 के लिए f(d) = 1, और ब्रश की सीमा पर अचानक कटऑफ़।

इनवर्स स्क्वेयर: प्राकृतिक "मिट्टी जैसा" एहसास देने के लिए स्मूथ और स्फ़ीयर के बीच का मिश्रण।

सभी मामलों में d = distance_to_center / brush_radius होता है, जिसे [0, 1] तक सीमित किया जाता है। प्रत्येक बिंदु पर फ़ील्ड में होने वाला वास्तविक बदलाव निकालने के लिए फ़ॉलऑफ़ मान को ब्रश की शक्ति से गुणा किया जाता है।

फ़ॉलऑफ़ स्पेस

Blender स्फ़ीयर फ़ॉलऑफ़—3D वर्ल्ड स्पेस में निकाली गई दूरी—और प्रोजेक्टेड फ़ॉलऑफ़—2D स्क्रीन स्पेस में निकाली गई दूरी—के बीच अंतर करता है। प्रोजेक्टेड फ़ॉलऑफ़ का अर्थ है कि स्क्रीन पर पास दिखने वाले दो बिंदु एक-दूसरे को समान रूप से प्रभावित करते हैं, भले ही वर्ल्ड स्पेस में उनकी गहराई बहुत अलग हो। टेरेन स्कल्प्टिंग के लिए 3D वर्ल्ड स्पेस फ़ॉलऑफ़ आम तौर पर अधिक सहज होता है।

मुख्य ब्रश ऑपरेशन

ऊपर उठाना/नीचे करना (डिस्प्लेसमेंट): फ़ॉलऑफ़ के अनुसार भारित करके ब्रश की त्रिज्या के भीतर स्केलर फ़ील्ड में मान जोड़ें या घटाएँ। हाइटमैप के लिए: height[i] += strength * falloff(d)। SDF के लिए: sdf[i] -= strength * falloff(d)—घटाने से सामग्री अधिक ठोस होती है और सतह ऊपर उठती है।

स्मूथ (Laplacian): फ़ॉलऑफ़ के अनुसार भारित करके प्रत्येक मान को उसके पड़ोसी मानों के औसत से बदलें। इससे सूक्ष्म विवरण मिटते हैं और नॉइज़ घटता है। Laplacian फ़िल्टर एक छोटे कर्नेल—हाइटमैप के लिए 3x3 और वॉल्यूम के लिए 3x3x3—से सैंपल लेकर औसत की ओर ब्लेंड करता है। HC (Humphrey's Classes) स्मूथिंग इसका एक वेरिएंट है, जो सामान्य Laplacian की तुलना में वॉल्यूम को बेहतर बनाए रखता है।

फ़्लैटन: फ़ॉलऑफ़ के अनुसार ब्लेंड करते हुए फ़ील्ड मान को लक्ष्य ऊँचाई—या SDF स्पेस में दूरी—पर सेट करें। स्ट्रोक शुरू होने पर लक्ष्य को आम तौर पर ब्रश के केंद्र से सैंपल किया जाता है और फिर स्थिर रखा जाता है। इससे समतल पठार बनते हैं।

पिंच/इन्फ़्लेट: वर्टेक्स को सतह के नॉर्मल की ओर या उससे दूर ले जाएँ। SDF स्पेस में यह ग्रेडिएंट की दिशा में डिस्प्लेसमेंट के बराबर है।

ग्रैब: फ़ील्ड के किसी क्षेत्र को ऐसे स्थानांतरित करें जैसे आप मिट्टी खींच रहे हों। डिस्प्लेसमेंट वेक्टर, वर्ल्ड स्पेस में प्रोजेक्ट किया गया माउस डेल्टा होता है, जिसे त्रिज्या के भीतर फ़ील्ड मानों पर लागू किया जाता है।

नॉइज़: ब्रश की त्रिज्या के भीतर फ़ील्ड में प्रोसीजरल नॉइज़ जोड़ें। यह चिकनी सतहों को खुरदरा बनाने के लिए उपयोगी है।

स्टैम्प: 2D ग्रेस्केल छवि को डिस्प्लेसमेंट के रूप में लागू करें और उसे कर्सर के नीचे की सतह पर प्रोजेक्ट करें। Unreal Engine का Landscape टूल टेरेन ब्रश के लिए इसका समर्थन करता है।

एडैप्टिव टेसेलेशन

sculpt-3D (React + Three.js ब्राउज़र स्कल्प्टिंग) एडैप्टिव टेसेलेशन लागू करता है: जैसे-जैसे ब्रश मेश पर चलता है, ब्रश के केंद्र के पास के ट्रायंगल को विभाजित किया जाता है ताकि डिफ़ॉर्मेशन के लिए अधिक वर्टेक्स मिलें। यह "लो-पॉली स्ट्रेच" समस्या को रोकता है, जिसमें स्कल्प्टिंग से मोटा मेश विकृत हो जाता है। समान ट्रायंगल गुणवत्ता के लिए सबडिविज़न सममित विभाजन का उपयोग करता है।

वॉल्यूमेट्रिक सिस्टम में एडैप्टिव टेसेलेशन की उसी तरह आवश्यकता नहीं होती, क्योंकि मेश को फ़ील्ड से दोबारा बनाया जाता है। इसके बजाय, समान प्रभाव के लिए आप संपादित क्षेत्रों के पास स्थानीय रूप से वॉक्सेल रिज़ॉल्यूशन बढ़ा सकते हैं—एडैप्टिव ऑक्ट्री का उपयोग करके।

SDF स्कल्प्टिंग: Dreams का तरीका

Media Molecule का Dreams (PS4, 2020) अब तक रिलीज़ किया गया सबसे महत्वाकांक्षी इन-गेम स्कल्प्टिंग सिस्टम है। Alex Evans ने SIGGRAPH 2015 में इसकी तकनीकी पद्धति प्रस्तुत की थी।

रिप्रेज़ेंटेशन

Dreams ज्योमेट्री को 83^3 fp16 वॉल्यूम टेक्सचर ब्लॉक में एक कंपाउंड SDF फ़ंक्शन के रूप में स्टोर करता है। प्रत्येक स्कल्प्ट 1 से 100,000 "संपादनों" की सूची होता है, जहाँ हर संपादन एक CSG ऑपरेशन—जोड़ना, घटाना, रंगना—होता है, जिसमें एक प्रिमिटिव आकार—स्फ़ीयर, क्यूब, सिलिंडर, कोन, एलिप्सॉइड, टोरस आदि—और एक ब्लेंड मोड शामिल होता है। ब्लेंड मोड सॉफ्ट-मैक्स और सॉफ्ट-मिन फ़ंक्शन का उपयोग करते हैं। एक "सॉफ्ट" ब्लेंड प्रिमिटिव्स के बीच गोलाकार संक्रमण बनाता है (जैसे मिट्टी को एक साथ दबाया गया हो)। एक "हार्ड" ब्लेंड स्पष्ट बूलियन कट बनाता है। ब्लेंड की त्रिज्या को उपयोगकर्ता नियंत्रित कर सकता है।

रेंडरिंग

Dreams कोई त्रिभुज मेश एक्सट्रैक्ट नहीं करता। इसके बजाय, यह एक कस्टम पॉइंट-क्लाउड रेंडरर ("flecks") का उपयोग करके सीधे SDF से रेंडर करता है। प्रत्येक fleck एक छोटी डिस्क होती है, जिसे सतह के नॉर्मल के अनुरूप उन्मुख किया जाता है। सतहें खोजने के लिए SDF का सैंपल लिया जाता है और उन पर flecks वितरित किए जाते हैं। इससे मेश एक्सट्रैक्शन की बाधा पूरी तरह समाप्त हो जाती है, लेकिन इसके लिए एक कस्टम रेंडरर आवश्यक है।

Three.js/WebGL दुनिया के लिए यह तरीका सीधे लागू नहीं होता। हमें मेश एक्सट्रैक्ट करने होंगे। लेकिन CSG एडिट सूची की अवधारणा undo/redo और नेटवर्क सिंक्रोनाइज़ेशन के लिए अत्यंत उपयोगी है।

Mike Turitzin का डायनेमिक SDF इंजन (2026)

Mike Turitzin द्वारा वर्तमान में विकसित किया जा रहा एक गेम इंजन डायनेमिक SDF को अपने मुख्य निरूपण के रूप में उपयोग करता है। इंजन इनका समर्थन करता है:

गेमप्ले के दौरान विस्तृत संशोधन: पदार्थ को सुचारु रूप से या तीखे किनारों के साथ जोड़ना और हटाना। ऐसे गैर-विनाशकारी बदलाव, जैसे छेदों को खिसकाना या अस्थायी सुरंगें बनाना जो खिलाड़ी के पीछे गायब हो जाती हैं।

स्पार्स कैशिंग के लिए ब्रिक मैप और ब्रिक एटलस। पूरे SDF फ़ील्ड को एक सघन 3D ग्रिड में संग्रहीत करने के बजाय, फ़ील्ड को "ब्रिक्स" (छोटी 3D टाइलों) में विभाजित किया जाता है। केवल सतह की सीमा वाले ब्रिक्स ही आवंटित किए जाते हैं। इससे उन दृश्यों में मेमोरी का उपयोग नाटकीय रूप से घट जाता है जिनका अधिकांश भाग खाली या ठोस होता है।

LOD के लिए जियोमेट्री क्लिपमैप (Losasso & Hoppe, SIGGRAPH 2004)। बढ़ते रिज़ॉल्यूशन वाले नेस्टेड नियमित ग्रिड कैमरे की स्थिति को घेरे रहते हैं। सबसे अंदरूनी ग्रिड का रिज़ॉल्यूशन सबसे अधिक होता है; बाहरी ग्रिड क्रमशः अधिक मोटे होते जाते हैं। इससे विशाल स्थानों के समर्थन के साथ मेमोरी का उपयोग नाटकीय रूप से घटता है। कैमरे के हिलने पर क्लिपमैप क्रमिक रूप से अपडेट होते हैं, जिससे वे ओपन वर्ल्ड स्ट्रीमिंग के लिए कुशल बनते हैं।

भौतिकी और टकराव सीधे SDF के विरुद्ध काम करते हैं। स्फीयर-ट्रेसिंग (जिसमें SDF दूरी को चरण के आकार के रूप में उपयोग करके रे मार्चिंग की जाती है) कुशल रेकास्टिंग प्रदान करती है। टकराव का पता लगाने में SDF ग्रेडिएंट को सतह के नॉर्मल और दूरी के मान को पैठ की गहराई के रूप में उपयोग किया जाता है।

Teardown: बड़े पैमाने पर वॉक्सेल विनाश

Teardown (Voxagon) स्पेक्ट्रम के दूसरे छोर का प्रतिनिधित्व करता है: दुनिया की प्रत्येक वस्तु एक वॉक्सेल वॉल्यूम है, जिसे टुकड़ा-दर-टुकड़ा नष्ट किया जा सकता है।

आर्किटेक्चर

ऑब्जेक्ट्स को नियमित अंतराल वाले वॉक्सेल ग्रिड के रूप में संग्रहीत किया जाता है। इंजन रेंडरिंग के लिए Marching Cubes या SDF का उपयोग नहीं करता। इसके बजाय, यह OpenGL 3.3 पर निर्मित, फ़्रैगमेंट शेडर्स में संशोधित DDA (Digital Differential Analyzer) एल्गोरिदम का उपयोग करके सीधे वॉक्सेल की रे-ट्रेसिंग करता है। रे इंटरसेक्शन के दौरान खाली स्थान से तेज़ी से गुजरने के लिए मिपमैप एक सघन ऑक्ट्री संरचना बनाते हैं।

प्रत्येक ऑब्जेक्ट के लिए, इंजन उसके ओरिएंटेड बाउंडिंग बॉक्स (OBB) को रास्टराइज़ करता है और वॉक्सेल इंटरसेक्शन खोजने के लिए उसमें से एक रे ट्रेस करता है। OBB के केवल बैकफ़ेस रेंडर किए जाते हैं, जिससे कैमरा बाउंडिंग वॉल्यूम के भीतर क्लिप कर सकता है।

विनाश सिंक्रोनाइज़ेशन (मल्टीप्लेयर)

Teardown का मार्च 2026 का मल्टीप्लेयर अपडेट अर्ध-नियतात्मक तरीका अपनाता है। संरचनात्मक विनाश (छेद काटना, स्वामित्व बदलना, जॉइंट्स को फिर से जोड़ना) को एक विश्वसनीय नेटवर्क स्ट्रीम पर फ़िक्स्ड-पॉइंट पूर्णांक गणित के माध्यम से संभाला जाता है। सभी क्लाइंट समान नियतात्मक कमांड निष्पादित करते हैं और दुनिया की समान स्थिति तक पहुँचते हैं। गैर-संरचनात्मक बदलावों (मलबा, कण) के लिए अविश्वसनीय स्टेट सिंक्रोनाइज़ेशन का उपयोग किया जाता है।

यह हमारी मल्टीप्लेयर दुनिया के लिए एक महत्वपूर्ण सीख है: टेरेन एडिट नियतात्मक होने चाहिए। यदि खिलाड़ी A किसी पहाड़ को तराशता है, तो सभी क्लाइंट को समान फ़ील्ड डेटा से वही मेश बनाना चाहिए। एडिट कमांड (ब्रश की स्थिति, त्रिज्या, तीव्रता, ऑपरेशन का प्रकार) आधिकारिक डेटा होने चाहिए, उनसे बनने वाला मेश नहीं।

ALICE-SDF: कम्प्रेशन और CSG ट्री

ALICE-SDF (Adaptive Lightweight Implicit Compression Engine, v1.3.0 मार्च 2026) पॉलीगॉन मेश की तुलना में 10-1000 गुना कम्प्रेशन के साथ SDF-आधारित स्थानिक डेटा का Rust कार्यान्वयन प्रदान करता है। यह इनका समर्थन करता है:

126 बिल्डिंग ब्लॉक: 72 प्रिमिटिव्स, 24 ऑपरेशंस, 7 ट्रांसफ़ॉर्म और 23 मॉडिफ़ायर। स्मूथ ब्लेंडिंग ऑपरेशंस (यूनियन, सब्ट्रैक्शन, इंटरसेक्शन), साथ ही कठोर किनारों वाले बेवेल और सीढ़ीनुमा CSG संक्रमणों के लिए चैम्फ़र और स्टेयर्स ब्लेंड।

undo/redo और नेटवर्क सिंक्रोनाइज़ेशन के लिए CSG ट्री diff/patch। मल्टीप्लेयर स्कल्प्टिंग के लिए यह प्रमुख विशेषता है: पूरे फ़ील्ड की स्थिति भेजने के बजाय, आप दो CSG ट्री के बीच का संरचनात्मक diff भेजते हैं। क्लाइंट नई स्थिति पुनर्निर्मित करने के लिए patch लागू करता है। यह कच्चे वॉक्सेल डेटा को डेल्टा-कम्प्रेस करने की तुलना में कहीं अधिक बैंडविड्थ-कुशल है।

CSG ट्री ऑप्टिमाइज़ेशन, जिसमें आइडेंटिटी ट्रांसफ़ॉर्म हटाना, नेस्टेड ट्रांसफ़ॉर्म मर्ज करना और मॉडिफ़ायर डिमोशन शामिल हैं। इससे एडिट जमा होने पर भी ट्री संक्षिप्त बना रहता है।

Marching Cubes और Dual Contouring, दोनों के माध्यम से मेश जनरेशन। भौतिकी-आधारित टकराव का पता लगाना सीधे SDF के विरुद्ध काम करता है।

WebAssembly समर्थन ब्राउज़र इंटीग्रेशन संभव बनाता है। इंजन WASM बाइंडिंग्स के साथ Rust में लिखा गया है, जिससे यह Three.js एप्लिकेशन के लिए एक व्यावहारिक विकल्प बनता है।

टेरेन के लिए WebGPU कंप्यूट

2025 के अंत तक WebGPU सभी प्रमुख ब्राउज़रों में उपलब्ध हो चुका है। Chrome 113+, Edge 113+, Firefox 141+ और Safari 26+ में यह सक्षम रूप से उपलब्ध है। इससे वे कंप्यूट शेडर पाइपलाइन संभव हो गई हैं जो पहले केवल GPU तक सीमित थीं।

प्रदर्शन

विशाल पैमाने पर समानांतर प्रोसेसिंग के कारण WebGPU कंप्यूट शेडर CPU विधियों की तुलना में लगभग 100 गुना तेज़ी से टेरेन जनरेट करते हैं। GPU एक साथ हज़ारों गणनाएँ निष्पादित करता है और टेरेन जनरेशन लगभग पूरी तरह समानांतर होता है (प्रत्येक वर्टेक्स/वॉक्सेल स्वतंत्र होता है)।

कार्य को तीन स्तरों में व्यवस्थित किया जाता है: Dispatch Level (GPU में वर्कलोड का वितरण), Workgroup Level (एक प्रोसेसिंग यूनिट के भीतर साझा मेमोरी) और Thread Level (व्यक्तिगत गणनाएँ)। WGSL (WebGPU Shading Language) इसकी शेडर भाषा है।

रियल-टाइम टेरेन स्कल्प्टिंग पाइपलाइन

WebGPU स्कल्प्टिंग पाइपलाइन कुछ ऐसी होगी:

  1. ब्रश लागू करना (कंप्यूट शेडर): ब्रश की त्रिज्या के भीतर स्केलर फ़ील्ड के मान अपडेट करें। प्रत्येक थ्रेड एक वॉक्सेल संभालता है। यूनिफ़ॉर्म बफ़र से ब्रश पैरामीटर (स्थिति, त्रिज्या, तीव्रता, फ़ॉलऑफ़ का प्रकार, ऑपरेशन) पढ़कर संशोधन लागू करता है।

  2. मेश एक्सट्रैक्शन (कंप्यूट शेडर): संशोधित क्षेत्र पर Surface Nets या Marching Cubes चलाएँ। Nijhoff का WebGPU SDF Editor इसे बहु-चरणीय पाइपलाइन के रूप में लागू करता है: 16,384 सेल में स्थान का विभाजन, ऑक्ट्री-आधारित सेल स्प्लिटिंग और फिर सतह एक्सट्रैक्शन।

  3. वर्टेक्स बफ़र अपडेट (GPU की ओर): CPU मेमोरी से होकर वापस आने की आवश्यकता के बिना एक्सट्रैक्ट किए गए वर्टेक्स सीधे रेंडर बफ़र में लिखें।

  4. नॉर्मल की गणना (कंप्यूट शेडर): मेश या SDF ग्रेडिएंट से वर्टेक्स नॉर्मल की गणना करें।

  5. रेंडर (मानक पाइपलाइन): मानक PBR मटेरियल के साथ मेश ड्रॉ करें।

चरण 1-4 सभी GPU पर चल सकते हैं और किसी डेटा को JavaScript में वापस आने की आवश्यकता नहीं होती। CPU को हर फ़्रेम केवल ब्रश पैरामीटर भेजने होते हैं।

WebGPU SDF Editor

Reinder Nijhoff का WebGPU SDF Editor (जनवरी 2026) Chrome में चलते हुए इस तरीके को प्रदर्शित करता है। यह छह प्रिमिटिव्स (कोन, सिलिंडर, कैप्सूल, टोरस, बॉक्स, स्फीयर), कॉन्फ़िगर किए जा सकने वाले स्मूथ ब्लेंडिंग के साथ तीन ब्लेंड ऑपरेशंस (यूनियन, सब्ट्रैक्शन, इंटरसेक्शन) और पदानुक्रमित सीन ग्राफ़ का समर्थन करता है। प्रत्येक प्रिमिटिव एकल GPU बफ़र में 112 बाइट घेरता है।

रेंडरिंग पाइपलाइन एम्बिएंट ऑक्लूज़न और टेम्पोरल एंटी-अलियासिंग के लिए 1,024 शैडो मैप का उपयोग करती है। यह उच्च-स्तरीय GPU पर इंटरैक्टिव फ़्रेमरेट से चलता है।

हाइटमैप स्कल्प्टिंग: सरल रास्ता

यदि गुफ़ाओं और ओवरहैंग के समर्थन की आवश्यकता नहीं है, तो हाइटमैप स्कल्प्टिंग पूरी वॉल्यूमेट्रिक पाइपलाइन से बचाती है। अधिकांश जारी किए गए गेम टेरेन एडिटिंग को इसी तरह संभालते हैं।

रनटाइम कार्यान्वयन पैटर्न

Unity Runtime Terrain (JohannHotzel, जनवरी 2026) मानक पैटर्न प्रदर्शित करता है:

  1. टेरेन पर हिट बिंदु खोजने के लिए कैमरे से माउस की स्थिति के आर-पार रेकास्ट करें।
  2. हिट बिंदु को हाइटमैप निर्देशांकों पर मैप करें।
  3. फ़ॉलऑफ़ के अनुसार भारित करके पास के हाइटमैप मानों पर ब्रश लागू करें
  4. संशोधित हाइटमैप से वर्टेक्स की Y स्थिति सेट करके मेश अपडेट करें
  5. नए मेश से मिलान करने के लिए फ़िज़िक्स कोलाइडर फिर से बनाएँ

हमारे Three.js टेरेन के लिए चरण 1-4 सीधे मौजूदा आर्किटेक्चर पर लागू होते हैं। Chunk क्लास पहले से हाइटमैप संग्रहीत करती है और उनसे मेश बनाती है। स्कल्प्टिंग जोड़ने का अर्थ होगा:

  • चंक मेश के विरुद्ध रेकास्टिंग सिस्टम (Three.js Raycaster)
  • chunk.heightmap मानों को संशोधित करने वाले ब्रश एप्लिकेशन फ़ंक्शन
  • मेश वर्टेक्स अपडेट (Y स्थिति सेट करना, नॉर्मल की दोबारा गणना करना)
  • प्रभावित क्षेत्र के लिए स्प्लैट मैप की दोबारा गणना (ताकि टेक्सचर ब्लेंडिंग नई ढलान/ऊँचाई को दर्शाए)
  • मौजूदा WebSocket प्रोटोकॉल के माध्यम से अन्य क्लाइंट को एडिट (ब्रश की स्थिति, त्रिज्या, तीव्रता, ऑपरेशन) का नेटवर्क प्रसारण

क्लिपमैप तरीका

Landow.dev हाइटमैप टेरेन के लिए एक "wandering clipmap" का वर्णन करता है: परिवर्तनीय सबडिवीज़न घनत्व वाला एकल मेश जो खिलाड़ी का अनुसरण करता है। हाइटमैप को अलग-अलग LOD स्तर वाले पृथक मेश चंक में बाँटने के बजाय (जैसा हम अभी करते हैं), क्लिपमैप एक सतत मेश होता है जो कैमरे के पास सघन और किनारों पर मोटा होता है।

इससे LOD स्टिचिंग पूरी तरह समाप्त हो जाती है। जहाँ अधिक त्रिभुजों की आवश्यकता होती है, वहाँ मेश में अधिक त्रिभुज होते हैं और जहाँ उनकी आवश्यकता नहीं होती, वहाँ कम। इसकी कीमत यह है कि स्कल्प्टिंग के लिए अलग-अलग चंक के बजाय एक बड़े मेश को अपडेट करना पड़ता है, जो बड़े एडिट के लिए महँगा हो सकता है।

गैर-विनाशकारी SDF हाइटमैप

Landow.dev एक ऐसी तकनीक का भी वर्णन करता है जिसमें हाइटमैप स्वयं SDF कंपोज़िशन से जनरेट होता है। आकार इंस्टेंस (स्फीयर, बॉक्स, नॉइज़ फ़ंक्शन) को CSG ऑपरेशंस का उपयोग करके कंप्यूट शेडर में संयोजित किया जाता है और आउटपुट को हाइटमैप के रूप में सैंपल किया जाता है। यह हाइटमैप रेंडरिंग की सरलता बनाए रखते हुए गैर-विनाशकारी एडिटिंग देता है (आप किसी भी आकार इंस्टेंस को किसी भी समय खिसका या हटा सकते हैं)।

यह एक आकर्षक हाइब्रिड है: डेटा निरूपण वॉल्यूमेट्रिक (SDF CSG ट्री) होता है, लेकिन रेंडरिंग पथ एक मानक हाइटमैप मेश है। SDF पक्ष से आपको undo/redo और नेटवर्क-अनुकूल एडिट ऑपरेशंस मिलते हैं, जबकि हाइटमैप पक्ष से सरल रेंडरिंग और भौतिकी मिलती है। सीमा वही रहती है: गुफ़ाएँ या ओवरहैंग संभव नहीं हैं।

बड़ी दुनियाओं के लिए स्पार्स वॉक्सेल ऑक्ट्री

सघन 3D ग्रिड बड़े पैमाने पर कारगर नहीं होते। हर दिशा में 1 किमी लंबी दुनिया को 0.5 मीटर रिज़ॉल्यूशन पर 8 अरब वॉक्सेल की आवश्यकता होगी। स्पार्स वॉक्सेल ऑक्ट्री (SVO) स्थान को पुनरावर्ती रूप से विभाजित करके और केवल सतह की सीमा वाले ऑक्टेंट के लिए स्टोरेज आवंटित करके इस समस्या को हल करती हैं।

SVO स्वाभाविक रूप से पदानुक्रमित LOD प्रदान करता है: किसी भी बिंदु पर ट्री की गहराई प्रभावी रिज़ॉल्यूशन निर्धारित करती है। खिलाड़ी के पास ट्री पूरी तरह विस्तृत होता है (अधिकतम विवरण)। दूर के क्षेत्रों में इसे अधिक मोटे स्तर पर सीमित कर दिया जाता है।

रेंडरिंग के लिए SVO की सीधे रे-ट्रेसिंग की जा सकती है (मेश एक्सट्रैक्शन की आवश्यकता नहीं होती)। GPU रे मार्चर प्रत्येक ट्री स्तर पर अक्ष-संरेखित बॉक्स के साथ रे का इंटरसेक्शन करता है और खाली सबट्री को पूरी तरह छोड़ देता है। इससे चंक-आधारित रेंडरिंग की ओवरड्रॉ समस्याएँ समाप्त होती हैं और ग्रीडी मेशिंग की विकृतियों से बचा जाता है।

AdamYuan का Vulkan-आधारित SVO बिल्डर उल्लेखनीय प्रदर्शन दिखाता है: GTX 1660 Ti पर 2^10 रिज़ॉल्यूशन में Crytek Sponza के लिए 19ms का बिल्ड समय।

स्कल्प्टिंग के लिए SVO संशोधन कुशल है: केवल ब्रश की त्रिज्या के भीतर मौजूद लीफ़ नोड अपडेट करने होते हैं और ट्री संरचना अलग-अलग रिज़ॉल्यूशन को स्वाभाविक रूप से संभालती है। जहाँ खिलाड़ी तराशता है वहाँ अधिक विवरण जोड़ना (नोड को उच्च रिज़ॉल्यूशन में विभाजित करना) और जहाँ वह स्मूथ करता है वहाँ विवरण हटाना (नोड को निम्न रिज़ॉल्यूशन में मर्ज करना) इस डेटा संरचना में सहज रूप से हो जाता है।

ब्राउज़र पर डिप्लॉयमेंट की चुनौती यह है कि WebGL कंप्यूट शेडर का समर्थन नहीं करता। WebGPU उनका समर्थन करता है, लेकिन SVO निर्माण और ट्रैवर्सल एल्गोरिदम को WGSL में लागू करना जटिल है।

मल्टीप्लेयर स्कल्प्टिंग के लिए नेटवर्क सिंक्रोनाइज़ेशन

हमारी दुनिया में Cloudflare Durable Objects (world-chunk-do.ts) के माध्यम से पहले से मल्टीप्लेयर है। स्कल्प्टिंग जोड़ने का अर्थ है सभी कनेक्टेड क्लाइंट के बीच टेरेन संशोधनों को सिंक्रोनाइज़ करना।

डेल्टा कम्प्रेशन

कच्चा वॉक्सेल डेटा भेजना महँगा है। Oulu University के 2024 के एक अध्ययन ने डेल्टा-एन्कोडिंग को DEFLATE कम्प्रेशन के साथ संयोजित करके पेलोड में 2-8 गुना सुधार प्राप्त किया और वॉक्सेल अपडेट को प्रति वॉक्सेल एक बाइट से कम में पैक किया। SDEC कोडेक बिट-पैक्ड डेल्टा एन्कोडिंग का प्रदर्शन करता है, जो सामान्य सीरियलाइज़ेशन के 1114 बाइट की तुलना में औसतन 259-बाइट के पैकेट बनाता है।

ऑपरेशन-आधारित सिंक (अनुशंसित)

फ़ील्ड की स्थिति सिंक्रोनाइज़ करने के बजाय ऑपरेशंस को सिंक्रोनाइज़ करें। प्रत्येक स्कल्प्टिंग क्रिया एक संदेश बन जाती है:

typescript
interface TerrainEditMsg {
  t: MsgType.TerrainEdit
  brush: {
    position: [number, number, number]
    radius: number
    strength: number
    falloff: 'smooth' | 'linear' | 'sharp' | 'constant'
    operation: 'raise' | 'lower' | 'smooth' | 'flatten' | 'noise'
    targetHeight?: number
  }
}

सर्वर इसे सभी क्लाइंट को प्रसारित करता है और प्रत्येक क्लाइंट अपने स्थानीय टेरेन डेटा पर समान नियतात्मक ब्रश ऑपरेशन लागू करता है। संरचनात्मक विनाश के लिए Teardown भी यही तरीका उपयोग करता है: विश्वसनीय स्ट्रीम पर नियतात्मक कमांड।

ALICE-SDF का CSG ट्री diff/patch इसे और आगे ले जाता है: अलग-अलग ब्रश स्ट्रोक के बजाय diff पूरे CSG ट्री में हुए संरचनात्मक बदलाव को दर्शाता है। इससे नेटवर्क पर कुशल undo/redo संभव होता है (उलटा patch भेजें) और बाद में शामिल होने वाले क्लाइंट ऑपरेशन लॉग को दोबारा चलाकर दुनिया की पूरी स्थिति पुनर्निर्मित कर सकते हैं।

प्राथमिकता और थ्रॉटलिंग

कनेक्टेड खिलाड़ियों के पास होने वाले टेरेन एडिट को उच्च प्राथमिकता मिलनी चाहिए (तत्काल प्रसारण)। किसी भी खिलाड़ी से दूर होने वाले एडिट को बैच करके कम आवृत्ति पर भेजा जा सकता है। Enshrouded की वॉक्सेल नेटवर्किंग इस पैटर्न का उपयोग करती है: खिलाड़ी के पास के टेरेन के लिए 60Hz अपडेट और पृष्ठभूमि क्षेत्रों के लिए 10Hz।

वायर पर ZSTD कम्प्रेशन टेरेन अपडेट संदेशों के पैकेट आकार को 60% तक घटाता है।

सहयोगात्मक स्कल्प्टिंग: समवर्ती एडिट

जब कई खिलाड़ी एक ही क्षेत्र को एक साथ तराशते हैं, तो आपको टकराव समाधान की आवश्यकता होती है। cSculpt (CNR Visual Computing Lab, 2016) ने इसे बहु-रिज़ॉल्यूशन मर्ज एल्गोरिदम से हल किया। प्रत्येक एडिट को कई पैमानों पर निरूपित किया जाता है और एक-दूसरे पर चढ़ने वाले समवर्ती एडिट को उनके बहु-रिज़ॉल्यूशन निरूपणों को ब्लेंड करके मर्ज किया जाता है। हमारे उद्देश्यों के लिए, एक सरल तरीका पर्याप्त है: सर्वर क्रम के साथ लास्ट-राइट-विन्स। Durable Object हर संपादन को टाइमस्टैम्प देता है और उन्हें क्रम से ब्रॉडकास्ट करता है। सभी क्लाइंट संपादनों को एक ही क्रम में लागू करते हैं। चूँकि ब्रश स्ट्रोक छोटे, स्थानीय और जोड़ने/घटाने वाले होते हैं, इसलिए समकालिक संपादनों के क्रम में मामूली बदलाव से मिलने वाला दृश्य परिणाम आम तौर पर "सही" क्रम से अलग नहीं दिखता।

INST-Sculpt: न्यूरल SDF संपादन (अनुसंधान की अग्रिम सीमा)

INST-Sculpt (arxiv 2502.02891, फ़रवरी 2025) न्यूरल SDF के स्ट्रोक-आधारित संपादन को संभव बनाता है। उपयोगकर्ता सतह पर स्ट्रोक बनाते हैं और सिस्टम स्ट्रोक पथ के आसपास के नलिकाकार क्षेत्रों में अंतर्निहित न्यूरल फ़ील्ड को विकृत करता है। कस्टम ब्रश प्रोफ़ाइल (कॉन्फ़िगर करने योग्य क्रॉस-सेक्शन) विकृति के आकार को नियंत्रित करती हैं।

यह AI-जनित टेरेन के लिए दिलचस्प है: यदि आधार वर्ल्ड को न्यूरल SDF के रूप में प्रस्तुत किया जाता है (एक छोटा न्यूरल नेटवर्क जो 3D निर्देशांकों को साइन्ड डिस्टेंस में मैप करता है), तो स्कल्प्टिंग स्पष्ट वॉक्सेल डेटा के बजाय नेटवर्क वेट्स को संशोधित करती है। यह प्रस्तुतीकरण बेहद कॉम्पैक्ट है (पूरे वर्ल्ड के लिए कुछ MB), लेकिन इसका मूल्यांकन लुकअप टेबल की तुलना में अधिक महँगा है।

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

World Creator 2026.3: व्यावसायिक टेरेन तकनीक की वर्तमान सर्वोच्च स्थिति

World Creator (BiteTheBytes, मार्च 2026) टेरेन ऑथरिंग टूल्स की व्यावसायिक अत्याधुनिक स्थिति को दर्शाता है। संस्करण 2026.3 ने स्वचालित टेरेन अनुकूलन के साथ GPU-आधारित टेरेन जनरेशन (टेरेन रखी गई ऑब्जेक्ट्स के अनुरूप ढलता है), LOD ऑप्टिमाइज़ेशन के लिए कैमरा-केंद्रित ऑब्जेक्ट वितरण और वास्तविक दुनिया का एलिवेशन डेटा इम्पोर्ट (GeoTIFF, HGT, DTED) जोड़ा।

इसके बाद, World Creator 2026.4 (28 अप्रैल, 2026) ने संख्यात्मक फ़ील्ड्स में गणितीय एक्सप्रेशन, प्रमुख ऑब्जेक्ट्स को सतह में ठीक से बैठाने के लिए टेरेन नॉर्मल ब्लेंडिंग, पूर्ण डीकैल समर्थन और उपलब्ध GPU मेमोरी के अनुसार अधिकतम ऑब्जेक्ट संख्या समायोजित करने वाली VRAM स्केलिंग जोड़ी। BiteTheBytes ने एक निःशुल्क Community Edition भी जारी किया, जिसमें सभी फ़ीचर्स उपलब्ध हैं लेकिन एक्सपोर्ट अक्षम है, इसलिए यह प्रभावी रूप से असीमित ट्रायल है।

उनका तरीका सभी टेरेन ऑपरेशंस के लिए GPU कंप्यूट का उपयोग करता है: इरोजन सिमुलेशन, नदी तराशना और टेक्सचर पेंटिंग। ब्रश टूल्स GPU-त्वरित हैं और रियल-टाइम व्यूपोर्ट फ़ीडबैक देते हैं। यह ऊपर वर्णित WebGPU कंप्यूट पाइपलाइन से मेल खाता है, जो डेस्कटॉप GPUs पर चलती है।

हमने पहले से क्या बनाया है: 24 स्पाइक्स और एक प्रोडक्शन वर्ल्ड

world/spikes/ डायरेक्टरी में 24 स्व-निहित प्रोटोटाइप हैं। ये साधारण खिलौना डेमो नहीं हैं। ये एक क्रमिक R&D पाइपलाइन हैं, जिसमें हर स्पाइक ने एक विशिष्ट समस्या हल की, उसे लक्ष्य के विरुद्ध बेंचमार्क किया और अगले स्पाइक को दिशा दी। स्कल्प्टिंग सिस्टम केवल बाद के वॉल्यूमेट्रिक स्पाइक्स पर नहीं, बल्कि इन सभी पर आधारित है।

प्रोडक्शन हाइटमैप टेरेन (world/client/)

लाइव वर्ल्ड Three.js WebGL में चंक-आधारित हाइटमैप सिस्टम का उपयोग करता है:

  • noise.ts नियतात्मक terrainHeight(wx, wz) फ़ंक्शन के साथ FBM वैल्यू नॉइज़ के माध्यम से टेरेन की ऊँचाई जनरेट करता है (पहाड़ियों के लिए 5 ऑक्टेव, रिज के लिए 4 और सूक्ष्म विवरण के लिए 3)
  • chunk.ts, Float32Array हाइटमैप्स से 3 LOD स्तरों (प्रति 64-यूनिट चंक 32/8/4 सेगमेंट) वाले PlaneGeometry मेश बनाता है और सीडेड रैंडम प्लेसमेंट तथा प्रति-ऑब्जेक्ट कोलाइडर्स के साथ इंस्टैंस्ड पेड़/बिलबोर्ड रखता है
  • chunk-manager.ts खिलाड़ी के चारों ओर छल्लों में चंक्स स्ट्रीम करता है (LOD0 पर त्रिज्या 1, LOD1 पर त्रिज्या 3 और LOD2 पर त्रिज्या 6), stitchEdge() में लीनियर इंटरपोलेशन के माध्यम से किनारों को जोड़ता है और फ़िज़िक्स लेयर के लिए getHeight(), getNormal() तथा resolveCollisions() उपलब्ध कराता है
  • terrain-material.ts, ढलान और ऊँचाई-आधारित वेट्स के साथ MeshStandardMaterial.onBeforeCompile के माध्यम से 4-लेयर स्प्लैट-आधारित टेक्सचर ब्लेंडिंग (घास/चट्टान/रेत/मिट्टी), साथ ही प्रति-लेयर नॉर्मल मैप ब्लेंडिंग करता है
  • character-controller.ts गुरुत्वाकर्षण, ज़मीन से संपर्क और ढलान अस्वीकृति (अधिकतम ढलान cos 50 डिग्री) के लिए हर फ़्रेम टेरेन की ऊँचाई सैंपल करता है। स्कल्प्टिंग को संशोधित ऊँचाइयाँ तुरंत इस सिस्टम में देनी होंगी, अन्यथा खिलाड़ी संपादित टेरेन के आर-पार गिर जाएगा
  • placement.ts में ऑब्जेक्ट प्लेसमेंट टूल के लिए पहले से चंक मेश पर हिट करने वाला Raycaster मौजूद है। ब्रश टूल को शुरुआत से रेकास्टिंग बनाने के बजाय ठीक इसी पैटर्न का पालन करना चाहिए
  • protocol.ts, world-chunk-do.ts Durable Object के माध्यम से मल्टीप्लेयर सिंक के लिए MessagePack-एन्कोडेड संदेश परिभाषित करता है, जो अभी PlayerState, PlaceObject, RemoveObject और Snapshot संदेश संभालता है। टेरेन संपादनों के लिए एक नए संदेश प्रकार की आवश्यकता होगी
  • world-chunk-do.ts (Cloudflare Worker) रखी गई ऑब्जेक्ट्स को Durable Object स्टोरेज में स्थायी रूप से सहेजता है और 50ms के अंतराल पर जुड़े खिलाड़ियों को ब्रॉडकास्ट करता है। इसमें अभी टेरेन संशोधनों की कोई अवधारणा नहीं है

स्पाइक्स 01-11: आधारभूत लेयर

इन स्पाइक्स ने उन मुख्य सिस्टम्स को सत्यापित किया जिन पर स्कल्प्टिंग निर्भर करेगी। इन्हें छोड़ने का अर्थ उन बाधाओं को नज़रअंदाज़ करना है जिनका स्कल्प्टिंग सिस्टम को पालन करना होगा।

स्पाइक 01 (टेरेन + इंस्टैंसिंग): Three.js में पहला टेरेन प्रोटोटाइप। इसने वह PlaneGeometry + हाइटमैप पैटर्न और इंस्टैंस्ड ऑब्जेक्ट प्लेसमेंट स्थापित किया जिसका उपयोग chunk.ts आज भी करता है।

स्पाइक 02 (Rapier फ़िज़िक्स वर्कर): ColliderDesc.heightfield() कोलाइडर के साथ Web Worker में चलने वाला Rapier 3D। ऑटोस्टेप, ढलान सीमाओं और स्नैप-टू-ग्राउंड के साथ एक काइनेमैटिक कैरेक्टर कंट्रोलर बनाया। इस स्पाइक ने सिद्ध किया कि फ़िज़िक्स हाइटफ़ील्ड के विरुद्ध मुख्य थ्रेड से अलग चल सकती है। यदि हम टेरेन को स्कल्प्ट करते हैं, तो फ़िज़िक्स हाइटफ़ील्ड को दोबारा बनाना होगा या MC चंक्स के लिए ट्राइमेश कोलाइडर से बदलना होगा।

स्पाइक 05 (LLM व्यवहार): इसका टेरेन से सीधा संबंध नहीं है, लेकिन इसने गेम ऑब्जेक्ट्स के लिए JSON व्यवहार स्कीमा स्थापित किया। यह इसलिए प्रासंगिक है क्योंकि स्कल्प्ट की गई टेरेन विशेषताएँ व्यवहार ट्रिगर कर सकती हैं (उदाहरण के लिए, तराशी गई नदी जल प्रभाव उत्पन्न करती है)।

स्पाइक 06 (चंक स्ट्रीमिंग): खिलाड़ी के चलते समय डायनेमिक लोडिंग के साथ पहला चंक लोड/स्वैप सिस्टम। इसने वह पैटर्न स्थापित किया जिसका उपयोग chunk-manager.ts करता है: रंगीन क्षेत्र जो लोड और अनलोड होते हैं। चंक्स के अनलोड और दोबारा लोड होने पर स्कल्प्टिंग को संपादन स्थिति सुरक्षित रखनी होगी।

स्पाइक 07 (डेंसिटी मैप्स से GPU वनस्पति): टेरेन की ऊँचाई और ढलान सैंपल करने वाले डेंसिटी मैप्स के माध्यम से रखी गई इंस्टैंस्ड घास और पेड़। स्कल्प्टिंग वनस्पति प्लेसमेंट को अमान्य कर देती है: यदि टेरेन की ऊँचाई बदलती है, तो पेड़ हवा में तैरते या ज़मीन में दबे रह सकते हैं। संपादित चंक्स के लिए डेंसिटी मैप को दोबारा जनरेट करना होगा।

स्पाइक 08 (टेरेन मटेरियल शेडर लागत): ट्राइप्लेनर प्रोजेक्शन, नॉर्मल मैप्स और 4-लेयर ब्लेंडिंग को बेंचमार्क किया। हर फ़ीचर की सटीक ms लागत मापी। पाया कि ट्राइप्लेनर + नॉर्मल्स + 4 लेयर्स 45+ FPS पर बजट के भीतर रहते हैं। यह बजट स्कल्प्ट किए गए टेरेन के लिए महत्वपूर्ण है: यदि हम "संपादित मिट्टी" के लिए पाँचवीं लेयर जोड़ते हैं या तराशी गई सतहों की ब्लेंडिंग बदलते हैं, तो हमें ठीक-ठीक पता है कि कितनी अतिरिक्त क्षमता उपलब्ध है।

स्पाइक 09 (CSM शैडो बजट): 1024^2 रिज़ॉल्यूशन पर 3 कैस्केड वाले कैस्केडेड शैडो मैप्स। शैडो लागत लगभग 1.5ms मापी गई। स्कल्प्ट किया गया टेरेन शैडो मैप्स बदलता है, लेकिन टेरेन के आकार से स्वतंत्र रूप से लागत स्थिर रहती है।

स्पाइक 10 (ज्योमेट्री क्लिपमैप्स + जियोमॉर्फ़िंग): LOD स्तरों के बीच जियोमॉर्फ़िंग वाले नेस्टेड क्लिपमैप रिंग्स, जो अचानक दृश्य बदलाव समाप्त करते हैं। स्थिर ट्रायंगल संख्या का अर्थ है अनुमानित GPU लागत। जियोमॉर्फ़िंग स्कल्प्टिंग के लिए महत्वपूर्ण है: जब खिलाड़ी LOD सीमा के पास स्कल्प्ट करता है, तो LOD स्तरों के बीच मॉर्फ़ में संपादन दिखाई देना चाहिए। यदि संपादन केवल हाई-रेज़ रिंग में मौजूद है, तो जियोमॉर्फ़ लक्ष्य गलत होगा।

स्पाइक 11 (हाइटमैप चंक स्ट्रीमिंग): अधिक उन्नत चंक स्ट्रीमिंग, जिसमें हर LOD स्तर पर लोडेड/लोडिंग/अनलोडेड स्थितियाँ दिखाने वाला विज़ुअल ग्रिड है। इसने स्ट्रीमिंग बजट स्थापित किया: प्रति फ़्रेम लोड किए जाने वाले अधिकतम चंक्स और LOD अपग्रेड की आवश्यकता वाले चंक्स की प्राथमिकता। स्कल्प्टिंग एक नया प्राथमिकता संकेत जोड़ती है: जिन चंक्स को खिलाड़ी सक्रिय रूप से संपादित कर रहा है, उन्हें कभी अनलोड नहीं किया जाना चाहिए।

स्पाइक्स 12-14: WebGPU + Three.js एकीकरण

स्पाइक 12 (WebGPU Marching Cubes): पहला वॉल्यूमेट्रिक स्पाइक। एनिमेटेड गोलाकार गुफाओं वाले चार 64^3 SDF चंक्स, जो पूरी तरह GPU पर चलते हैं। रॉ WebGPU का उपयोग करता है: SDF मूल्यांकन के लिए कंप्यूट पाइपलाइंस, Twinklebear केस टेबल (256 कॉन्फ़िगरेशन, प्रत्येक में 16 प्रविष्टियाँ) के साथ MC एक्सट्रैक्शन, एटॉमिक वर्टेक्स काउंटर और इनडायरेक्ट ड्रॉ। प्रदर्शन लक्ष्य प्रति चंक <4ms और सभी 4 के लिए <12ms था। इससे सत्यापित हुआ कि GPU MC ब्राउज़र में रियल-टाइम री-मेशिंग के लिए पर्याप्त तेज़ है। इसके बाद का हर वॉल्यूमेट्रिक स्पाइक यहाँ परिभाषित MC केस टेबल और WGSL शेडर्स का पुनः उपयोग करता है।

स्पाइक 13 (स्पाइक 12 से बेसलाइन रीसेट): Spike 12 के रॉ WebGPU ड्रॉ पाथ को Three.js के WebGPURenderer के भीतर चलने के लिए पोर्ट किया, जिसमें बैकएंड के device को सीधे एक्सेस किया गया। रेंडर पाइपलाइन अभी भी रॉ WebGPU (drawIndirect with struct Vertex vec4+vec4) का उपयोग करती है। इससे सिद्ध हुआ कि कस्टम कंप्यूट और Three.js सीन रेंडरिंग एक ही GPU डिवाइस पर साथ-साथ चल सकते हैं।

स्पाइक 14 (Three.js WebGPU क्रमिक सुदृढ़ीकरण): रॉ रेंडर पाइपलाइन को पोज़िशन और नॉर्मल्स के लिए Three.js StorageBufferAttribute से बदला। MC कंप्यूट सीधे इन GPU-निवासी बफ़र्स में लिखता है। drawIndirect बफ़र यह नियंत्रित करता है कि Three.js कितने वर्टिसेज़ ड्रॉ करे। यही पैटर्न बाद के सभी स्पाइक्स उपयोग करते हैं: कंप्यूट रॉ WebGPU के रूप में रहता है, जबकि रेंडरिंग Three.js सीन ग्राफ़ के माध्यम से होती है। जैसे-जैसे WebGPU बैकएंड स्थिर हुआ, इन स्पाइक्स में Three.js संस्करण 0.170.0 से बढ़कर 0.172.0 हो गया।

स्पाइक्स 15-17: Transvoxel LOD सिलाई

स्पाइक 15 (Transvoxel सीम स्कैफ़ोल्ड): तीन-ज़ोन आर्किटेक्चर जोड़ा: MC चंक (वॉल्यूमेट्रिक केंद्र), ट्रांज़िशन स्ट्रिप (MC सीमा और हाइटमैप के बीच सीम) और टेरेन रिंग (आसपास का हाइटमैप)। तीनों एक मटेरियल पास साझा करते हैं। इस चरण पर ट्रांज़िशन स्ट्रिप एक प्लेसहोल्डर मेश है, वास्तविक Transvoxel सेल्स नहीं।

स्पाइक 16 (साझा हाइटमैप वाला Transvoxel +X फ़ेस): एक ही स्पाइक में दो महत्वपूर्ण सफलताएँ। पहली, SDF के फ़्लैट टेरेन प्लेन को साझा Perlin हाइटमैप से बदला: GPU पर स्टोरेज बफ़र के रूप में अपलोड किया गया 257x257 Float32Array, जिसे SDF कंप्यूट शेडर में बिलीनियर इंटरपोलेशन के माध्यम से सैंपल किया जाता है। अब MC सतह और हाइटमैप मेश एक ही मूल डेटा पर सहमत हैं। दूसरी, GitHub से Eric Lengyel की संदर्भ डेटा टेबल्स (transitionCellClass, transitionVertexData, transitionCellData) और npm transvoxel-data पैकेज प्राप्त करके +X फ़ेस के लिए वास्तविक Transvoxel ट्रांज़िशन सेल्स लागू किए। CPU 9-सैंपल ट्रांज़िशन सेल्स (512 कॉन्फ़िगरेशन, 73 समतुल्यता वर्ग) का मूल्यांकन करता है, ग्रिड पॉइंट्स पर SDF मानों को इंटरपोलेट करके वर्टिसेज़ रखता है और मिरर किए गए मामलों के लिए वाइंडिंग इनवर्ज़न संभालता है।

स्पाइक 17 (डुअल MC 1x/2x LOD): अलग-अलग रिज़ॉल्यूशन वाले दो MC चंक्स साथ-साथ। हाई-रेज़: cell_scale=1.0 वाले 62 सेल्स। लो-रेज़: cell_scale=2.0 वाले 31 सेल्स। MC शेडर में cell_scale और grid_points यूनिफ़ॉर्म जोड़े गए। transition_shrink पेश किया गया: लो-रेज़ चंक के face-0 सीमा वर्टिसेज़ को cell_scale के 15% तक अंदर खींचा जाता है, जिससे एक पतला अंतर बनता है जिसे Transvoxel ट्रांज़िशन सेल्स z-fighting के बिना भरते हैं। प्रोडक्शन सिस्टम को इसी LOD मॉडल की आवश्यकता है: पास के चंक्स पूर्ण रिज़ॉल्यूशन पर, दूर के चंक्स आधे रिज़ॉल्यूशन पर और हर सीमा पर Transvoxel।

स्पाइक्स 18-21: Transvoxel के विशेष मामले और GPU त्वरण

इन चार स्पाइक्स में से प्रत्येक ने Transvoxel कार्यान्वयन की एक विशिष्ट विफलता हल की। उन्हें एक साथ समूहीकृत करने से अलग-अलग समस्याएँ अस्पष्ट हो जाती हैं।

स्पाइक 18 (हाइटमैप 2:1 सीम): Transvoxel को एक शुद्ध हाइटमैप सीमा पर लागू किया, जहाँ एक ओर का रिज़ॉल्यूशन दूसरी ओर से दोगुना है। इसमें MC शामिल नहीं है। 62-सेल और 31-सेल हाइटमैप चंक के बीच की सीम, 15% लो-फ़ेस श्रिंक के साथ Transvoxel ट्रांज़िशन टेबल्स से जनरेट होती है। इससे सत्यापित हुआ कि Transvoxel केवल MC ही नहीं, बल्कि हाइटमैप-मात्र मामले में भी काम करता है।

स्पाइक 19 (64/32/32/16 कॉर्नर ग्रिड): सिलाई का सबसे कठिन मामला: अलग-अलग रिज़ॉल्यूशन वाले चार चंक्स एक कोने के बिंदु पर मिलते हैं (64, 32, 32 और 16 सेल्स)। सीम सिस्टम को चार किनारों (A-B, A-C, B-D, C-D) पर प्रत्येक दिशा के लिए सही वाइंडिंग के साथ ट्रांज़िशन सेल्स जनरेट करने होंगे। इस स्पाइक ने सिद्ध किया कि Transvoxel टेबल्स कस्टम-केस लॉजिक के बिना बहु-रिज़ॉल्यूशन कोने को संभालती हैं।

स्पाइक 20 (GPU Transvoxel कॉर्नर): 64/32/32/16 कॉर्नर लेआउट के लिए Transvoxel ट्रांज़िशन सेल जनरेशन को GPU पर स्थानांतरित किया। एनिमेटेड टेरेन के लिए हर फ़्रेम ट्रांज़िशन सेल्स दोबारा जनरेट करते समय CPU एक बाधा बन रहा था। GPU कंप्यूट, MC एक्सट्रैक्शन वाले ही पास में सीम वर्टिसेज़ जनरेट करता है।

स्पाइक 21 (GPU MC + Transvoxel कॉर्नर): एकल कंप्यूट डिस्पैच क्रम में पूर्ण GPU MC एक्सट्रैक्शन को GPU Transvoxel सीम जनरेशन के साथ संयोजित किया। MC चंक्स और सभी चार सीम GPU पर जनरेट होते हैं, वर्टेक्स काउंट्स को एटॉमिक काउंटर्स के माध्यम से प्रबंधित किया जाता है और drawIndirect से ड्रॉ किया जाता है। यह निर्बाध LOD ट्रांज़िशन वाले बहु-रिज़ॉल्यूशन वॉल्यूमेट्रिक टेरेन के लिए पूर्ण GPU पाइपलाइन है।

स्पाइक्स 22-24: हाइब्रिड आर्किटेक्चर

स्पाइक 22 (हाइब्रिड MC/हाइटमैप नीति): मुख्य आर्किटेक्चर स्पाइक। डिफ़ॉल्ट रूप से चंक्स हाइटमैप होते हैं। जब एनिमेटेड विकृति गोला किसी चंक के AABB को काटता है, तो वह चंक MC मोड पर स्विच हो जाता है। बाकी स्थिर हाइटमैप मेश के रूप में रहते हैं। लेआउट: अलग-अलग रिज़ॉल्यूशन पर 64, 32/32 और 16-सेल चंक्स। Transvoxel सीम हर सीमा को संभालती हैं, जिसमें MC-से-हाइटमैप ट्रांज़िशन भी शामिल हैं। स्पाइक प्रति फ़्रेम MC चंक संख्या बनाम HM चंक संख्या और वर्टेक्स ओवरफ़्लो ट्रैक करता है।

स्पाइक 23 (नीति-संचालित चंक मोड्स): Spike 22 के ऊपर पैच के रूप में लोड किया गया। कैमरा-दूरी हिस्टैरिसिस जोड़ा (कैमरा किसी थ्रेशोल्ड के पास होने पर चंक्स मोड्स के बीच झिलमिलाते नहीं हैं) और एक एडिट मास्क जोड़ा (विकृत किए गए चंक्स MC मोड में बने रहते हैं, भले ही विकृति स्रोत दूर चला जाए)। स्कल्प्टिंग को इसी "स्थायी संपादन" व्यवहार की आवश्यकता है: एक बार खिलाड़ी गुफा तराश देता है, तो वह चंक हमेशा वॉल्यूमेट्रिक रहता है।

स्पाइक 24 (नीति + क्लिपमैप रिंग्स): सबसे उन्नत स्पाइक। Spike 23 के निकट-क्षेत्र नीति सिस्टम को Spike 10 के दूर-क्षेत्र ज्योमेट्री क्लिपमैप रिंग्स के साथ संयोजित करता है। Three.js 0.183.1 पर अपग्रेड किया गया। निकट-क्षेत्र 64/32/16 रिज़ॉल्यूशन पर Transvoxel सीम के साथ HM/MC हाइब्रिड का उपयोग करता है। दूर-क्षेत्र कैमरे का अनुसरण करने वाले स्थिर-केंद्र क्लिपमैप रिंग्स का उपयोग करता है। यह पूर्ण टेरेन रेंडरिंग आर्किटेक्चर है: जहाँ आवश्यक हो वहाँ चंक-आधारित वॉल्यूमेट्रिक स्कल्प्टिंग, और बाकी हर जगह कम लागत वाला क्लिपमैप टेरेन।

Surface Nets के बजाय Marching Cubes क्यों

इस गाइड का बाहरी शोध अनुभाग ब्राउज़र में भूभाग को आकार देने के लिए Surface Nets को सबसे मजबूत विकल्प बताता है। लेकिन पाइपलाइन का हर स्पाइक Marching Cubes का उपयोग करता है। यह संयोग नहीं है।

MC का प्रमुख लाभ इसकी अत्यधिक समानांतरता है: प्रत्येक क्यूब पूरी तरह स्वतंत्र होता है। Spikes 12-24 के WGSL कंप्यूट शेडर बिना किसी इंटर-सेल संचार के प्रत्येक क्यूब के लिए एक थ्रेड डिस्पैच करते हैं। एटॉमिक काउंटर वर्टेक्स आवंटन संभालते हैं। यह GPU वर्कग्रुप के लिए बिल्कुल उपयुक्त है।

Surface Nets प्रत्येक सतह-युक्त सेल में एक वर्टेक्स रखता है, फिर पड़ोसी सेल को जोड़ता है। पड़ोसियों की यह कनेक्टिविटी एक इंटर-सेल निर्भरता है। fast-surface-nets क्रेट सावधानीपूर्ण पुनरावृत्ति क्रम के साथ इसे CPU पर संभालता है। GPU पर इसके लिए या तो दो-पास दृष्टिकोण (पहले वर्टेक्स ढूँढना, फिर उन्हें जोड़ना) या वर्कग्रुप के भीतर साझा मेमोरी की आवश्यकता होती है। WebGPU में दोनों संभव हैं, लेकिन जटिलता बढ़ाते हैं।

व्यावहारिक सुझाव: स्कल्प्टिंग पाइपलाइन के लिए Marching Cubes का ही उपयोग करें। यह हमारे कोडबेस में प्रमाणित है, WGSL शेडर मौजूद हैं और उनका बेंचमार्क किया जा चुका है, और Transvoxel सीम प्रणाली MC के किनारा-आधारित वर्टेक्स प्लेसमेंट के अनुरूप बनी है। यदि बाइनरी डेटा पर MC की एलियासिंग एक दृश्यमान समस्या बनती है, तो Surface Nets पर दोबारा विचार करना उचित होगा, लेकिन SDF भूभाग के लिए, जहाँ मान सुचारु ग्रेडिएंट होते हैं, MC साफ परिणाम देता है।

स्कल्प्टिंग के लिए व्यावहारिक आर्किटेक्चर

स्पाइक क्रम ने रेंडरिंग पाइपलाइन की समस्या हल कर दी। अब ब्रश प्रणाली, गेम सिस्टम में फैलने वाले दुष्प्रभाव और मल्टीप्लेयर सिंक्रोनाइज़ेशन शेष हैं। प्रत्येक स्पाइक के आधार पर आगे की योजना यह है।

चरण 1: हाइटमैप स्कल्प्टिंग (न्यूनतम बदलाव, अधिकतम पहुँच)

प्रोडक्शन world/client/ कोड में ऐसे ब्रश टूल जोड़ें जो चंक हाइटमैप को संशोधित करते हैं। यह मौजूदा WebGL रेंडरर के भीतर काम करता है और इसके लिए WebGPU की आवश्यकता नहीं है।

ब्रश इनपुट: placement.ts में दिए गए PlacementTool पैटर्न का अनुसरण करें। इसमें पहले से ही एक Raycaster है, जो chunkManager.getChunkMeshes() पर हिट करता है और हिट बिंदु पर एक घोस्ट मेश को ट्रैक करता है। एक TerrainBrushTool वही रेकास्ट करेगा, लेकिन कोई ऑब्जेक्ट रखने के बजाय चंक हाइटमैप को संशोधित करेगा। World.onMouseDown हैंडलर पहले से ही टूल की स्थिति के आधार पर डिस्पैच करता है।

चंक संशोधन (Chunk.applyBrush): ब्रश की वर्ल्ड स्थिति को हाइटमैप ग्रिड निर्देशांकों से मैप करें। ब्रश त्रिज्या के भीतर प्रत्येक ग्रिड बिंदु के लिए, फॉलऑफ से भारित विस्थापन की गणना करें और उसे हाइटमैप मान में जोड़ें या उससे घटाएँ। फिर मेश अपडेट करें: संशोधित हाइटमैप से वर्टेक्स की Y स्थितियाँ सेट करें, केंद्रीय अंतर विधि से नॉर्मल की दोबारा गणना करें (chunk.ts की पंक्तियों 155-158 में पहले से उपयोग किया गया वही terrainHeight(wx +/- eps, wz) पैटर्न), और प्रभावित क्षेत्र के लिए terrain-material.ts में createSplatMap() के माध्यम से स्प्लैट मैप दोबारा बनाएँ, ताकि ढलान-आधारित टेक्सचर ब्लेंडिंग अपडेट हो सके।

कैरेक्टर कंट्रोलर: CharacterController.update() ग्राउंडिंग के लिए हर फ्रेम getHeight() को कॉल करता है। ChunkManager.getHeight() कार्य Chunk.sampleHeight() को सौंपता है, जो चंक के heightmap Float32Array से पढ़ता है। चूँकि हम उस ऐरे को सीधे संशोधित कर रहे हैं, कैरेक्टर कंट्रोलर बिना किसी अतिरिक्त वायरिंग के अगले फ्रेम में बदलाव अपना लेता है।

ऑब्जेक्ट अमान्यकरण: chunk.ts में ट्री इंस्टेंस स्पॉन के समय terrainHeight() का नमूना लेकर रखे जाते हैं। स्कल्प्टिंग के बाद प्रभावित क्षेत्र के पेड़ गलत ऊँचाई पर हो सकते हैं। चरण 1 में इसे टाला जा सकता है (छोटे बदलावों पर पेड़ थोड़ा तैरेंगे)। चरण 2 में ऐसे chunk.invalidateObjects() की आवश्यकता है, जो ऊँचाइयों का दोबारा नमूना ले और इंस्टेंस मैट्रिक्स फिर से बनाए। resolveCollisions() में उपयोग किए जाने वाले कोलाइडर के लिए भी यही करना होगा।

Rapier फ़िज़िक्स (यदि एकीकृत हो): Spike 02 ने सिद्ध किया कि हाइटफील्ड कोलाइडर काम करते हैं। यदि Rapier सक्रिय है, तो संशोधित चंक के हाइटफील्ड कोलाइडर को दोबारा बनाना या पैच करना होगा। Rapier का ColliderDesc.heightfield() एक सपाट Float32Array लेता है, इसलिए इसे सीधे बदला जा सकता है।

नेटवर्क सिंक: protocol.ts में MsgType.TerrainEdit = 10 जोड़ें:

typescript
interface TerrainEditMsg {
  t: MsgType.TerrainEdit
  cx: number
  cz: number
  brush: {
    wx: number
    wz: number
    radius: number
    strength: number
    falloff: number
    operation: number
  }
}

WorldChunkDO इसे सभी क्लाइंट पर ब्रॉडकास्ट करता है और Durable Object स्टोरेज में संग्रहित प्रति-चंक संपादन लॉग में जोड़ता है। बाद में जुड़ने वाले क्लाइंट Snapshot संदेश में संपादन लॉग प्राप्त करते हैं और भूभाग की स्थिति पुनर्निर्मित करने के लिए उसे रीप्ले करते हैं। सभी क्लाइंट एक ही नियतात्मक ब्रश फ़ंक्शन लागू करते हैं, इसलिए वे एक समान हाइटमैप पर अभिसरित होते हैं।

चंक अनलोड/रीलोड: Spike 06 और Spike 11 ने स्ट्रीमिंग पैटर्न स्थापित किया। जब कोई चंक अनलोड होने के बाद दोबारा लोड होता है, तो उस चंक का संपादन लॉग आधारभूत प्रक्रियात्मक हाइटमैप पर रीप्ले किया जाना चाहिए। संपादन लॉग सर्वर-साइड (Durable Object) संग्रहीत होता है और Snapshot संदेश में शामिल किया जाता है।

चरण 2: Spikes 22-24 आर्किटेक्चर के साथ वॉल्यूमेट्रिक स्कल्प्टिंग

Spike 24 पाइपलाइन को प्रोडक्शन वर्ल्ड में पोर्ट करें। जब कोई खिलाड़ी सतह के नीचे स्कल्प्ट करता है (गुफा तराशना या सुरंग खोदना), तो प्रभावित चंक हाइटमैप मोड से MC मोड में बदल जाता है।

WebGPU रेंडरर माइग्रेशन: Spikes 13-14 ने सिद्ध किया कि Three.js का WebGPURenderer सीन ग्राफ के साथ कस्टम कंप्यूट को होस्ट कर सकता है। प्रोडक्शन वर्ल्ड MC चंक के लिए StorageBufferAttribute के साथ WebGLRenderer से WebGPURenderer पर जाता है। WebGPU उपलब्ध न होने पर चरण 1 के केवल-हाइटमैप पथ पर वापस जाएँ।

प्रति-चंक SDF आवंटन: Spike 22 के हाइब्रिड पैटर्न का अनुसरण करें। प्रत्येक चंक एक हाइटमैप के रूप में शुरू होता है। पहले वॉल्यूमेट्रिक ब्रश स्ट्रोक पर 64^3 Float32Array आवंटित करें, हाइटमैप का नमूना लेकर उसे आरंभ करें (प्रत्येक बिंदु पर SDF मान world.y - heightmap_value है), और MC रेंडरिंग पर स्विच करें। Spike 23 की नीति प्रणाली सुनिश्चित करती है कि चंक स्थायी रूप से MC मोड में रहे (संपादन मास्क का "स्टिकी एडिट" व्यवहार)।

SDF शेडर में साझा हाइटमैप: Spike 16 का height_at() फ़ंक्शन। चंक का हाइटमैप GPU स्टोरेज बफ़र में अपलोड करें। SDF कंप्यूट शेडर max(height_sdf, edit_sdf) का मूल्यांकन करता है, जहाँ height_sdf = world.y - height_at(world.xz) है और edit_sdf में ब्रश संशोधन होते हैं। MC और हाइटमैप चंक अपनी सीमाओं पर एक ही आधारभूत सत्य पर सहमत रहते हैं।

Transvoxel सीम: Spikes 15-21 का पूरा स्टैक। MC-से-हाइटमैप सीमाएँ श्रिंक गैप वाले ट्रांज़िशन सेल का उपयोग करती हैं। अलग-अलग रिज़ॉल्यूशन वाली MC-से-MC सीमाएँ Spike 17 के डुअल-LOD पैटर्न का उपयोग करती हैं। Spike 19 का कॉर्नर केस 4-तरफ़ा प्रतिच्छेद संभालता है। Spike 21 का GPU कंप्यूट उसी डिस्पैच में सारी सीम ज्यामिति उत्पन्न करता है।

क्लिपमैप सुदूर क्षेत्र: स्कल्प्टिंग सीमा से बाहर के भूभाग के लिए Spike 24 के क्लिपमैप रिंग। स्कल्प्टिंग इन रिंग को कभी नहीं बदलती; ये आधारभूत प्रक्रियात्मक हाइटमैप का नमूना लेते हैं।

जियोमॉर्फिंग: Spike 10 की जियोमॉर्फिंग LOD ट्रांज़िशन पर अचानक दिखने वाले बदलाव को समाप्त करती है। संपादित चंक के लिए जियोमॉर्फ लक्ष्य में संपादन शामिल होना चाहिए। यदि कोई चंक LOD0 पर MC है और उसका LOD1 पड़ोसी हाइटमैप है, तो जियोमॉर्फ दोनों निरूपणों के बीच ब्लेंड करता है। इसके लिए निचले LOD पर भी संपादन लॉग का नमूना लेना आवश्यक है।

मटेरियल बजट: Spike 08 ने 45+ FPS पर 4-लेयर ट्राइप्लानर + नॉर्मल का बेंचमार्क किया। MC चंक को भी यही मटेरियल चाहिए। स्प्लैट मैप को हाइटमैप ढलान के बजाय SDF ग्रेडिएंट से उत्पन्न किया जा सकता है (खड़ी ढलान = चट्टान, समतल = घास)। यह 4-लेयर बजट के भीतर रहता है।

वनस्पति अमान्यकरण: Spike 07 की डेंसिटी-मैप वनस्पति भूभाग की ऊँचाई और ढलान पर निर्भर करती है। जब कोई चंक MC मोड में बदलता है, तो SDF सतह का नमूना लेकर ट्री इंस्टेंस दोबारा उत्पन्न करने होंगे। ओवरहैंग पर या गुफाओं के भीतर मौजूद पेड़ों को हटाना होगा। chunk.ts के इंस्टैंस्ड मेश मैट्रिक्स नई सतह से दोबारा बनाए जाते हैं।

चरण 3: अनडू/रीडू और नेटवर्क सिंक के लिए CSG संपादन ट्री

कच्चे SDF म्यूटेशन को CSG ऑपरेशन ट्री से बदलें। प्रत्येक ब्रश स्ट्रोक एक ऑपरेशन (जोड़ना, घटाना, स्मूथ ब्लेंड) के साथ एक प्रिमिटिव (स्फीयर, कैप्सूल, बॉक्स) जोड़ता है। ट्री से SDF की दोबारा गणना की जाती है।

लाभ:

  • अविनाशी: किसी भी संपादन को पूर्ववत करने के लिए उसे ट्री से हटाया जा सकता है
  • नेटवर्क-कुशल: कच्चे फ़ील्ड मानों के बजाय CSG ऑपरेशन ब्रॉडकास्ट करें
  • नियतात्मक: सभी क्लाइंट समान ऑपरेशन क्रम से एक ही SDF बनाते हैं
  • ALICE-SDF का CSG ट्री डिफ़/पैच पूरे नेटवर्क में बैंडविड्थ-कुशल सिंक्रोनाइज़ेशन और अनडू/रीडू उपलब्ध कराता है

Durable Object स्टोरेज: प्रति-चंक संपादन ट्री चरण 1 के सपाट संपादन लॉग की जगह लेता है। WorldChunkDO कच्चे हाइटमैप डेल्टा के बजाय CSG ट्री संरचना संग्रहीत करता है। Snapshot संदेशों में ट्री शामिल होता है और बाद में जुड़ने वाले क्लाइंट स्थानीय SDF उत्पन्न करने के लिए उसका मूल्यांकन करते हैं।

चरण 4: सहयोगी स्कल्प्टिंग

सर्वर-क्रमित ऑपरेशन रीप्ले के साथ समवर्ती संपादन समर्थन जोड़ें। Durable Object प्रत्येक संपादन को टाइमस्टैम्प देता है और क्रम से ब्रॉडकास्ट करता है। बाद में जुड़ने वाले क्लाइंट ऑपरेशन लॉग प्राप्त करते हैं और वर्ल्ड की स्थिति पुनर्निर्मित करते हैं। मौजूदा Snapshot संदेश प्रकार को प्रत्येक चंक का भूभाग संपादन इतिहास शामिल करने के लिए विस्तारित किया जाता है।

चूँकि ब्रश स्ट्रोक छोटे, स्थानीय और योगात्मक/घटावात्मक होते हैं, इसलिए थोड़े अलग क्रम में किए गए समवर्ती संपादनों का दृश्य परिणाम आम तौर पर "सही" क्रम से अप्रभेद्य होता है। सर्वर क्रम के साथ लास्ट-राइट-विन्स पर्याप्त है। Durable Object का tick() फ़ंक्शन (जो वर्तमान में प्लेयर स्थिति के लिए 50ms अंतराल पर चलता है) उसी लूप में भूभाग संपादन ब्रॉडकास्ट जोड़ता है।

प्रमुख संदर्भ

एल्गोरिदम:

  • Lorensen & Cline, "Marching Cubes" (1987)
  • Eric Lengyel, "Transvoxel Algorithm" (2009), transvoxel.org
  • Losasso & Hoppe, "Geometry Clipmaps" (SIGGRAPH 2004)
  • "A High-Performance SurfaceNets Discrete Isocontouring Algorithm" (arxiv 2401.14906, 2024)
  • MCHex (arxiv 2511.02064, 2025)

कार्यान्वयन:

  • bevy-sculpter v0.18.0 (Rust, Surface Nets + SDF ब्रश)
  • fast-surface-nets (Rust, 20M त्रिभुज/सेकंड)
  • ALICE-SDF v1.3.0 (Rust + WASM, CSG ट्री डिफ़/पैच)
  • WebGPU SDF Editor (Nijhoff, जनवरी 2026)
  • SculptingPro (Unity रनटाइम स्कल्प्टिंग API)
  • TerraBrush (Godot भूभाग स्कल्प्टिंग GDExtension)

गेम:

  • Dreams (Media Molecule, SDF + पॉइंट क्लाउड रेंडरिंग, SIGGRAPH 2015)
  • Teardown (Voxagon, वॉक्सेल DDA रे ट्रेसिंग, नियतात्मक मल्टीप्लेयर विनाश)
  • Mike Turitzin का SDF इंजन (ब्रिक मैप + ज्यामिति क्लिपमैप, जनवरी 2026)

नेटवर्क:

  • "Optimizing payload size for voxel state synchronization" (Oulu, 2024)
  • Teardown मल्टीप्लेयर (अर्ध-नियतात्मक विनाश सिंक, मार्च 2026)
  • cSculpt (मल्टीरिज़ॉल्यूशन मर्ज के साथ सहयोगी मेश स्कल्प्टिंग)
अभी आज़माएँकम तराशें, जल्दी खेलें

ब्रश छुए बिना भूभाग-आधारित गेम पाएँ।

मुफ़्त में बनाएँ →मुफ़्त है, ब्राउज़र में चलता है, कुछ इंस्टॉल नहीं करना।