You are browsing as a guest. Sign up (or log in) to start making projects!

gungu

@gungu

Joined June 5th, 2026

  • 27Devlogs
  • 1Projects
  • 0Ships
  • 0Votes
I'm an indie developer, I worked on a bunch of Playdate games and I've been passionately pursuing graphics programming since the Hackclub program last summer. Glad to be back.
Open comments for this post

19m 41s logged

NORMAL MAPPING

This was a really easy update, most of the shader changes were copied from my last engine, and the CPU side of things was just changing the vertex struct and loading the tangents in the mesh loading function. But it works.

0
0
2
Open comments for this post

3h 49m 34s logged

Well well well. Seems like it’s time for

LIGHTING !!!!! finally

This was not easy, and yet it was made so much easier by having done it once before last year. I added support for a directional light, a dynamic (aka not hard coded, so pratically infinite amount of) point lights and spot lights, full PBR, and I also made a little handy editor to go along with it, although that’s not in the renderer that’s just in the demo project. Anyways, this was an incredible journey filled with pain and suffering like never before, and I’m so glad I’m through it all.
And if this was a challenge, I don’t know what shadow mapping is going to be, which is going to be basically right now, I’m going to add tanget space normal mapping and then it’s already shadowmapping. I’m mentally unprepared, but oh well what can I do?

0
0
3
Open comments for this post

1h 53m 9s logged

This change is not too visible, but it is a major change in the engine

MATERIALS

Everybody who worked in any sort of 3D graphics knows what materials are. And those know, that the next step after this is lighting. This wouldn’t have been that big of a change, if not for one issue. I’m developing on linux, and every once in a while my GPU drivers uninstall themselves, so everything runs on the integrated graphics on the CPU. That happened, but I thought that the code just became really slow because I was sending 6 images to the GPU every single frame, and that slowed it down. So I spent a bunch of time making a large optimization, and it worked like a charm, it ran fast. Then I found out the entire thing was running on the CPU and I didn’t even need to optimize it. Anyway, it’s here, and it’s fast

0
0
4
Open comments for this post

2h 42m 51s logged

POST-PROCESSING STACK and TONEMAPPING AND COLOR GRADING (post-processing effect 5)

This is the finale to the post-processing saga, because I’m finished with tonemapping and color grading. Everything will look really good and cool and whatever, altough I’ve been coding non-stop for 2.5 hours and I don’t really care to give an explanation right now. I don’t have to explain color grading everybody knows that, and tonemapping is the process of mapping the internal HDR render image to an LDR (whatever it’s called) image that the display can actually render properly, how cool is that?

0
0
4
Open comments for this post

1h 22m 22s logged

BLOOM (post-processing effect 4)

I’m almost done with all of the post-processing effects, and this was by far the hardest of them all, but I managed to push through it. I’m really proud of myself, because I finally understand Vulkan enough where I didn’t need any sort of outside help to debug this error. I think I can finally call myself someone who understands Vulkan now. Anyway, now I just need to make tonemapping and the effects are done. After that I just make the simplest pipeline to composite it all, and I’m done with that as well.

0
0
1
Open comments for this post

1h 6m 54s logged

VIGNETTE (post-processing effect 3)

This was the most fun I’ve had debugging something in a while. This was really simple to implement, although I can’t really say a lot. The initialization was the same as the other effects, the actual logic of it was pretty similar, the shader wasn’t too hard to write too, but added up it was pretty bad. I accidentally left one of the push parameters in the CPU code as an int, but a float in the GPU code, which I ended up having to chase down for quite a while. The values are over the top on the image so it is more visible on the screenshot, of course I won’t leave it like this.

Also, I have written a new readme for the github page.

I just kinda wanted to, and thought why not?

0
0
3
Open comments for this post

18m 22s logged

BOX BLUR (post-processing effect 2)

I have to admit this took 11 minutes, and the rest of the 5 minutes I spent in this devlog was spent debugging 3 new errors so I can make a post about this feature too. It took so little because I literally just copied and renamed the gaussian blur functions, and changed the shader. Still, I have box blur now. Actually, I think there’s quite a difference between the 2 blurs, quite cool. Of course now that I look at it it’s barely visible in the screenshots.

0
0
2
Open comments for this post

2h 37m 10s logged

I thought how cool would it be if I just did a whole 10 hour devlog with all of post-processing in it, but I realized I wouldn’t be able to show off all the cool stuff I’ve done, so I’m doing it effect by effect, anyway,

GAUSSIAN BLUR (post-processing effect 1)

But not just that, I also brainstormed out the entire post-processing system, and “implemented” it. I didn’t exactly implement it yet because I need to finish all the effects, but it’s there. I still have to finish: box blur, bloom, vignette and tonemapping, and I also want support for custom effects, but that’ll be really easy so I don’t want to put it on this list.

0
0
1
Open comments for this post

1h 35m 51s logged

MSAA !! (multisampled anti-aliasing)

I always viewed anit-aliasing as this mystery thing that can make a game prettier and I’ll never know how it works. I have to say, it was way easier than expected, most of the time I spent was on some stupid bug or general debugging. You can’t really see the difference in a small screenshot, but it looks so much better full screen.

0
0
17
Open comments for this post

1h 33m 15s logged

2D rendering!!

I have to admit this feature was kinda easy to implement, because most of it was ripped straight from my last game engine, but I did it because I think it is a really smart way of handling how a 2D system should work. Everything relies on the Surface class, the display itself is a surface, the loaded images are surfaces, and those surfaces can draw to eachother. This makes the system easy yet expandable. I think it’s kinda cool. It was heavily inspired by how pygame does things.

0
0
5
Open comments for this post

1h 19m 42s logged

And just like that, the next major update is done!

SKYBOXES and other stuff

Here’s a full changelog of the last 3 posts:

  • I wrote a really handy shader compiler to make this update just a bit easier, now it automatically compiles all shaders at once I don’t have to do it one by one
  • I wrote a compositing pass that finally has a use case as can be seen right now. The skybox and the objects are rendered separately to separate images, and the compositing pass combines them and renders them to the screen together. Might sound simple, and I have to admit if I understood Vulkan a bit better it might have been, but right now I’m really proud of myself for it.
  • Of course the headline feature: The Skybox. This is most of what I’ve been working on for the last 3 updates. It’s done in a really cool way. The easy way of doing a skybox is to just render it as one giant object and then bim bam boom there it is, but sadly that has a couple of issues, the largest one is that this is extremely lazy. So I did it the smart way instead. What you’re seeing there is actually a cube a tad bit smaller than the monkey, but it’s rendered in a separate pass, where I only pass the camera’s rotation and not the position, and I also have the depth disabled. I render that to a separate image, use the compositing pass, and there it is, a beautiful, very stable and very professional skybox.
  • I’m almost done rambling, but I have to mention one last feature, and that is the loading of equirectangular images into a cubemap texture. I think I’ve typed enough for this update, but if you care you can look it up or like look at my code.

Next up: 2D rendering

and I have some great ideas for it

0
0
6
Open comments for this post

1h 33m 42s logged

This is a change that cannot be seen, but the composite pipeline is actually working. This is a really simple step in the graphics pipeline, it takes the images from the previous passes and combines them to make a final image. This will be useful for future features like 2D drawing, post-processing, the skybox, etc., so I’m happy I managed to implement it. It’s not something that can be seen with the naked eye, but believe me it’s there and I’m so happy for it.

As always, this is next to some generic bugfixes here and there, but it’s been 1.5 hours and I forgot what I fixed and what I didn’t so if you happen to care enough this is open-source just like go and check it out.

0
0
3
Open comments for this post

1h 40m 31s logged

I’m well into developing the skybox system along with a compositing pass, but since I needed to write so many new shaders for this update, I decided to write a simple shader compiler, and I kinda want to show it off so it’s not lost in the giant list of changes that I’ll push in the next update. That’s it, I rest my case, that’s all I wanted until I’m finished.

0
0
2
Open comments for this post

2h 12m 51s logged

I finished frustum culling.

You’ve probably seen this feature in some random wannabe gamedevs post on tiktok saying how they “optimized their game” by enabling frustum culling in Unity and calling themselves genius for it. Well it wasn’t as easy as pressing a button for me.

Here’s how it works:

I generate an axis aligned bounding box (AABB) for every object when loaded. Every frame I generate 6 planes for each boundary of the camera, the left, right, bottom, top, near and far planes. Then I also calculate the world position AABB for each mesh, which is just translating the original AABB and making a new one from that’s boundary. From that, it’s actually quite simple to compare if the box is inside the frustum or not, though it’s kinda hard to explain so I won’t bother, but I just run that for every object,
and it basically makes it, so if an object is not inside the camera’s vision, then it just makes it disappear.

I attached the majority of the logic in the second picture

0
0
2
Open comments for this post

1h 18m 44s logged

I implemented a fully automatic mipmap system. Basically, mipmaps are lower quality version of a texture that appear the farther you are from an object. The image I attached is of mipmap layer 4, but of course this was set manually to showcase the system working.

0
0
2
Open comments for this post

39m 49s logged

I wrote a giant list on what I want to implement into this framework to make it full. I’m pretty sure I’ll be done in about 150-200 hours, which I have about 40 days to make before the end of this thing. That is 3.75 - 5 hours of coding in a day. Anyway, here’s the list:

TODO FEATURES:

  • lighting
    • gpu scene data uniform buffer
    • ambient light
    • directional light
    • point lights
    • tangent space normal mapping
    • tangent generation in gltf loading
    • dynamic light count
    • proper api for handling lights
  • shadow mapping
    • depth-only pipeline
    • shadow map image
    • light space matrix
    • shadow pass
    • shadow sampling in the main fragment shader
    • shadow bias
    • PCF filtering
  • material system
    • material struct (albedo map, normal map, roughness map, emissive map, scalar tint and roughness and metallic factors)
    • material descriptor layout
    • default fallback textures
    • gltf material loading
    • draw_mesh api update
    • emissive support in the shader
    • creating and destroying materials for user-made materials
  • mipmaps and proper sample management
    • mipmap generation on upload
    • mip count calculation
    • sampler cache (so samplers are never duplicated)
  • instanced rendering
    • per-instance storage buffer
    • draw_mesh_instanced api
    • write the shader for it (gl_InstanceIndex)
    • move to indirect drawing so the instance count can eventually come from gpu-side data
  • skybox
    • cubemap loading
    • skybox pipeline
    • skybox shader
    • set_skybox api
  • frustrum culling
    • bounding sphere per mesh (compute in loading by finding the disctance from the centroid across all vectires)
    • frustrum plane extraction (gribb-hartmann)
    • cull loop
    • stats readout
  • post processing stack
    • fullscreen traingle pipeline
    • HDR tonemapping
    • guassian blur api
    • box blur api
    • bloom
    • vignette
  • 2D rendering
    • quad mesh
    • 2D pipeline
    • surface class
    • default surface
    • draw_surface
    • draw_rect
    • font atlas rendering
  • MSAA
    • multisample draw image
    • resolve attachment
    • configurable sample count
0
0
2
Open comments for this post

52m 43s logged

I have to admit I’m pretty proud of myself. I implemented the proper transformations for objects, I also made a good camera system, and I fixed the uv mapping of objects, so textures finally work properly. All this in under an hour.

0
0
2
Open comments for this post

1h 2m 27s logged

To be completely honest this engine development thing is going a lot more awful than I could have imagined. I tried to implement a proper camera and transformations for the objects, and now nothing works, yet I barely changed anything. I have been staring at this function for like 2 hours, I’ve tried everything, and nothing works.

0
0
3
Open comments for this post

1h 4m 7s logged

I finally finished the guide (🥳🥳🥳), so it’s time to make the game engine I want. My first improvement was adding a render queue, which basically means I can render anything in a much user friendly way.

0
0
2
Open comments for this post

48m 22s logged

Thanks to the major rework of the allocation of descriptors, I have
managed to implemented textures into rendering. I haven’t made
texture loading yet, since it’ll be an engine feature and I’m working on
project setup
, so enjoy the beautiful pink-black checkerboard pattern
on Suzie, the Blender monkey.

0
0
3
Loading more…

Followers

Loading…