First of all, thanks for the very nice game engine!
I have seen in the render class an option to define an ambient light (AmbientColor I think). However, it doesn’t seem to work at all. Your forum advises to add an extra light source, which is logical to some extent. I have already created one directional light facing the opposite direction of the Sun, with very low strength (0.10). The problem is, it’s an additional light, and it’s a directional light. It causes shiny parts in the shadow to reflect the “non existing” light, and generally creates undesired effects here and there. A roof that is in the shadow is apparently much brighter than it supposed to be, etc.
Having a non-directional light as a constant value could be much more practical from game development point of view. It’s actually quite popular approach in other software. I understand your engine doesn’t support that, so my question is: Is it possible to implement it in my code without changing the source code? E.g. some hook, or event. X3DLightSource specification used ambientIntensity. Or, at least, maybe it can be done with shaders, but I haven’t checked your shaders system yet.
Another thing: the shadows. Is there an option to change the shadow quality? From what I’ve seen you treat light source with shadows as a camera (can’t remember exact details). Can we change this “camera” resolution to say 25%, perform the shady stuff, and then resize it back to 100?
For my test I have used just 1 model of a house duplicated 4 times. It’s quite detailed with many polygons and small parts. I stripped it from textures, and it’s empty inside with opaque windows now. Only other thing there is a terrain (low poly mesh). My FPS dropped to 35-ish which is reasonable with high level shadows, but not every customer has a hi-end device.
However, the loading time of the level is somewhere between 2 and 3 minutes no matter I use 1 instance of my house, 5 or 8. The same happens inside CGE editor when I load project saved with “Shadows: True”.
The model is in binary glb format directly from blender (no lights, no anims, 361kb) and without shadows the game is loading very fast.
In the editor, when I reload my project saved with “Shadows: False” it load fast - just need to remember to switch them off again before quitting. Would be great to have a separate property “Shadows in Design mode”.
When I try the same trick for the compiled game - I start the game first and load shadows by key press - the game loads fast but then enabling shadows takes ages anyway.
After the game is loaded, and shadows on, changing the light direction is immediate which suggests it’s not just shadows being the problem. But I’m testing the engine for just 12 maybe 15 hours so far.
Another question is about LOD. Do your engine have a support for it out-of-the-box? In CGE editor I haven’t seen an option to enable it, or to use different URLs, or to control it in any way. I’m not sure if I missed something, but better to ask rather than reinventing the wheel.
Last thing on my list is the CGE editor itself. I didn’t check its source code yet, but have you considered an option to set custom font size for the hierarchy list and the property list? Or the editor form at all. I can change them for me myself, or even change the positions - I use big 50in screen, but I thought it could be an idea worth sharing. Also if the property editor was a Stay-on-top tool window, it wouldn’t steal focus from 3d view (I see an error message “wwasdq isn’t a valid number” often ). It’s just a philosophical question because you may have tried it before and the were reasons to abandon it. I’m aware that any changes I make can mess with future updates.
With shadows, now I see, the property switches shadow volumes on/off, and the long loading time is because of calculating them. Probably pre-calculating them and storing somewhere would solve it. Nevertheless I’ll wait for the big shadow maps update.
The editor’s font I have already sorted and the setting sits comfortably in the General tab in Preferences. I’ve only changed the right side Controls view, bottom Messages view, left Inspectors and the grid showing design files at the start so they can be easier to read on high DPI without the need of changing DPI settings for the whole system. I can upload the changes if you are interested in this most-precious feature of all times.
Hi and thank you very much for the good words and feedback about the engine!
We have 2 lighting models in Castle Game Engine:
Physical-based rendering (PBR). The modern, realistic, compatible with glTF 2.0, Blender and X3D 4.0 node TPhysicalMaterialNode.
Phong lighting model (not to be confused with Phong shading, an independent thing). This happens when you use X3D TMaterialNode.
We advise using AD 1, PBR, for all new things. It is modern, matches other modern engines/3D software/formats. This is what happens when you load glTF 2.0 by default.
And indeed, as you found, we have no simple “ambient light color” in case of AD 1. The property TRenderContext.GlobalAmbient is indeed ignored when using the physical-based rendering (PBR). This property still works when using the older Phong lighting model, it does the same as old fixed-function OpenGL GL_LIGHT_MODEL_AMBIENT.
The primary reason why we ignore TRenderContext.GlobalAmbient (for PBR) is that it’s very not realistic. It’s quite similar to adding a non-zero emissive color to every material. Modern rendering engines/software using PBR generally doesn’t have such thing as “simple global ambient color”, from what I know.
Solutions:
The recommended solution is indeed, as you say, to add additional “fake” light source(s). It’s not ideal, I absolutely agree with you that new fake light sources require some handling.
You mention another possibility yourself – indeed, it would be possible to use shader effects to do this.
But there’s even easier way: just set the EmissiveColor of all your materials to something like 0.2 * BaseColor. I think this is pretty much all that “global ambient” does anyway, looking at equations and at my own GlobalAmbient implementation Once you have an instance of TCastleScene (e.g. you have a view with a TCastleScene component named MyScene), you can do it like this:
procedure TMyView.HandleMaterialNode(Node: TX3DNode);
var
Material: TPhysicalMaterialNode;
begin
Material := Node as TPhysicalMaterialNode;
Material.EmissiveColor := Material.BaseColor * 0.2;
end;
procedure TMyView.Start;
begin
inherited;
MyScene.RootNode.EnumerateNodes(TPhysicalMaterialNode,
{$ifdef FPC}@{$endif} HandleMaterialNode, false);
end;
I did not actually test above, but hopefully this is enough to get you started Let me know if you want to follow this path and have trouble applying this.
Another, not recommended but possible, solution is to downgrade your material usage to old Phong lighting model. To do this, use CastleLoadGltf unit and set global GltfForcePhongMaterials to true early in your application (e.g. at the beginning of ApplicationInitialize). Then you can set RenderContext.GlobalAmbient (e.g. on TMyView.Render) to something like Vector3(0.2, 0.2, 0.2) and it will work.
This will give you all the capabilities of Phong lighting model, like in X3D 3.x, like in OpenGL fixed-function GL_LIGHT_MODEL_AMBIENT (but we do it using shaders, at least if your GPU is modern).
Finally, we have plans to make it perfect: support Environment Lighting, aka “image-based lighting”, which is a great way to represent a light cast from a sphere / hemi-sphere, like from a sky.
This is what one usually wants to simulate by “global light”.
This is something supported in most modern rendering engines, and we miss it badly, and we shall have it in the future. Sorry, tt’s not there yet, but the work is ongoing, you can see my notes about EnvironmentLight node that is the prerequisite to internally handle it.
It seems you mixed a bit 2 shadow techniques in the description above To be clear, we have 2 techniques for shadows, independent:
One is shadow maps. Then indeed each light source is a bit like a camera. And we can control the resolution of the texture being rendered (the “shadow map”). We also have plans to improve shadow maps.
Another is shadow volumes. This is what happens when you use the Shadows checkbox on the light sources. Such shadows don’t have a “resolution” or such that we can control, they don’t treat light source as a camera.
So, there’s no control for “resolution” of shadow volumes. But they also should not cause a slowdown at loading like you describe. This sounds like a bug. Can you submit a testcase? I.e. send the project that opens so long (either in editor or at runtime), the project with houses that opens for 2-3 minutes if the shadows are active.
I see you also confirmed that it’s a loading time in the next post. To be clear, this is still weird Do submit a testcase. Possibly it’s something I can just improve.
As for performance (FPS) of shadow volumes, note that we had improvements around September 2024 to shadow volumes performance. Make sure you test with latest 7.0-alpha.3.snapshot from Download | Castle Game Engine . If it’s still slow, then also submit a testcase (or maybe it will be the same testcase as above?). I can work and improve.
We have a basic support for LODs using the X3D node TLODNode.
The way to use it is to create an X3D file like this (assuming you have 3 glTF models to use at different distances):
#X3D V3.2 utf8
PROFILE Interactive
LOD {
children [
Inline { url "model-close.glb" } # used when distance < 10
Inline { url "model-medium.glb" } # used when distance between 10 and 100
Inline { url "model-far.glb" } # used when distance > 100
]
range [ 10 100 ]
}
Save this file with .x3dv extension, like my-model.x3dv, place it alongside your 3 glTF files model-close.glb, model-medium.glb, model-far.glb. Then load the my-model.x3dv in TCastleScene.
Yeah, I know it’s not very obvious It’s using X3D nodes, and you have to write the X3D file manually, it’s not possible to be done in the editor. We should improve it eventually.
The editor should use the standard system font size, so it should just follow your theme settings, for WinAPI or GTK (GTK 2, for now, though you can also compile the editor with Qt backend on Linux) or such.
In general, if one likes larger font, it’s better to change the system font size, and then our editor automatically follows it.
If this doesn’t work for you as expected – what OS, what graphical environment do you use?
Can you describe the problem in more detail, e.g. by a video?
To clarify, the property editor indeed gets focused when you click on it, so that you can type text like “wwasdq” in a text fields, e.g. as a TCastleLabel.Caption. You can hit Escape to quickly bring focus to the designer view, where W will “go forward”. What can we do better in this regard? I mean, we need to handle w for entering text, and w for moving forward in the 3D view, so it’s a bit tricky – you indeed need to be aware when you are focused, and sometimes one can write w in the wrong place. This happens for me in other game engines as well, and I don’t see easy solution – we need to handle both text input and 3D navigation.
But maybe you mean something more specific and I just don’t understand the problem Please tell me / show me more, we can surely improve things.
Thank you for your replay. It’s very informative and I’ll try to apply the new knowledge in my design. For the “fake” light I think it’ll be better if I use smaller point lights in various places instead of directional one. It would definitely help with large landscape where fake Sun makes undesirable reflections.
The model of a house has thousands of triangles, and by no any means is a game asset. I use it for photorealistic renders, however it’s a good testing ground for engine capabilities. And your engine done the job well. It’s just the shadow volume calculation time. I’ll try with some other models that are more suited for a game. Especially that now I know better what option does what. If the problem persists I will definitely let you know.
Also your description of LOD makes a lot of sense. Thanks.
About the fonts. I use Win 11 so I could change DPI settings easily. But as I use a big screen I can stick to 100% font size, having more space on screen. It’s easier to work with few windows tiled instead of switching between them. However, sometimes it’s good to have an option to change font in the editor without changing it system-wide.
I have changed FormPreferences, FormProject and FrameDesign to update, load & save the new font size. It’s basically just few lines of code but makes huge difference for me.
Here are 2 screenshots. 1) with default font size = 9, and 2) with modified size 13. Both are in original 4k resolution. I hope it makes sense
I was thinking about it, and my guess is that our analysis of manifold/border edges may take a weirdly long time on some models (the code in CGE is at TShapeShadowVolumes.CalculateIfNeededManifoldAndBorderEdges). The analysis looks for edge “pairs”, for every edge on some polygon we look for the same edge but in a different direction in the adjacent polygon. This confirms we have 2-manifold mesh and later the connection information is used to find the “silhouette edges” each frame. The “silhouette edges” in turn determine the “shadow volume” that in turn determines what is in the shadow.
… And it’s definitely something we could optimize. Our approach is naive right now and it’s pessimistically n^2. We could use smarter structure to look for edges and get O(n log n) easily (or even faster if we go with hash list).
So, don’t hesitate to submit a bug with a testcase Even if your model is not yet optimized – we strive for performance even for unoptimal data, no worries
Makes sense on the screenshots, thanks. I agree it would be nice to have this available as editor preference – I can see other applications also having font size preference (so they don’t defer to “system-wide”), like Blender. If it’s a simple thing to maintain, I’m for it. You’re welcome to a create a pull request for it.
Regarding the font sizes, I’ll pull request as soon as I have tested it.
The code works fine, thanks. But it gave me an idea. Changing everything in bulk may have undesired consequences, like a black metallic gate becoming silver. But I could change emissions in 3d modelling software (blender in my case) to some 0.001-0.003, only for the objects that I need. Such a low value is ok for FullScreen. Details are visible but not unnatural.
Just a quick screenshot from the editor, hopefully you can see it. Well, always better than complete darkness.
What I think… If player goes to a dark interior then I can check his position and adapt the light/emission (Unreal also does the box-thingy). What it means means, I could also place invisible collision boxes along tall walls and other places that I know can get dark. Then comparing direction X of the sun with direction X of the box I can determine if the shadow is there and which wall I need to lighten up, without fancy calculations. I’ve done some testing with these ideas and it looks promising. I share it with hope it could be helpful.
Ok, so I have finished the fonts update. On one of your videos I’ve noticed someone complaining about lack of Dark Scheme, so I went to the dark side on my Windows 11, and it doesn’t work indeed.
It’s the best that can be done without hacking the LCL. I know there’s a 3rd party dark-mode package for Lazarus, I use it for my IDE, but it needs extra packages, is windows-only too.
From programming point of view, inside my code there are no new components or anything, you just drop what you want on the form as you always do. It only uses what you use in your project. I change colors basing on common class ancestors (TControl vs TWinControl), or explicitly (like TCustomTreeView or ObjectInspector). Usage is mostly "FormShow(); UpdateStyle"
From user point of view, there are 3 settings to choose + ability to change colors to their own taste. All changes are saved in UserConfig. Also there’s an ability to change TSplitter size, so its better visible on higher resolutions.
Menus use OnDraw which I provide. The custom OnDraw is applied automatically to every menuitem that has no OnDraw created by someone else. Unticking “Change menu” in preferences reverse the OnDraw.
Don’t get me wrong, it’s great that you can do this. But, if I understand the limitations right, the GitHub - zamtmn/metadarkstyle is just more complete solution, so we would rather adopt it. This will make users who like dark mode happy, i.e. it will be “pretty dark mode”, with everything consistently dark.
To be honest I came here for the game engine not GUI colors I love programming and just couldn’t resist the temptation. Plus by doing this code I had a good opportunity to X-ray the internals of your application.
I could do it with the scrollbars, buttons, etc, it’s not that difficult, I may get back to it some day - I keep my copy. But I didn’t want to do something very platform specific, as it would require extra maintenance on your team’s side in the future. Windows will change, and it will break existing code I was thinking about settings that are 1) free from unnecessary maintenance - just “drop & forget” without much management, 2) reduce the dependency on other packages, and 3) that are for all users rather than just for windows. Only way to achieve these goals would be making custom components, it has benefits. However, I’m not sure if that’s so much needed or that you’d like the idea.
In my recent contract I had to make the whole GUI from a scratch, don’t ask why and I was thinking about similar approach to your editor. Window is white because of request, but it’s customizable, and don’t steal focus.
It’s doable, and independent of underlying system.
But if you’re up for metadarkstyle that’s great, I didn’t know you consider it.
I will submit my FontSize fix anyway, I think it’s more important Anyway, thank for taking time to answer. I really hoped to know what you think about it.
Oh, I absolutely agree with this sentiment – we want to avoid maintenance burden, we want to choose always the simplest solution that still solves the issue properly. If a feature is not critical, it may mean even aborting from doing something at all.
( Sidenote: I recall a great interview with SVN creator on Software That Doesn't Suck Building Subversion With Jim Blandy - CoRecursive Podcast . A quote I remember, more-or-less: “what do you choose to not solve (by your software) can be very smart decision (as you avoid doing things that are more burden than useful)”. OK, I see that literally it was said as "Almost what problems you decide not to take on can kind of define things, right?" )
But now, after many people asked for dark mode on Windows (and I understand them – I just didn’t feel this need so much, as I mostly work on Linux where one can have dark mode by just changing GTK theme) → I decided we really need to add it to CGE editor It seems to me now that this extra package just does the job well. Maintenance in this case is “delegated” to maintainers of this package. I heard the package being also mentioned by others so I’m relatively confident it will be actively maintained.
We have a plan for redoing editor one day to use only Castle Game Engine’s UI components. This is our 2nd plan to have “dark mode”. It’s a big work, but in this case it will have many other benefits – e.g. the editor will be capable to work as a web application, i.e. just in your browser, using our web target.
Already, a very simple attempt at “editor done using CGE components” can be seen if you press F8 in debug builds of any game, we show then inspector which has a hierarchy and very-simple-object-inspector using our own controls.
So, I’m actually thinking about “CGE editor with GUI done from scratch, not LCL”. But that’s a very future plan. I described it at length in the roadmap section.