IblEnvironment

from acron.shading import IblEnvironment
class IblEnvironment

Bases:

Bases: TypedReferenceCount

The image-based light of the PBR shader: an environment’s radiance, prefiltered for GGX, and its irradiance as spherical harmonics.

The source is a cube map or an equirectangular panorama (a 2-D texture), in linear light: float or half-float data, or 8-/16-bit data (sRGB formats are decoded). Directions are world directions with Acron’s Z up, as the shader looks them up: a cube map texel is seen along the direction OpenGL’s cube lookup gives it, and a panorama’s column and row follow longitude atan2(x, y) and latitude asin(z), as PanoramaRemap::equirect_to_cube_face reads them.

The radiance is a size x size cube map with a full mipmap chain. Level 0 is the source (area-filtered to the size); level l < levels holds the split-sum prefiltered radiance of perceptual roughness l / (levels - 1) (Karis, “Real Shading in Unreal Engine 4”, SIGGRAPH 2013): GGX importance samples (a Hammersley set) with N = V = R, weighted by N.L, each read from the source mip whose texel matches the sample’s solid angle (Krivanek and Colbert, “Real-time Shading with Filtered Importance Sampling”, 2008). The levels below are box-filtered, so the chain is complete. The data is RGBA16F.

The irradiance is the source projected on the nine real spherical harmonics up to l = 2 (the shader convolves them with the cosine lobe; Ramamoorthi and Hanrahan 2001), with exact texel solid angles.

The prefilter runs on the CPU, on a few worker threads, and releases the GIL. The result depends only on the inputs (for one platform’s libm): write() and read() cache it as a file. apply() puts it on a node as the inputs of pbr_ibl.glsl: pbr_env_radiance, pbr_env_sh and pbr_env_params.

The values are radiance in nits when the source is calibrated; otherwise set an intensity, which scales both the radiance and the irradiance.

Inheritance diagram

digraph inheritancea7e2ef104d { bgcolor=transparent; rankdir=BT; size="8.0, 12.0"; "DTOOL_SUPER_BASE" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style=""]; "IblEnvironment" [URL="acron.shading.IblEnvironment.html#acron.shading.IblEnvironment",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "TypedReferenceCount" -> "IblEnvironment" [arrowsize=0.75,style=""]; "ReferenceCount" [URL="acron.core.ReferenceCount.html#acron.core.ReferenceCount",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "DTOOL_SUPER_BASE" -> "ReferenceCount" [arrowsize=0.75,style=""]; "TypedObject" [URL="acron.core.TypedObject.html#acron.core.TypedObject",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "DTOOL_SUPER_BASE" -> "TypedObject" [arrowsize=0.75,style=""]; "TypedReferenceCount" [URL="acron.core.TypedReferenceCount.html#acron.core.TypedReferenceCount",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "TypedObject" -> "TypedReferenceCount" [arrowsize=0.75,style=""]; "ReferenceCount" -> "TypedReferenceCount" [arrowsize=0.75,style=""]; }
__init__()

An empty, invalid environment (for read()).

Prefilters the source (a cube map or an equirectangular panorama with a RAM image) into a size x size cube with levels roughness levels and samples GGX samples per texel. On an unreadable source the environment is black and is_valid() is false.

apply()

Puts the environment on a node as the PBR shader’s image-based light: pbr_env_radiance, pbr_env_sh and pbr_env_params (x: the mip level of roughness 1; y: the intensity times the storage scale). Call it again after changing the intensity.

static get_class_type()
static get_cube_direction()

The world direction (not normalised) that OpenGL’s cube lookup maps to face (0-5: +X, -X, +Y, -Y, +Z, -Z) at texture coordinates s, t in [0, 1]; t = 0 is the face’s first row in RAM.

get_intensity()

See set_intensity().

get_irradiance()

The irradiance divided by pi that the shader computes from the SH for a world normal (a uniform environment of L nits gives L), before the intensity.

get_num_levels()

The prefiltered levels: level l holds roughness l / (levels - 1).

get_num_sh()

The spherical-harmonic coefficients: nine, L00 to L22.

get_radiance()

The prefiltered radiance as a cube map (RGBA16F, full mipmap chain, trilinear filtering), made on first call: the shader’s pbr_env_radiance. Its texels are the radiance divided by a power-of-two storage scale (1 unless the source exceeds half-float range), which apply() passes on.

get_samples()

GGX importance samples per texel of the prefiltered levels.

get_sh()

Spherical-harmonic coefficient i (0-8: L00, L1-1, L10, L11, L2-2, L2-1, L20, L21, L22) of the radiance, before the intensity.

get_shs() → list
get_size()

The width and height of the radiance cube map’s faces at level 0.

get_storage_scale()

The power of two that the stored texels are divided by, so that the brightest fits in half-float range: 1 for most environments. apply() multiplies it back in through pbr_env_params.y.

get_texel()

The radiance of one texel of the cube’s mip level (0 is the source; level l < num_levels is roughness l / (num_levels - 1)), as stored (half floats) times the storage scale, before the intensity. Row y = 0 is the first row in RAM, t = 0 of OpenGL’s cube lookup.

property intensity → float

A scale on the radiance and the irradiance, applied by the shader (pbr_env_params.y): 1 for a source in nits.

is_valid()

False when the source could not be read (an unsupported texture or a corrupt file); the environment is then black.

static make_uniform()

An environment of the same radiance in every direction (nits, linear), e.g. for a white furnace test or a plain overcast ambient.

property num_levels → int

The prefiltered levels: level l holds roughness l / (levels - 1).

property radiance → Texture

The prefiltered radiance as a cube map (RGBA16F, full mipmap chain, trilinear filtering), made on first call: the shader’s pbr_env_radiance. Its texels are the radiance divided by a power-of-two storage scale (1 unless the source exceeds half-float range), which apply() passes on.

static read()

Reads an environment that write() wrote. Returns nullptr, with an error, when the file is missing, corrupt or of another version.

sample()

The radiance the shader reads in a world direction at a perceptual roughness (0-1), before the intensity: a trilinear lookup of the prefiltered cube, bilinear within a face (the GPU also filters across face edges).

property samples → int

GGX importance samples per texel of the prefiltered levels.

set_intensity()

A scale on the radiance and the irradiance, applied by the shader (pbr_env_params.y): 1 for a source in nits.

property size → int

The width and height of the radiance cube map’s faces at level 0.

property storage_scale → float

The power of two that the stored texels are divided by, so that the brightest fits in half-float range: 1 for most environments. apply() multiplies it back in through pbr_env_params.y.

property valid → bool

False when the source could not be read (an unsupported texture or a corrupt file); the environment is then black.

write()

Writes the environment (the prefiltered cube and the SH) to a file that read() loads without prefiltering again.