More trouble with latest cge update

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 how it looked before the update…

This defines the base plane…

   baseplane := tcastlePlane.create(objectview);
   baseplane.Size := vector2( 10, 10 ); { 10x10 meters }
//   baseplane.Color := vector4(1,0,0,1);
   baseplane.doublesided := false;
   baseplane.texture := 'castle-data:/grid.png';
   baseplane.RenderOptions.Lighting := true;
   baseplane.Material := pmPhysical;
   baseplane.Color := vector4(1,1,1,1);
   Objectview.Items.Add(baseplane);

This defines the scene…

 Root := TX3DRootNode.Create;
   Root.AddChildren( builder.buildshape );
   buildingscene.Load(Root, true );
   ObjectView.Items.Add( buildingscene );
   buildingscene.CastShadows := true;
   buildingscene.RenderOptions.WireframeColor := Vector3(0,0,0.1);
   buildingscene.RenderOptions.WireframeEffect := weSilhouette;
   buildingscene.renderoptions.linewidth := 6;
   buildingscene.renderoptions.lighting := true;
   buildingscene.RenderOptions.wholescenemanifold := true;      

This defines the camera and lighting…

   Camera := TCastleCamera.create( self );
   Camera.Perspective.FieldOfView := 0.5;
   positioncamera;

   Items.Add(Camera);

   l := TCastlePointLight.create( self );
   l.Translation := Vector3( -8, 15, 10 );
   l.Color := Vector3(1,1,1);
   l.Intensity := 8;
   l.Shadows := true;
   Items.Add(l);

   l := TCastlePointLight.create( self ); { ambient light }
   l.Translation := Vector3( 8, 15, -10 );
   l.Color := Vector3(1,1,1);
   l.Intensity := 2;
   l.Shadows := false;
   Items.Add(l);                            

All very simple.

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.

1 Like

Thanks, that sounds like the issue and will get me back on track. … and it does…

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)

If you are useing the SpotLight, check the value Attenuation.Z which is now at 1 per default. Maybe this could help.

Yes, it is the same for PointLight. That was the fix.

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 :slight_smile:

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 :slight_smile:

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).

1 Like

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 :slight_smile: 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 :slight_smile: 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?

How do you save tcastlescenes?

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.

You can save a scene by, well, the Save method :slight_smile: See Castle Game Engine: CastleSceneCore: Class TCastleSceneCore .

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.

1 Like

I like how the silhouette effect works to really give it the ‘drawn’ look.

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.

.

@edj @Didi I finally made a promised news post explaining what/why changed in regards to the lighting: Important rendering bugfix: Light components (TCastlePointLight and TCastleSpotLight) defaults are correctly applied now, look realistic out-of-the-box (but also, look a bit different – read on for details) – Castle Game Engine .