Environment: background, ambient, SSAO and glow
Select camera/world environments and run controlled effect comparisons in current Compatibility.
Runnable authored scene
Download the gallery project. Requires Reckfell 1.0.0 with the C# SDK and Forward+/Vulkan. Open project.reckfell, build C# and run Main.rscene. The authored Pawn Shop interior was created by James Ray Cock and Rico Cilliers for Poly Haven under CC0. Architecture, furniture, plants and props come from that scene; materials and lighting are adapted for Reckfell. All resources and credits are included in Assets. The environment outside the windows is Kloofendal 48d Partly Cloudy Pure Sky, Poly Haven, CC0.
Output is 2560×1440 with a 3840×2160 internal render: Scaling3DScale=1.5, MSAA 8×, TAA and a 4096 shadow atlas. The scene configures ACES, SDFGI, SSAO, glow, SSR and volumetric fog. This is an expensive illustration profile; select resolution and effects for the game's target device. Enabling a property alone does not establish effect quality or performance on another GPU.
The comparisons below keep the camera, geometry, materials, exposure and antialiasing fixed. Only the stated parameter changes. The simple C# lab below isolates behavior; it is separate from the illustrated gallery.
Assign an environment
Environment is a settings resource, not an entity or a light by itself. Assign it through WorldEnvironment.Environment or Camera3D.Environment.
Priority is active-camera environment, then its World3D environment, then an available fallback environment. Camera3D.Environment=null clears the override. Check the active camera first if WorldEnvironment edits have no effect.
The one-WorldEnvironment rule applies to one world. A single EntityTree can contain independent SubViewports with owned World3D instances and different environments, as verified natively. Multiple WorldEnvironment entities in one world do not blend automatically; the first registered one is selected.
Run three modes
Save LightingMaterials.cs from materials, LightingLab3D.cs from lighting, and EnvironmentLab3D.cs below. Use C# SDK 1.0.0 and net10.0. Run dotnet build and attach EnvironmentLab3D.cs to the .rscene Entity3D root instead of LightingLab3D.cs.
Before startup, select exported Preview: Lighting, AmbientOcclusion or Glow. EffectEnabled chooses the effect state. Exported settings are read in _Ready; editing them during play does not automatically reconfigure the example. Running code can call ShowAmbientOcclusion(bool) or ShowGlow(bool) after _Ready.
EnvironmentLab3D.cs
using Reckfell;
public partial class EnvironmentLab3D : LightingLab3D
{
public enum PreviewMode { Lighting, AmbientOcclusion, Glow }
[Export] public PreviewMode Preview { get; set; } = PreviewMode.Lighting;
[Export] public bool EffectEnabled { get; set; } = true;
private MeshInstance3D? emitter;
public override void _Ready()
{
base._Ready();
if (Preview == PreviewMode.AmbientOcclusion) ShowAmbientOcclusion(EffectEnabled);
if (Preview == PreviewMode.Glow) ShowGlow(EffectEnabled);
}
public void ShowAmbientOcclusion(bool enabled)
{
Key.Visible = false; Point.Visible = false; Spot.Visible = false;
Floor.Visible = true; Cube.Visible = true; MetalSphere.Visible = true;
if (emitter != null) emitter.Visible = false;
var env = World.Environment;
env.BackgroundColor = new Color(0.025f, 0.03f, 0.045f);
env.AmbientLightEnergy = 1;
env.FogEnabled = false; env.GlowEnabled = false;
env.SsaoEnabled = true;
env.SsaoRadius = 2;
env.SsaoIntensity = enabled ? 3 : 0;
}
public void ShowGlow(bool enabled)
{
Key.Visible = false; Point.Visible = false; Spot.Visible = false;
Floor.Visible = false; Cube.Visible = false; MetalSphere.Visible = false;
var env = World.Environment;
env.BackgroundColor = Colors.Black;
env.AmbientLightEnergy = 0;
env.SsaoEnabled = false; env.FogEnabled = false;
env.GlowIntensity = 1.5f;
env.GlowBloom = 0.1f;
env.GlowHdrThreshold = 0.8f;
env.GlowEnabled = enabled;
if (emitter == null)
{
var material = LightingMaterials.Surface(Colors.Black);
material.EmissionEnabled = true;
material.Emission = Colors.White;
material.EmissionEnergyMultiplier = 8;
emitter = new MeshInstance3D
{
Mesh = new BoxMesh { Size = Vector3.One },
Position = new Vector3(0, 0.7f, 0),
MaterialOverride = material
};
AddChild(emitter);
}
emitter.Visible = true;
}
}Separate background, ambient and reflections
| Setting | Role |
|---|---|
| BackgroundMode and BackgroundColor | Output behind geometry |
| AmbientLightSource, AmbientLightColor, AmbientLightEnergy | General surface illumination |
| ReflectedLightSource | Environment-reflection source |
| TonemapMode and exposure | Output brightness transformation |
A colored background does not guarantee a lit cube. The example explicitly selects Color ambient and disables environment reflections. A different Camera.Environment background overrides WorldEnvironment; clearing it restores the world background.
Start with predictable materials and one light, then adjust tone mapping/exposure and effects. This comparison holds TonemapMode=Linear constant. Identical numeric settings across renderers do not promise identical output.
SSAO: contact darkening
AmbientOcclusion mode disables direct lights, sets ambient energy=1 and SsaoRadius=2. With EffectEnabled=false, SSAO stays enabled but SsaoIntensity=0; true sets intensity 3. This compares the same post-processing path rather than two different output paths.
The figures show the Forward+ gallery: SsaoEnabled=true in both frames, SsaoIntensity=0/1.6. The C# lab above uses separate 0/3 values.
The comparison confirms local darkening around geometry while leaving the background unchanged. Values 2/3 are exaggerated for demonstration, not universal game defaults.
Current Compatibility has a basic SSAO implementation using Radius/Intensity. Source applies its own radius/intensity scaling; extended Forward+ settings should not be assumed equivalent. SSAO uses visible depth, does not create a physics shadow and cannot inspect the entire off-screen world.
Glow: a bright-object halo
Glow mode hides the floor, cube and sphere, disables lights and displays a separate emissive mesh against black. EmissionEnergyMultiplier=8; glow uses Intensity=1.5, Bloom=0.1 and HdrThreshold=0.8.
The figures show the Forward+ gallery: GlowEnabled=false/true, GlowIntensity=0.55 and GlowBloom=0.03. Geometry and exposure remain unchanged.
Native checks confirm an actual halo in the current OpenGL runtime. Individual glow levels, blend/map and quality settings vary by renderer and are outside this example. Glow does not light neighboring geometry. Excess bloom reduces contrast; tune it after exposure and source brightness.
Fog and other effects
FogEnabled enables regular fog; density 0 versus 0.15 is separately verified within the already enabled mode. VolumetricFogEnabled is a different mechanism, not demonstrated here. Setting a boolean property alone does not prove renderer implementation.
SSIL, SSR, GI, reflections, volumetric fog and compositors require their own configuration and target verification. Do not enable everything to solve one lighting issue. For stronger contact, check geometry and lights before SSAO; light transfer between surfaces is a separate indirect-lighting task.
Diagnosis
| Problem | Check |
|---|---|
| World edits have no visible effect | Camera3D.Environment and the viewport’s actual World3D |
| Background exists but geometry is black | AmbientLightSource/energy and actual Light3D sources |
| SSAO appears to change the whole image | Compare the same enabled path at intensity 0 and the required intensity |
| Glow is absent | EmissionEnabled, brightness/exposure, threshold and assigned environment |
| Glow does not illuminate neighbors | Add Light3D or separate indirect illumination |
| Editing Preview during play does nothing | It is read in _Ready; call the public configuration method |
Figures are actual current local 1.0.0 Forward+/Vulkan frames at 2560×1440. The simple C# lab is separately checked in Compatibility/OpenGL. These are different scenes, not a renderer, performance or editor-interface comparison.