New example: get random image using Unsplash REST API

Posted on

Get random image from Unsplash
Get random image from Unsplash

We have a new example in our repository: examples/network/random_image_from_unsplash. This shows using our TCastleDownload to access Unsplash API and ask for a random image matching a given search term (like a “cute fox”).

The main part of the example is the unit gameunsplash.pas with a reusable class to download images from Unsplash.

There are 2 ways how this can be useful:

  1. You can learn how to use TCastleDownload with some REST API, to access the resources in an asynchronous manner (with blocking your application).

  2. And/or you can just use gameunsplash.pas unit in your own applications (feel free to just copy it, it’s on permissive BSD license) to get images from Unsplash.

    For example, you can use the images as randomized pretty background, or an image for a puzzle (to arrange puzzle pieces etc.)

    The images are generally free to use (see Unsplash license) for various, though not all, purposes. And there’s a ton of high-quality images.

To use this example, you need an API key (“access key”) from Unsplash. Don’t worry, it’s rather trivial (and free) to obtain it 🙂 Please follow the instructions in the README for details.

This is based on an actual fun application I (Michalis) did this week for our family! We have a monitor playing a role of a “wall clock” powered by the Raspberry Pi, showing clock with a nice background using TablissNG extension (a fork of it, that refreshes image from custom URL every 15 mins). I wrote a simple Pascal application to randomize the image, choosing randomly from a collection of our private photos and pretty images from Unsplash matching terms like “cute fox”. My daughter loves this 🙂 Note that Pascal application just exposes the image on local server, I deliberately made the separation between “display of image” (using TablissNG) and “choosing the image” (using my small Pascal program) to enable more future experiments with various fun ways to use these images.

I hope you enjoy it 🙂 And if you do, we appreciate your support on Patreon!

Comments on the forum ➤

Android: Updated applications (Castle Model Viewer, Platformer…) in Google Play, on the engine side: upgraded Google Play Services to v2 and Android SDK to 35

Posted on

Castle Model Viewer Mobile - Dungeon in Examine Mode
Castle Model Viewer on Android
Castle Model Viewer - cat
  1. Castle Model Viewer for Android version 2.8 has been released! This brings:
    • Support for IFC format right in our mobile viewer.

    • Small UI improvements: better button order (left-most changes model), show more built-in files.

    • Opening ZIP files underneath doesn’t create temp directory on your device. Internally, this is achieved by using TCastleZip to open ZIP files. The TCastleZip class also makes code simpler, and compatible with both FPC and Delphi.

    • Fix: No more crashes on Android 15 (on some devices, like Google Pixel 6a, argv is broken after Android upgrade).

    • Fix: Take into account safe borders on left/right.

    • And all improvements and optimizations from the Castle Game Engine done recently. Including target Android version bump, mentioned below.

  2. All other Castle Game Engine applications on Google Play have been upgraded as well, to include all the latest improvements from the engine, including the target Android version bump.

  3. On the engine side, we have migrated google_play_games service to use version 2 of the Google API. New applications uploaded to Google Play are required to use this version.

    Please note that v2 is somewhat less functional than v1. E.g. there’s no way to explicitly request sign-out. It’s just how Google made it, and we have to adjust, see migrating to Play Games Services v2 about all changes.

  4. We also bump the “target” Android version to 35, as required by Google Play. This will be required by Google Play since 31 August 2025, see Target API level requirements for Google Play apps. Nothing in practice changes for you because of this (it doesn’t affect minimal version supported).

If you like it, we appreciate your support on Patreon. We also appreciate a good review for Castle Model Viewer on Google Play and our other apps!

Comments on the forum ➤

Lazarus packages: moved, renamed

Posted on

lazarus-installnew-31
Installing Lazarus package with TCastleControl - 2
Installing Lazarus package with TCastleControl - 3
Registering Lazarus packages

We did a few moves and renames to our Lazarus packages.

After upgrading to the latest engine version, be sure to run again “Register Lazarus Packages” button (from the “Preferences -> FPC and Lazarus” in our editor, as documented in our Lazarus docs).

Note that the existing applications will continue to work even without you doing the above, because new packages provide the old names too. But we advise to just use new names from now on.

The short version of the changes: Lazarus packages are now in the packages/lazarus/ subdirectory of the repository, with some better names.

Full list of changes and their reasons:

  1. We moved Lazarus packages to subdirectory packages/lazarus.

    Reason: This is consistent (sibling) to Delphi packages in packages/delphi, and good for TMS Smart Setup, and likely just more obvious to both Lazarus and Delphi users.

  2. We rename packages to add _engine. So we have

    • castle_base.lpk -> castle_engine_base.lpk
    • castle_window.lpk -> castle_engine_window.lpk
    • and so on.

    Reason:

    • Avoids having castlewindow.pas and castle_window.pas (the latter just auto-generated package unit) being too close to each other. They are completely unrelated units.
    • New names are consistent with Delphi packages (which always had the _engine part).
  3. We rename castle_components to castle_engine_lcl. So in addition to adding _engine, we change components -> lcl.

    Reason:

    • The components word there was confusing for a long time. Because this is not the only package with “components”, other packages (including base) also provide components (though they don’t register them now in Lazarus component palette, but they did in the past). However, this is the only package that depends on LCL and thus provides TCastleControl that uses LCL. This package may provide more LCL components in the future.
    • It also makes name of alternative_castle_engine_window_based_on_lcl.lpk more obvious. Now alternative_castle_engine_window_based_on_lcl.lpk depends on castle_engine_lcl.lpk — which looks obvious and natural.
    • We have planned to do this rename for quite a while now. We mentioned it in TCastleControl docs and packages README that “this should probably be renamed to castle_lcl” already.
    • This seemed to be a good moment to do this, as we go with rename/move anyway.

Note that the packages/lazarus/README.md has been updated to reflect it all. We also updated Lazarus docs, TCastleControl docs and everything else we found.

Comments on the forum (3) ➤

14 engine improvements from June/July — window sizing docs, TCastleAbstractPrimitive and TCastleImageTransform extensions, cubemaps and 3D textures in all texture slots, VS Code integration improved, rendering optimizations…

Posted on

Window with castle model
Cubes test
Cubes test

Presenting a big batch of engine improvements done last ~month. Lots of small things. Everyone, pick what you like 🙂 Upgrade to the latest engine version and enjoy them all!

If you like what you see, we appreciate your support on Patreon (we also have other ways to donate).

  1. We added a new documentation page Window size and fullscreen. Nicely explains how to change window size, fullscreen mode, anti-aliasing, and even (not recommended, we explain why) the OS-wide screen resolution.

    This is also linked from the new projects’ gameinitialize.pas template code. Previous template placed there a long comment — now it’s just a short concise comment with a link to the above page.

  2. Added TCastleAbstractPrimitive.TextureScale property, useful to easily scale the texture (in descendants like TCastlePlane, TCastleBox).

  3. TCastleImageTransform has new properties to make it lit and configure other options: TCastleImageTransform.Material, TCastleImageTransform.UrlNormalMap, TCastleImageTransform.RenderOptions. Details:

    • Material, can be pmPhysical or pmPhong or (as default, backward-compatible) pmUnlit.

    • UrlNormalMap allows to specify a normal map (for bump mapping).

    • RenderOptions allow to specify some rendering details. E.g. adjust bump mapping algorithm by RenderOptions.BumpMapping is useful.

    See this forum thread that caused these improvements and contains some testcases.

    And yes, we are fully aware that TCastleImageTransform and TCastlePlane features bring them closer and closer to each other. They both can display a textured rectangle in 3D or 2D, be lit or unlit, support various display options. For now, we think it makes sense to have both components, as they start from a different approach to sizing — it’s whether “image size determines the geometry size” (TCastleImageTransform) or “image is just an optional decoration, and never affects the geometry size” (TCastlePlane). It seems combining all their features would result in a complicated API… but we will keep an eye on this.

  4. We have enabled using cubemaps and 3D textures (nodes like TImageTexture3D, ImageCubeMapTexture) to be used in any material “texture slot”. For example, they can be used to define a TPhysicalMaterialNode.EmissiveTexture, TMaterialNode.SpecularTexture and more now.

    Previously, some of the material texture slots supported only 2D textures and the 3D / cubemaps were allowed only in the “main” slot (which was: TPhysicalMaterialNode.BaseTexture, TMaterialNode.DiffuseTexture, TUnlitMaterialNode.EmissiveTexture). This limitation no longer exists, all material slots allow 3D and cubemaps.

    Note: There is still some special code for the “main” slots, so e.g. ShaderTexture is still not supported in all slots. With time, we want to get rid of all such constraints, feel welcome to submit issues / ping us about it.

    See this issue for sample testcase.

  5. We allow customizing the proposed_unit_prefix in project settings. This makes sense if you don’t want your unit names to start with Game (e.g. because you’re not making a game).

  6. We have improved physics interaction with TCastleTransformReference. We warn when collider / bodies are inside. We calculate bounding box properly when collider is at TCastleTransformReference.

    See this forum thread for some notes and tests that caused this.

  7. Our pasls (used for the code completion by our VS Code extension) has been improved:

  8. I spend some time with Valgrind optimizing a few engine low-level operations. This was fruitful. Per-frame work (rendering) is in one testcase now 0.579 fraction of the old one (so it’s almost ~2x faster).

    For this work, I used the “many cubes” testcase on GitHub – michaliskambi/many-cubes which followed from the “Drawing Many Cubes Faster” forum thread.

    The gains do not translate to all possible applications that easily, so don’t expect a 2x FPS increase in your applications now… but maybe you will notice some speedup 🙂 So give new engine a try, let us know (e.g. in the forum thread) about your tests and speed. You’re also welcome to provide us “testcases to optimize” (though try to keep them real-life, not contrived :). This helps, when I can just run profiler on some something concrete, and advise what to adjust (in your code and/or in the engine).

  9. Moving / resizing window (TCastleWindow) on WinAPI is now fixed to be smooth.

    For details what we do, what was wrong, and how we fixed it see this GitHub issue.

  10. We have internally a nice WinAPI messages debugging feature. Compile with CASTLE_DEBUG_WINAPI_MESSAGES symbol defined.

  11. We had to bump requirements of our Raspberry Pi 32-bit (Arm) builds. They require now Bookworm OS version. This matches now builds on all other systems (Linux on regular x86_64, and Raspberry Pi 64-bit (Aarch64)).

    Before 2025-06-13, we provided binaries for 32-bit Raspberry Pi (Arm CPU) in a version compatible with older GLIBC, including the one in Debian’s bullseye (to support older Raspberry Pi 4 32-bit installations). However, this gets hard, as DietPi removed some old images which we relied on, by this GHA action. We migrated to use official images from raspberrypi.org.

  12. We expose now TX3DNode.WaitForRelease and NodeRelease, simpler and with more obvious names alternatives to TX3DNode.KeepExistingBegin, TX3DNode.KeepExistingEnd, FreeIfUnusedAndNil.

  13. Fixes to castle-editor-portable editing 2D game template with Spine, and more general: DataDirectoryInformation and ApplicationDataOverride interaction fixed.

  14. To improve the comfort of cloning from GIT the engine, we now limit our paths to 130 (previously, our longest path reached 165). This decreases changes you will run into trouble on Windows, with Windows long paths or GIT on Windows long paths disabled.

    See resources like How To Fix ‘Filename too long’ Errors in Git on Windows for details, linked also from our compiling from sources. These problems can be avoided by better Windows and GIT configuration, but it’s not default, so we improved the engine to minimize the chances you run into this.

Comments on the forum ➤

More scenes are shadow casters for shadow volumes out-of-the-box, because of the auto-detection of 2-manifold scenes

Posted on

Demo from Delphi Summit 2025, with shadows
Demo from Delphi Summit 2025, with shadows
Alpaca, bull, shadows and WholeSceneManifold
Throwing chickens demo

(Yes, it’s a 3rd news about Castle Game Engine in 3 days. More to come — we have a backlog of things to announce! Brace yourselves 🙂 )

We introduced an algorithm to detect 2-manifold scenes better, meaning that all scenes that are really 2-manifold (even if not all shapes inside are 2-manifold) are automatically shadow casters for shadow volumes.

This improves shadow volumes usage experience. You no longer have to mark such scenes with TCastleRenderOptions.WholeSceneManifold.

OK, I can see that the above description, while correct, may be confusing if you’re not familiar with how shadow volumes work. Let’s unpack this slowly 🙂

  • Shadow volumes is one of the algorithms to achieve shadows using Castle Game Engine. It’s right now the simplest one to use, you only need to have 2-manifold models and then flip the Shadows checkbox at the light source to true.
    • Note: The “simplest shadows algorithm to use” award will likely change to shadow maps in the future, once we implement a few improvements to it. See also recent news post about shadow maps plans.

    • But even then, both algorithms (shadow volumes and shadow maps) will remain useful and available and in our engine. They both have their advantages and disadvantages (how shadows look, performance and possible optimizations, what is valid shadow caster…).

  • For shadow volumes, only 3D objects that are 2-manifold can cast shadows. 2-manifold means that each edge has 2 neighbor faces. This is the most natural state for 3D models that represent real things, that have a volume and are watertight, though in practice many 3D models have only most edges with 2 neighbors. The shadow volumes algorithm strictly requires that all the edges of things that cast shadows have 2 neighbors.

  • We allowed already 2 ways to cope with 2-manifold requirement: either make all shapes 2-manifold, or use TCastleRenderOptions.WholeSceneManifold to treat whole scene (unchecked) as 2-manifold.

    • BTW, what is a “shape”? Shape is part of the scene, the simplest unit passed to the GPU.
      • In glTF, it’s a primitive.
      • n Blender, it’s a subset of Blender’s object with a single material.
      • In X3D, it’s literally the X3D Shape node, loaded to TShapeNode instance in our engine.

The new improvements means that you don’t need to touch TCastleRenderOptions.WholeSceneManifold if the scene is already 2-manifold.

Now, using the TCastleRenderOptions.WholeSceneManifold is only necessary if:

  • You want to force the scene to be shadow caster for shadow volumes, even if it was not detected as 2-manifold, Beware that rendering artifacts are possible in this case. However, we did find a number of cases when this forcing actually works properly (at least for the camera position/orientations that mattered in a given demo), despite scene not being a correct 2-manifold.

  • Or if you just want to speed up loading. Marking scene as TCastleRenderOptions.WholeSceneManifold avoids any automatic detection, the appropriate check “passes automatically”.

We took care to check that this auto-detection doesn’t cause any issues:

  • We checked it doesn’t cause unnecessary slowdown. We time it, showing in log if it would take more time > 0.01 sec (it never did in our tests).

  • We checked it doesn’t cause problems due to per-shape TCastleScene.DistanceCulling being disabled on scenes that are 2-manifold, but when shapes are not 2-manifold. The per-shape TCastleScene.DistanceCulling check is now really only done when shadow volumes are used, and scene is shadow caster, and whole scene is 2-manifold (but some shapes are not 2-manifold).

We have updated example on examples/viewport_and_scenes/shadow_volumes_whole_scene_manifold, along with README description and screenshots inside. Part of this demo now works “out of the box”, alpaca model is automatically a shadow caster.

We also updated documentation about shadow volumes. Many things have been upgraded, and naturally the section about 2-manifold objects (when they are detected, and when is RenderOptions.WholeSceneManifold useful) has been rewritten to reflect the current state.

We also updated the Castle Model Viewer menu “Help -> 2-Manifold Information (Shadow Volumes Casting)”. New colors of edges:

  • yellow: manifold edges in the same shape, so this edge connects 2 faces within the same shape.
  • white: manifold edges in the whole scene, so this edge connects 2 faces from different shapes.
  • blue: border edge that doesn’t have 2 face neighbors. If you have this, this scene cannot be (reliably) a shadow caster for shadow volumes, because it is not 2-manifold.

Testing shows that this detection makes sense in many cases (and avoids you having to toggle dangerous TCastleRenderOptions.WholeSceneManifold) but also it fails in many cases (so TCastleRenderOptions.WholeSceneManifold still has a use-case, there are often no noticeable artifacts despite model not being 2-manifold).

All in all, testing shows it’s a benefit, and doesn’t have any drawbacks 🙂

Sadly, it doesn’t mean we can get rid of TCastleRenderOptions.WholeSceneManifold (it would be nice to get rid of this dangerous checkbox, but it still makes sense).

Test it on your own projects and let us know (e.g. in the comments on the forum) how it works for you!

And if you like this work, please support us on Patreon. Thank you!

Comments on the forum (1) ➤

Register for the upcoming Pascal Conference in Germany (Early Bird price until 31.07)

Posted on

Walking around Sundern

I will be at the Pascal Conference 2025 in Germany, in September this year. And you can be there too 🙂

The schedule has been announced on the conference site. A number of great people, influential in both FPC and Delphi development, will be giving talks, so this is going to be very interesting.

I will also be presenting. On Friday I will talk about a real use-case of our IFC integration for Sorpetaler window construction. And on Thursday, we will have plenty of time to discuss everything about Castle Game Engine during the Expert Q&A session!

The conference takes place in Sundern (Sauerland), Germany. I’ve actually been there twice already, and it’s quite a beautiful place. Let me attach a nice real photo (from my walk there about 2 months ago) to this post, instead of the typical screenshot from some 3D rendering you usually see on this blog 🙂

The dates are September 18th to 21st, 2025. The first 2 days feature English talks. There’s an early bird price for attending (see details) available until the end of July, so I advise you to book your tickets now 🙂

See you there!

Comments on the forum ➤

Delphi advancements: groundwork for more platforms (Android, macOS, iOS), Castle Model Viewer + Delphi, cli Delphi tools on macOS, fixes for C++ Builder, Delphi 64-bit IDE

Posted on

Castle Game Engine on FMX form
Delphi application on macOS using Castle Game Engine

We have a few treats for Delphi users in this post:

  1. Base engine units (but not yet rendering!) are now compatible with more Delphi platforms. To opens the door to make our engine compatible with more platforms with Delphi.

    This means we have a “groundwork” to add support for more targets with Delphi:

    • Android (tested both “Android 64-bit” and “Android 32-bit” now)
    • macOS (tested both “macOS 64-bit” and “macOS ARM 64-bit”)
    • iOS (tested both “iOS Device 64-bit” and _”iOS Simulator 64-bit”)
    • To remind: above platforms are in addition to already-supported platforms with Delphi, which are Windows and Linux. And this is in addition to all platforms (all desktops, Android, iOS, and web, and Nintendo Switch) supported with FPC.

    This “groundwork” means that base units compile for the aforementioned platforms. If you try compiling a full game, it will compile until the ContextCreateBestInstance compilation with message Define how to create OpenGL context for this platform.. This is OK, this means that basic units compiled OK.

    We have initial documentation about Delphi + macOS, Android, iOS here.

  2. The above “groundwork” already achieves something useful: you can write various 3D and 2D processing tools with the engine on the new platforms. For example, command-line applications, or regular FMX applications that invoke our engine to do some processing (just not using yet our engine for display).

    An example is in scene_information_cli_tool in our examples. See the screenshot on the side of this post — built by Delphi, working as a command-line tool on macOS.

  3. Castle Model Viewer (source code here on GitHub) compiles now with Delphi (as well as FPC). This improves our ability to test everything, we like to have every part of our engine working with both FPC and Delphi.

  4. Thanks to Adrian Gallero, our Delphi design-time packages install our “Tools → Castle Game Engine” menu also in 64-bit Delphi IDE version.

  5. Finally, since we’re on topic of Delphi, let’s add that we also fixed compilation of the latest code with C++ Builder. We had accumulated 2 small bugs since the last time we checked it, see this GH issue. All good now. Thank you Zatupitel for reporting!

Comments on the forum ➤

Support for new Tangent node in X3D, with vectors as 4D, better aligned with glTF

Posted on

Bump mapping with explicit tangent vectors. See https://github.com/castle-engine/demo-models/tree/master/gltf/tangents for info and credits.
Bump mapping with explicit tangent vectors. See https://github.com/castle-engine/demo-models/tree/master/gltf/tangents for info and credits.
Bump mapping with explicit tangent vectors. See https://github.com/castle-engine/demo-models/tree/master/gltf/tangents for info and credits.
Tangent vectors test from Khronos sample assets

The short version of this post, if you don’t want to go into technical details, is that one aspect of using bump mapping is now better in Castle Game Engine. Our data transfer and logic is more efficient and more aligned with glTF and latest X3D specifications.

And if you still don’t want to go into technical details, you can clone our demo-models repository and open the models in subdirectory bump_mapping/tangents/. There are 3 models there, and they are all available in both glTF and X3D model formats (scene.gltf, scene.x3d). Open them using the latest Castle Model Viewer snapshot (5.3.0) and they should work equally well and pretty.

You can also clone glTF-Sample-Assets and open the testcase NormalTangentMirrorTest there and observe that we handle it correctly (well, as much as we can without environment lighting).

You can also watch our old video about using normalmaps with Blender and Castle Game Engine. When using normal maps, you do bump mapping and then exporting your models with tangent vectors makes sense. It’s literally one checkbox when doing Blender->glTF export.

An if you’re still reading, time’s out! Now I assume you want to go into technical details 🙂 So what are tangents and what’s going on?

  • To make bump mapping look good, the 3D models may provide explicit information about the tangent vectors at the surface.

  • Our proposal of Tangent node contains a good explanation what tangent vectors are and why do we recommend to provide them in 3D models (if you use bump mapping). In short, tangent vectors, along with normal vectors, define the tangent coordinate space in which the values of the normal map are provided. Whatever process you use to create normal maps (most of you bake normal maps), it’s best to provide to the rendering engine the same tangent vectors as have been assumed when creating the normal map. In other words, simplifying, it’s best if Blender calculates tangent vectors, and uses the same tangent vectors for normalmap baking and passes the same vectors to glTF.

  • glTF standard defines how to store tangent vectors, Blender->glTF exporter can generate them, and we read the information from glTF, and convert it into X3D Tangent node.

  • We already had Tangent node in our engine for some time, but with a definition that had a small simplification: I defined the vectors there as 3D, right-handed. In contrast, glTF defines them as 4D, with XYZ designating direction, and W designating the handedness. We think the glTF idea is quite smart and useful 🙂

  • We have recently recommended to add Tangent node to the X3D spec, the proposal is here. While adding to X3D, we also proposed to add them in a version more aligned with glTF, so 4D.

  • Of note is that X_ITE, another cool open-source X3D viewer, also has compatible Tangent node. With 4D, matching also glTF. So after this, we’re all better aligned.

  • The new X3D prose about Tangent node is here.

  • And to close the circle, the Castle Game Engine has now adopted this Tangent node specification with 4D vectors. This means we display X3D models with the new Tangent node, and when reading glTF we convert the glTF -> X3D information in the trivial way (glTF 4D tangents -> X3D 4D tangents).

Does anyone still follow? 🙂 Hopefully above was a good summary and link to hopefully useful resources.

If you like what we do, in Castle Game Engine but also around standardization efforts like X3D, we always appreciate your donations. Thank you!

Comments on the forum ➤

URL improvements: castle-config:/ protocol, use UriExists and FindFiles on any URL (including e.g. zip), TCastleMemoryFileSystem

Posted on

Scene inspired by Metal Gear Solid from Sketchfab https://sketchfab.com/3d-models/chibi-gear-solid-a4ca0e3864e143af9bf1dffc7fc8029b

We present a number of improvements to our URL system, which is the basis for all engine resource loading and saving:

  1. We introduced castle-config:/ URL protocol, to save files in a system-specific place (directory) that is “persistent” for given user.
    • It points to a specific directory that is by convention writeable and should be used to save user data. For example, something like C:/Users/<username>/AppData/Local/<application_name>/ on Windows or /home/<username>/.config/<application_name>/ on Linux and FreeBSD. We follow system-specific conventions and APIs.
    • This replaces previous ApplicationConfig routine.
    • It is consistent with castle-data:/ which is read-only location with your application data.
  2. We added TCastleMemoryFileSystem – useful to create a temporary filesystem, living only in memory, registered at given URL.

    It is, for now, our implementation of castle-config:/ on the web — so the data is not persistent if you reload the page, but at least it makes sense within a single session. This made our portable editor possible. Of course it is a TODO to actually persist the data using WWW browser mechanisms.

    That said, TCastleMemoryFileSystem may be useful for your own purposes too, if you want a temporary virtual filesystem in your application.

  3. RegisterUrlProtocol exposes now a class that allows to configure URL behavior. (So we can extend the functionality offered by custom URLs, aka virtual file systems, without adding more and more parameters to RegisterUrlProtocol.)

  4. Many built-in URLs, and URLs pointing to ZIP (using TCastleZip), and URLs pointing to TCastleMemoryFileSystem, use above, so their resources can be tested using UriExists and searched using FindFiles.

  5. Queries like UriExists('castle-data:/my_texture.png') on the web are also useful now, as we use castle-data:/auto_generated/CastleDataInformation.xml to test data files existence.

What’s the image shown at this news post? Chibi Gear Solid by glenatron on Sketchfab, cool 3D scene rendered using our Castle Model Viewer. It has no relation to this news post (except that’s it’s rendered using our engine and you can download it too and turn into a game right now!), just something pretty I wanted to show 🙂

Comments on the forum (4) ➤

Slides and example from Delphi Day 2025 presentation and after-thoughts (Afterwarp, shadow maps, BGFX and deferred rendering)

Posted on

Throw chickens

I’m traveling back home after enjoying Delphi Day 2025 in Piacenza.

  1. I think I’ve made a nice presentation about the engine features.

    Slides are available here and one new (simple and fun 🙂 ) example is part of the engine now: examples/physics/physics_throw_chickens.

    During the talk, I also showed a number of existing projects, including platformer, fps_game, complete FPS game using Blender, Sketchfab, Quaternius models, TCastleMoveAttack (shown first at Zlot 2024).

  2. I also watched a number of inspiring presentations from fellow Delphi users. It was really good to see so much activity around Delphi and Pascal!

  3. One talk that in particular remains in my memory was about the Afterwarp Framework by Yuriy Kotsarenko. I was truly amazed by some features he shown, in particular the deferred shading implementation combined with shadow maps that allows to have 65k dynamic light sources casting shadows (and he showed demos really proving it — one demo with really ridiculous 65k dynamic lights, one demo with over a thousand lights casting shadows and car with headlights moving through them). Really impressive, and it makes me jealous, and I told him about it 🙂

    To make it happen, deferred rendering is the key (in contrast to the current CGE forward rendering). I was looking into this in the past… but there was never enough time to “attack” it, as it’s a bigger task.

    Edit 1: My intention here is not “let’s just switch to deferred rendering”. The cited Wikipedia page about deferred rendering already mentions disadvantages of this approach, and Afterwarp that inspired me is actually using a hybrid approach (“uses a hybrid forward, deferred rendering using clustered shading”). My intention here is to explore our options for lots of dynamic lights and shadows in the engine, and I note 2 things: 1. it’s high time to focus on shadow maps, as I already wrote in roadmap (see more below) and 2. I want to experiment with deferred rendering.

    Edit 2:: Originally I wrote here that our optimal path to deferred rendering may be to speedup BGFX renderer integration, as BGFX will give us deferred rendering, and we want to have BGFX as alternative renderer anyway. However, while BGFX indeed allows for deferred rendering, it’s a manual approach (not a simple toggle “forward / deferred rendering”). So: 1. we still want to have BGFX!, 2. but it’s independent from deferred rendering, as we can introduce deferred rendering either on top of BGFX or CGE current renderer, with ~similar work.

  4. I had a few “nudges” recently to focus more on our shadow maps as a preferred shadows algorithm, and maybe leave the shadow volumes as… maintained, but not default.

    To explain more:

    • In the current engine version, shadow volumes are more comfortable to setup (just click 1 checkbox, if only your models are 2-manifold), while we have a few TODOs to make shadow maps comfortable.

    • But the shadow maps have likely a brighter future: more performance, because you can control the shadow map resolution and frequency of updates, which was pointed both by Afterwarp presentation and recent forum thread where Erik Johnson managed to use our shadow maps with great performance gain. Also, shadow maps work out-of-the-box with our upcoming (not yet merged to master) skinned animation on GPU, while shadow volumes… in short, require fallback to animate skin on CPU (see TODO there for more details). So, again, shadow maps seem to give “more performance, easily”.

    • And of course shadow maps “just work” with any geometry, 2-manifold or not, and even account for alpha testing (e.g. precise shadows cast by typical leaf textures). So there’s no need to worry about whether your 3D model is 2-manifold, and no need to tweak RenderOptions.WholeSceneManifold either.

  5. So, thoughts coming from the above:

    • shadow maps improvements are important (and don’t be afraid to make shadow maps, not shadow volumes, default),

    • deferred rendering is important (to experiment with, and maybe come up with a hybrid approach),

    • BGFX renderer is important, albeit independent from us “getting deferred rendering option”.

    OK, this mostly validates our roadmap, with shadow maps before 7.0, and BGFX after 🙂

Have fun everyone! Stay tuned for more technical announcements next week. And if you like what we do please support us e.g. by subscribing on Patreon.

Comments on the forum (3) ➤