Skip to main content

Post

Struct Post 

Source
pub struct Post {
Show 23 fields pub render_scale: f32, pub sharpen: f32, pub ambient_occlusion: AmbientOcclusion, pub ao_half_resolution: bool, pub ao_temporal: bool, pub contact_shadows: f32, pub ssr: f32, pub ssr_max_distance: f32, pub anti_aliasing: AntiAliasing, pub taa_sharpness: f32, pub exposure: f32, pub tonemap: Tonemap, pub bloom: f32, pub bloom_threshold: f32, pub contrast: f32, pub saturation: f32, pub temperature: f32, pub tint: f32, pub vignette: f32, pub chromatic_aberration: f32, pub lens_distortion: f32, pub lens_scale: f32, pub lut: Option<Texture>,
}
Expand description

What happens to the lit 3D frame before it reaches the screen. Sprites and UI drawn on top are not changed.

ctx.post.exposure = 0.5; // half a stop brighter
ctx.post.bloom = 0.15;
ctx.post.tonemap = Tonemap::Neutral;
ctx.post.temperature = 0.2; // warmer

Fields§

§render_scale: f32

The 3D scene is drawn at this fraction of the window’s size in each direction, then scaled to the window before sprites and UI, which stay at the window’s resolution: below 1 is cheaper and softer, above 1 (supersampling) sharper and costlier. From MIN_RENDER_SCALE to MAX_RENDER_SCALE; anything else is clamped. Default 1 (no extra pass).

§sharpen: f32

How much the scaled image is sharpened, 0 to 1 (an adaptive contrast filter that only touches soft edges). Only used with a render_scale other than 1. Default 0.

§ambient_occlusion: AmbientOcclusion

Ambient-only GTAO, before opaque lighting.

§ao_half_resolution: bool

Trace GTAO at half width and height, then bilaterally upsample. Contact shadows remain full resolution. Default false.

§ao_temporal: bool

Accumulate GTAO over frames with rotating slices, following the camera and moving models (the same motion vectors as TAA) and rejecting history whose depth disagrees. Independent of TAA. Default false; enable to trade history cost for fewer samples.

§contact_shadows: f32

Contact shadows: how far, in world units, each pixel looks toward the sun across the depth buffer for something close that blocks it. They catch the small shadows the shadow map is too coarse for: under feet, pebbles and cups, in creases. 0 (the default) is off; 0.3 suits people and props. Only things on screen cast them. Shares a full-screen pass with AmbientOcclusion (one pass for both).

§ssr: f32

Screen-space reflections: how strongly glossy surfaces (roughness below about 0.7, fully below 0.4) reflect what’s on screen, 0 to 1, on top of the sky and reflection probes they reflect anyway. Where the reflected ray finds nothing on screen (it leaves the screen, goes behind something, or runs past ssr_max_distance), the environment’s reflection stays. Wet streets, polished floors, still water. Things off screen or hidden aren’t reflected, and normal maps don’t bend the reflection. The colors come from the last frame’s image, so the first frame after a camera cut reflects only the environment. A half-resolution pass after the depth prepass; AntiAliasing::Taa smooths its grain. Reflections use depth-aware filtered mips as roughness increases; the blur footprint is bounded in screen pixels. 0 (the default) is off.

use ponko::*;
assert_eq!(Post::default().ssr, 0.0);
let wet_street = Post { ssr: 1.0, ..Default::default() };
assert_eq!(wet_street.ssr_max_distance, 30.0);
§ssr_max_distance: f32

How far, in world units, a screen-space reflection looks along the reflected ray; it fades out toward the end. Default 30.

§anti_aliasing: AntiAliasing

Post antialiasing. Default off to preserve existing scenes.

§taa_sharpness: f32

How much AntiAliasing::Taa sharpens the result (it softens the image a little), 0 to 1. Default 0.25.

§exposure: f32

Brightness in stops: +1 doubles the light, -1 halves it. Default 0.

§tonemap: Tonemap

How light maps to the screen. Default Tonemap::Aces.

§bloom: f32

How strongly bright light glows into its surroundings; 0 turns bloom off. Default 0.05.

§bloom_threshold: f32

How bright light must be to glow (1 is white). Default 1.

§contrast: f32

1 keeps the contrast, higher is punchier, lower flatter. Default 1.

§saturation: f32

1 keeps the colors, 0 is grey, higher is more vivid. Default 1.

§temperature: f32

White balance, -1 (cool, blue) to 1 (warm, orange). Default 0.

§tint: f32

White balance, -1 (green) to 1 (magenta). Default 0.

§vignette: f32

How much the corners darken, 0 to 1. Default 0.

§chromatic_aberration: f32

Color fringes toward the edges, as a cheap lens splits red, green and blue apart, 0 to 1. Default 0.

use ponko::*;
let speed = Post { chromatic_aberration: 0.8, lens_distortion: -0.26, lens_scale: 1.04, ..Default::default() };
assert_eq!(Post::default().chromatic_aberration, 0.0);
§lens_distortion: f32

Bends the picture as a lens would, -1 to 1: above 0 bulges the middle out (barrel), below 0 pinches it in (pincushion). Default 0.

§lens_scale: f32

Zooms the picture in (above 1) or out after the distortion, to hide the edges it pulls in. Above zero; default 1.

§lut: Option<Texture>

A color lookup table for grading, applied after tone mapping: a strip of n squares of n x n pixels (for example 1024 x 32), red across each square, green down it, blue from square to square. A neutral one changes nothing; paint over it in an image editor to grade. Default none.

Implementations§

Source§

impl Post

Source

pub fn render_size(&self, window: (u32, u32)) -> (u32, u32)

The size the 3D scene is drawn at in a window of window pixels: scaled by render_scale (clamped; a NaN counts as 1), at least 1 pixel and at most limit wide (0: no limit).

use ponko::*;
let post = Post { render_scale: 0.5, ..Default::default() };
assert_eq!(post.render_size((1920, 1080)), (960, 540));
Source

pub fn neutral_lut(n: u32) -> (u32, u32, Vec<u8>)

A neutral lookup table of n x n x n colors as RGBA pixels, n * n wide and n high: the starting point for a Post::lut.

let (w, h, pixels) = Post::neutral_lut(32);
ctx.post.lut = Some(ctx.create_texture(w, h, &pixels));
§Panics

If n is not between 2 and 64.

Trait Implementations§

Source§

impl Clone for Post

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Post

Source§

impl Debug for Post

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Post

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl PartialEq for Post

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Post

Auto Trait Implementations§

§

impl Forget for Post

§

impl Freeze for Post

§

impl RefUnwindSafe for Post

§

impl Send for Post

§

impl Sync for Post

§

impl Unpin for Post

§

impl UnsafeUnpin for Post

§

impl UnwindSafe for Post

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Component for T
where T: Send + Sync + 'static,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> MaybeSync for T
where T: Sync + ?Sized,

Source§

impl<T> MaybeSync for T
where T: Sync + ?Sized,

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Scalar for T
where T: 'static + Clone + PartialEq + Debug,

Source§

impl<T> SerializableAny for T
where T: 'static + Any + Clone + for<'a> Send + Sync,

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more