Hmm, so back to my parametric buildings and it has changed too. Everything is almost black though you can still see the texture peeking through. It has been maybe 6 weeks since I last updated.
This is a very simple tcastlescene with a tcastleplane and an x3d TIndexedTriangleSetNode with a physical material node that points to the same grid texture as the plane
. Shadows are enabled and there is a primary and an ambient light source. Can you think of any changes in the past couple months that would account for this?
This is almost for sure a result of our attenuation fix, which Iâm going to write news about today. In the engine a ~month ago, we didnât apply Attenuation correctly, it was 0 0 1 by default but was treated as 0 0 0.
In short: set the l.Attenuation := Vector3(0, 0, 0) on point light above, to have backward-compatible behavior (and effectively unrealistic lights that not do attenuate with distance).
See the news today about it, I will explain why it had to be broken (previous behavior was unfortunately broken too). Iâll mention this as 7.0-alpha.3 release page too, Castle Game Engine 7.0-alpha.3 - Release notes | Castle Game Engine , as an issue to be aware of when upgrading.
This does lead to another small question⌠look at the lighting on the shape above? Why is there an arced ring like that of spotlight with border? wouldnât a pointlight be omnidirectional so the whole face should have the same shading? I donât really mind, but it is not what I expected. (I actually like it for this design model view, it makes it look more like a model than fullsize building which is appropriate)
The rendering is correct â the source of TCastlePointLight is from the same point, which means that on each corner of the face receiving the light, the light comes from a bit different direction, and thus it is brighter / dimmer (as the amount of light received depends on the angle direction from which it comes, and face normal).
If youâd like the light to come from the same direction (and then indeed whole face would always have uniform shading, no gradient) then you want TCastleDirectionalLight.
Experiment with it in the CGE editor, moving the point light over a plane â this should make them more natural
To clarify, we always had Attenuation.Z by default = 1 for lights, but due to a nasty bug (which was present way too long undetected) we didnât apply this attenuation correctly for some time, so they behaved as if they had Attenuation.Z = 0 in many cases. Iâm ashamed I let this bug be present for so long, the new lights (with attenuation = 0 0 1) are much more realistic, as they always should have been
Iâll write a news post about this really soon (had it scheduled even before 7.0-alpha.3 release, but the times have been lately very busy).
Now I am allowing for more building blocks that can work as a single building. Each block with its roof is its own scene built from tindexedtriangleset. I am still troubled by the lighting. The lighting should be continuous across these coplanar faces and instead looks quite rounded like a crayon for each face. So it is not a matter of the angle to the pointlight being more oblique. It seems to me that the problem is that with the indexedtriangleset and the vertices being shared that the lighting is using the normal for a vertex averaged from the faces that share it instead of for a specific face. (there are unseen faces between the blocks) Does that seem plausible? Is there a way to solve this short of going to ttriangleset and losing the efficiency of indexing?
Hm, Iâd like to see this object (if you have it in glTF or X3D, please make a testcase) to understand the issue you describe. Otherwise, I can recommend various things, some of them conflicting, so please be sure you first diagnose the problem So let me instead give a general overview how it works:
Lighting follows the normal vectors specified for each vertex. If the normal vector is not specified, it is calculated following the X3D specification â either all smooth, or they follow CreaseAngle available at some nodes (TIndexedFaceSet and a few others, but not TIndexedTriangleSet; that is, TIndexedTriangleSet doesnât have CreaseAngle feature, and thatâs actually nice because 1. implementing CreaseAngle is a pain and 2. itâs actually more efficient and more obvious what happens if you provide normals explicitly â see below).
If the automatic calculation is used, it indeed matters how the vertex is shared (or not shared) between various faces.
If you want the vertex to have different normal on different faces, then you need to actually have 2 vertexes, with equal positions â donât worry, you will not loose any efficiency by doing so, because thereâs nothing else possible to do to achieve what you want. Even: the engine will actually sometimes âexpandâ the indexes provided (that is, effectively convert indexed â not indexed geometry before passing it to GPU) when the indexes are not possible to be used, e.g. the vertex position is shared but something else forces using different normals for different vertex occurrences. Thereâs no choice then, for GPUs it has to be different vertex. We of course avoid it like fire in the engine code :), itâs best if we keep indexed geometry as indexed for GPU, but there are edge-cases when weâre effectively forced to do this (indexed â not indexed) to have correct rendering.
If you think the lighting is wrong because the automatic calculation of normal vectors results in something unexpected, my best recommendation is to export from your 3D software including explicit normal vectors. This makes 3D files slightly bigger, but makes loading faster (since the engine doesnât need to calculate normals) and removes any questions âwhy did the automatic calculation do this and not thatâ. When exporting from Blender to glTF ( Blender | Creating Game Data | Castle Game Engine ) thereâs a checkbox to select to include âNormalsâ in the output. And you can also visualize normals in Blender to see what they are.
The model is just constructed in code so there are no files. It with divisions=2 it is 3 tcastlescenes each with a loaded tindexedtriangleset that are then added to the root tcastlescene for the whole building and plane. Is there a way to save this? Or maybe I just save one of the x3dnodes and you can just duplicate in the editor?
I think the solution is to not use the indexed triangle set and have duplicate vertices. Then normals should be correct by face. I think that will also help when I go to try to texture individual faces which might be complicated by shared vertices.
Or save X3D node (must be TX3DRootNode) using SaveNode.
Note: You can duplicate the necessary vertexes, but still keep using TIndexedTriangleSet, to share the rest. Unless the model is simple like you show, then it doesnât much matter, thatâs a small shape and itâs more important that you test DynamicBatching than worrying about this single modelâs performance.
Haha, yes, Save is pretty obvious. I havenât gotten around to saving anything yet. But I have already progressed and deindex the model construction so it is too late to save the old way. This results in the expected flat looking faces. The model will get more complicated as I add new ways to parametrically modify faces to add detail and add blocks. But no individual element will ever know much about the overall context and model shape to know if points will be shared or not, so easy to stay unindexed for everything.
Now it looks more fun⌠this building made of 4 blocks, each with different roof parameters. It takes 84 bytes to represent the parameters of this building with 4 blocks (including roof and facade materials even though they arenât building yet) before it builds into a scene. So there can be very many distinctly different buildings using very little memory. They can then build with variable LOD as needed to build scenes for densely populated world.