diff options
-rw-r--r-- | img/desmos-braids.png | bin | 0 -> 88993 bytes | |||
-rw-r--r-- | img/goal.png | bin | 0 -> 236856 bytes | |||
-rw-r--r-- | img/hello-fragment.png | bin | 0 -> 769711 bytes | |||
-rw-r--r-- | img/toy-braids.png | bin | 0 -> 157464 bytes | |||
-rw-r--r-- | readme.md | 110 |
5 files changed, 94 insertions, 16 deletions
diff --git a/img/desmos-braids.png b/img/desmos-braids.png Binary files differnew file mode 100644 index 0000000..0776c98 --- /dev/null +++ b/img/desmos-braids.png diff --git a/img/goal.png b/img/goal.png Binary files differnew file mode 100644 index 0000000..848ef4d --- /dev/null +++ b/img/goal.png diff --git a/img/hello-fragment.png b/img/hello-fragment.png Binary files differnew file mode 100644 index 0000000..3dc199c --- /dev/null +++ b/img/hello-fragment.png diff --git a/img/toy-braids.png b/img/toy-braids.png Binary files differnew file mode 100644 index 0000000..e1b760f --- /dev/null +++ b/img/toy-braids.png @@ -1,21 +1,99 @@ -# Voorstel +# Individueel project -Een clone van de Windows Media Player "Batterij" visualizer: +Doel: een clone van de Windows Media Player "Batterij" visualizer: -![voorbeeld](https://static.wikia.nocookie.net/wmpvis/images/7/74/Battery_%28Randomization%29.jpg/revision/latest?cb=20150219231850) +![voorbeeld](img/goal.png) -## Stappenplan +De batterij visualizer ondersteunt een aantal presets. Op de bovenstaande +afbeelding is de 'DrowningFlower' preset te zien. -0. OpenGL tutorial afmaken - - ook opzoeken of mijn laptop de OpenGL code kan draaien op geïntegreerde - graphics kaart **-> dit kan, maar er zijn subtiele verschillen tussen de - implementaties van de OpenGL driver op mijn desktop PC (met nvidia) en - mijn laptop (intel)** (zoals [SPIR-V - reflectie](https://stackoverflow.com/a/78500726/5006337)) -1. Video's vinden van de originele visualizer -2. De visualizer opbreken in een lijst van effecten/beeldgenerators die als - losse shaders geïmplementeerd kunnen worden -3. De shaders implementeren -4. (Als ik tijd over heb) proberen de visualizer live op audio te laten - reageren +Alle presets lijken te bestaan uit het volgende: +- een laag die patronen genereert +- een filter die (voor of na het patroon) het beeld op een unieke manier + vervormt + +Voor elk beeld wordt het nieuwe patroon boven op het vorige beeld getekend. Dit +zorgt voor een soort "visuele galm" die erg lijkt op bijv. een feedbacklus die +je met een analoge videocamera zou kunnen maken ([voorbeeld][september]). + +## Logboek + +Eerst heb ik geprobeerd de "[Hello Triangle][hellotriangle]" tutorial te maken +van <learnopengl.com>. Aan het einde van deze tutorial had ik een simpel +programma dat reageert op window resize events, en die een fragment shader +gebruikt om een enkele driehoek te tekenen in een effen kleur. Omdat het effect +dat ik probeer na te maken geen 3D nodig heeft, was ik van plan alles met +fragment shaders te implementeren. + +Ik had de applicatie hierna nog aangepast om de driehoek schermvullend te +tekenen. Om dit te doen had ik al snel ondekt dat ik de z-coördinaat van +`gl_Position` uit mijn vertex shader op 0 kon zetten, omdat de xyz coördinaten +uiteindelijk door z gedeeld worden. Op mijn NVIDIA kaart zorgde dit zoals ik +verwachtte voor een schermvullende driehoek (die oneindig groot was omdat er +gedeeld wordt door 0), maar op Intel zorgde dit voor een leeg scherm. Ik heb +uiteindelijk de z-coördinaat op 0.001 gezet, en ben hierna direct bewust +geworden van de verschillen tussen graphics drivers. + +Hierna had ik de fragment shader nog wat aangepast om via uniforms de huidige +tijd en schermgrotte binnen te krijgen. De schermgrotte gebruikte ik om een +schermvullende kleurovergang te maken (op het groene en blauwe kleurkanaal), en +de tijd waarde om een ruissignaal te maken (op het rode kleurkanaal): + +![](img/hello-fragment.png) + +Toen dit allemaal werkte vond ik het een goed moment om mijn tooling wat te +verbeteren voor het schrijven en compileren van GLSL. Ik heb gekozen om de +`glslc` 'compiler' te gebruiken, die GLSL omzet naar [SPIR-V][spirv]. Dit heb +ik gedaan zodat ik GLSL compilatiewaarschuwingen krijg tijdens het bouwen van +mijn complete applicatie inplaats van tijdens runtime, en zodat ik de C +preprocessor kan gebruiken tijdens compileertijd, waarmee ik geen broncode hoef +te bundelen met mijn applicatie. De compiler zelf werkt prima op zowel mijn +desktop PC als mijn laptop, maar ik liep hier gelijk weer tegen verschillen +tussen de Intel en NVIDIA graphics drivers aan. + +Ik heb er een uitgebereide [vraag op StackOverflow][so-spirv-reflection] over +gesteld, en ben gewezen op het feit dat de SPIR-V specificatie geen eis stelt +dat drivers die SPIR-V programma's laden reflectie moeten ondersteunen. Dit zou +betekenen dat ik de uniform locaties van mijn fragment shader zou moeten +hard-coden, of toch GLSL gebruiken zodat ik de uniform locaties kan opvragen +via hun naam als string. + +Ik heb ook het build systeem iets uitgebereid om de SPIR-V binaries mee te +linken met linker scripts en gegenereerde C headers om de data door te geven +aan OpenGL functies. Dit was niet bijzonder spannend. + +Om verder te gaan met het maken van het effect dat in de eerste afbeelding in +dit document te zien is, heb ik eerst geprobeerd de spiraalvorm in +[Desmos][desmos-braids] na te maken. Dit was het makkelijkst te doen met een +parametrische functie, wat een duur wiskunde woord is voor een functie die (in +dit geval) een 2D punt geeft voor een willekeurige parameter (t). Deze functie +bestaat uit het dynamische duo, de sinus en cosinus, die samen een cirkel +maken. Bij deze cirkelvorm tel ik een kleinere 'snellere' cirkel op, en deze +functie heeft parameters voor het aantal wikkelingen, en de grootte van de +wikkelingen: + +[![](img/desmos-braids.png)][desmos-braids] + +Deze functie zou ontzettend snel en eenvoudig zijn om te implementeren op de +CPU. Omdat de functie periodiek is kun je met alleen een `for`-lus genoeg +punten uitrekenen om het te laten lijken alsof je een ononderbroken kromme +tekent. Helaas moet zoveel mogelijk in dit project met OpenGL, dus heb ik deze +functie als fragment shader geïmplementeerd. Dit is ontzettend inefficiënt, +omdat je voor elke pixel de parameter t probeert terug te rekenen, inplaats van +andersom. Hierdoor moet de functie een paar duizend keer uitgerekend worden per +pixel. Helaas valt mijn visualizer hiermee buiten de duurzaamheidsdoelen van de +vakbeschrijving. + +![](img/toy-braids.png) + +TODO: +- waarom de framebuffer +- hoe framebuffer +- hoe kleur?? + +[september]: https://www.youtube.com/watch?v=Gs069dndIYk +[hellotriangle]: https://learnopengl.com/Getting-started/Hello-Triangle +[spirv]: https://www.khronos.org/opengl/wiki/SPIR-V +[so-spirv-reflection]: https://stackoverflow.com/a/78500726/5006337 +[desmos-braids]: https://www.desmos.com/calculator/yh3tuebwp8 |