Physical lights and camera exposure
Lux, lumens, ISO and shutter speed: units, setup and brightness diagnosis.
Physical units give 3D lights and cameras a consistent starting scale: lux for directional illumination, lumens for positional light output, Kelvin for color temperature and photographic parameters for camera exposure. They do not fix geometry, materials, light leaks or missing indirect lighting.
Use this workflow when you need a reproducible lighting scale. For an art-directed game, ordinary light energy and a fixed exposure can also be appropriate. Do not switch an existing project to physical units and expect its old brightness balance to remain unchanged.
Enable the complete workflow
- Open Project Settings, enable Advanced, then enable Rendering → Lights And Shadows → Use Physical Light Units (
rendering/lights_and_shadows/use_physical_light_units). Restart the editor and running game. This is a startup configuration, not a reliable per-frame toggle. - Assign
CameraAttributesPhysicalto the activeCamera3D.Attributes. Camera attributes control exposure separately from theEnvironmentresource controlling tone mapping. - For consistent world/editor-preview exposure, also assign appropriate camera attributes to
WorldEnvironment.CameraAttributes. A game camera's own attributes take precedence for that camera. Focal length and clip distances apply to a Camera3D when the physical resource is assigned to it; a world default alone does not configure every camera's lens. - Keep Auto Exposure disabled while establishing the lighting balance. Set
ExposureMultiplierandEnvironment.TonemapExposuredeliberately; they are separate multipliers. - Configure light intensity, color temperature and background intensity. Start with
LightEnergy = 1so an extra artistic multiplier does not hide the scale you are setting. Remove or rebalance a preview sun/background when authoring an interior. - Compare the same camera and material before changing further settings. Validate the intended renderer and target device; these settings do not imply identical effects across backends.
When the setting is off, the physical camera still controls lens/FOV and clip distances. However, ISO, shutter speed and aperture do not affect its exposure normalization. The explicit ExposureMultiplier remains active. Aperture can still participate in depth-of-field calculations on a supported renderer.
Camera values: use the correct units
With physical units enabled, auto exposure off and the same lit surface:
| C# property | Unit / meaning | Change in scene-linear lighting |
|---|---|---|
ExposureSensitivity | ISO | 100 → 200: twice as bright. |
ExposureShutterSpeed | Reciprocal seconds, in C# too | 50 → 100: exposure time changes from 1/50 s to 1/100 s; half as bright. |
ExposureAperture | f-number | 2 → 4: quarter as bright. A larger f-number means a smaller opening. |
ExposureMultiplier | Unitless multiplier | 1 → 2: twice as bright; works with physical units off too. |
FrustumFocalLength | Millimeters | Controls vertical FOV and participates in depth of field. Not an exposure multiplier. |
FrustumFocusDistance | Meters | Focus distance, not focal length or clipping distance. |
FrustumNear, FrustumFar | Meters | Near/far clipping. Supply positive distances with near less than far. |
To specify 1/50 second, write ExposureShutterSpeed = 50f, not 0.02f. The latter describes 50 seconds in this API and can cause extreme overexposure.
For fixed physical exposure, 1.0.0 calculates normalization as ISO / (120 × f-number² × shutter-speed-value), then multiplies it by ExposureMultiplier. This explains the ratios above; it does not calibrate an arbitrary asset to real-world measurements. Tone mapping, clipping and display encoding mean that doubling scene-linear illumination does not necessarily double the numbers in a screenshot.
Changing ISO does not by itself create photographic sensor noise. The shutter parameter adjusts exposure; it is not a switch for motion blur. Depth of field is a separate rendering effect and has a GPU cost where active. The source supports DOF in Forward+ and Mobile, not Compatibility; this guide's rendered checks use Forward+ only.
Create camera attributes in C#
The helper below returns a resource with a 35 mm lens, a 3 m focus distance and fixed exposure. It is an example starting point, not a brightness preset suitable for every scene. Enable the project setting and restart first, then assign the returned resource to the intended camera's Attributes.
using Reckfell;
public static class PhysicalCameraSetup
{
// Example starting point, not a universal lighting preset.
// Enable use_physical_light_units in Project Settings and restart first.
public static CameraAttributesPhysical Create()
{
return new CameraAttributesPhysical
{
ExposureSensitivity = 100f,
ExposureAperture = 2.8f,
ExposureShutterSpeed = 50f, // 1/50 second, not 0.02 here.
ExposureMultiplier = 1f,
AutoExposureEnabled = false,
FrustumFocalLength = 35f, // Millimeters.
FrustumFocusDistance = 3f, // Meters.
FrustumNear = 0.1f,
FrustumFar = 100f,
};
}
}The Camera3D retains the assigned resource; do not immediately dispose it after assignment. If several cameras share one attributes resource, editing that resource changes all its users. Create separate instances when their settings must differ.
Assigning CameraAttributesPhysical to Camera3D replaces its FOV, near/far and aspect behavior with the physical resource's settings. A longer focal length narrows vertical FOV; the implementation uses a 36 × 24 mm sensor and keeps vertical framing. Widening the viewport therefore widens horizontal coverage. Move the camera if you want to change perspective; changing focal length alone is a lens/framing change.
Light and background values
| Setting | Meaning in physical mode | Common mistake |
|---|---|---|
DirectionalLight3D.LightIntensityLux | Directional illuminance, lux. | Entering a lamp's lumen rating here. |
OmniLight3D / SpotLight3D.LightIntensityLumens | Positional luminous flux, lumens. | Treating it as illuminance measured at an arbitrary surface distance. |
Light3D.LightEnergy | Additional energy multiplier. | Changing both intensity and energy without tracking which changed. |
Light3D.LightTemperature | Kelvin tint combined with LightColor. | Expecting a colored light to become neutral just because temperature is near 6500 K. |
Environment.BackgroundIntensity | Background intensity in nits, combined with its energy multiplier. | Balancing indoor lamps against an unintentionally bright sky. |
Temperature near 6500 K is approximately neutral; lower values tend toward warm tones and higher values toward cool tones. The engine combines the temperature color with LightColor in linear space. With physical units disabled, the temperature and physical intensity controls do not affect light rendering.
SpotLight3D uses a simplified flux-to-intensity convention: changing the cone angle does not provide a fully calibrated real-world spotlight model. Do not claim exact photometric matching from a lumen number alone. Source light data, scale, materials, attenuation and camera exposure all matter.
Diagnose brightness without guessing
| Problem | Action |
|---|---|
| Enabling physical units makes the scene extremely bright | Restart, check the active camera's attributes, then sun/sky intensity and both exposure multipliers. |
| ISO or shutter values have no effect | Verify the startup setting, the attributes assigned to the active camera and whether the material uses unshaded. |
| A custom unshaded surface ignores camera exposure | Its unlit ALBEDO bypasses camera light normalization in the tested Forward+ path. It still responds to Environment tone-map exposure. Compare physical lighting on a lit material. |
| Editor preview and game look different | Check world/default attributes versus camera overrides, preview lighting and the Environment used by each view. |
| Changing exposure seems to undo itself | Disable auto exposure before comparing fixed settings. Auto exposure is supported by Forward+, not all renderers. |
| Lamp brightness is wrong after changing room scale | Check object distances and whether you entered lumens or lux. Camera exposure cannot repair incorrect scene scale. |
| Objects disappear after assigning physical attributes | Check the resource's near/far clip values and new lens framing. |
| A wall is lit through the ceiling | Inspect geometry and shadows. Physical units do not create missing occlusion. |
Validation: 30 native checks in two separate Windows Forward+/Vulkan game runs. They measure rendered exposure/lux/energy ratios, temperature tint, unshaded behavior and camera projection updates. They do not establish absolute photometric calibration, DOF quality, auto-exposure adaptation, motion blur, editor-preview parity, other renderers or exported builds. See HDR and exposure for clipping and image-file pitfalls.