跳转至

Jendrik Illner

Graphics Programming weekly - Issue 345 - June 23rd, 2024


[video] GDC 2024 - GPU Work Graphs: Welcome to the Future of GPU Programming

  • the GDC video presents a discussion of the new work graph features for D3D (also a Vulkan AMD-specific extension exists)
  • explains the issue with the current ExecuteIndirect model
  • shows an overview of the API model and how it aims to solve the challenges
  • presents an overview of a compute shader rasterizer and a runtime GPU scattering system based on the technology
  • additionally discusses the support level


CPU performance optimization guide – part 1

  • the first blog in a series about CPU optimizations
  • this part presents how different implementations of max between floats can generate very different code
  • presents the effect of branch misprediction on performance and how to use the AMD profiler to detect through hardware counters


[video] I3D 2024 Papers Session 6 - Efficient Forward and Differentiable Rendering

  • the video recording of I3D 2024 sessions covers the following papers
  • Efficient Particle-Based Fluid Surface Reconstruction Using Mesh Shaders and Bidirectional Two-Level Grids,  ShaderPerFormer: Platform-independent Context-aware Shader Performance Predictor
  • Transforming a Non-Differentiable Rasterizer into a Differentiable One with Stochastic Gradient Estimation
  • these papers cover a focus on performance from an academic focus


Jobs

C++ Gameplay and UI Programmers

Auckland, New Zealand

Grinding Gear Games are seeking experienced C++ Gameplay and UI Programmers to join our incredibly talented team. We’re after programmers to help design and implement gameplay and UI elements for Path of Exile using modern C++.


[video] Triangle Visibility Buffer 2.0

  • the talk provides an overview of the experimental Triangle Visibility Buffer 2.0 implementation
  • The presented approach uses only compute shaders to write the visibility buffer
  • discusses the pipeline design, different approaches based on triangle sizes, and how performance compares
  • additionally presents which features are still missing compared to hardware rasterization


From microfacets to participating media: A unified theory of light transport with stochastic geometry

  • the paper presents a method that aims to unify microfacets and volumes for light transport purposes
  • the paper shows that both can be expressed as stochastic implicit surfaces (SIS) and, more specifically, Gaussian process implicit surfaces (GPIS)
  • discusses the derivation, representation generation, and tracing aspects of GPIS
  • additionally discusses limitations regarding performance and quality


5 Reasons Why Box Plots are the Better Default Choice for Visualizing Performance

  • the blog post presents why the author suggests using box plots over bar charts as the default way to represent performance
  • shows annotated examples of how box plots can express a lot of helpful information in a concise form


Thanks to Jon Greenberg for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 344 - June 17th, 2024


[video] REAC 2024 DAY 1 Testing Rendering Code at Frostbite

  • the talk presents the system used by EA’s Frostbite team to test the rendering engine
  • shows an overview of the current state of the system and why they are the way they are
  • discusses all the complexities and difficulties
  • shows the tooling available and how different tools exist for different use cases
  • additionally discusses trade-offs and development approaches


[video] Coding Adventure: Optimizing a Ray Tracer (by building a BVH)

  • the video explains the concept of a BVH (bounding volume hierarchy) and presents how it increases the performance of a raytracing implementation
  • shows a detailed explanation and many visualizations of the behavior of the data structure and how to build an efficient implementation
  • presents different heuristics that can be used to order the data for efficient access
  • shows the results and presents performance improvements


Raymarching explained interactively

  • the article provides an interactive walkthrough into the implementation of the Raymarching algorithm
  • explains the logic of signed distance functions in 2D and expands these to 3D
  • presents the implementation of a simple 3D raymarching scenes
  • the provided code samples are interactive and can be used to get a better understanding of the presented techniques through experimentations


[video] Quaternions to Homogeneous Points, Lines, and Planes

  • the second path of the math tutorial series from GDC 2024 extends the dual quaternion knowledge (see last week 338 for prerequisite)
  • starts by developing an intuition for plane representation (normal + distance), difference between positions and directions, and behavior under reflections
  • additionally explains the understanding of homogenous concepts


[video] REAC 2024 DAY 2 Modernizing geometry rendering in Alan Wake 2

  • the presentation presents updates done to the rendering pipeline of the internal engine used for Alan Wake 2
  • focuses on explaining the technique selection and why the choices were made
  • in-detail discusses the meshlet geometry pipeline and changes to the material system
  • additionally discusses updates on the used transparency models


[video] I3D 2024 Papers Session 5 - Noise and Reconstruction

  • the video recordings of Noise and Reconstrictions papers from I3D have been released
  • covers  FAST: Filter-Adapted Spatio-Temporal Sampling for Real-Time Rendering, Filtering After Shading With Stochastic Texture Filtering, and Cone-Traced Supersampling for Signed Distance Field Rendering


The engine of the future.

  • following the REAC 2024 conference, this author composes his 10 predictions on how graphics engine architecture might evolve
  • looks back at the history, current developments and looks into the future
  • additional discusses how mobile requirements vary and how it might indicate a future on consoles and PCs as well


Thanks to Graham Wihlidal for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 343 - June 9th, 2024


[video] Rendering Engine Architecture Conference

  • the video recordings for the Rendering Engine Architecture Conference have been released
  • covering a large number of topics from resource management, GPU-based mesh pipeline, testing approaches, and much more


Virtual Geometry in Bevy 0.14

  • the blog post provides a detailed discussion of implementing meshlet-based virtual geometry rendering into Bevvy
  • discusses how meshlet LODs are calculated, how meshlet culling has been implemented, and how they are rendered without mesh shader support
  • presents findings from different approaches and discusses the pros/cons of the various approaches
  • Additionally, it shows the integration work for supporting systems (depth pyramid generation, material shading, etc.).


How I learned Vulkan and wrote a small game engine with it

  • the blog post discusses the author’s experience learning Vulkan through the development of a small 3d engine
  • presents the approach for keeping things focused and decisions leading to using Vulkan
  • explains the API concepts and how they are used in the engine (shaders, pipelines, queues, etc.)
  • additionally presents how higher-level techniques are implemented inside the engine


Seiler’s Interpolation

  • the short paper presents how to reformat bezier interpolation using cheaper functions
  • shows the implementation of quadratic, cubic, and higher-order polynomials
  • additionally shows how a GPU implementation could take advantage of hardware linear interpolation


On Hash Functions for the GPU

  • the article presents a geometric and statistical analysis of the PCG2D hash function
  • explains the terminology of random number generators and how they can be mapped onto GPUs
  • visualization of provided using shader toys


Machine Learning on the GPU - Case Study: Open Image Denoise

  • the blog post provides a high-level view that explains machine learning concepts for practical usage by graphics programmers
  • presents the individual concepts and how DirectML maps them into compute shaders
  • additionally presents an overview of the different passes that make up the Open Image Denoise implementation


Academy Software Foundation Releases OpenPBR 1.0

  • the blog post introduces the release of the first stable release of OpenPBR
  • discusses the importance of the standard and the history of its development
  • MaterialX now contains a reference implementation of the model


Perspective-Correct Interpolation

  • the article presents how a rasterizer calculates intermediate values on a triangle
  • explains barycentric Interpolation and explains the cause for common artifacts on PS1-level hardware
  • then derives perspective-correct Interpolation that resolves the artifacts  


[video] I3D 2024 Papers Session 4 - Points and Splats

  • The videos for I3D paper presentations have been released
  • covering Reducing the Memory Footprint of 3D Gaussian Splatting, SimLOD: Simultaneous LOD Generation and Rendering for Point Clouds
  • additional Deblur-GS: 3D Gaussian Splatting from Camera Motion Blurred Images as well as Light Field Display Point Rendering


[video] The OpenGL Software Ecosystem

  • the video provides an overview of the OpenGL Ecosystem
  • explains the history of OpenGL and how OS integration compares to Direct3D
  • presents what software layers are involved and which software components enable easier cross-platform development


Thanks to Cort Stratton for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 342 - June 2nd, 2024


Efficient Visibility Reuse for Real-time ReSTIR

  • the paper presents a variance reduction technique for ReSTIR aimed at reducing shadow noise
  • presents a comparison against existing methods
  • discusses side-effects of the technique


[video] I3D'24 Technical Paper: Filtering After Shading with Stochastic Texture Filtering

  • extended presentation of the I3D paper presentation discussed last week
  • the paper presents an investigation into applying texture filtering after shading instead of before shading
  • shows comparisons of the approaches and a background into the underlying theory
  • presents guidelines on the tradeoffs and when to use different approaches


Specular Polynomials

  • the paper presents a way to reformulate SDS (a path with at least a specular, diffuse, specular bounce) paths into a polynomial system
  • explains how to use root finding to solve the paths
  • shows the presented solutions for caustics in a unidirectional ray tracer


Ray Tracing with Voxels in C++ Series – Part 6

  • the article series extends the voxel rendering implementation to use path tracing
  • discusses and explains the different components of the rendering equation
  • additionally presents the effect of importance sampling for reduced convergence time


Microsoft® DirectSR and AMD FidelityFX™ Super Resolution technology

  • the blog post explains the new DirectSR (Super Resolution) API
  • provides a walkthrough of the API and how to integrate it into an existing engine
  • provides an overview and discussion of the different exposed parameters


DXC 1.8.2405 Available Now, Including HLSL 202x

  • the blog post introduces the ongoing work of implementing future HLSL versions directly into Clang
  • discusses the expected difference between legacy and future HLSL versions
  • additionally shows the first version of DXC compiled with clang and performance improvement


Renderdoc - Version v1.33

  • the latest version of Renderdoc includes a custom and improved DXIL disassembler
  • additionally lists the improvements for SM6.6 feature support


Real-Time Physically Guided Hair Interpolation

  • the paper presents a new method that aims to improve hair interpolation from a smaller number of guided hairs
  • presents the theory and implementation of the technique
  • compares against existing solutions in quality and performance


Implementing General Relativity: Rendering the Schwarzschild black hole, in C++

  • the blog post provides a high-level introduction to general relativity
  • takes the underlying theory and shows how to convert it into code
  • shows a C++ based implementation of the technique


Texture Streaming

  • the blog post discusses the streaming system implementation in the Wicked Engine
  • discusses how the data is provided, loading streaming processed in the background, and finalized for rendering
  • additionally discussed techniques to improve streaming information, such as GPU streaming feedback buffers


[video] I3D 2024 Papers Session 2 - Light Transport and Storage

  • video of the I3D 2023 Paper session on Light Transport
  • covers Bounded VNDF Sampling for the Smith–GGX BRDF, ZH3: Quadratic Zonal Harmonics and  Interactive Rendering of Caustics using Dimension Reduction for Manifold Next-Event Estimation


Thanks to Matt Pharr for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 341 - May 26th, 2024


Construction of a Microfacet Specular BSDF: A Geometric Approach

  • the paper provides a walkthrough explanation of the different components that define a BSDF (bidirectional scattering distribution function) that defines the shading behavior of a materials
  • covers the underlying theory, explaining the derivation as well as the geometric interpretations


Hemispherical Lighting Insights

  • the paper introduces models to solve the reconstruction of irradiance in the vertex-normal space
  • applies the developed framework to hemispherical and cone occlusion to volumetric lighting
  • as well as mitigating light leakage for normal-mapped surfaces’ appearance of runtime ambient occlusion
  • shadertoy implementation is provided


Ray Tracing with Voxels in C++ Series – Part 5

  • the series on voxel ray tracer continues by presenting how to accumulate samples over time with a nonstatic camera
  • explains temporal pixel reprojection, how to deal with sub-pixel blending, and how to improve results with occurring object occlusions


Getting Started In Computer Graphics

  • the blog post provides a detailed description for programmers interested in graphics programming
  • explains what the job entails, different specializations in games, and what topics graphics programmers often work on
  • additionally gives insights into the technologies the author recommends to start learning with


Sun Beams / God Rays Shader Breakdown

  • the article explains an approach to implementing Sun Beams using Billboarding techniques
  • implementation is shown using the visual shading language of Unity


Agility SDK 1.614.0: R9B9G9E5 support for Render Targets and UAVs

  • the blog post presents that the latest D3D12 SDK update introduces support for R9B9G9E5 for Render Target and UAVs
  • explains how the R9B9G9E5 format allows higher precisions compared to half-floats and less memory usage than float formats
  • additionally expressed the importance of verifying hardware support


Unity Shader Graph Basics (Part 8 - Scene Intersections 1)

  • the video shows how to implement a shader effect that allows objects to change their appearance close to existing depth values in the depth buffer
  • the presented technique relies on a rendering order that ensures the depth values are written before the objects want to read them
  • technique is implemented using the visual shader language of Unity  


Recording the clear command // Vulkan For Beginners #9

  • the video tutorial continues to discuss the implementation of a Vulkan renderer
  • this week’s videos explain how to clear the back buffer to a solid color in every frame
  • C++ implementation is shown


Thanks to Graham Wihlidal for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 340 - May 19th, 2024


Filtering After Shading with Stochastic Texture Filtering

  • the paper presents an investigation into applying texture filtering after shading instead of before shading
  • shows comparisons of the approaches and a background into the underlying theory
  • presents guidelines on the tradeoffs and when to use different approaches


Death To Shading Languages

  • the author presents his view on shading languages and the (lack of) evolution
  • discusses the shortcomings and issues arising from them
  • shows an outlook on why the concept of shading language is outdated and should be retired


Real-Time Path Guiding Using Bounding Voxel Sampling

  • the paper introduces a path-guiding method that utilizes an irradiance voxel data structure
  • the presented method is a spatial distribution
  • shows an evaluation of static and dynamic scenes, containing quality and performance


Area ReSTIR: Resampling for Real-Time Defocus and Antialiasing

  • the paper introduces Area ReSTIR that extends ReSTIR to be able to be applied to sub-pixel details
  • presents how to allow the reservoir to integrate with the area for the lens and film
  • shows the technique applied to depth of field and antialiasing


Ray Tracing with Voxels in C++ Series – Part 4

  • the article continues the series that covers the implementation of a voxel raytracer
  • this week explains the concept of noise patterns and presents the effects using soft shadows
  • explains white noise, blue noise, and stratification
  • additionally, it shows how to temporally apply noise to allow temporal accumulation


A Fully-correlated Anisotropic Micrograin BSDF Model

  • the paper presents an improved version of a BSDF developed for micro grain materials
  • shows how it explicitly models height-normal dependencies to summarize shadowing and masking inside the porous layer


[video] Beyond White Noise for Real-Time Rendering

  • the video presents how different types of noise for random number generation can affect the results
  • discusses Randomness/fairness when generating random numbers
  • present how different noises affect stochastic rendering techniques and suggest solutions to common problems
  • discusses FAST noise generator utility and available pre-generated noise patterns


Shapes and forms of DX12 root signatures

  • the article provides an excellent overview of the different ways to create root signatures in D3D12
  • starts with a brief overview of what a root signature is and how it’s used
  • then discusses different methods to author, create, decompile, and use the concept
  • presents a brief discussion on how root signatures are used and how other engines handle it


Recreating Nanite: Mesh shader time

  • the article discusses how to implement cluster-based mesh rendering using mesh shaders
  • discusses how to set mesh shaders using Vulkan
  • extends the pipeline to use task shaders to execute LOD selection and frustum culling
  • presents performance numbers and how wave utilization is essential


N-BVH: Neural ray queries with bounding volume hierarchies

  • the paper introduces a new neural method to compress BVH for raytracing workloads
  • shows how the technique is designed to be integrated into existing raytracing pipelines
  • presents a comparison against existing solutions on memory and performance


Thanks to Angel Ortiz for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 339 - May 12th, 2024


AMD GPU architecture programming documentation

  • AMD released documentation for the Micro engine and the RDNA 3 ISA


Pre-condition block compressed textures with Brotli-G

  • the blog post presents that the Brotli-G (GPU compression library) now allows a pre-condition step that allows further file reduction
  • shows how to use the feature and what image formats are currently supported


Ray Tracing with Voxels in C++ Series – Part 3

  • the article continues the development of a voxel raytracer by explaining anti-aliasing and soft shadows
  • presents the difference between numerical integration and stochastic integration solvers
  • shows the technique with anti-aliasing first and derives soft shadows as a follow-up


Buffer Those Commands! // Vulkan For Beginners #8

  • the video tutorial explains the Vulkan command buffer concepts
  • presents limitations that OpenGL had and how Vulkan can solve these
  • shows the command buffer lifecycle, explains memory management
  • presents how to use the API to operate on command buffers


The shader graph contract

  • the article discusses the design trade-offs for a shader graph system
  • presents the complexity when integrating with modern complex shading systems
  • shows how Unreal and Unity implement the ideas


ZH3: Quadratic Zonal Harmonics

  • the paper introduces the ZH3 format for spherical harmonics that fills the gap between linear and quadratic SHs
  • The proposed solution improves the quality at the cost of a single extra coefficient per channel
  • the source code is provided


Apple’s Mysterious Fisheye Projection

  • the blog post discusses projection methods for spherical videos
  • presents issues with existing methods
  • reverse engineers what apples Methods appears to be doing and how it’s able to achieve higher quality


Thanks to Keith O’Conor for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 338 - May 5th, 2024


[video] Math in Game Development Summit: A Visual Guide to Quaternions and Dual Quaternions

  • the GDC talk presents a great explanation of Quaternions and expands the concepts to cover dual quaternions
  • presents interactive and visual examples of the different components and operations involved
  • shows issues and limitations with matrix interpolations and how quaternions and dual quaternions can solve these limitations


Ray Tracing with Voxels in C++ Series – Part 2

  • this blog post covers how to extend a raytracer in a voxel world with support for reflections
  • expands perfect reflection to allow for refraction
  • contains challenges for the reader to develop their understanding further


Meshed Radiance Manifolds for Efficient Volumetric Rendering of Dynamic Faces

  • the paper introduces a method for view synthesis of facial expression captures in 3D views not captured
  • the presented solution is running at real-time rates without relying on machine learning techniques
  • achieved using a layered mesh for view-dependent information and mixing this with view-independent RGBA texture video
  • the included paper presents a summary of the technique, compares it against existing solutions, and discusses the limitations of the approach


[video] I3D 2024 Papers Preview

  • the video presents a summary of all the papers that will be presented at the I3D Conference 2024
  • shows a brief summary of a couple of seconds for each paper
  • papers cover an extensive range of topics, from ML techniques, VR research, upcoming display technologies, new filtering approaches, and much more


One Noise to Rule Them All: Learning a Unified Model of Spatially-Varying Noise Patterns

  • the paper discusses a generative model that is trained to generate multiple types of noise and blend between them
  • presents the network architecture, how it has been implemented and improved
  • shows many examples of the generated results


Filter-Adapted Spatio-Temporal Sampling for Real-Time Rendering

  • the paper presents a framework to shape rendering noise to optimize samples for perceptual quality and denoising performance
  • shows how sampling patterns can be optimized to take advantage of knowledge about post-processing spatial and temporal filtering characteristics
  • demonstrates how to use the framework on example applications


[video] Nanite for Artists | GDC 2024

  • the video shows the limitations of Nanite from an artist’s perspective
  • presents the debug views to explain why vegetation scenes are more difficult for the system to process
  • discusses possible solutions through the use of procedural generations and fallback LODs


Introducing Reverse Z (AKA I'm sorry for breaking your shader)

  • the Godot engine is switching the definition of near/far plane, with the near plane now mapping to a depth of 1 and the far plane to 0
  • this post explains common patterns that are affected by this change
  • additionally provides links to explain why this new mapping allowed significantly improved depth buffer precision


Thanks to John Burton for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 337 - April 28th, 2024


Take a deep dive into Nanite GPU-driven materials

  • the presentation is packed with detailed information about the process of implementing shader graph support into the Nanite shading model
  • starts with an overview of the system and discusses the steps taken to reach the current support level
  • provides many details on the lower-level aspects and how GPU hardware influences decisions
  • additionally explains how the system has been optimized on PS5 and Series X with console-level access
  • also shows that work graphs for PC enable a new set of optimizations


Real-time denoising of importance sampled direct lighting

  • The Master Thesis is a collaboration with Remedy Entertainment and discusses the implementation of a denoising solution for direct lighting
  • the focus is to find a solution that balances performance and quality to allow real-time utilization of consoles
  • reviews existing solutions and provides evaluation methods to provide analysis capabilities
  • discusses the implementation and tradeoffs done
  • presents performance, memory, and image comparisons of the developed solution against existing solutions


Ray Tracing with Voxels in C++ Series – Part 1

  • the start of a series of articles covering the implementation of ray tracing for a voxel system
  • presents the initials of light and shadow calculations
  • concludes with challenges to the reader to improve their understanding of the material


How to Compact Acceleration Structures in D3D12

  • the blog post shows how to implement Acceleration Structure compaction using D3D12
  • this compaction step is run on the GPU timeline and often reduces the memory size required by 40%
  • discusses the necessary API steps, GPU synchronization, and memory management strategies


Demystifying multiple importance sampling

  • the article provides a full explanation of the derivation of multiple-importance sampling
  • explains the different components and how to combine them correctly


GPU Compute in the Browser at the Speed of Native: WebGPU Marching Cubes

  • the article explains how to implement a marching cube compute shader
  • the implementation is shown both in Vulkan and WebGPU
  • compares the performance of both implementations and finds that WebGPU performance is close to native Vulkan


The Performance Impact of C++'s final Keyword

  • a blog post covering the effect of using C++ final on a ray-tracing demo
  • the author presents the findings with several platforms, compilers, and scenes and presents the performance results


Raytracing - Articles

  • this page serves as a starting point for the articles of the author
  • covering topics such as BVH building series, Probability Theory, CPU Optimization series
  • also contains various articles on Ray Tracing, graphics techniques, and fixed point math


Radeon™ GPU Profiler 2.1 adds interoperability with Radeon™ GPU Analyzer (and more)!

  • the article introduces how shaders from GPU Profiler captures can now be opened in the GPU Analyzer for more detailed investigation
  • additionally shows UI updates and presents how instruction latency provides more information about where the latency occurs


Alan Wake 2: A Deep Dive into Path Tracing Technology

  • the video presentation (free login required) discusses the implementation details of Path Tracing within the Alan Wake 2 technology stack
  • starts with an overview of the implementation used (vertex accessing, BVH creation, dealing with dynamic geometry, etc.)
  • shows how Opacity Micromaps are used for alpha-tested geometry
  • from there, explain how Path tracing has been implemented, covering the whole pipeline from shading, shadows, reflections, and reconstruction techniques


Thanks to Aras Pranckevičius for support of this series.


Would you like to see your name here too? Become a Patreon of this series.

Graphics Programming weekly - Issue 336 - April 21st, 2024


Transforming a Non-Differentiable Rasterizer into a Differentiable One with Stochastic Gradient Estimation

  • the paper presents a method that allows existing non-differentiable rasterizers to be made differentiable
  • explains the underlying technique and how to derive per-pixel stochastic gradient estimation
  • shows how to use the concepts to implement a 3D assets optimization system


VNDF importance sampling for an isotropic Smith-GGX distribution

  • the article introduces a specialization for the isotropic distribution of visible normals for GGX-Smith
  • discusses the limitations and implementation
  • source-code for HLSL and GLSL is provided


Colour Science Precis for the CGI Artist

  • a collection of summaries about color science aimed at computer graphics artists
  • provides a summary of the physics of color, the human vision, as well as the representation in computer graphics
  • additionally discusses color transformation onto displays


Real-time Seamless Object Space Shading

  • the paper introduces an object space shading method based on per-half-edge texturing (Htex)
  • presents a comparison against existing and shows how a Htex based method helps to reduce texturing seams
  • implementation of ReSTIR GI in object space using Unity is provided


[video] Terrain Tessellation Shaders // Terrain Rendering Episode 13

  • the video explains how to use OpenGL tessellation shaders to implement a dynamic level of detail for mesh based terrain system
  • explains how to setup the data for usage with the shaders
  • presents the shader and C++ code implementation required


[video] An Optimisation 6 Years In The Making

  • the video presents techniques to represent light shafts
  • explains an overview of two existing approaches
  • present an approximation technique that uses 2D planes combined with shadow map sampling and temporal filtering


Thanks to Joakim Dahl for support of this series.


Would you like to see your name here too? Become a Patreon of this series.