How to set ambient light?

Is it possible to add ambient light in scene?

Hi!

  • If you do not use PBR materials, then you can set RenderContext.GlobalAmbient, like RenderContent.GlobalAmbient := Vector3(0.4, 0.4, 0.4). Admittedly this is very simple ambient light, it is just added to calculated color of everything, like a GL_LIGHT_MODEL_AMBIENt in old OpenGL.

  • If you do not use PBR materials, you can also use light source’s “ambientIntensity” value. For this, you would have to create an X3D file by hand, like

#X3D V3.2 utf8
PROFILE Interactive

PointLight {
  location 1 2 3
  ambientIntensity 1
}

I admit, both of the above answers are poor. They are not comfortable to use, and they do not work on materials using PBR, which means that they do not affect materials defined in glTF. And glTF is our recommended format for 3D, see glTF (model format) | Creating Game Data | Castle Game Engine . glTF PBR model doesn’t have “ambient” lighting, as non-realistic.

What are you trying to achieve? Can you describe / post screenshot? Maybe you actually look for something else than “ambient light”?

1 Like

Hi and welcome!

I don’t think it’s possible to add an ambient light to the whole scene, instead you’ll have to traverse every model inside of the scene recursively and set Material properties, e.g. something like this:

procedure UpdateAmbientIntensity(const Root: TX3DRootNode);

  procedure ScanNodesRecoursive(const Source: TAbstractX3DGroupingNode);
  var
    I: integer;
  begin
    for I := 0 to Source.FdChildren.Count - 1 do
      if Source.FdChildren[I] is TAbstractX3DGroupingNode then
        ScanNodesRecoursive(TAbstractX3DGroupingNode(Source.FdChildren[I]))
      else
      {NOT FOUND exception is a normal error here, it's processed internally,
       set it to "always ignore this type of exceptions"}
      if (Source.FdChildren[I] is TShapeNode) then
        try
          (TShapeNode(Source.FdChildren[I]).FdAppearance.Value.FindNode(
            TMaterialNode, False) as TMaterialNode).AmbientIntensity := SomeNewValue;
        except
        end;
  end;

begin
  ScanNodesRecoursive(Root);
end;

UPDATE: Oh, I see @michalis was faster than me :smiley:

Thanks for answers.

Well, I just try to make bright light in scene, without using “Headlight”. With “Sun” light source, “back” sides of objects is too dark.

Ah, in that case, the best answer is – you should add more lights :slight_smile: Don’t be afraid to just add another DirectionalLight (which is “Sun” in Blender) that shines in the opposite direction. Don’t be afraid of adding lots of local point/spot lights to make the scene brighter.

This is a general advice for 3D modeling and light sources: “you probably want to have more light sources than you thought” :slight_smile: The reason is that real-time renderers (like game engines) don’t do “indirect” lighting (which means that light doesn’t “bounce off” surfaces ~infinite number of times, like it does in reality). This means that typically you need to place in your scene much more lights than exist in reality, to achieve a similar brightness as in reality. Of course it’s not that easy – if you add too many lights you can easily achieve “flat”, non-interesting, non-realistic light (in particular, you can easily make it if you add too many DirectionalLights).

See e.g. Blender guru series about lighting, https://www.youtube.com/watch?v=Ys4793edotw , https://www.youtube.com/watch?v=cg1K_ZWB0Uw .

Yeah, I already tried adding more lights, but I thouht there was some other way to make scene brighter. Something like “ambient light” :slight_smile:

I know this thread is old, and also that I’m a newbie, but I’ve found a way to add ambient light in the editor.

So you have a MainLight that is a directional light (TCastleDirectionalLight) with Shadows on. Duplicate that MainLight and rename to FillLight1, set Shadows to False and dim the light to a minimum (i.e. 1 while main is 10), don’t change anything else. Then duplicate this new FillLight1, rename it to FillLight2 and rotate it to be exactly in the opposite direction. You may dim it a bit also (i.e. 0.5 or 0.25). You may also dim the MainLight to 9 or 8.5 because the new lights will light everything up.

Test it, it looks quite nice.
Ambient light example

1 Like

Thanks! I second that, I mean this is indeed a valid and effective (in PBR) method of achieving an ambient. 2x directional lights, with inverted direction.

rotate it to be exactly in the opposite direction

Note that you can also negate light Direction. I.e. expand Direction property of TCastleDirectionalList and negate (make negative if the number was positive, make positive if it was negative) all 3 numbers.