simvx.core.world_environment¶

WorldEnvironment, Environment, and PostProcessEffect for SimVX.

Module Contents¶

Classes¶

FogMode

How distance fog thickens with depth, for :attr:WorldEnvironment.fog_mode.

TonemapMode

The HDR-to-display curve, for :attr:WorldEnvironment.tonemap_mode.

PostProcessEffect

User-defined fullscreen post-processing shader effect.

WorldEnvironment

Scene-wide rendering settings: ambient, sky, fog, tonemapping and post-processing.

Environment

Environment resource that can be shared between WorldEnvironment nodes.

Data¶

log

API¶

simvx.core.world_environment.log¶

‘getLogger(…)’

class simvx.core.world_environment.FogMode[source]¶

Bases: enum.StrEnum

How distance fog thickens with depth, for :attr:WorldEnvironment.fog_mode.

Members: LINEAR: Ramps from fog_start to full strength at fog_end. EXPONENTIAL: Thickens exponentially with distance at fog_density; the default. EXPONENTIAL_SQUARED: Squares the exponent, so fog stays clear close in and closes in quickly further out.

Initialization

Initialize self. See help(type(self)) for accurate signature.

LINEAR¶

‘linear’

EXPONENTIAL¶

‘exponential’

EXPONENTIAL_SQUARED¶

‘exponential_squared’

__new__(*values)¶
__add__()¶
__contains__()¶
__delattr__()¶
__dir__()¶
__eq__()¶
__format__()¶
__ge__()¶
__getattribute__()¶
__getitem__()¶
__getnewargs__()¶
__getstate__()¶
__gt__()¶
__hash__()¶
__iter__()¶
__le__()¶
__len__()¶
__lt__()¶
__mod__()¶
__mul__()¶
__ne__()¶
__reduce__()¶
__reduce_ex__()¶
__repr__()¶
__rmod__()¶
__rmul__()¶
__setattr__()¶
__sizeof__()¶
__str__()¶
__subclasshook__()¶
capitalize()¶
casefold()¶
center()¶
count()¶
encode()¶
endswith()¶
expandtabs()¶
find()¶
format()¶
format_map()¶
index()¶
isalnum()¶
isalpha()¶
isascii()¶
isdecimal()¶
isdigit()¶
isidentifier()¶
islower()¶
isnumeric()¶
isprintable()¶
isspace()¶
istitle()¶
isupper()¶
join()¶
ljust()¶
lower()¶
lstrip()¶
partition()¶
removeprefix()¶
removesuffix()¶
replace()¶
rfind()¶
rindex()¶
rjust()¶
rpartition()¶
rsplit()¶
rstrip()¶
split()¶
splitlines()¶
startswith()¶
strip()¶
swapcase()¶
title()¶
translate()¶
upper()¶
zfill()¶
__deepcopy__(memo)¶
__copy__()¶
name()¶
value()¶
class simvx.core.world_environment.TonemapMode[source]¶

Bases: enum.StrEnum

The HDR-to-display curve, for :attr:WorldEnvironment.tonemap_mode.

LINEAR is a clamp, which keeps flat 2D art at its authored colour; the others are filmic curves that roll bright values off instead of clipping.

Initialization

Initialize self. See help(type(self)) for accurate signature.

ACES¶

‘aces’

NEUTRAL¶

‘neutral’

REINHARD¶

‘reinhard’

UCHIMURA¶

‘uchimura’

LINEAR¶

‘linear’

__new__(*values)¶
__add__()¶
__contains__()¶
__delattr__()¶
__dir__()¶
__eq__()¶
__format__()¶
__ge__()¶
__getattribute__()¶
__getitem__()¶
__getnewargs__()¶
__getstate__()¶
__gt__()¶
__hash__()¶
__iter__()¶
__le__()¶
__len__()¶
__lt__()¶
__mod__()¶
__mul__()¶
__ne__()¶
__reduce__()¶
__reduce_ex__()¶
__repr__()¶
__rmod__()¶
__rmul__()¶
__setattr__()¶
__sizeof__()¶
__str__()¶
__subclasshook__()¶
capitalize()¶
casefold()¶
center()¶
count()¶
encode()¶
endswith()¶
expandtabs()¶
find()¶
format()¶
format_map()¶
index()¶
isalnum()¶
isalpha()¶
isascii()¶
isdecimal()¶
isdigit()¶
isidentifier()¶
islower()¶
isnumeric()¶
isprintable()¶
isspace()¶
istitle()¶
isupper()¶
join()¶
ljust()¶
lower()¶
lstrip()¶
partition()¶
removeprefix()¶
removesuffix()¶
replace()¶
rfind()¶
rindex()¶
rjust()¶
rpartition()¶
rsplit()¶
rstrip()¶
split()¶
splitlines()¶
startswith()¶
strip()¶
swapcase()¶
title()¶
translate()¶
upper()¶
zfill()¶
__deepcopy__(memo)¶
__copy__()¶
name()¶
value()¶
class simvx.core.world_environment.PostProcessEffect(shader_code: str = '', *, enabled: bool = True, order: int = 0, language: str = 'glsl', wrap: str = 'clamp')[source]¶

User-defined fullscreen post-processing shader effect.

Holds fragment GLSL source, uniform values, enable state, and execution order. The graphics backend compiles the shader and executes it as a fullscreen pass.

Standard uniforms provided automatically to every effect: - u_time (float): elapsed time in seconds - u_resolution (vec2): screen resolution in pixels - u_colour_tex (sampler2D): current framebuffer colour - u_depth_tex (sampler2D): scene depth buffer (sample by normalised UV; under render-scale/TAAU it may be at a lower resolution than the colour)

Example::

effect = PostProcessEffect(
    shader_code="""
        void main() {
            vec2 uv = gl_FragCoord.xy / u_resolution;
            vec3 colour = texture(u_colour_tex, uv).rgb;
            frag_colour = vec4(vec3(dot(colour, vec3(0.299, 0.587, 0.114))), 1.0);
        }
    """,
    order=10,
)
effect.set_uniform("intensity", 0.5)
world_env.add_post_process(effect)

Initialization

__slots__¶

(‘_shader_code’, ‘_enabled’, ‘_order’, ‘_uniforms’, ‘_uniform_types’, ‘_dirty’, ‘_language’, ‘_wrap’…

WRAP_MODES¶

(‘clamp’, ‘repeat’, ‘mirror’)

property language: str[source]¶

Shader language: ‘glsl’ (default) or ‘wgsl’ (WebGPU).

property wrap: str[source]¶

Addressing for u_colour_tex taps outside [0,1]: ‘clamp’ (default), ‘repeat’, or ‘mirror’.

‘clamp’ matches the scene-colour behaviour of the built-in screen-space passes and is correct for edge-neighbourhood sampling. Choose ‘repeat’/’mirror’ only for an effect that deliberately tiles or reflects the framebuffer (scroll, kaleidoscope).

property shader_code: str[source]¶

Fragment shader source (the body; version/layout is auto-wrapped by the renderer).

property enabled: bool[source]¶
property order: int[source]¶

Execution priority: lower values run first.

property uniforms: dict[str, Any][source]¶

Read-only copy of current uniform values.

property dirty: bool[source]¶

Whether the shader or uniforms have changed since last GPU sync.

clear_dirty() → None[source]¶

Mark as synced with GPU (called by the renderer).

set_uniform(name: str, value: Any) → None[source]¶

Set a shader uniform value. Type is inferred from the value.

Supported: float, int, vec2/3/4 (tuple or ndarray), mat4 (4x4 ndarray).

get_uniform(name: str) → Any[source]¶

Get current uniform value. Raises KeyError if not set.

__repr__() → str[source]¶
class simvx.core.world_environment.WorldEnvironment(name: str = 'WorldEnvironment', **kwargs)[source]¶

Bases: simvx.core.node.Node

Scene-wide rendering settings: ambient, sky, fog, tonemapping and post-processing.

This node is how a scene talks to the renderer. Add one anywhere in the tree and set its properties; the backend reads them each frame. Never reach for the renderer directly.

Only the first WorldEnvironment found in the tree drives the global settings (the renderer resolves it with root.find(WorldEnvironment)), so a scene should have exactly one. Custom :class:PostProcessEffect instances are the exception: those are collected from every WorldEnvironment in the tree, so an additive effect can ride along on a sub-scene’s own node.

A scene with no WorldEnvironment renders at the backend’s built-in defaults; that absence is also what keeps a pure-2D scene out of the HDR post path entirely. Adding the node is therefore an opt-in, and every heavyweight feature on it (bloom, SSAO, SSR, SSGI, TAA, volumetric fog, occlusion culling, depth of field) is off by default so it stays zero-cost until asked for.

Properties are grouped for the inspector: Ambient, Fog, Tonemap, Bloom, Quality, Shadows, SSAO, Reflections, Global Illumination, Weather, Film Effects, Anti-Aliasing, Colour Grading, Sky, Depth of Field, Motion Blur, Culling, Performance and Debug.

How ambient works. Three layers combine, gated by ambient_mode:

  • the flat fill ambient_light_colour, which every surface always gets and which stops an unlit scene going pure black,

  • image-based lighting from the sky or environment_map, scaled by ambient_light_energy,

  • nearby ReflectionProbe3D captures, blended over the IBL.

ambient_mode is a ceiling, not a switch: "probe" (the default) allows all three, "ibl" drops the probe blend, "flat" leaves only the flat fill. Each layer also self-gates on what the scene actually has, so a scene with no sky falls back to the flat fill even under "probe".

Tuning the look. ambient_light_energy and tonemap_exposure are the two dials to reach for first: the former decides how much the sky bleeds into shadowed surfaces, the latter how bright the whole frame lands before tonemapping (and it composes with Camera3D.exposure).

Example::

env = WorldEnvironment()
env.sky_mode = "procedural"      # sun-driven Preetham sky + IBL
env.ambient_light_energy = 0.5   # let more sky bounce into the shade
env.fog_enabled = True
env.bloom_enabled = True
root.add_child(env)

Initialization

ambient_light_colour¶

‘Colour(…)’

ambient_light_energy¶

‘Property(…)’

ambient_light_mode¶

‘Property(…)’

ambient_mode¶

‘Property(…)’

ambient_light_2d¶

‘Colour(…)’

fog_enabled¶

‘Property(…)’

fog_colour¶

‘Colour(…)’

fog_density¶

‘Property(…)’

fog_start¶

‘Property(…)’

fog_end¶

‘Property(…)’

fog_mode¶

‘Property(…)’

fog_height¶

‘Property(…)’

fog_height_density¶

‘Property(…)’

tonemap_mode¶

‘Property(…)’

tonemap_exposure¶

‘Property(…)’

tonemap_white¶

‘Property(…)’

bloom_enabled¶

‘Property(…)’

bloom_threshold¶

‘Property(…)’

bloom_intensity¶

‘Property(…)’

bloom_soft_knee¶

‘Property(…)’

quality_tier¶

‘Property(…)’

probe_blend_count¶

‘Property(…)’

probe_face_size¶

‘Property(…)’

shadow_caster_count¶

‘Property(…)’

render_scale¶

‘Property(…)’

scene_feedback_max_depth¶

‘Property(…)’

shadow_debug_cascades¶

‘Property(…)’

debug_view¶

‘Property(…)’

shadow_cascade_count¶

‘Property(…)’

volumetric_fog_enabled¶

‘Property(…)’

volumetric_fog_density¶

‘Property(…)’

volumetric_fog_albedo¶

‘Colour(…)’

volumetric_fog_emission¶

‘Colour(…)’

volumetric_fog_anisotropy¶

‘Property(…)’

volumetric_fog_length¶

‘Property(…)’

volumetric_fog_gi_inject¶

‘Property(…)’

volumetric_fog_temporal_reprojection¶

‘Property(…)’

ssao_enabled¶

‘Property(…)’

ssao_radius¶

‘Property(…)’

ssao_bias¶

‘Property(…)’

ssao_intensity¶

‘Property(…)’

ssao_normals¶

‘Property(…)’

ssr_enabled¶

‘Property(…)’

ssr_intensity¶

‘Property(…)’

ssr_max_distance¶

‘Property(…)’

ssr_roughness_cutoff¶

‘Property(…)’

ssgi_enabled¶

‘Property(…)’

ssgi_intensity¶

‘Property(…)’

ssgi_max_distance¶

‘Property(…)’

wind_direction¶

‘Property(…)’

wind_strength¶

‘Property(…)’

wind_gustiness¶

‘Property(…)’

wetness¶

‘Property(…)’

rain_intensity¶

‘Property(…)’

ripple_strength¶

‘Property(…)’

occlusion_culling_enabled¶

‘Property(…)’

render_mode¶

‘Property(…)’

dof_enabled¶

‘Property(…)’

dof_focus_distance¶

‘Property(…)’

dof_focus_range¶

‘Property(…)’

dof_max_coc¶

‘Property(…)’

motion_blur_enabled¶

‘Property(…)’

motion_blur_intensity¶

‘Property(…)’

motion_blur_samples¶

‘Property(…)’

film_grain_enabled¶

‘Property(…)’

film_grain_intensity¶

‘Property(…)’

vignette_enabled¶

‘Property(…)’

vignette_intensity¶

‘Property(…)’

vignette_smoothness¶

‘Property(…)’

chromatic_aberration_enabled¶

‘Property(…)’

chromatic_aberration_intensity¶

‘Property(…)’

crt_enabled¶

‘Property(…)’

crt_intensity¶

‘Property(…)’

pixelate_enabled¶

‘Property(…)’

pixelate_size¶

‘Property(…)’

blur_enabled¶

‘Property(…)’

blur_radius¶

‘Property(…)’

fxaa_enabled¶

‘Property(…)’

taa_enabled¶

‘Property(…)’

colour_grading_enabled¶

‘Property(…)’

lut_enabled¶

‘Property(…)’

lut_tex_id¶

‘Property(…)’

sky_mode¶

‘Property(…)’

sky_colour_top¶

‘Colour(…)’

sky_colour_bottom¶

‘Colour(…)’

sky_texture¶

‘Property(…)’

sky_turbidity¶

‘Property(…)’

sky_ground_albedo¶

‘Colour(…)’

environment_map¶

‘Property(…)’

property env_dirty: bool[source]¶
clear_env_dirty() → None[source]¶
__setattr__(name: str, value: Any) → None[source]¶
add_post_process(effect: simvx.core.world_environment.PostProcessEffect) → None[source]¶

Register a custom post-processing effect.

remove_post_process(effect: simvx.core.world_environment.PostProcessEffect) → None[source]¶

Unregister a custom post-processing effect.

get_post_processes() → list[simvx.core.world_environment.PostProcessEffect][source]¶

Return registered effects sorted by order.

strict_errors: ClassVar[bool]¶

True

dev_checks: ClassVar[bool]¶

None

dev_warnings: ClassVar[bool]¶

None

freeze_check_interval: ClassVar[float]¶

1.0

dynamic: bool¶

False

visible¶

‘Property(…)’

update_mode¶

‘Property(…)’

focus_mode¶

‘Property(…)’

drag_threshold¶

‘Property(…)’

focus_entered¶

‘Signal(…)’

focus_exited¶

‘Signal(…)’

__properties__: ClassVar[dict[str, simvx.core.descriptors.Property]]¶

None

classmethod __init_subclass__(**kwargs)¶
property name: str¶
property visible_in_tree: bool¶
property input_player: simvx.core.input.players.InputPlayer¶
property input_context: simvx.core.input.contexts.InputContext | None¶
reset_error() → None¶
add_child(node: simvx.core.node.T) → simvx.core.node.T¶
remove_child(node: simvx.core.node.Node) → None¶
reparent(new_parent: simvx.core.node.Node)¶
node_at(path, default=_NO_DEFAULT)¶
find(target, *, direct: bool = False)¶
find_all(target, *, direct: bool = False)¶
expect(target, *, direct: bool = False)¶
ancestor(target)¶
walk(*, include_self: bool = True) → collections.abc.Iterator[simvx.core.node.Node]¶
property path: str¶
property is_scene_root: bool¶
add_to_group(group: str)¶
remove_from_group(group: str)¶
is_in_group(group: str) → bool¶
on_ready() → None¶
on_enter_tree() → None¶
on_exit_tree() → None¶
on_update(dt: float) → None¶
on_fixed_update(dt: float) → None¶
on_draw(canvas) → None¶
on_draw_3d(gizmos) → None¶
on_picked(event: simvx.core.input.events.PickEvent) → bool | None¶
on_gui_input(event: simvx.core.input.events.GuiInputEvent) → bool | None¶
start_coroutine(gen: simvx.core.descriptors.Coroutine) → simvx.core.descriptors.CoroutineHandle¶
stop_coroutine(gen_or_handle)¶
property focused: bool¶
property focus_rect: tuple[float, float, float, float] | None¶
drag_threshold_for(pointer_type: simvx.core.input.enums.PointerType | str) → float¶
grab_focus() → None¶
release_focus() → None¶
capture_pointer(pointer_id: int | None = None) → None¶
release_pointer(pointer_id: int | None = None) → None¶
queue_redraw() → None¶
property render_dirty: bool¶
clear_children()¶
destroy()¶
property destroying: bool¶
property destroyed: bool¶
call_deferred(method: collections.abc.Callable[..., Any], *args: Any) → None¶
property app¶
property tree: simvx.core.scene_tree.SceneTree¶
property viewport_size: simvx.core.math.types.Vec2¶
property viewport_insets: tuple[float, float, float, float]¶
property physics¶
property physics_2d¶
__getitem__(key: str)¶
classmethod get_properties() → dict[str, simvx.core.descriptors.Property]¶
__repr__()¶
class simvx.core.world_environment.Environment[source]¶

Environment resource that can be shared between WorldEnvironment nodes.

Initialization

add_post_process(effect: simvx.core.world_environment.PostProcessEffect) → None[source]¶

Register a custom post-processing effect.

remove_post_process(effect: simvx.core.world_environment.PostProcessEffect) → None[source]¶

Unregister a custom post-processing effect.

get_post_processes() → list[simvx.core.world_environment.PostProcessEffect][source]¶

Return registered effects sorted by order.