Skip to content

ब्राउज़र में एक ओपन वर्ल्ड बनाना, भाग 30: एक कैमरा जो दीवारों का सम्मान करता है

Oleg Sidorkin द्वारा, Cinevva के CTO और सह-संस्थापक

यहाँ नए हैं? सीरीज़ गाइड का इस्तेमाल करें। यह बताती है कि स्पाइक क्या होता है और सभी भागों को लिंक करती है।

भाग 29 ने हमें एक ऐसा कंट्रोलर दिया जो किसी भी बॉडी को चलाता है। बॉडी अब सही तरीके से चलती है। वह चलती है, फिसलती है, तैरती है, ग्लाइड करती है, caves में चढ़ती है, और overhangs के नीचे झुकती है। समस्या यह है कि उसे क्या देख रहा है। उनतीस भागों तक कैमरा एक stock orbit rig था जो प्लेयर के पीछे चलता था और शर्मिंदगी से बचने के लिए ठीक एक चतुर काम करता था, वह क्षितिज से नीचे झुकने से इनकार करता था ताकि वह समतल ज़मीन के नीचे न फिसल सके। वह clamp ही पोल खोलता है। यह इसलिए मौजूद है क्योंकि कैमरे को यह पता ही नहीं था कि वर्ल्ड की geometry असल में कहाँ है, इसलिए clipping के खिलाफ़ एकमात्र बचाव वही angles मना करना था जहाँ clipping की सबसे ज़्यादा संभावना थी। किसी पहाड़ी की तरफ़ चलें और कैमरा पहाड़ी के अंदर बैठ जाता था। भाग 7 की marching-cubes caves में से किसी एक में कदम रखें और आप एक चट्टान के अंदर देख रहे होते थे। भाग 16 के authoring tools से एक घर बनाएँ और किसी कमरे में खड़े हों, तो कैमरा दीवार के बाहर तैरता रहता था और siding को देखता रहता था। यह भाग कैमरे को geometry के लिए वही सम्मान देता है जो बॉडी के पास पहले से है।

समस्या का आकार, और समाधान का आकार

एक third-person कैमरे का एक काम मुश्किल होता है और एक दर्जन आसान। आसान काम हैं फॉलो करना, smoothing, और orbit input, और ये हमारे पास पहले से थे। मुश्किल वाला यह है कि academic साहित्य इसे एक visibility constraint कहता है, और जिस survey का हर कोई हवाला देता है, Christie और Olivier का Camera Control in Computer Graphics, वह पूरे क्षेत्र को इसी के इर्द-गिर्द ढालता है: subject को framed और बिना रुकावट के रखें जबकि वर्ल्ड का सम्मान करते रहें। runtime पर यह हर frame पूछे जाने वाले एक धोखे से सरल सवाल में सिमट जाता है। प्लेयर pivot है। user ने घुमाकर और zoom करके उनके पीछे कुछ दूरी पर एक मनचाही कैमरा position तय की है। कैमरा असल में उस रेखा के साथ कितना पीछे बैठ सकता है, इससे पहले कि वह किसी ठोस चीज़ में घुस जाए? इसका ईमानदारी से जवाब दें और कैमरा खुद को पहाड़ी के सामने टिका लेता है, जब आप किसी कोने में पीछे हटते हैं तो boom के नीचे सरक जाता है, और cave की छत के बीच से घुसने के बजाय वहीं रुक जाता है।

जो pattern इसका जवाब देता है वह पुराना और आज़माया हुआ है। Unreal इसे spring arm कहता है, Godot एक SpringArm3D node देता है, और Unity का Cinemachine इसे एक third-person follow rig और एक deoccluder extension में बाँट देता है। विचार हमेशा एक ही रहता है। कैमरे को pivot पर लगे एक boom के सिरे से लटका दें। जब रास्ता साफ़ हो तो उसे मनचाही लंबाई पर रखें, जब कुछ रास्ते में आए तो उसे pivot की तरफ़ खींच लें, और जब रास्ता साफ़ हो जाए तो उसे वापस बाहर spring कर दें। Mark Haigh-Hutchinson की Real-Time Cameras, जिसे Metroid Prime के camera lead ने लिखा था, उन failure modes पर पूरे-पूरे अध्याय खर्च करती है जो इसके किसी भोले संस्करण को कुछ ऐसा बना देते हैं जो प्लेयर्स को बीमार कर देता है। हमने वह pattern लिया और अपना खुद का बनाया, इतना छोटा कि एक ही बैठक में पढ़ा जा सके, public/world/src/camera-rig.mjs में।

wallpivot (player head)desired (user zoom)camera + probe radius rℓ (clamped)
boom कैमरे को user की मनचाही zoom पर तब तक रखता है जब तक कोई रुकावट बीच में न आ जाए, फिर उसी रेखा के साथ खुद को खींच लेता है ताकि probe sphere near plane के बीच से घुसने के बजाय सतह से टिक जाए।

एक boom जो सिर्फ़ अपनी लंबाई का मालिक है

जिस design नियम ने rig को छोटा रखा वह भाग 29 के कंट्रोलर काम से उधार लिया गया है: एक चीज़ का मालिक बनो, पूरी तरह, और बाकी सब से इनकार कर दो। rig boom की लंबाई का मालिक है और कुछ नहीं। Yaw, pitch, orbit की damping, touch और wheel gestures, यह सब OrbitControls के पास रहता है, जो इसे पहले से ही अच्छी तरह सुलझा देता है और जिसे दोबारा लिखने में हमारी कोई दिलचस्पी नहीं। तो rig एक camera controller नहीं है। यह एक post-process है जो orbit math के बाद चलता है और ठीक एक संख्या को सही करता है, pivot से कैमरे तक की दूरी।

वह फ़ैसला सुथरा लगता है और यह लगभग तुरंत टूट गया, क्योंकि OrbitControls जिस तरह सोचता है। हर update की शुरुआत में वह कैमरे की मौजूदा position पढ़ता है और उससे अपना orbit radius निकालता है। यह आम तौर पर अदृश्य रहता है। लेकिन जिस पल हमारा rig किसी दीवार से बचने के लिए कैमरे को छोटा करता है, अगले frame में OrbitControls उस छोटी की गई position को पढ़ता है, यह नतीजा निकालता है कि user ने ज़रूर zoom in किया होगा, और उस छोटे होने को user की मनचाही zoom में पका देता है। इसके कुछ frames और कैमरा प्लेयर के सिर पर ढह जाता है और वापस बाहर नहीं आता। इसका समाधान दो calls हैं जो orbit update को घेरती हैं और यही पूरा integration है। OrbitControls चलने से पहले, beforeControls() कैमरे को पिछले frame की पूरी, बिना-छोटी की गई दूरी पर वापस लाता है, ताकि orbit math हमेशा user की असली zoom पढ़े। OrbitControls चलने के बाद, afterControls(dt) उस ताज़ा orbit की गई मनचाही position को पढ़ता है, collision सुलझाता है, लंबाई को damp करता है, और कैमरे को वहाँ लिखता है जहाँ उसे असल में render होना चाहिए। user का इरादा और collision की सुधार कभी एक-दूसरे को नहीं छूते, और dolly ठीक उतना ही responsive रहता है जितना rig के मौजूद होने से पहले था। rig के लिए हमने जो headless test लिखा वह इसे बिल्कुल पिन कर देता है: boom को साठ frames तक एक दीवार में घुसाओ, दीवार साफ़ करो, और लंबाई collision की दूरी पर अटकने के बजाय user की दस मीटर की पूरी zoom पर वापस spring हो जाती है।

एक contract, कोई भी collider

rig कभी नहीं पूछता कि वर्ल्ड किस चीज़ से बना है। एक collider बस एक ऐसा object है जिसके पास एक probe method है, और rig उसे एक ray, एक अधिकतम दूरी, और कैमरे का probe radius देता है, और बदले में एक संख्या पाता है, वह सबसे दूर की दूरी जहाँ तक कैमरा उस collider के रोकने से पहले सफ़र कर सकता है। rig हर पंजीकृत collider से पूछता है और सबसे नज़दीकी hit लेता है। यही पूरा contract है, और यह वही चाल है जो character controller ने तब चली थी जब उसने locomotion को pluggable behaviors में बदला था। Terrain प्लग होता है, props प्लग होते हैं, building shells प्लग होते हैं, हर एक उसी probe के पीछे, और rig इन सब से अनजान रहता है। एक नई तरह की रुकावट जोड़ना मतलब एक list में एक collider जोड़ना है, कैमरा edit करना नहीं।

contract में एक बात अपनी कीमत वसूल करती है, और वह है probe radius। हम pivot से कैमरे तक एक पतली ray नहीं डालते, हम एक sphere डालते हैं जो इतना बड़ा हो कि कैमरे के near plane को समा सके। एक अकेली ray कैमरे के केंद्र को दीवार पर रोक देती है, लेकिन near plane की चौड़ाई होती है, इसलिए उसके कोने दीवार में पहले से दब चुके होते, इससे पहले कि केंद्र वाली ray कभी कोई hit रिपोर्ट करती। एक ray के बजाय एक छोटा sphere चलाना ही वह है जो हर shipping implementation करता है, Unreal इसे probe size के रूप में सामने रखता है, और यही उस कैमरे और उस कैमरे के बीच का फ़र्क है जो सतह से साफ़-साफ़ टिकता है बनाम वह जो स्क्रीन के किनारों पर आपको आर-पार देखने देता है।

हम उस radius का अंदाज़ा नहीं लगाते, हम उसे निकालते हैं। कैमरे से near plane का सबसे दूर का बिंदु उसके कोनों में से एक है, और उस तक की दूरी सीधे projection से निकल आती है। near plane n और vertical field of view θ के साथ, half-height h=ntan(θ/2) है, half-width w=haspect है, और कोना यहाँ बैठता है

rnear=n2+w2+h2

probe radius वही कोने की दूरी है, एक छोटे safety margin से गुणा, एक तय floor के साथ ताकि वह बहुत संकरे frustum पर कभी एक समझदार न्यूनतम से नीचे न गिरे। जब भी field of view, aspect ratio, या near plane बदलता है, radius दोबारा गणना होता है, ताकि एक window resize या एक ऐसी zoom जो projection को छूती है, चुपचाप probe को इतना छोटा न छोड़ दे कि वह उन कोनों को ढक न सके जिन्हें उसे बचाना है।

वह collider जो caves के बारे में जानता है

terrain collider वह जगह है जहाँ यह दिलचस्प हो जाता है, क्योंकि हमारे engine में terrain एक heightmap नहीं है। भाग 7 से यह एक signed distance field रहा है, एक ऐसा function जो लौटाता है कि space में कोई भी बिंदु निकटतम ठोस सतह से कितनी दूर है और वह चट्टान के अंदर है या बाहर। धनात्मक मतलब हवा, ऋणात्मक मतलब चट्टान, और वही एक तथ्य यही वजह है कि हमारा कैमरा कुछ ऐसा कर सकता है जो एक heightmap कैमरा संरचनात्मक रूप से नहीं कर सकता। एक heightmap किसी x और z पर ज़मीन की ऊँचाई जानता है। उसके पास छत की कोई धारणा नहीं है, क्योंकि किसी भी बिंदु के ऊपर कभी सिर्फ़ एक ही सतह होती है। तो एक heightmap कैमरा आपको पहाड़ी में चलने से रोक सकता है, लेकिन उसे यह पता ही नहीं कि एक overhang का किनारा या एक cave की छत pivot के ऊपर लटक रही है, और वह दोनों के बीच से सीधे निकल जाता है। एक distance field तीन dimensions में हर सतह के बारे में जानता है, इसलिए वही probe जो कैमरे को एक पहाड़ी की ढलान पर रोकता है, उसे एक cave की छत पर भी एक भी special case के बिना रोक देता है।

cavesolid rockplayerheightmap: clips through ✗SDF: stops at ceiling ✓
एक heightmap हर column के लिए एक सतह संग्रहित करता है, इसलिए वह प्लेयर के ऊपर चट्टान के उस स्लैब को कभी नहीं देखता और boom को छत के बीच से ऊपर घुसने देता है। distance field उस स्लैब के अंदर ऋणात्मक है, इसलिए probe उससे संपर्क करता है और कैमरा cave की छत के ठीक नीचे रुक जाता है।

field के साथ probe को चलाना एक ऐसी तकनीक है जिसका एक नाम है और जिसके पीछे एक paper है। John Hart की Sphere Tracing, 1996 से, एक distance field के खिलाफ़ एक ray को march करने का मानक तरीका है, और चाल यह है कि field आपको सिर्फ़ यह नहीं बताता कि आपने किसी चीज़ से टकराया या नहीं, वह आपको एक सुरक्षित दूरी बताता है जितनी आप किसी चीज़ से टकराए बिना आगे बढ़ सकते हैं। तो छोटे-छोटे तय कदमों में रेंगने के बजाय, आप field को sample करते हैं, उतना आगे बढ़ते हैं जितनी ढील वह रिपोर्ट करता है, और दोहराते हैं, खुली हवा में लंबे डग भरते हुए और किसी सतह के पास पहुँचते ही छोटे, सावधान कदम लेते हुए।

हालाँकि एक पेच है जो हमारी terrain हम पर थोपती है। एक असली distance field निकटतम सतह तक की असल Euclidean दूरी रिपोर्ट करता है, और उस ढील के बराबर एक पूरा डग हमेशा सुरक्षित होता है। लेकिन जहाँ terrain अभी भी carved voxels के बजाय एक heightmap है, वह field जिसे हम सस्ते में sample कर सकते हैं वह असली distance नहीं है, वह vertical clearance है, सीधे नीचे ज़मीन तक का अंतर। किसी ढलान पर वह संख्या ज़्यादा बता देती है कि कैमरा असल में कितना दूर जा सकता है, क्योंकि निकटतम चट्टान बगल में है, सीधे नीचे नहीं। ईमानदार दूरी एक ऐसे factor से छोटी होती है जो gradient के साथ बढ़ता है, 1+h2, इसलिए रिपोर्ट की गई ढील के हिसाब से नापा गया एक डग आगे निकल जाता है और एक चोटी के साफ़ ऊपर से कूद सकता है। इसका समाधान under-relaxation है, रिपोर्ट की गई ढील के पूरे के बजाय सिर्फ़ एक अंश के हिसाब से आगे बढ़ना, जो लगभग साठ डिग्री की ढलान तक सुरक्षित रहता है और true-distance voxel क्षेत्रों पर कुछ अतिरिक्त samples के अलावा कुछ खर्च नहीं करता। हम इसे एक stride floor के साथ जोड़ते हैं, ताकि एक या दो cell मोटी cave की दीवार कभी साफ़ ऊपर से न लाँघी जाए, और एक सख़्त ceiling के साथ जो march को सस्ता रखता है। जब sphere आखिरकार सतह को छूता है तो एक छोटा bisection contact point को कस देता है, और कैमरा अपने ही radius जितना पीछे हटकर वहीं टिक जाता है।

लिखकर बताएँ तो, boom pivot p से unit दिशा d के साथ एक ray r(t)=p+td है, और march field की ढील के एक under-relaxed अंश के हिसाब से contact तक आगे बढ़ता है, दोनों सिरों पर clamp किया हुआ:

tn+1=tn+clamp(λ(Φ(r(tn))r),smin,smax)

यहाँ Φ signed distance है, हवा में धनात्मक और चट्टान में ऋणात्मक, r probe radius है, λ(0,1] वह under-relaxation factor है जो ज़्यादा बताने वाले heightmap field को एक ढलान कूदने से रोकता है, और smin,smax वे step clamps हैं जो एक पतली दीवार को skip होने से और march को लंबा चलने से रोकते हैं। Contact पहला t है जहाँ Φ(r(t))r, मतलब sphere की सतह चट्टान तक पहुँच गई है, और कैमरा उस arc लंबाई पर रुकता है, अपने radius जितना कम।

collider एक और method एक safety net के रूप में रखता है, depenetration। Collision को सबसे पहले तो कैमरे को ठोस से बाहर रखना चाहिए, लेकिन कुछ हालात इसके पास से सरक जाते हैं, एक pivot जो एक ऐसी पतली दीवार के दोनों तरफ़ बँटा है कि boom उसके अंदर ही शुरू हो जाता है, एक cave जिसे terrain tools ने तब ताज़ा तराशा जब कैमरा उस चट्टान में बैठा था जो अब गायब है, एक building piece जो कैमरे के चारों ओर गिरा दिया गया। उनके लिए collider जाँचता है कि क्या कैमरे ने frame ठोस के अंदर खत्म किया, जहाँ Φ(c)<r, और अगर ऐसा हुआ, तो field के gradient को पढ़ता है, जो सीधे खुली हवा की तरफ़ इशारा करता है क्योंकि Φ तब बढ़ता है जब आप चट्टान छोड़ते हैं, और कैमरे को उसके साथ बाहर कदम रखाता है:

cc+(rΦ(c))Φ(c)Φ(c)

उन कुछ iterations से यह r-isosurface पर converge हो जाता है, और यही वह चीज़ है जिसका मतलब है कि एक sculpting tool कैमरे के नीचे से ज़मीन खोद सकता है और view अगले frame पर रिकवर हो जाता है, काला होने के बजाय।

अंदर snap होना, बाहर easing, और fence posts पर न झिझकना

एक boom जो हर frame बस collision की दूरी पर कूद जाता है, किसी boom न होने से भी बदतर है, क्योंकि वर्ल्ड पतली चीज़ों से भरा है जिनके पीछे कैमरा एक frame के लिए गुज़रता है, एक fence post, एक lamp, एक पेड़ का तना, और एक कैमरा जो हर एक से बचने के लिए झपटता है और वापस झपटता है, मतली पैदा करता है। Haigh-Hutchinson की किताब और Itay Keren का camera motion पर खूब पसंद किया गया talk दोनों एक ही अंतर्ज्ञान पर पहुँचते हैं, कि कैमरे को खतरों और जोखिम पर उससे तेज़ प्रतिक्रिया करनी चाहिए जितनी तेज़ी से वह उनसे आराम पाता है। तो damping जानबूझकर असममित है। जब कोई occluder दिखता है और boom को छोटा होने की ज़रूरत होती है, तो वह लगभग तुरंत अंदर snap हो जाता है, क्योंकि clipping का एक frame भद्दा होता है और प्लेयर एक तेज़ tuck को माफ़ कर देता है। जब occluder साफ़ हो जाता है और boom लंबा होना चाहता है, तो वह धीरे-धीरे बाहर ease होता है, और सिर्फ़ तब जब लगातार साफ़ रहने का एक छोटा dwell timer बीत चुका हो। वह dwell ही वह hysteresis है जो झिझक को खत्म कर देती है। कैमरे को एक पतले post के पास से तेज़ी से घुमाएँ और post कभी इतनी देर तक साफ़ नहीं रहता कि धीमी extension को trigger करे, इसलिए कैमरा उसके पास से ऐसे सरकता है जैसे वह वहाँ था ही नहीं, जो ठीक वही है जो आपकी आँख चाहती है। Cinemachine इसी विचार को collision में damping और collision से बाहर damping के अलग-अलग मानों के रूप में सामने रखता है, और असममितता ही वह हिस्सा है जो इसे एक spring के बजाय एक camera operator जैसा महसूस कराता है।

code में यह exponential smoothing की एक लाइन है जिसकी rate बदलाव के चिह्न पर switch होती है। अगर मौजूदा boom लंबाई है, a वह लंबाई है जिसकी इस frame collision इजाज़त देता है, और Δt frame समय है, तो

+(a)(1ekΔt),k={kinakouta>,kinkout

और ease-out branch सिर्फ़ तब चलती है जब clearance dwell समय τ तक टिकी रहे। 1ekΔt रूप सुथरा दिखने से कहीं ज़्यादा मायने रखता है। यह response time constant को frame rate की परवाह किए बिना 1/k पर तय कर देता है, इसलिए कैमरा 30 और 144 frames प्रति सेकंड पर एक जैसा महसूस होता है, जहाँ भोला constant-blend +α(a) एक तेज़ मशीन पर ज़्यादा तेज़ी से snap होता और एक धीमी मशीन पर लसलसा जाता।

आखिरी behavior उन तंग interiors के लिए है जिन्होंने यह पूरा भाग शुरू किया। जब boom इतना छोटा ढह जाता है कि कैमरा प्लेयर के ठीक ऊपर होता है, तो हम प्लेयर के अपने avatar को छिपा देते हैं और view को first person के पास बैठने देते हैं। यही Breath of the Wild एक तंग shrine में करता है और यही ज़्यादातर third-person games एक कोने में सहारा लेते हैं, क्योंकि विकल्प, एक कैमरा जो दीवार से सटा हुआ एक सिर के पिछले हिस्से को घूर रहा हो, बेकार है। rig इसके लिए एक अकेला flag सामने रखता है, और world loop उस flag को पढ़ता है और local avatar की दृश्यता को toggle करता है। एक मीटर boom से नीचे आप असल में first person में होते हैं, दीवारों का सम्मान होता है, और जिस पल आप जगह वाले किसी कमरे में पीछे हटते हैं avatar वापस fade in हो जाता है और boom बढ़ जाता है।

आगे क्या प्लग होता है

terrain collider आज ship होता है और यही मुश्किल आधा है, क्योंकि terrain हर जगह है और एक distance field probe करने के लिए मुश्किल चीज़ है। authoring spikes के props और building shells आसान आधा हैं, और contract पहले से ही उनका इंतज़ार कर रहा है। एक दूसरा collider, एक raycast collider, pivot से कैमरे की तरफ़ meshes की एक list के खिलाफ़ cast करता है और निकटतम hit को उसी तरह रिपोर्ट करता है जैसे terrain collider करता है। सस्ता संस्करण एक अकेली ray cast करता है, जो तब तक ठीक है जब तक prop की गिनती न चढ़े, और upgrade यह है कि ray को three-mesh-bvh का इस्तेमाल करके एक swept sphere से बदल दें, Garrett Johnson की library जो एक mesh को एक bounding-volume hierarchy में लपेटती है ताकि spatial queries brute force के बजाय log time में चलें। किसी भी तरह rig नहीं बदलता। वह colliders की एक लंबी list से पूछता है और निकटतम hit लेता है, जो पहले contract और बाद में colliders बनाने का पूरा मक़सद है।

इस अध्याय में संदर्भित तकनीक

एक boom जो एक संख्या का मालिक है। camera rig OrbitControls के ऊपर एक post-process है, उसका विकल्प नहीं। यह boom की लंबाई का मालिक है और yaw, pitch, zoom, और gesture handling को उस orbit controller के पास छोड़ देता है जिस पर हम पहले से भरोसा करते थे। integration दो घेरने वाली calls हैं: beforeControls() पिछले frame की पूरी दूरी बहाल करता है ताकि orbit math user की असली zoom पढ़े, न कि एक collision की छोटाई को एक dolly-in समझे, और afterControls(dt) collision सुलझाता है और render की गई position लिखता है। उस जोड़ी के बिना कैमरा कुछ frames में प्लेयर पर ढह जाता है।

एक pluggable collider contract। एक collider कोई भी ऐसा object है जिसके पास एक probe है जो जवाब देता है कि "कैमरा pivot से इस ray के साथ कितना दूर सफ़र कर सकता है इससे पहले कि तुम उसे रोको।" rig हर collider से पूछता है और निकटतम hit लेता है, इस बात से अनजान कि रुकावट terrain है, एक prop है, या एक दीवार है, जो वही एक-चीज़-का-मालिक अनुशासन है जो pluggable character controller ने locomotion के लिए इस्तेमाल किया था। probe एक swept sphere है जो near plane को समाने जितना बड़ा है, एक पतली ray नहीं, इसलिए frustum के कोने कभी किसी ऐसी सतह को clip नहीं करते जिसे केंद्र वाली ray चूक जाती। इसका radius projection से निकाला जाता है, एक near-plane कोने तक की दूरी n2+w2+h2 एक safety margin से गुणा, और जब भी field of view, aspect, या near plane बदलता है तो दोबारा गणना होता है।

एक signed-distance terrain probe जो overhangs और caves का सम्मान करता है। क्योंकि terrain एक heightmap के बजाय एक signed distance field है, वही probe जो कैमरे को एक पहाड़ी की ढलान पर रोकता है उसे एक cave की छत पर भी रोकता है, वह case जिसे एक heightmap raycast संरचनात्मक रूप से नहीं देख सकता। march Hart-शैली का sphere tracing है, field जो ढील रिपोर्ट करता है उसके एक under-relaxed अंश के हिसाब से कदम बढ़ाते हुए और दोनों सिरों पर clamp किया हुआ, क्योंकि heightmap क्षेत्र असली distance के बजाय vertical clearance रिपोर्ट करते हैं और ज़्यादा बताते हैं कि कैमरा एक ढलान पर कितना दूर जा सकता है, इसलिए एक पूरा डग एक चोटी कूद जाता। एक gradient-संचालित depenetration pass वह safety net है जो view को रिकवर करता है जब कैमरे के नीचे से ज़मीन तराश दी जाती है।

dwell timer के साथ असममित damping। boom तब तेज़ी से अंदर snap होता है जब कोई occluder दिखता है और एक बार साफ़ होने पर धीरे-धीरे बाहर ease होता है, और सिर्फ़ लगातार साफ़ रहने की एक छोटी खिड़की के बाद, ताकि एक fence post के पास से तेज़ी से गुज़रना कभी कैमरे को झपटाए नहीं। एक collapse threshold से नीचे rig near-first-person flag करता है और world loop local avatar को छिपा देता है, जो तंग interiors के लिए मानक सहारा है, दीवार में दबे एक कैमरे के बजाय।

संदर्भ

camera control को एक visibility constraint के रूप में ढालना Marc Christie और Patrick Olivier के Camera Control in Computer Graphics (Computer Graphics Forum, 2008) से आता है। distance-field march John C. Hart का Sphere Tracing: A Geometric Method for the Antialiased Ray Tracing of Implicit Surfaces (The Visual Computer, 1996) है। spring-arm pattern और इसका probe-sphere collision Epic के Spring Arm Component और Unity के Cinemachine Deoccluder और Third Person Follow में documented हैं। motion और damping का अंतर्ज्ञान Mark Haigh-Hutchinson की Real-Time Cameras (Morgan Kaufmann, 2009), और Itay Keren के Scroll Back: The Theory and Practice of Cameras in Side-Scrollers (GDC 2015) से है। mesh-collider upgrade path Garrett Johnson का three-mesh-bvh है।


30 में से भाग 30। पिछला: भाग 29 - एक कंट्रोलर, कोई भी बॉडी सीरीज़ गाइड: /hi/blog/2026-02-25-open-world-browser-series-guide