Release Notes

What changed in each Acron release, newest first. An Acron version is the engine’s base version with a build number, 1.11.0.post<N>; the number is given when the release is built.

1.11.0: the environment and native PBR release

First published as 1.11.0.post59.

New: native physically based shading

The engine draws physically based materials with a shader of its own, in C++ with Python bindings, so a C++ game gets the same materials and light as a Python one (Physically Based Shading):

  • acron.shading: the PbrMaterial (glTF’s metallic-roughness model with the ior, specular, emissive-strength and unlit extensions, saved in Bam files; an Acron Material is read as a fallback) and the PbrMaterialAttrib that puts it on nodes; the PbrShaderGenerator, which writes one shader per combination of features and can compile a level’s shaders up front (precompile); the image-based light of an environment map (IblEnvironment); a physical camera; a minimal frame of scene buffer and tonemapper (PbrPipeline); and the lighting context through which the environment modules light the materials.

  • The shader: GGX with height-correlated Smith visibility, multiple scattering, specular anti-aliasing and specular occlusion; shadows of spotlights, directional and point lights (filtered with 4 taps by default, shading-shadow-taps); at most 16 maps a material, dropping the least important ones past that with a warning.

  • acron.pbr.init() sets it up for a Python game in one call, and acron.hdri makes the image-based light from an HDR panorama (Materials and PBR).

Physical units. Light is photometric: Light.set_intensity is in lux for a directional light, candela for a point light or a spotlight and nits for an ambient light, and the light’s colour is a tint; emission is in nits; the exposure comes from a camera’s aperture, shutter time and ISO (EV100). acron.shading.LightUnits converts, lumens included. Point lights and spotlights fall off as the windowed inverse square, reaching zero at their range (max_distance, or where the light drops to 0.01 lux); spotlights have an inner cone; ambient light lights the diffuse lobe only. Lights keep an intensity of 1 by default, so scenes and shaders that do not use it look as before (Lighting).

New: the environment

A sky, weather, clouds, fog, forests and grass, as engine modules a game sets up in a few calls (Sky, Weather and Forests):

  • acron.sky: a physically based sky and day-night cycle (sun, moon and stars from the date and place), sun shadows in four cascades, an environment probe for reflections and ambient light, and an eye that adapts to the hour’s light. The night sky (stars, the Milky Way, airglow, light pollution) lights the ground. See The Sky, Day and Night and The Night Sky.

  • acron.clouds and the native acron.atmosphere: volumetric clouds over a weather simulation, with presets from clear to thunderstorm, cloud shadows, light shafts, rain curtains and lightning. Storm cells close to the camera are drawn as voxel clouds. See Clouds and Weather and Storms and Voxel Clouds.

  • acron.fog: volumetric fog, lit by the sun, the moon and the game’s own lamps (Volumetric Fog).

  • acron.trees and the native acron.proctree: procedural trees for a dozen species, with wind, levels of detail, impostors and forests drawn by instancing (Trees and Forests).

  • acron.ecosystem and the native acron.vegetation: forests that grow from the terrain, and grass that bends in the wind, is trampled and casts shadows near the camera (Ecosystems and Grass).

  • acron.pipeline: a frame pipeline with temporal anti-aliasing, ambient occlusion and tone mapping (The Frame Pipeline).

  • PBR materials join the environment: pbr.init(environment=env) lights them with the sun, the probe, the shadows and the fog, and draws them into the frame pipeline (Materials and PBR).

These modules need OpenGL 4.5 on Windows and Linux; macOS is supported for development with OpenGL 4.1. They do not run on OpenGL ES, the web, Android or the Vulkan renderer yet.

Removed: simplepbr

simplepbr is no longer part of the acron wheel, and there is no shim: acron.pbr.init() builds the native path, and the keywords that were simplepbr’s raise a TypeError that names their replacement (acron.pbr.REMOVED):

simplepbr

Now

max_lights

the configuration variable shading-max-lights (or pipeline.generator.builder.max_lights)

use_normal_maps, use_emission_maps, use_occlusion_maps

nothing: the shader reads every map a material has

exposure

physical_camera=PhysicalCamera(aperture, shutter_speed, sensitivity) (EV100; simplepbr’s exposure was in stops)

enable_shadows

the light’s own set_shadow_caster()

enable_fog

environment= (the air and fog of acron.sky)

use_330

nothing: the shaders are GLSL 4.50 (4.10 on macOS)

use_hardware_skinning

the configuration variable hardware-animated-vertices

msaa_samples

the frame pipeline’s TAA (the native frame has no multisampling)

sdr_lut, sdr_lut_factor

tonemap=: 'clamp', 'shoulder', 'neutral', 'aces' or 'reinhard'

env_map

ibl=: an IblEnvironment, or a cube map or panorama texture (acron.hdri.load_env(path) makes one)

shader_defines, shader_filter

nothing: the generator writes the shader for each material

enable_post_processing

post_process=

taskmgr

nothing: the native frame needs no task

When moving a scene over, set the lights in physical units (a sunlit scene: the sun about 100 000 lux and an exposure of about f/16, 1/125 s, ISO 100), and give emissive materials their luminance in nits. Under the environment modules the light still comes in the environment’s own units (Materials and PBR).

Changed

  • The Python tier needs neither numpy nor scipy any more.

  • Archives (.zip, .sog) that are damaged or malicious are refused instead of hanging the program. Zip archives with an archive comment, with more than 65535 files, or with extra fields in their local headers open correctly now. Reading a damaged member raises an error (in Python, an AssertionError, as before) rather than returning partial data. Archives that name the same member twice are refused.

  • Gaussian splat files (PLY, SOG) are checked before they are read.

Fixed

  • A texture given to a shader with set_shader_input is bound again whenever it changes, also when the rest of the render state stays the same.

  • On drivers that load SPIR-V directly (OpenGL 4.6 drivers, Mesa), a texture read by both the vertex and the fragment shader read back as black in the fragment shader.

  • A shader with no uniforms crashed on drivers before OpenGL 4.3.

  • Calls that release Python’s lock while they run (long native calls) converted their arguments after releasing it, which could crash.

Known limits

  • Up to shading-max-lights (16) lights a material and four of them with shadows; a directional light’s own shadow is one map, not cascades (the environment’s sun has cascades). No light cookies.

  • No clear coat, sheen, anisotropy or transmission yet.

  • IblEnvironment prefilters on the CPU (about 50 ms at start-up for a 256-texel cube): prefilter once with acron.hdri.save_env for a release.

  • Shaders are compiled at run time, with no cache on disk: call precompile() after loading a level.

  • Under the environment, lights set in lux or candela are not yet in the environment’s units, and PhysicalCamera has no effect there.

  • Hardware-skinned meshes move in the motion vectors only with their node, and the frame pipeline’s ambient occlusion is the previous frame’s.

  • The glTF loader does not carry occlusionTexture.strength yet.

  • OpenGL 4.5 on Windows and Linux, 4.1 on macOS; not on OpenGL ES, the web, Android or the Vulkan renderer yet.

  • The whole environment stack does not meet its frame-time targets yet: on the GTX 660 at 1080p it takes 54 to 113 ms a frame from low to ultra against about 21 to 87 ms (the “Performance” section of Sky, Weather and Forests).