ब्राउज़र में open world बनाना, भाग 5: खूबसूरत चीज़ों का बजट तय करना
लेखक Oleg Sidorkin, Cinevva के CTO और सह-संस्थापक
यहां नए हैं? सीरीज़ गाइड का इस्तेमाल करें। इसमें बताया गया है कि spike क्या होता है और सभी भागों के लिंक दिए गए हैं।
यह वह अध्याय था जहां visual महत्वाकांक्षा का सामना गणित से हुआ।
हमने rendering की लागत को अलग-अलग spikes में बांटा क्योंकि एक साथ मिले हुए नतीजों की जांच करना मुश्किल होता है। अगर आप सब कुछ एक ही बार में चालू कर देते हैं, तो आपको सिर्फ इतना पता चलता है कि frame धीमा है। यह पता नहीं चलता कि किस feature ने बजट खा लिया।
Spike 7 का निशाना vegetation density और animation की लागत थी। तरीका यह था कि हर terrain chunk के लिए 32x32 density maps से runtime scattering की जाए, जो बड़े InstancedMesh sets को feed करे। हर घास की पत्ती और झाड़ी के cluster को एक scrolling noise texture से चलने वाला vertex-shader wind मिला। हम जिस मुख्य आंकड़े पर नज़र रखते थे वह triangle count नहीं बल्कि mid-range GPUs पर draw call overhead और vertex throughput था। हमें पता चला कि instances को कम meshes में batch करना, हर पत्ती के polygon count को घटाने से ज़्यादा मायने रखता है।
Spike 7 को नए tab में खोलें ↗ · सोर्स देखें
Spike 8 ने terrain material की जटिलता को आगे बढ़ाया। slope angle और altitude के हिसाब से weighted multi-layer blending, cliff faces के लिए optional triplanar projection, और per-layer normal maps। shader चार texture layers के साथ slope-based splatting कर रहा था, और हर layer को एक diffuse और एक normal sample की ज़रूरत थी। यानी lighting जोड़ने से पहले ही हर fragment पर
Spike 8 को नए tab में खोलें ↗ · सोर्स देखें
Spike 9 का फोकस वास्तविक terrain और object load के तहत cascaded shadow map की लागत पर था। तीन cascades वाला CSM baseline था। हमने खासतौर पर low-angle sun positions के साथ टेस्ट किया क्योंकि cascade pressure सबसे बुरी वहीं होती है। दूर वाला cascade frustum के एक बहुत बड़े हिस्से को कवर करता है, और shadow detail texel density से तय होती है,
Spike 9 को नए tab में खोलें ↗ · सोर्स देखें
इस चरण में सबसे मुश्किल हिस्सा product discipline था। कुछ effects बेहद शानदार दिखते थे फिर भी उन्हें सीमित करना पड़ा क्योंकि वे अपने visual असर के मुकाबले frame budget का बहुत बड़ा हिस्सा खा रहे थे।
हमारा नियम सीधा बन गया। कोई feature तभी आगे बढ़ता है जब वह मापे गए frame-time data के साथ अपनी लागत को सही ठहरा सके।
यह सुनने में स्पष्ट लगता है। लेकिन तेज़ prototype cycles में यह आम नहीं है, जहां हर कोई अगली visual जीत को लेकर उत्साहित रहता है। इस नियम को शुरू से बनाए रखने से बाद में clipmaps और volumetric zones को लेकर लिए गए architecture फैसले काफी साफ-सुथरे रहे, क्योंकि हमें पहले से पता था कि उसी 16ms के लिए होड़ करने वाली हर चीज़ की per-feature लागत क्या है।
भाग 6 में हम geometry clipmaps के साथ पहले बड़े terrain architecture pivot तक पहुंचे।
इस अध्याय में संदर्भित तकनीक
InstancedMesh और GPU vegetation. Three.js का InstancedMesh एक ही geometry की N copies को एक draw call में render करता है। vegetation के लिए, एक density map (हर chunk में 32x32) घास की पत्तियों और झाड़ी के clusters का runtime scattering instance buffers में चलाता है। Wind animation vertex shader में एक scrolling noise texture का इस्तेमाल करके चलता है। scale पर, WebGPU का ComputeInstanceCulling rasterization से पहले off-screen और दूर के instances को हटा देता है, और IndirectBatchedMesh कई vegetation types को एक ही buffer में पैक करता है जो multi-draw indirect से draw होता है। हमारी GPU vegetation culling पर landscape गाइड देखें।
Triplanar mapping. सामान्य UV-mapped textures steep slopes पर खिंच जाते हैं क्योंकि UV coordinates सिकुड़ जाते हैं। Triplanar mapping textures को तीनों axes (X, Y, Z) के साथ project करती है और surface normal के आधार पर blend करती है। Cliff faces को X या Z projection मिलता है (कोई खिंचाव नहीं), flat ground को Y projection। blending बिना किसी UV unwrapping के अपने आप और smooth होती है। PBR terrain के लिए, वही blending weights albedo, normal, roughness, और ambient occlusion channels पर लागू होते हैं। triplanar mapping की जानकारी देखें।
Slope और altitude आधारित material splatting. हाथ से बनाए गए splat maps के बजाय, materials को terrain properties के आधार पर fragment shader में procedurally assign किया जाता है। कम altitude पर flat ground को घास मिलती है, steep slopes को चट्टान, high altitude को बर्फ (सिर्फ उन्हीं surfaces पर जो जमाव के लिए काफी flat हों), sea level के पास रेत। transitions smooth blending के लिए smoothstep का इस्तेमाल करते हैं। हमारे implementation में, हर terrain chunk चार texture layers को हर layer पर diffuse और normal samples के साथ evaluate करता है, जिससे lighting से पहले हर fragment पर आठ texture fetches होते हैं। slope और altitude material assignment देखें।
Cascaded Shadow Maps (CSM). CSM camera के view frustum को 3-4 distance ranges (cascades) में बांटता है। हर cascade sun के नज़रिए से एक shadow map render करता है, जिसका resolution उसकी distance के हिसाब से होता है। पास वाले cascades को high-resolution shadows मिलती हैं (पेड़ों और इमारतों के नीचे विस्तृत contact shadows), दूर वाले cascades को कम resolution (चौड़ी पहाड़ी shadows)। terrain shader सभी cascades को sample करता है और हर fragment के लिए उपयुक्त एक चुनता है। Performance लागत: 1024x1024 पर 3-4 cascades shadow map rendering के लिए ~0.5-1 ms और sampling के लिए ~0.2-0.3 ms जोड़ते हैं। terrain के लिए shadows देखें।
भाग 5, कुल 12 में से।
पिछला: भाग 4 - फैंसी terrain से पहले streaming
अगला: भाग 6 - Clipmaps ने कहानी बदल दी
सीरीज़ गाइड: /hi/blog/2026-02-25-open-world-browser-series-guide