Godot में लागू FFT-आधारित समुद्री लहर रेंडरिंग
(github.com/2Retr0)- GodotOceanWaves, Godot Engine में directional ocean wave spectrum के inverse Fourier transform का उपयोग करके खुले समुद्र की सतह बनाने वाला एक rendering experiment है, और real-time script-adjustable parameters के साथ अलग-अलग समुद्री वातावरणों का अनुकरण करता है
- Gerstner waves शांत पानी के low-frequency details के लिए उपयुक्त हैं, लेकिन उग्र खुले समुद्र की सतह के लिए उनकी सीमाएँ हैं, इसलिए यह प्रोजेक्ट अनुभवजन्य oceanography data-आधारित spectrum और FFT का उपयोग करता है
- लहर निर्माण Tessendorf पद्धति का पालन करता है: पहले initial spectrum state बनती है, फिर dispersion relation के साथ उसे समय के अनुसार propagate किया जाता है, और उसके बाद inverse Fourier transform से displacement, normal, और foam maps बनाए जाते हैं
- rendering, Atlas GDC प्रस्तुति के BSDF का अनुसरण करता है, लेकिन GGX distribution का उपयोग करता है; foam उन क्षेत्रों में accumulate और decay होता है जहाँ displacement का Jacobian negative होता है, और sea spray को Godot के GPUParticles3D तथा custom shader से लागू किया गया है
- multi-wave cascade, update-rate control, और cascade-वार load distribution के जरिए tiling और GPU workload को संभाला जाता है, लेकिन सभी cascades को एक ही spectrum texture resolution का उपयोग करना पड़ता है और sea spray particle approach में density बढ़ाने की efficiency कम है
GodotOceanWaves क्या करता है
- GodotOceanWaves Godot Engine में खुले समुद्र की rendering का एक experimental project है
- लहर निर्माण के लिए directional ocean wave spectrum के inverse Fourier transform का उपयोग किया जाता है
- exposed parameters को सरल रखा गया है, और उन्हें script के जरिए real time में बदलकर अलग-अलग समुद्री लहर वातावरणों का अनुकरण किया जा सकता है
- demo video के रूप में
ocean_demo.mp4औरenvironment_demo.mp4शामिल हैं
Gerstner waves के बजाय Fourier-आधारित लहरें क्यों इस्तेमाल की जाती हैं
- गेम्स में पानी को animate करने का एक सामान्य तरीका Gerstner waves के जरिए vertices को displace करना है
- Gerstner waves शांत पानी के low-frequency details को मॉडल करने के लिए उपयुक्त हैं, लेकिन खुले समुद्र की उग्र सतह को सटीक रूप से दिखाने में कमज़ोर पड़ती हैं
- अगर oceanographers द्वारा एकत्र किए गए अनुभवजन्य data-आधारित ocean wave spectrum का उपयोग किया जाए, तो किसी विशेष समुद्री स्थिति को बनाने के लिए किन लहरों और parameters को बदलना है, इसे अधिक सीधे ढंग से नियंत्रित किया जा सकता है
- FFT की complexity पारंपरिक discrete Fourier transform के
O(N^2)से कम, यानीO(N log N)होती है, और यह parallel systems तक scale कर सकती है, इसलिए GPU execution के लिए उपयुक्त है - Gerstner waves में हर thread को
Nलहरों के लिए गणना करनी पड़ती है, जबकि FFT-आधारित लहरों में हर thread केवलlog(N)के अनुरूप गणना करता है
shading, foam, और sea spray
- ocean lighting model मुख्यतः Atlas GDC प्रस्तुति के BSDF का अनुसरण करता है
- microfacet distribution के लिए Beckmann की जगह GGX का उपयोग किया गया है
- क्योंकि GGX के अधिक सपाट और मुलायम highlights ने परीक्षण किए गए कई ocean wave environments में अधिक समान appearance दिया
- normal/foam maps को world-space pixel density के अनुसार bicubic और bilinear filtering मिलाकर sample किया जाता है
- कम surface resolution पर यह texture aliasing artifacts को कम करता है, और अधिक surface resolution पर detail बनाए रखता है
- Sea foam Tessendorf पद्धति के अनुसार उन स्थानों पर उत्पन्न होती है जहाँ wave crest अंदर की ओर मुड़ती है, यानी जहाँ displacement का Jacobian negative हो
- foam कई wave updates के दौरान texture पर linearly accumulate होती है
"foam grow rate"और"foam decay rate"parameters क्रमशः accumulation और exponential decay को नियंत्रित करते हैं
- Sea spray को Godot के
GPUParticles3Dnode और custom particle shader से लागू किया गया है- particles को
GPUParticles3Dbounding box के भीतर एक plane पर uniformly distribute किया जाता है - उस स्थान पर foam की मात्रा के आधार पर उन्हें cull किया जाता है, और जो particles cull नहीं होते वे random offset से अपनी lifecycle शुरू करते हैं
- हर particle एक static texture वाले billboard sprite का उपयोग करता है
- lifecycle के दौरान scale और displacement बदलकर splash appearance का अनुकरण किया जाता है, और mesh shader का dissolve effect हवा में spray के atomize होने जैसा एहसास देता है
- particles को
- इस sea spray approach की बड़ी कमी यह है कि particle count बहुत बढ़ाने पर भी density में वृद्धि बहुत कम होती है
- क्योंकि particles bounding box में uniformly वितरित होते हैं और जोड़े गए अधिकांश particles cull हो जाते हैं
wave simulation pipeline
- surface waves बनाने की विधि Tessendorf का काफ़ी नज़दीकी रूप से अनुसरण करती है
- directional ocean wave spectrum function को Gaussian-distributed random numbers से गुणा करके initial spectral ocean state बनाई जाती है
- initial state को waves की frequency और propagation speed को जोड़ने वाले dispersion relation के साथ समय के अनुसार propagate किया जाता है
- propagated state पर inverse Fourier transform लागू करके displacement map और normal map बनाए जाते हैं
- implementation, Godot की
RenderingDeviceabstraction का उपयोग करने वाली compute shader pipeline से बनी है
ocean wave spectrum की संरचना
- directional ocean wave spectrum function
S(ω, θ)किसी दी गई frequencyωऔर directionθपर wave energy लौटाती है - यह function nondirectional spectrum function
S(ω)और directional spreading functionD(ω, θ)से मिलकर बनती है, और दोनों के चयन एक-दूसरे से स्वतंत्र हैं - nondirectional spectrum के लिए Horvath द्वारा वर्णित Texel-Marsen-Arsloe(TMA) spectrum का उपयोग किया गया है
- TMA, wind speed
U, water depthD, और fetch lengthFका उपयोग करता है - TMA अपने पूर्ववर्ती JONSWAP spectrum और water-depth attenuation function को जोड़ता है
- TMA, wind speed
- directional spreading function के लिए Horvath के flat और Hasselmann directional spreading को
spreadparameterμके साथ मिलाने वाली विधि का उपयोग किया गया है- इसमें Horvath द्वारा प्रस्तावित
swellparameterξभी शामिल है, जो ocean waves के elongation को मॉडल करता है - Hasselmann directional spreading को इसलिए चुना गया क्योंकि यह normalization coefficient
Q(σ)के लिए approximate analytic solution देता है
- इसमें Horvath द्वारा प्रस्तावित
- Tessendorf के प्रस्ताव के अनुसार, अंतिम spectrum function को small-wave suppression term से भी गुणा किया जाता है
- यह term wave number vector magnitude
kऔरdetailparameterδका उपयोग करती है
- यह term wave number vector magnitude
- अंतिम directional ocean wave spectrum, TMA, mixed directional spread, और small-wave suppression को जोड़ती है
GPU FFT implementation
- FFT के लिए compute shader में लिखी गई custom GPU implementation का उपयोग किया गया है
- Cooley-Tukey की जगह Stockham FFT algorithm का उपयोग किया गया है ताकि शुरुआती bit-reversal permutation से बचा जा सके
- Flügge के अनुसार, FFT के data flow को encode करने वाली
"butterfly"texture की गणना की जाती है- यह texture spectrum texture resolution बदलने पर हर बार एक बार गणना की जाती है
- 2D FFT में पहले spectrum texture की rows पर FFT kernel लागू किया जाता है
- उसके बाद compute shader से texture को transpose किया जाता है ताकि उसी row-direction FFT kernel को column-direction FFT की तरह दोबारा इस्तेमाल किया जा सके
- transpose न केवल pipeline reuse को संभव बनाता है, बल्कि memory access pattern को भी बेहतर करता है
wave cascade और tiling से निपटना
- दूर की दूरी पर, खासकर sea foam के साथ, tiling artifacts बहुत स्पष्ट हो जाते हैं
- wave generation system इस समस्या से निपटने के लिए कई wave cascades को एक साथ layer कर सकता है
- हर cascade का अपना tiling size और parameter set होता है
- cascades को real time में dynamically जोड़ा या हटाया जा सकता है
- चूँकि सभी cascades एक ही compute pipeline का उपयोग करते हैं, इसलिए उनके पास एक ही spectrum texture resolution होना चाहिए
- एक वैकल्पिक तरीका यह है कि wave displacement और normals को noise के साथ blend करके कम performance cost पर tiling artifacts घटाए जाएँ
- cascades को ओवरलैप करते समय wave interference से बचने के लिए हर cascade के parameters और size को सावधानी से चुनना पड़ता है
- cascade की wave phase भी एक-दूसरे से interfere न करे, इसके लिए उसे offset किया जाना चाहिए
- system हर cascade के start time को अलग-अलग offset करके इसे अपने आप करने की कोशिश करता है
- साथ ही यह caveat भी दिया गया है कि यह तरीका वास्तव में काम करता है या नहीं, यह निश्चित नहीं है
update load distribution
- waves की गति अनियमित होती है, इसलिए हर frame पर displacement अपडेट न करने पर भी दृश्य रूप से smooth महसूस हो सकता है
"update rate"parameter नियंत्रित करता है कि wave cascade को प्रति सेकंड कितनी बार अपडेट किया जाए- frames skip करने से FFT में लगने वाला GPU time कम होता है, लेकिन जिन frames में wave generation pipeline चलती है उनमें stutter फिर भी होता है
- Godot के local
RenderingDeviceके साथ cascade updates को asynchronous computation बनाने का प्रयोग, CPU और GPU के बीच texture transfer के कारण बड़ा performance overhead लाया - इसके बजाय system cascade की load distribution करने की कोशिश करता है
- अगर frame time, update rate से छोटा हो, तो हर frame में केवल एक cascade अपडेट किया जाता है
- यह तरीका stutter को कम करते हुए frame skipping से मिलने वाले कम GPU workload के लाभ को बनाए रखता है
संदर्भ सामग्री
- Realtime GPGPU FFT Ocean Water Simulation: Fynn-Jorin Flügge, Hamburg University of Technology, 2017
- I Tried Simulating The Entire Ocean: Garrett Gunnell, 2023
- Empirical Directional Wave Spectra for Computer Graphics: Christopher J. Horvath, DigiPro, 2015
- Simulating Ocean Water: Jerry Tessendorf, SIGGRAPH, 2004
- Implementing Fast Fourier Transform Algorithms of Real-Valued Sequences: Robert Matusiak, Texas Instruments, 2001
- Wakes, Explosions and Lighting: Interactive Water Simulation in 'Atlas': Mark Mihelich, GDC, 2019
- FFT-Ocean: Ivan Pensionerov, GitHub, 2020
1 टिप्पणियां
Hacker News की रायें
इस व्यक्ति के बनाए दो अन्य Godot repositories भी बहुत दिलचस्प हैं। repositories का वर्णन करते समय वह काफी details डालता है, यह बात अच्छी लगी, और खास तौर पर यह repository ध्यान खींचती है: https://github.com/2Retr0/GodotGaussianSplatting
सोच रहा हूँ कि क्या वह छात्र है। वह अक्सर दूसरे कामों का हवाला देता है, और हाल में प्रकाशित सामग्री को काफी अच्छी तरह समझता हुआ दिखता है
ENGR96A-coursework,Relevant coursework for ENGR 96A Introduction to Engineering Design F23है, और commit dates के हिसाब से F23 का मतलब शायद 2023 का fall semester हैबेशक, repository में जिन UCLA classes का ज़िक्र है वे सबके लिए public भी हो सकती हैं, इसलिए यह ज़रूरी नहीं कि उन्हें लेने के लिए पारंपरिक अर्थ में UCLA में enrolled छात्र होना ही पड़े
20 साल पहले rendering में समुद्र की सतह को महीनों tweak करने के बाद भी शायद हम इस स्तर के आसपास भी नहीं पहुँच पाते। वाकई बहुत अच्छी तरह बनाया गया output है
हालांकि demo video थोड़ा exaggerated लगता है। sailing logs में खुले समुद्र की 50,000 nautical miles से ज़्यादा यात्रा के अनुभव से कहूँ तो, इतनी नुकीली और ऊँची लहरों के लिए हवा कहीं ज़्यादा तेज़ चलनी चाहिए। फिर भी लगता है कि यह parameters adjust करने वाली बात है
अगर यह Godot में बना है, तो क्या इसे real-time rendering माना जा सकता है? यह भी जानना चाहूँगा कि क्या monster-class GPU चाहिए
साथ ही यहाँ sea spray post-effect जैसा लगता है, जबकि असली समुद्र में spray लहरों की sharpness को blunt कर देता है और visually भी हल्का-सा दिखता है
बेशक इस elegant, simple और effective model में लगभग physics नहीं है, इसलिए इसे हाथ बाँधकर की गई आलोचना की तरह नहीं, बल्कि अलग-अलग directions में poke करके try करने के सुझावों की तरह लें
इस विषय पर मेरे पसंदीदा videos में से एक: https://m.youtube.com/watch?v=yPfagLeUa7k
यह भी ठीक है: https://m.youtube.com/watch?v=kGEqaX4Y4bQ
इसकी जगह मैं हर weekend water shader के साथ खेलता रहता हूँ, जब तक मनचाहा look न मिल जाए। लेकिन मेरा game puzzle game है, इसलिए पानी की ज़रूरत ही नहीं। अब बस एक शानदार start screen बन गई है
आजकल यह game engine में बस एक checkbox है, और ऐसी अनगिनत features हैं। modern engines ने कितना अच्छा environment दे दिया है, लोग इसका ठीक से अंदाज़ा नहीं लगा पाते
इस काम की value कम करने की बात नहीं है; यह सचमुच शानदार achievement है और creator को salute। बस कहना चाहता था कि हम कितने अच्छे दौर में हैं
फिर भी यह बहुत अच्छा दिखता है, और हाल में मैंने जितना हल्का-फुल्का search किया, उसमें संभव विकल्पों में शायद best-in-class है
व्यक्तिगत रूप से, मैं खुले समुद्र की लहरों को आम तौर पर थोड़ी ज़्यादा rhythm के साथ देखना चाहूँगा। उत्सुक हूँ कि 15-knot हवा जब 1 km पानी की सतह पर कई घंटों तक चलती है, तो simulation क्या वैसा match करती है जैसा असल में दिखता है—यानी relatively organized breakers बनते हैं और फिर बिखरते हैं
ऐसी ही चीज़ों ने मुझे computer world में खींचा था, लेकिन कब मैं libraries, endpoints और corporate bakwaas को जोड़ने वाली आसान और boring जिंदगी में फँस गया, जो burnout की ओर ले जा रही है, पता ही नहीं चला
उम्मीद है किसी दिन वापस लौट सकूँगा
try कीजिए। हम सब support कर रहे हैं
approach अलग है, लेकिन अगर wave/ocean simulation में रुचि है, तो Acerola ने इस topic पर, हमेशा की तरह, एक बेहतरीन video डाला है। https://youtu.be/PH9q0HNBjT4 और https://youtu.be/yPfagLeUa7k
edit: इनमें से एक reference list में पहले से link था, लेकिन nickname के बजाय real name से था, इसलिए अब जाकर पहचाना
यह समस्या कितनी कठिन है, यह दिलचस्प है। दशकों से कोशिश हो रही है, फिर भी अभी तक uncanny valley में ही है
अगर इस scene को pause करें तो उठी हुई लहरें बर्फ़ीले पहाड़ जैसी दिखती हैं। पानी को इतना sharp shape पाने के लिए हवा काफी तेज़ होनी चाहिए, लेकिन हवा सीधे ऊपर तो नहीं चलेगी, इसलिए यह unreal लगता है। ऐसे sharp features में directionality होनी चाहिए
फिर भी swell waves की nature काफी अच्छी पकड़ी है। horizontal movement से ज़्यादा up-and-down movement है, जो open ocean में expected है
पता नहीं वे light transmission कैसे simulate करते हैं, लेकिन यह अच्छा काम करता है। sunrise या sunset के समय लहरों के बीच से आती रोशनी शानदार लगती है और effect को सचमुच believable बना देती है
इसे थोड़ा painterly कहा जा सकता है, लेकिन यह गलत नहीं लगता
मैं कई साल beach पर रहा हूँ। beach पर रहने पर समुद्र इतना mesmerizing और sensory रूप से अच्छा लगता है कि आप उसे घंटों देखते रहते हैं। इसे देखकर मुझे एक पल के लिए भी नहीं लगता कि यह rendering है
Shadertoy पर भी एक अच्छा example है: https://www.shadertoy.com/view/Ms2SD1
Fourier को tidal waves measure करते हुए wave frequency transform का idea आया था, इसलिए एक तरह से यह लगभग full circle जैसा है
बेहद impressive
शानदार है, लेकिन बहुत बड़ी waves में यह approach nonlinearity की वजह से कुछ हद तक टूट जाएगी। water waves sine waves नहीं होतीं, लेकिन छोटी और medium-height waves में इतनी मिलती-जुलती होती हैं कि यह method बहुत अच्छी तरह काम करता है
बहुत बड़ी waves सिर्फ sine waves से बहुत अधिक अलग ही नहीं होतीं, बल्कि waves आपस में nonlinear तरीके से interact करने लगती हैं, जिसे यहाँ इस्तेमाल किया गया linear superposition approach capture नहीं कर सकता
इसलिए ज़्यादातर sea states के लिए यह fantastic है। लेकिन अगर ‘Perfect Storm’ जैसी waves realistically बनानी हों, तो अलग approach चाहिए
बहुत impressive है और अब तक देखी चीज़ों से बेहतर है, लेकिन swell थोड़ा off लगता है। अगर समझाने की कोशिश करूँ, तो video जैसा high-frequency waves low-frequency waves के ऊपर सवार होकर चलती हुई नहीं दिखतीं