Web: water, terrain, shadow maps, alpha treatment, keys on losing focus

Posted on

Terrain + water demo on web
Shadow maps on web
Walking Adventure - tree on web
Platformer on web
Chromatic aberration on web

Rendering to texture (FBO, our TGLRenderToTexture) works now on the web.

This enables a few features on the web:

We also fixed alpha treatment on the web.

  • This fixes a few subtle bugs, as in various edge-cases we wrote to the color buffer pixels with alpha < 1. This happened e.g. when displaying hearts in the platformer demo (source code in examples/2d_games/platformer/), cat hair in model viewer, tree leaves in the walking adventure demo (source code in examples/3d_games/walking_adventure/).

  • This was harmless on non-web platforms (where pixel alpha of the color buffer is used only for eventual blending with incoming colors; nothing cares what is the final calculated alpha left in the buffer). But on web, in the past, our canvas was using “blending with page background (typically white)”.

  • This is fixed now, making the web rendering work just like other platforms. See comment here for more information.

We now correctly “reset” keys pressed state after you switch a browser page or application:

  • Previously, switching tabs or applications by key combo like Ctrl+Tab, Alt+Tab could leave the engine thinking that “Ctrl” or “Tab” are pressed.

  • This had some consequences, e.g. TCastleWalkNavigation will refuse movement by AWSD if it thinks that you hold down Ctrl/Alt modifier. (And it will do “run” if it thinks you hold down Shift!)

  • This is fixed now, we react to blur event by switching all keys “up”.

We have also fixed both terrain and water shaders for Chromium-based browsers (like Vivaldi or Google Chrome). They needed highp in certain shaders to work reliably (water waves, terrain textures smooth), as they multiply bigger floats with small floats.

As always, we hope you have fun developing games with Castle Game Engine! And if you like what we do, we appreciate support on Patreon!

Comments on the forum ➤

Web: bump mapping, clip planes, fog, terrain, occlusion culling; also Unholy Society demo on web updated

Posted on

Unholy Society - web build - wedding
Steep parallax mapping
Occlusion culling - web build
Explore impressive castle - web build

Shaders on web fixes:

Our shaders on the web platform can render now all our effects:

  1. Bump mapping (normal maps). As shown by demos:
  2. ClipPlane X3D node, useful to clip part of 3D/2D content when rendering. The node can be instantiated using Pascal class TClipPlaneNode or by writing X3D file like this:

    Save this as my_cut_model.x3dv and open (using our Castle Model Viewer, or from Pascal load it using our TCastleScene). In effect, you will see my_model.gltf but cut by a 3D plane. To be precise, the plane equation is Ax+By+Cz+D=0 with the (A,B,C,D) values given by the ClipPlane.plane vector above. The points we render are ones that satisfy Ax+By+Cz+D>=0, so they are in half-space determined by the plane.

  3. Fog.

  4. TCastleTerrain shader.
    • Used by terrain example (source code).
    • Note: Water used in this demo doesn’t work on web yet — we need to fix our FBO on web.
  5. Shader effects using varying, like “time to shader” in Castle Model Viewer (Mobile) on web.

The above features failed to work in the past due to a bug in ANGLE, library used to processes shaders (and optionally render) in both Firefox and Chromium-based browsers (I test with Vivaldi).

Occlusion culling on web:

We have fixed how occlusion culling works on the web. We needed to account for the fact that occlusion queries on the web can run for multiple frames.

See the running demo here: occlusion_culling (source code).

Unholy Society demo on web:

We have updated The Unholy Society web demo. We fixed audio, comic bubbles size, “pope call” animation (using ClipPlane, see above). Overall, at this point the complete game works on the web and yes, you can just play it for free here 🙂

Note that the web version doesn’t support persistent savegames (reloading the page will reset the game state), which is of course something we plan to fix soon.

Enjoy and please support us on Patreon to make it possible to continue improving the engine!

Comments on the forum ➤

Audio (sound, music) on the web, sound API improvements (arbitrary channels, float frequency etc.)

Posted on

game_3d_sounds example
play_sounds example

We have implemented audio playback on the web. Underneath we use WebAudio API but you don’t really need to know anything about it — just use Castle Game Engine sound API and components and everything will work on the web.

Try these examples (links below lead to ready builds — they should work out-of-the-box in your browser):

We have documented some important notes about WebAudio here, a short recap:

  • Audio playback will be in a suspended state when loading the page in modern web browsers. Audio starts in response to user interaction with a page, like clicking any button. You can solve it also by putting your web application inside an iframe with allow="autoplay", which is done e.g. by wrapper generated for HTML games on itch.io.

  • OggVorbis and other formats support relies on the sound decoding support on the browser side. The exception is WAV format support, which we decode on the engine side.

We also did a few improvements around the sound formats API, which benefits all platforms by improving our cross-platform API.

  • The old TSoundDataFormat enum (with 4 values: mono 8-bit, stereo 8-bit, mono 16-bit, stereo 16-bit) is now gone. It was needlessly limiting us to 4 arbitrary combinations of channels/format.

  • We expose new property TCastleSound.Channels, as Cardinal. This can express sound files with more than 2 channels, like Quadraphonic. Already playable by some backends, like FMOD and new WebAudio. Our OpenAL could also play them in the future, see extensions to provide surround sound buffer formats.

  • We have an internal sound sample format (not exposed by public API), which describes just formats we decode on the engine side right now. It’s right now just pcm 8-bit (unsigned) or pcm 16-bit (signed) but can be easily extended. Moreover, it is now only used when we decode on the engine side — because some backends (FMOD and WebAudio) are capable of decompressing + playing without passing through our engine, so are not limited to these formats. E.g. FMOD can also use float sound data.

  • Sound frequency in TCastleSound.Frequency type changed from Cardinal to Single. This again matches better full FMOD and WebAudio backends capabilities. Prefer to express it as TSoundFrequency type, in case in the future we need to upgrade this to Double.

  • We tested and documented that some backends (again FMOD and WebAudio) support more sound formats (like mp3 and flac).

We hope you like our work and we appreciate your support on Patreon!

Comments on the forum ➤

More April News: training timer demo, delayed view changes, URL processing on save, how to easier install web compiler, notes on copyright and AI, in progress: audio on web

Posted on

Training Timer 2 by Serufu Yua

We already announced some new features in April (PLY, InlineGeometry, web: URL parameters and TCastleDownload). Below we report more goodies 🙂 Enjoy!

  1. Check out Training Timer 2: Zero Time project by Serufu Yua, available for Windows and Android. Downloads on itch.io and source code on GitHub (thank you!).

    See also ready UI list box components also from Serufu Yua. Thank you!

  2. View changes (setting Container.View:=.., calling Container.PushView, Container.PopView) may be now performed with a delay. We have extensive documentation what it means, and why we do it, here. The forum thread, with even more information and reasons, is here. Thanks to Vlad (Phomm) for reporting this — this was a critical design problem we had, now “defused”.

    Please note that this change may require to adjust your code in some cases. We tried to make it backward-compatible, and in many cases it is, but it cannot be 100% — inherently, some things are now done later -> so some assumptions break.

    For example, you can no longer assume that new view is started right after PushView:

    Another example (of logic that will no longer work) is if you assumed that old view is stopped right away:

  3. We have a new utility to process URLs of the model (useful before saving it) to e.g. force URLs to be relative or embedded. See ProcessUrls and TUrlProcessing API for the possibilities. See also pull request for all details. Thank you to Jan Adamec for implementing this!

  4. We have added documentation how to install web prerequisites using “WA” button in FpcUpDeluxe. Thanks to Vlad (Phomm)!

  5. I (Michalis) attended FOSS Backstage 2026 conference recently and enjoyed a lot of talks with fellow open-source devs (and walking in Berlin!). The talk “AI generated violations of FOSS Licences” was in particular informative, and fun, and sad -> because AIs indeed ignore copyrights and licenses. To put it bluntly, all the open-source code in the wild has been abused — it is now reproduced, ignoring copyrights. Watch it and maybe you can spot the back of my bald(ing) head in the front :).

    There’s a lot of related discussion and opinions, see e.g. here at Gitea and this article.

    I have added a suitable section about it to our AI guidelines.

  6. Finally, something in progress: we work on audio playback on the web using WebAudio. Current progress is on branch webaudio. Details what works / what needs to be completed before merge in forum post here.

Enjoy using our engine? Please support us on Patreon. And have fun making games:)

Comments on the forum ➤

Web target: getting URL parameters, downloading resources using TCastleDownload

Posted on

random_image_from_unsplash example on web
asynchronous_download example on web
remote_logging example on web

We add 2 new features to our web target:

  1. New methods to read URL through which your page was accessed, and get query parameters of this URL. The use-case is creating webpages that react to URL parameters, e.g. expose a model viewer on URL like https://viewer.castle-engine.io/?url=http://example.org/model.gltf (working version of this coming soon!). Use these methods:

    This API exists on all platforms, just returns nothing on non-web platforms. So you don’t need to use any $ifdef WASI when accessing this.

  2. TCastleDownload class works on the web now. It allows to make HTTP requests, e.g. download files or communicate with REST APIs. See URLs, loading resources and Multi-player (network communication) for general usage description.

    Underneath, it uses XMLHttpRequest which is the standard way to make HTTP requests on the web. It supports all HTTP methods, custom headers, progress monitoring and generally all features of our TCastleDownload.

    Examples:

    Note that CORS (Cross-Origin Resource Sharing) security will prevent our application on the web from downloading things from other domains.

    This is a standard security feature of web browsers. It is unavoidable from our side (application living inside a web page). All web application (using JS or WebAssembly) have to deal with it.

    • For development, you can disable CORS in your browser. E.g. on Firefox with CORS Everywhere extension does the job. Chrome supports --disable-web-security command-line option. Search the web for details specific to your browser.

    • For real usage, the server has to be configured to allow downloading from it. It generally involves configuring the server to return appropriate header, like Access-Control-Allow-Origin: *. See CORS documentation at MDN and example configuration for Apache.

Comments on the forum ➤