{
    "version": "https://jsonfeed.org/version/1",
    "title": "Moldling Dev Blog",
    "home_page_url": "https://moldling.com/",
    "feed_url": "https://moldling.com/api/feed.json",
    "description": "A feed containing the latest blog posts about the development of the game Moldling.",
    "author": {
        "name": "soraslove",
        "url": "https://soras.love/"
    },
    "items": [
        {
            "id": "https://moldling.com/blog/2026-06-06-ray-traced-shadows",
            "content_html": "<p>Every now and then I try to experiment with the visuals of my game to see if there&#39;s anything I can improve on. This\ntime I wanted to see if I could implement dynamic shadows to make my game look a little less flat.</p>\n<p>This was hugely inspired by the shadows\nin <a href=\"https://rainworldgame.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Rain World</a>\nand <a href=\"https://ironbramble.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Iron Bramble</a>.</p>\n<p><strong>First:</strong> Results!</p>\n<p>The top video is the before and below is the after.</p>\n<p><video src=\"https://moldling.com/blog/2026-06-06-ray-traced-shadows/before.mp4\" controls></video>\n<video src=\"https://moldling.com/blog/2026-06-06-ray-traced-shadows/after.mp4\" controls></video></p>\n<p>It&#39;s a very subtle change, but I think it achieves my goal of giving my world more visual depth.</p>\n<p>First of all, my game is made in (my custom fork of) Godot so some of the implementation details will be specific to\nthat, but the general idea can be applied to other environments.</p>\n<p>Alright, onto how I made this. Since I was inspired by Rain World I first tried to see if there were any resources on\nhow they implemented their shadows. I found\nthis <a href=\"https://x.com/joar_lj/status/1525445116789497856\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter\nthread</a> which explains nicely how they approached their implementation. I used this as a starting point, but ended\nup diverging from it and working on my own approach.</p>\n<h2>Rendering the depth map(s)</h2>\n<p>The first thing we need is a depth map of our scene. I did this by assigning each object (CanvasItem) in my scene a\ndepth value and an optional depth texture in case I want the depth to vary across the object. Each object also has a\nboolean called <code>is_solid</code> which decides if the object is solid (meaning that no light rays can pass behind the\nobject), or if the object is flat (meaning that light can pass behind the object, just not through the object). Things\nlike doors are solid since I don&#39;t want any light to pass through them. Additionally, every light source also has a\ndepth, which comes into play later.</p>\n<p>Then I create two additional render passes (using SubViewports in Godot) which render my depth maps. They use the\naforementioned depth values and textures and calculate the objects total depth based on those (depth value +/- depth in\nthe texture). The first pass renders all the solid objects, the second one all the flat (non-solid) ones. These get\nstored in textures and are used in my shader.</p>\n<details>\n    <summary>Technical Note</summary>\n    <div>\n        <p>\n        The depth value was implemented by adding a depth property\n        to the CanvasItem node.<br/>The depth texture was done by adding a depth texture property to the CanvasTexture\n        resource.<br/>Both of these properties get passed onto the canvas shader.\n        </p>\n        <hr/>\n        <p>\n        The render passes were done by\n        adding an overwrite material property to Viewports. This overwrite material gets applied to all elements rendered in the\n        viewport and handles the depth.\n        </p>\n    </div>\n</details>\n\n<p>The depth maps end up looking something like this:</p>\n<p>First the solid one, second the flat one.</p>\n<img src=\"https://moldling.com/blog/2026-06-06-ray-traced-shadows/depth-map-solid.png\">\n<img src=\"https://moldling.com/blog/2026-06-06-ray-traced-shadows/depth-map-thin.png\">\n\n<h2>Rendering the shadows</h2>\n<p>Now that we have depth maps &quot;all&quot; that is left is to actually calculate the shadows. This is done in my main shader\nwhich is used for every CanvasElement. I have a function in my fragment shader that gets executed for every fragment of\nevery light source.</p>\n<p>The basic idea is this: We shoot a ray from our current position to the light&#39;s position and if we hit anything, then we\nare in shade.</p>\n<p>In detail this means the following:</p>\n<ol>\n<li>We get the lights depth value. If the depth value is 0.0 then no shadows will be drawn (we don't want this light to draw shadows).</li>\n<li>Then we get the current position by taking the <code>SCREEN_UV</code>.</li>\n<li>Then we sample both depth maps (the solid one and the thin one) at the current position and save the higher depth as our start depth value.</li>\n<li>If our start depth is higher than the light depth no shadows will be drawn (the object is in front of the light).</li>\n<li>We then assemble two vec3s one is the spatial start position <code>(start_pos.xy, start_depth)</code>, and one is the spatial light position <code>(light_pos.xy, light_depth)</code>.</li>\n<li>We then step from the spacial start position to the spacial light position in increments of a constant step size (This step size determines how well we catch every shadow caster. A step size of half a pixel has worked well for me).</li>\n<li>At every interpolated position we first sample the solid depth map and check if our current interpolated depth is less than the sampled depth. If it is smaller, then that means there is a solid object casting a shadow on us, and we can break out of the loop.</li>\n<li>After not finding a solid object casting a shadow on us, we sample the thin depth map. If our current interpolated depth is within a small error margin of our sampled depth, then that means there is a thin object casting a shadow on us, and we can also break out of the loop.</li>\n<li>If we don't find either a solid or a thin object casting a shadow on us, we continue stepping towards the light.</li>\n<li>If we reach the light without finding any shadow casters, then that means that we are in view of the light and we are fully lit.</li>\n<li>Finally, we multiply the current Light color based on if we found a shadow or not. Multiplying it with <code>0.0</code> would mean that things in shade are fully unlit. I've also found that interpolating the factor based on how far away the shadow caster is gives a nice decaying shadow effect.</li>\n</ol>\n\n<p>That&#39;s basically it. As you can imagine tracing a ray for every fragment can get quite expensive and only works since my\ngames resolution is so small (<code>320x180</code>). I&#39;ve also included an option to disable ray traced shadows in case weaker\nmachines struggle doing all of those calculations.</p>\n<details>\n    <summary>Technical Note</summary>\n    <div>\n        <p>\n        I added a custom function to the base canvas shader that I can overwrite in my shaders that gets called for every light. It is similar to the light function but does not overwrite any default light behaviour, so a similar implementation could definitely be implemented using the default light function.\n        </p>\n    </div>\n</details>",
            "url": "https://moldling.com/blog/2026-06-06-ray-traced-shadows",
            "title": "Dev-Log: Ray Traced Shadows",
            "summary": "Implementation of real time ray traced shadows.",
            "image": "https://moldling.com/blog/2026-06-06-ray-traced-shadows/thumbnail.png",
            "date_modified": "2026-06-06T00:00:00.000Z",
            "author": {
                "name": "soraslove",
                "url": "https://soras.love/"
            }
        },
        {
            "id": "https://moldling.com/blog/2026-03-26-screen-transition-improvements",
            "content_html": "<p>I&#39;ve been able to improve screen transition performance drastically. Moving into a big screen used to have stutters of\nup to 50ms, meaning that the frame that you go into a screen would take 50ms. This is much longer than a frame should\ntake. Now there is no additional frame delay when going into screens of any size, meaning that the frame rate stays a\nconstant smooth rate.</p>\n<p><strong>First:</strong> Results!</p>\n<p>This is before. First is the screen transition frame itself. In the top graph you can see the red bar being the frame,\nand you can see that the frame takes 54ms. Below you can see the game in action and the stutter when moving between the\nlarge screen.</p>\n<img src=\"https://moldling.com/blog/2026-03-26-screen-transition-improvements/before.png\">\n<video src=\"https://moldling.com/blog/2026-03-26-screen-transition-improvements/before.mp4\" controls></video>\n\n<p>Now after my changes! As you can see the frame now takes as much time as any other frame (around 15ms in this case) and\nthe stutter in the game footage is gone!</p>\n<img src=\"https://moldling.com/blog/2026-03-26-screen-transition-improvements/after.png\">\n<video src=\"https://moldling.com/blog/2026-03-26-screen-transition-improvements/after.mp4\" controls></video>\n\n<p>Now onto how I achieved this.</p>\n<p>First of all, some necessary details on how my game works. My game is made in Godot so the implementation details will\nbe specific to that. My game loads neighboring screens in a separate thread whenever you enter a new screen. The loaded\nscreens get stored for later use.</p>\n<p>My previous setup was that I have a SubViewport that renders my game and a list of inactive nodes that store the\nneighboring screens. Whenever the player moved into a new screen the previous screen would be removed from the\nSubViewport and the new screen would be moved into the SV. Moving these large screens around was what caused the\nhiccups.</p>\n<p>My new solution inverts this approach. I have a list SubViewports. The active screen is in one of them and the\nneighboring screens are in the other ones. Only the one SV with the active screen renders anything the other ones are\ndisabled (meaning they have their Update Mode set to &#39;Disabled&#39;). Whenever the player moves into a neighboring, screen\ninstead of the screen being moved, I now only move the player. The player gets put into the SV of the screen and the SV\ngets set as the active one. Thats all that needs to happen now. This is much more performant since the player is a lot\nless complex than the screens, so moving it around in the scene tree is much simpler.</p>\n<p>That&#39;s it, thanks for reading. I&#39;m happy with how smooth my game runs now :)</p>\n",
            "url": "https://moldling.com/blog/2026-03-26-screen-transition-improvements",
            "title": "Dev-Log: Screen Transition Improvements",
            "summary": "Reduction of lag caused by screen transitions.",
            "image": "https://moldling.com/blog/2026-03-26-screen-transition-improvements/after.png",
            "date_modified": "2026-03-26T00:00:00.000Z",
            "author": {
                "name": "soraslove",
                "url": "https://soras.love/"
            }
        }
    ]
}