From 28f5ed067b4ed6ce061dd34669fe86ec1dbaeb0a Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Sat, 15 Jun 2024 19:23:16 +0200 Subject: meer wat heb ik gedaan? --- img/almostdone-1.png | Bin 0 -> 454915 bytes img/almostdone-2.png | Bin 0 -> 464156 bytes img/braids-feedback.png | Bin 0 -> 172674 bytes img/done.png | Bin 0 -> 510881 bytes img/opengl-feedback.png | Bin 0 -> 8455 bytes img/toy-feedback.png | Bin 0 -> 131926 bytes readme.md | 80 +++++++++++++++++++++++++++++++++++++++++++----- 7 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 img/almostdone-1.png create mode 100644 img/almostdone-2.png create mode 100644 img/braids-feedback.png create mode 100644 img/done.png create mode 100644 img/opengl-feedback.png create mode 100644 img/toy-feedback.png diff --git a/img/almostdone-1.png b/img/almostdone-1.png new file mode 100644 index 0000000..2f42e33 Binary files /dev/null and b/img/almostdone-1.png differ diff --git a/img/almostdone-2.png b/img/almostdone-2.png new file mode 100644 index 0000000..0f39444 Binary files /dev/null and b/img/almostdone-2.png differ diff --git a/img/braids-feedback.png b/img/braids-feedback.png new file mode 100644 index 0000000..c13df3b Binary files /dev/null and b/img/braids-feedback.png differ diff --git a/img/done.png b/img/done.png new file mode 100644 index 0000000..133d305 Binary files /dev/null and b/img/done.png differ diff --git a/img/opengl-feedback.png b/img/opengl-feedback.png new file mode 100644 index 0000000..481ded5 Binary files /dev/null and b/img/opengl-feedback.png differ diff --git a/img/toy-feedback.png b/img/toy-feedback.png new file mode 100644 index 0000000..ea624d0 Binary files /dev/null and b/img/toy-feedback.png differ diff --git a/readme.md b/readme.md index 6e0c622..736ac41 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,11 @@ 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 +- een filter die het tot nu toe gegenereerde beeld andere kleuren geeft + + (*deze stap heb ik later toegevoegd omdat het makkelijker is om een zwart-wit + beeld te tekenen, en hier de kleuren van te mappen, inplaats van direct in + kleur te werken en rekening te houden met doorzichtigheid en blending*) 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 @@ -79,21 +84,82 @@ 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 +functie als fragment shader geïmplementeerd (binnen ShaderToy omdat het +makkelijk was voor prototypes maken). 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) +[![](img/toy-braids.png)][shadertoy-braids] + +Hierna heb ik (ook met behulp van ShaderToy) een prototype gemaakt van het +video feedback effect. ShaderToy maakt het heel makkelijk om framebuffers op +willekeurige inputs te zetten, en maakte het snel mogelijk om een draaiende +cirkel met een feedback effect te maken. + +[![](img/toy-feedback.png)][shadertoy-feedback] + +Om dit zelfde effect in OpenGL te maken moest ik alleen handmatig een +framebuffer aanmaken. Om dit te doen heb ik deels stappen gevolgd van +[LearnOpenGL][framebuffers]. Ook heb ik mijn draw loop aan moeten passen om +eerst de 'custom' framebuffer en eerste fragment shader te gebruiken, en daarna +de output framebuffer en tweede fragment shader. + + +![](img/opengl-feedback.png) + +Omdat het algoritme die de spiraalvorm tekent zo traag draait heb ik +uiteindelijk besloten de visualizer te tekenen op een vaste resolutie van +800x600, net als Windows Media Player. Dit zorgt ervoor dat resolutie geen +invloed meer heeft op de snelheid van het effect, maar dat er wel merkbare +upscaling wordt toegepast bij hogere resoluties. Dit was makkelijk te +realiseren, door gewoon niks te doen met de framebuffer, en de tweede fragment +shader (die nog wel op volledige resolutie draait), te laten samplen van de +vaste 800x600 texture van de eerste pass. + +Hierna heb ik de feedback shader code samengevoegd met die van de spiraalvorm, +en daar kwam het volgende uit: + +![](img/braids-feedback.png) + +Om ervoor te zorgen dat het gerecyclede beeld weg zou krimpen, inplaats van +stil blijft staan, kun je gewoon de samplecoördinaten vermenigvuldigen met een +vergroottingsfactor. Dit moet alleen wel gedaan worden met (0.5, 0.5) als +middenpunt, omdat de texture coördinaten genormaliseerd zijn tussen (0, 0) en +(1, 1). Om het beeld te draaien gebruik je een 2D rotatiematrix, en deze kun je +gewoon toe passen door de texturecoördinaten ermee te vermenigvuldigen. + +Ook heb ik een paar parameters die in het [Desmos voorbeeld][desmos-braids] +zaten met wat willekeurig geplukte sinusfuncties laten bewegen. Dit leverde het +volgende beeld op: + +![](img/almostdone-1.png) + +Naast de kleuren en het feit dat de spiraalvorm in het origineel veel kleiner +is, viel mij om dat je de rand van de vorige beelden heel duidelijk kan zien in +het origineel. Het beeld zelf heeft geen duidelijk zichtbare rand, dus +misschien is dit een bijwerking van de graphics API die gebruikt wordt door +Windows Media Player. Om dit toch na te maken heb ik met een paar if statements +gewoon een rand toegevoegd aan het beeld. Hierdoor lijkt het effect er al een +stuk meer op: + +![](img/almostdone-2.png) + +Om het nu helemaal af te maken heb ik het zwart-wit naar een kleurovergang +gemapt met behulp van de GLSL `mix()` functie. De grijswaarde van het beeld pak +ik gewoon van een willekeurig kleurkanaal, omdat alle kleuren toch geen tint +bevatten. De kleuren van de kleurovergang heb ik geprobeerd zo dicht mogelijk +op de originele visualizer te pakken: -TODO: -- waarom de framebuffer -- hoe framebuffer -- hoe kleur?? +![](img/done.png) +![](img/goal.png) [september]: https://www.youtube.com/watch?v=Gs069dndIYk [hellotriangle]: https://learnopengl.com/Getting-started/Hello-Triangle +[framebuffers]: https://learnopengl.com/Advanced-OpenGL/Framebuffers [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 +[shadertoy-braids]: https://www.shadertoy.com/view/XX3SRr +[shadertoy-feedback]: https://www.shadertoy.com/view/X3cGz2 -- cgit v1.2.3