#Andromeda - Terrain/Landscape editor using Vulkan and Rust

1 messages Β· Page 4 of 1

shadow trench
#

sounds pretty fun

hot yarrow
#

liquidgas was its name

#

hmm maybe i should dig it out from some old backup cds πŸ˜„

#

it looked quite neat

shadow trench
#

would love some screenshots of what young deccer was up to :)

hot yarrow
#

: )

shadow trench
#

Seems about right

#

You can see the frame lag if I move too quickly though

hot yarrow
#

yeah

#

you probably need some lod

shadow trench
#

But as long as im standing still its perfectly centered

shadow trench
#

huh thats odd

hot yarrow
#

i mean redude the amound of triangles

shadow trench
#

ah wait nvm I put something there lol

hot yarrow
#

ah

#

you can also see it in the jiff.gif

shadow trench
hot yarrow
#

you clicked

shadow trench
#

eventually

#

it runs fine for now but yeah ill definitely need lods

#

okay so the position is fine

#

then either my komput logic is wrong or computing the uv from the position is wrong

livid geode
#

chunking will work wonderfully to reduce lag once you implement it

#

in this case probably a quadtree would work best

young oar
#

Yep quadtrees/octrees are beautiful

#

Without octree

shadow trench
#

ill look into them for sure

young oar
#

With octree

#

They are op when you manage to fix seams which is super easy for 2d planes

shadow trench
#

ok there now it doesnt do that weird half circle thing anymore

livid geode
#

sucks balls tho

shadow trench
#

πŸ‘€

#

oh

livid geode
#

but you could look into dual marching cubes

#

the results are pretty good

#

much better than marching cubes

shadow trench
#

yeah i have a lot of techniques to still look into

#

ahhhh

#

my uv calculation was indeed wrong

#

the mesh itself has as max uvs 0.98 ish or so because of a bug

#

but the uv calc from the pos assumed 1 was the max value

livid geode
#

bug accumulation

shadow trench
#

for the longest time that just meant a tiny part of the heightmap was cut off so it was barely noticable kek

hot yarrow
#

@young oar i like your terrains more πŸ™‚

shadow trench
hot yarrow
#

hihi

young oar
#

Heheheha

#

Tbf it doesn't have editing or anything cool like that

#

Just procedurally generated

shadow trench
#

next step for editing is holding the mouse down to brush instead of clicking once I guess

livid geode
shadow trench
#

Exactly that

livid geode
#

meheheh

shadow trench
#

huh I think it's also wrong in sasha's samples then

#

ill open an issue

shadow trench
#

It'll look a lot better once I regenerate normals

#

I dont think those normals are right

#

actually maybe it is and the brush just isnt smooth at all

#

ill have to experiment a bit with the weight function I guess

#

This is some interesting behaviour

#

I think I'll have to apply some sort of smoothing after each edit or something

young oar
shadow trench
#

egui is nice

shadow trench
#

There we go

#

return 1; at the start of my weight function was not helping the smoothness

shadow trench
#

i found a really cool crate

#
#[enum_dispatch]
#[derive(Debug, Copy, Clone)]
pub enum Brush {
    SmoothHeight,
}

#[enum_dispatch(Brush)]
trait ApplyBrush {
    fn apply(&self, bus: &EventBus<DI>, position: Vec3, settings: &BrushSettings) -> Result<()>;
}

struct SmoothHeight {
  // brush-specific settings
}

impl ApplyBrush for SmoothHeight {
  // ...
}

fn use_brush(brush: Brush) {
  // generated code automatically dispatches to the correct impl
  brush.apply(...);
}
livid geode
#

It should be something that is built in

shadow trench
#

Yeah that would be nice

#

but this is a decent substitute

livid geode
#

but tbh i'd just use dyn

shadow trench
#

meh

livid geode
#

i was like this before, trying to avoid dyn whenever possible

#

but like who cares the perf cost is minimal

#

and it is definitely cleaner

shadow trench
#

I mean I use it at times but I dont want to create a new boxed brush object on every stroke

livid geode
#

why the hell you creatin a brush on every stroke

shadow trench
#

the "brush" is only some settings

#

it doesnt actually hold any real data

livid geode
#

yes i know

#

but why don't you just store it

#

or actually you do store it, why do you need to create it on every stroke

shadow trench
#

I keep it around in the gui yeah

livid geode
#

then?

shadow trench
#

idk I feel like with a trait object creating the gui for each type of brush is going to be annoying

#

bc either I add it to the ApplyBrush trait which is not great

#

But with this I can just create a new trait, enum_derive it and keep it entire inside the gui crate

livid geode
#

what is gonna be annoying with enum dispatch tho is that every time you want to create, rename, etc a brush, you also need to change Brush

shadow trench
#

Yeah true

#

But tbh, probably not a huge deal

shadow trench
#

the decal seems a bit big compared to the actual size of the brush pepe_think

#

Maybe my distribution falls off too quickly

livid geode
#

can't you also display the distribution on the decal?

shadow trench
#

Yeah I'll try something like that eventually

#

thats a good idea

livid geode
#

i thought it wasn't a decal but just a vertex shader whose input was the mouse uv pos

shadow trench
#

I was thinking of just using a hardcoded texture but that'd be cool

shadow trench
#

what im doing rn is kind of a hack in the terrain fragment shader

#

I just check the distance to the mouse kek

livid geode
shadow trench
#

Yeah

livid geode
shadow trench
#

yeah

livid geode
#

yeah

shadow trench
#

right, the problem with a wider distribution is that you get ugly seams

#

I can just shrink the decal a bit I suppose

#

or add the blur pass again

nimble solar
#

hi

shadow trench
#

oi

#

hello there

nimble solar
#

I am quite intrigued by the terrain generation you have going on there

shadow trench
nimble solar
#

Do you plan to extend this generation to infinity and beyond?

shadow trench
#

That's definitely on the list yeah

#

im not doing any generation rn

#

Just editing a heightmap

nimble solar
#

Good, I could use your stuff as a reference for my Snowℒ️ thingy

shadow trench
#

whats that

nimble solar
#

It's basically Steep except it's mine.

shadow trench
#

i see

#

must be better then

nimble solar
#

How do you do generate the terrain?

#

As a mesh, I mean

shadow trench
#

its just loaded in from a heightmap asset i found

#

ah, the mesh

#

its a highly subdivided plane, the vertical deform happens on the fly when rendering

#

using tessellation to generate the subdivided mesh

nimble solar
#

I see, do you plan to use Mesh Shaders instead of Tess?

shadow trench
#

i honestly have not looked into them at all

#

But maybe

nimble solar
#

They're just a compute shader on steroids KEKW

shadow trench
#

Right now this already performs very well, 2ms total frametime with no LODing

nimble solar
#

A compute shader that can write to gl_Position gl_MeshPrimitivesNV

shadow trench
#

im definitely not bound by vertex throughput at least

nimble solar
#

Yeah I don't really care about performance, I just like using the new stuff

shadow trench
#

totally fair lol

shadow trench
#

wow my rendering code is a dumpsterfire

#

i have to clean that up some day

#

time to take a massive detour to implement decal rendering

#

at least itll be reusable for other things later

#

This whole terrain brush adventure is definitely a good subject for a second blog post

shrewd lynx
#

Now I have an ubershader

shadow trench
#

not sure if that counts as a win or not kek

shrewd lynx
#

I mean atleast I only have a single backend for almost everything except depthwrite

#

But yeah the tradeoff is messy code on That file

shadow trench
#

thats good at least yeah

hot yarrow
nimble solar
#

My follow list isn't big enough

shadow trench
hot yarrow
#

im just talking out of my ass

shadow trench
shrewd lynx
shrewd lynx
#

So ur fine haha

hot yarrow
#

are you not working on some homerolled engine miyagi?

shrewd lynx
#

Custom Source engine not unlike bms, respawn

hot yarrow
#

im sure people are interested

nimble solar
#

I am

hot yarrow
#

just saying πŸ™‚

#

lustri you shouldnt, you got work todo πŸ˜„ (jk)

nimble solar
#

I need to understand how other engines work to make my game

#

Atmospheric Scattering? I don't have the motivation for that 😦

shadow trench
#

but it looks great

nimble solar
#

Yeah I know

#

I watched Sebastian Lague's video

shadow trench
#

decals ℒ️ kekw

potent quest
#

πŸ’€

#

Wait so is Andromeda just to render terrain? Oh it's edit

shadow trench
#

terrain editing and everything related yes

potent quest
#

it would be cool if you added erosion

shadow trench
#

thats absolutely planned

potent quest
#

oh real

#

tectonic simulations?

shadow trench
#

maybe

#

that could be interesting

potent quest
#

Afaik from a very quick read

#

it looks like they're creating a bunch of points on a sphere and then using a bunch of math equations to describe what happens to them when they overlap with each other

shadow trench
#

Right

potent quest
shadow trench
hot yarrow
shadow trench
#

Yep

shadow trench
#

hmm that barrier looks okay to me

#

why is it not happy

#
SYNC-HAZARD-WRITE-AFTER-READ(ERROR / SPEC): msgNum: 929810911 - Validation Error: [ SYNC-HAZARD-WRITE-AFTER-READ ] Object 0: handle = 0x17e0579e890, type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0x376bc9df | vkQueueSubmit2: Hazard WRITE_AFTER_READ for entry 0, VkCommandBuffer 0x17e2f09a050[], Recorded access info (recorded_usage: SYNC_IMAGE_LAYOUT_TRANSITION, command: vkCmdPipelineBarrier2, seq_no: 3, reset_no: 1). Access info (prior_usage: SYNC_COMPUTE_SHADER_SHADER_SAMPLED_READ, read_barriers: VkPipelineStageFlags2KHR(0), queue: VkQueue 0x17e0579e890[], submit: 476, batch: 0, batch_tag: 9416, command: vkCmdDispatch, seq_no: 14, command_buffer: VkCommandBuffer 0x17e29576430[], reset_no: 1).
    Objects: 1
        [0] 0x17e0579e890, type: 4, name: NUL
#

ahhhh

#

I see

#

the initial start of frame barrier doesnt take the fragment stage too

#

another day, another bugfix in the rendergraph I guess

shadow trench
#

ffs not this again

#

no syncval output dread_cat

#

only happens when I get too close to the decal

#

time for a driver update

#

though i see nothing about an issue like this in the update notes

shadow trench
livid geode
#

neato

short surge
#

how did you do that

shadow trench
#

the DAG crate I use to back my rendergraph can output dot files

shadow trench
#

@livid geode I added the weight shader to the decal as you suggested

#
float4 main(PS_INPUT input, float4 frag_pos : SV_Position) : SV_TARGET {
    float2 uv = decal_uv(frag_pos);
    float2 centered_uv = uv * 2.0 - 1.0;
    // Discard everything outside the brush area
    float distance = length(centered_uv);
    if (distance >= 1.0) {
        return float4(0.0, 0.0, 0.0, 0.0);
    }

    // We will use our weight function to color the decal
    float weight = weight_function(distance);
    return float4(1.0, 0.0, 0.0, 1.0) * weight;
}

very shrimple to extend if needed

livid geode
#

i thought that by decal you meant texture

#

doesn't decal mean that?

#

like projected texture

shadow trench
#

Yeah generally

#

But here the texture is just implicitly defined in the shader logic

#

I can add a texture too

livid geode
#

this returns a color from black to red right

#

where are you doing the shading and whatnot

shadow trench
#

i have an include at the top that does all the decal logic

#

you get the uv with float2 uv = decal_uv(frag_pos);

#

Then you define what the decal looks like in function of that

#

Could be a texture, or in this case a circle shape that fades with the brush weight function

hot yarrow
#

looking forward to the "erode" brush

shadow trench
#

I think that would probably be a button/tool, since idk if it makes sense to erode parts of the terrain instead of the whole thing

hot yarrow
#

looks smoof when you watch it in fullscreen

#

fair

#

but perhaps you want to draw river beds somehow

shadow trench
#

Yeah thats true

#

im not sure how ill handle that yet

hot yarrow
#

and some rivers flow faster ie make the bed erode kwiker perhaps

#

but im no geologist

shadow trench
#

Maybe you first outline the general shape and then apply postprocessing on it when you release the brush? not sure

hot yarrow
#

possible yeah

livid geode
#

so this is not being applied directly to the terrain mesh?

#

it's something you project on top?

shadow trench
#

To the heightmap

#

The mesh itself is not modified

livid geode
#

wdym the heightmap

hot yarrow
#

hehe export displacement maps for 4 verticle quads

shadow trench
#

The terrain mesh is a flat plane

livid geode
#

with a really high resolution

#

yes

shadow trench
#

(after tessellation, yeah)

#

The brush just prepends commands to the frame's rendering commands to write to the heightmap in a compute shader

livid geode
#

i'm talking about the red dot you put on top bruv

shadow trench
#

ahh

hot yarrow
#

that wasnt really obvious πŸ˜„

shadow trench
#

yeah i project it onto the terrain

livid geode
#

so its a high resolution quad you project on top?

shadow trench
#

its a cube

livid geode
#

its a what

shadow trench
#

its pretty short

#

(the relevant part at least)

#

im not doing deferred rendering but for this I dont need a full g buffer, just depth info

livid geode
#

that is pretty cool, thanks

shadow trench
young oar
#

Ahhh deferred rendering

#

I need to implement it too

shadow trench
#

ehh

#

not really kekw

young oar
#

Sole reason I don't want to is because it makes materials a bit of a pain to write

young oar
shadow trench
#

deferred was cool 15 years ago

young oar
#

Is it not anymore??

livid geode
#

what's cool now

#

forward+?

shadow trench
#

nanite kekw

#

forward+ is nice yeah

livid geode
#

i have no idea what any of these mean 😎

young oar
shadow trench
#

with forward+ you split your screen into tiles and determine what lights affect what tiles in a culling pass

shadow trench
#

possibly not

young oar
#

I always thought only deferred allow you to do screen space stuff like that

#

(That are based on metallic/smoothness values)

shadow trench
#

that would make sense yeah

#

problem with deferred is bandwidth

hot yarrow
#

you still have some sort of mini gbuffer with forward, dont you?

shadow trench
#

depth prepass is not uncommon ye

livid geode
shadow trench
#

nanite is entirely different

shadow trench
livid geode
#

that was not very cash money of you

shadow trench
#

I added a reverse mode to decrease height

young oar
#

Awesome!

#

Those normals look so good

shadow trench
#

froge thanks

#

I generate a normal map the same resolution as the heightmap

young oar
#

Oh dang really

#

I though the normal map was higher res

#

But eh at least you have a normal map

shadow trench
#

having icons in my source is so cursed

shrewd lynx
#

@shadow trench nice

#

jwu and u did it already

shadow trench
#

Spent all day on this :P

#

its 10pm here now

#

im now fiddling with egui to make a good looking toolbar

livid geode
shadow trench
#

does that look centered

#

it does right

#

nvm thats not centered at all

#

maybe i should just use SelectableLabel but meh

livid geode
#

you can draw the icon yourself

#

from egui

shadow trench
#

Yeah I ended up copy pasting the selectable_label code and adapting it a bit

shadow trench
#

egui is such a joy to use and look at compared to imgui

livid geode
#

i don't like the default look of egui that much tbh

#

there's not much contrast

shadow trench
#

That's true

#

It's easy enough to style though

#

And way easier to navigate/customize imo

livid geode
#

you think so?

#

with imgui there were a lot of ready to go customization options

shadow trench
#

Yeah definitely

livid geode
#

i havent seen any for egui

#

and the style is kinda awkward to navigate thri

shadow trench
#

Creating custom widgets is super simple

livid geode
#

too many substructs

#

yeah that is a plus

shadow trench
#

idk if I have to look at imgui source code to see how a widget is implemented and how I can adapt it I can dig through a 3000 line cpp file

#

with egui its not too hard to figure out

livid geode
#

nono for widgets its easy

#

i mean for changing style settings

shadow trench
#

I havent fiddled with that too much tbh

livid geode
#

i recently fell in love with saleae's logic software

#

and frankly it doesn't look too off from egui

#

doesn't look too hard to replicate

shadow trench
#

Is it made using egui or

livid geode
#

nah its electron

shadow trench
#

ah

#

Ive seen some really cool things in the egui server from people with amazing customization

#

or on the showcase thread on the repo

livid geode
#

yeah thats true

#

just need to put in some work

shadow trench
#

yeah

#

ill definitely do some work to make this not look like default egui eventually

livid geode
#

heres some more inspiration :p

#

this one is egui

shadow trench
#

that looks really nice

livid geode
#

i wish it was easier to setup animations within egui

shadow trench
#

Is it not?

#

The custom toggle widget demo has a little animation thingy

#

But i havent tried much

livid geode
#

does it use the computer api?

#

value computer/cache

shadow trench
#
// Let's ask for a simple animation from egui.
        // egui keeps track of changes in the boolean associated with the id and
        // returns an animated value in the 0-1 range for how much "on" we are.
        let how_on = ui.ctx().animate_bool(response.id, *on);

i dont think so

livid geode
#

oh it does have animation utils? huh

shadow trench
#

Yeah, maybe not a lot but simple ones I think so

livid geode
#

yeah, seems only basics

shadow trench
#

At least you dont need to keep track of the animation progress yourself

livid geode
#

ye, that's p cool

shadow trench
#

Not recommended settings

shadow trench
#

writing a new post about the brush implementation

livid geode
#

lets fucking goooooooooooooooooooooo

hot yarrow
#

can you try this heightmap?

shadow trench
#

sure

hot yarrow
#

found that while looking for some siht

shadow trench
#

its pretty cool

#

takes ages to load though

#

I adjusted the scale a bit

#

I can play a bit more with the settings hang on

#

i did some brushing too

hot yarrow
#

weee

shadow trench
#

here have some mountains

hot yarrow
#

hehe i expected a little bigger mountain"ridges" somehow

shadow trench
#

I might need more patches

hot yarrow
#

comparfed to the rest of the terrain but it looks neat

#

if elevation was boosted a little it would probably make a super cool map for some canyon racer thingy

shadow trench
#

its pretty easy to scale elevation

#

but this was what it looked like on default settings

hot yarrow
#

uh

#

looks like there are some patches missing

shadow trench
#

this might be reasonable

hot yarrow
#

yeah

shadow trench
#

the shading still looks quite bad imo

hot yarrow
#

it feels like something is missing or cutting out inforation

#

the heightmap looks continuous

#

no spikes

shadow trench
#

i might be losing too much precision converting to fp16

hot yarrow
#

but in the last pic you can see some artifacts unless im just blind and moiree is fucking with my eyes πŸ˜„

shadow trench
#

though according to renderdoc its just 8 bit anyway so maybe not

hot yarrow
#

yeh then theh question is

#

why is the height data loaded as SRGB πŸ™‚

#

oh you mean for albedo

shadow trench
#

no

#

idk why renderdoc loads it like that actually

#

i load as 16-bit uint grayscale i think

hot yarrow
#

its possible that the png has colorprofile information

shadow trench
#

then convert to f16 and normalize

#

16 bit yeh

#
fn from_dynamic_image(img: DynamicImage) -> ImageBuffer<Self::Pixel> {
    let img = img.into_luma16();
    let raw = img.into_raw();
    let as_fp = raw
        .into_par_iter()
        .map(|px| f16::from_f32(px as f32))
        .collect::<Vec<_>>();
    ImageBuffer::from_raw(as_fp)
}

hm I cant imagine that im losing precision if I go u16 -> f32 -> f16 tbh

hot yarrow
#

me neither

#

hmm what happens if you dont convert to f16?

shadow trench
#

so just use f32?

hot yarrow
#

yeah

#

worf a try

shadow trench
#

pub type HeightmapFormat = Grayscale<f32>; I should only need to swap this out if I wrote this properly :)

hot yarrow
#

and remove the map i guess after iter

shadow trench
#

thats implemented in the Grayscale<T> impl for TextureFormat

shadow trench
#

f32 doesnt seem to help too much no

#

might be something with how im rendering then

hot yarrow
#

yeah perhaps i found the deccer_heightmap which breaks your terrain engine XD

shadow trench
#
// Normalizes height values in the height map to [-1, 1] based on the most extreme value
fn normalize_height(_width: u32, _height: u32, data: &mut [LumaPixel<f16>]) -> Result<()> {
    trace!("Normalizing heightmap data");
    // Find the largest absolute value in the dataset, and take the absolute value of it.
    let extreme_val = data
        .par_iter()
        .max_by(|lhs, rhs| lhs.to_f32().abs().total_cmp(&rhs.to_f32().abs()))
        .unwrap();
    let extreme_val = f16::from_f32(extreme_val.to_f32().abs());
    let extreme_val_inverse = f16::ONE / extreme_val;
    // Now divide every height value by this extreme value
    data.par_iter_mut().for_each(|value| {
        **value *= extreme_val_inverse;
    });
    Ok(())
}

Maybe I shouldnt do this at all

hot yarrow
#

ye i think everything should be raw

#

and then you compose it with all your other layers

shadow trench
hot yarrow
#

ahaaaaaaaa

#

thats more like it

shadow trench
#

Yeh

#

I wonder why normalizing it breaks the map

hot yarrow
#

rust bug πŸ˜›

shadow trench
#

The problem is I dont think the brush works very well with non-normalized heights

#

Also most f16 precision is in [0, 1]

#

i will investigate

livid geode
#

f16 has shit precision, perhaps you should do computation in f32 and then convert

livid geode
shadow trench
#

idk

hot yarrow
#

@wispy ore when you are online, give this heightmap a try too

shadow trench
#

i havent heard from him in a while

shadow trench
#

@hot yarrow your heightmap is serving a bigger purpose now

hot yarrow
#

i have no idea where i got this from

shadow trench
#

good height maps are hard to find tbh

hot yarrow
#

yeah

#

maybe future deccer got it from a program called Andromeda

shadow trench
#

if it can create that then ill be happy froge

shadow trench
#

https://www.notapenguin.blog/posts/terrain-brush/ the cool people who follow my fred have a chance to yell at me with feedback before i post it everywhere froge

NotAPenguin’s ramblings

In most digital content creation software, brush-like tools are a core way to paint visuals. This week I decided to take a crack at implementing a first terrain brush in my terrain editor, andromeda. At first this seemed like a huge undertaking, so I made a list of individual tasks to complete.

livid geode
#

will do

#

that is really neat @shadow trench

#

nice writeup

shadow trench
#

thanks :)

hot yarrow
#

heh

#

you could mention the normalization fookup with that heightmap

shadow trench
#

Mayhaps

#

but its not really related to the brush imo

hot yarrow
#

2nd article incoming

shadow trench
#

would be a short one

hot yarrow
#

but consistent

#

or was that a once off post blog thing only? πŸ™‚

shadow trench
#

hopefully not :)

hot yarrow
shadow trench
#

@potent quest SCohno

#

we lost him

potent quest
#

im gone

#

suffering if you will

shadow trench
#

ive been there

#

i dont play much anymore luckily

potent quest
#

best decision made in your life

#

πŸ’€

shadow trench
#

πŸ’€

#

my wallet is also glad about it

potent quest
#

let me tell you about genshin impact and honkai star rail

shadow trench
#

oh no

potent quest
#

Hour 2 of valorant: I have gone insane

#

(i got 3 aces :D)

potent quest
#

Hour 3 of valorant: maybe i don't need to understand ray tracing

shadow trench
shadow trench
#

i have so many sub crates by now NanaStare

#

this is fun to have

#

publish_error!(bus, "Error loading asset: {error}"); with a shrimple macro to use

young oar
#

(I am going to steal your code)

shadow trench
#

for shaders yeah

#

its really great

young oar
#

Yea I'm about to implement that for my terrain voxel shader

#

It'll make prototyping so much faster

shadow trench
#

super useful when debugging

#

yeah exactly

young oar
#

Good thing is that it wouldn't be hard to implement it for render materials as well

#

Just rebuild le render pipeline and you're good

shadow trench
#

yep

young oar
#

Now the only thing I'm worried about is that File::open actually locks the file

#

Which would be not good since you wouldn't be able to write to it, unless you open it and close it multiple times (in code)

shadow trench
#

you only open it once you get a notification that it changed

#

theres a nice crate for that

young oar
#

Oh awesome

#

It shouldn't be too hard to implement it myself tho

shadow trench
#

yeah but wrapping around the os-specific apis is ehh

young oar
#

Can't you use something like fs::metadata? I thought that's what the crate you're talking about uses internally, just wraps around it

shadow trench
#

the crate im talking about sends you events when the file gets events

#

it has some async watcher thingy that you just await for events

#

i spin up a thread and let it live there forever

young oar
#

Ohhhh I see I see

#

Yea that definitely does look like a nice wrapper

shadow trench
#

yeah its great

shadow trench
#

"Why is my blur shader not blurring"

#

my blur shader:

void main() {
  ...
  output /= accum;
}
#

what kind of crack was I on

#

ok i get that its an "equalize" brush but maybe this is a little too flat

#

heh this could totally be some road up to a castle on the mountain

shadow trench
#

today is a weird day

shadow trench
#

hmm

#

what do next

#

i guess its time to fix the rendering

#

its a bit ugly right now

hot yarrow
#

add texture layers

shadow trench
#

texturing definitely yeah

#

and some better shading

#

ill get the rendering code cleaned up a little first because its absolute hell right now

hot yarrow
#

and better starter heightmaps : >

#

or perhaps connect to some {Arc}GIS/WGS84/HTM/googlemap/ism (like those addons for blender)

shadow trench
#

maybe

#

but they usually have low resolutions

#

like 1 sample/100m

hot yarrow
#

no excuses

#

i was generally speaking

shadow trench
#

yeah

#

i had some format implemented but i yeeted it for now

hot yarrow
#

but textures is probably coolest feature next

#

to get some color in

shadow trench
#

because the parser library took 3 min to build

hot yarrow
#

oof

#

rewrite it in rust

shadow trench
#

i support textures but i dont have a good one for this mountain kekw

shadow trench
hot yarrow
#

then it will take 2.59mins to build πŸ˜„

shadow trench
hot yarrow
#

hihi

#

sorry

shadow trench
#

compile times are fine ish, its the linker thats dreadful

hot yarrow
#

someone should rewrite it in rust

#

ok, ill stop

shadow trench
livid geode
#

obviously c# is a thousand times faster but that's not a fair comparison

livid geode
#

but if you use mold as your linker it's pretty decent even with half a hundred deps

#

and considering those deps will only need to be compiled once per target config, once you do it once you're good to go for a long while

#

the real issue is target folder sizes...

shadow trench
#
ubo_struct!(
    atmosphere,
    ifc,
    struct Atmosphere {
        radii_mie_albedo_g: Vec4,
        rayleigh: Vec4,
        mie: Vec4,
        ozone_sun: Vec4,
    }
);
atmosphere.radii_mie_albedo_g = Vec4::new(
    world.atmosphere.planet_radius,
    world.atmosphere.atmosphere_radius,
    world.atmosphere.mie_albedo,
    world.atmosphere.mie_g,
);

cursed macro time

#

i honestly dont think i should keep this

#

but it saves a bunch of typing

#
#[macro_export]
macro_rules! ubo_struct {
    ($var:ident, $ifc:ident, struct $name:ident {$($fname:ident:$ftype:ty$(,)*),*}) => {
        concat_idents::concat_idents!(buffer_name = $var, _, buffer {
            #[repr(C)]
            struct $name {
                $($fname:$ftype,)*
            }

            let mut buffer_name = $ifc.allocate_scratch_ubo(std::mem::size_of::<$name>() as vk::DeviceSize)?;
            let mut $var = buffer_name.mapped_slice::<$name>()?;
            let mut $var = $var.get_mut(0).unwrap();
        });
    };
}

this is the macro in question

#

maybe its not so bad

hot yarrow
livid geode
#

not now

shadow trench
hot yarrow
#

what does ifc stand for? if condition?

#

inb4 "ifcourse"

shadow trench
shadow trench
livid geode
#

no i mean

#

is it implementable without a macro

shadow trench
#

should be but a bit less easy to read imo

#

i was considering ```rs
ubo_struct!(
camera,
ifc,
struct Camera {
projection_view: Mat4 = state.projection_view,
position: Vec4 = state.cam_position,
}
);

#

but that might be a bit too obscure

young oar
#

Yea I also thought of doing a macro for UBOs and stuff like that

#

At the end I just sticked with defining structs cause macros scare me

#

(or at least making them scares me)

shadow trench
#

i think i could get the assign version to work

#

ill try and see if its not too cursed kekw

#

you know its not that bad

#
#[macro_export]
macro_rules! ubo_struct_assign {
    (
        $var:ident,
        $ifc:ident,
        struct $name:ident {
            $(
                $fname:ident:$ftype:ty = $finit:expr,
            )*
        }) => {
        concat_idents::concat_idents!(buffer_name = $var, _, buffer {
            #[repr(C)]
            struct $name {
                $($fname:$ftype,)*
            }

            let mut buffer_name = $ifc.allocate_scratch_ubo(std::mem::size_of::<$name>() as vk::DeviceSize)?;
            let $var = buffer_name.mapped_slice::<$name>()?;
            let mut $var = $var.get_mut(0).unwrap();

            $(
                $var.$fname = $finit;
            )*
        });
    };
}
#

macros are kinda fun

hot yarrow
#

not so much the macro itself, but its what its πŸ™‚

shadow trench
#

are macros readable in any lang kek

#

but yeah this is a lot nicer than the alternative

nimble solar
#

What the hell is $(...)*?

#

Is it regex? It looks like it lol

shadow trench
#

it expands the repeated pattern

#

uhh

#

in the pattern for the macro inputs you also have a $(X)*

#

Which is like a "match zero or more X" in a regex

#

Then in the expansion you can do a similar thing to say "for each of those matches, expand it to this"

nimble solar
#

Ahh I see

shadow trench
#

so in this case it just takes a list of name: Type = initializer and writes var.name = initializer;

nimble solar
#

So it's the epic thing that C macros don't have

shadow trench
#

Yeah

nimble solar
#

Recursive expansion

shadow trench
#

rust macros are super nice

nimble solar
#

😦

young oar
shadow trench
#

it is quite shrimple

young oar
#

If that's what's all needed to have a fancy macro like that then sign me up lol

shadow trench
#

feel free to copy pasta

#

you do need to give rustfmt a little hand with it but other than that it works great

young oar
#

Also you were super right about hot reloading

#

Shit is so nice to use

shadow trench
#

its one of the first things I added lmao

#

definitely worth it

shadow trench
#

git submodule add ... some/path
git submodule init

fatal: No url found for submodule path 'fsr2-sys/src/vendor/fsr2' in .gitmodules
huh?

#

am i stupid

#

what

#

it did clone properly

#

it works if i use path/to/foo/ instead of the autocompleted .\path\to\foo

#

i hate git submodules

#

ok step 1 of fsr2-rust (generating cmake) is done kekw

#

being able to write rust for build scripts is such a nice feature

nimble solar
#

This isn't fair

#

You use Vulkan so you get to use FSR2 easily 😦

shadow trench
#

kekw superior API

#

why does it insist on putting the binaries in its own source dir

shadow trench
#

im making one

young oar
#

Ohh yea makes sense

#

Or anywhere else really lol

#

Unfortunately there's nothing like that for wgpu

#

I'm definitely gonna need to swap to vulkan later down the line

shadow trench
#

big progress

#

now i have to make the actual bindings

#

im a bit confused how the shader stuff works

#

ill ask jaker later

shadow trench
#

ok time to start writing bindings

#

lmao

livid geode
# shadow trench huh?

i can imagine that FFX_EOF is used for "ok, completed, encountered end of file" while FFX_ERROR_EOF is for an unexpected end of file

shadow trench
#

probably

#

looks ugly

#

anyway, phobos 0.8.0 with fsr2 support soon

livid geode
#

currently pogging

#

i may actually switch to phobos in rex tbh tbh

shadow trench
livid geode
#

library user jumpscare

shadow trench
#

imagine having users

livid geode
#

so true

shadow trench
#

i have a virtual user in danny but hes procrastinating kekw

livid geode
#

lmao

#

having users takes a lot of your time but its a must to improve the library

shadow trench
#

definitely

livid geode
#

i'm learning lots by maintaining and updating rs-tiled

shadow trench
#

i see it on my github feed sometimes

#

looks like a lot of work goes into it

livid geode
#

for now its mostly just maintenance and answering user questions

#

i dont have time to actually update the crate

#

i was planning to do some work this thursday

shadow trench
#

there are releases with features every now and then no?

livid geode
#

yeah last one was not so long ago and had been planned for a long while

#

added vfs support

shadow trench
#

good stuff

shadow trench
#

these are some obscure surface formats lol

#

wtf i just noticed

#

the fsr2 error codes overflow

#

nice docs

livid geode
#

fsr2-rs on github: An enumeration of surface dimensions.

shadow trench
#

truly

#

i have to use fsr2-sys as the crate name since someone reserved fsr2 only to abandon it

#

oh god no

#

wchar_t dread_cat

#

@livid geode is there a c_wchar type in rust

livid geode
#

isnt that a windows thing

shadow trench
#

no

#

wchars are 32 bit on lunix

#

16 on winblows

livid geode
#

i found this

shadow trench
#
The standard used to require wchar_t to be large enough to represent any supported character code point. However, such requirement cannot be fulfilled on Windows, and thus it is considered as a defect and removed. 

bleakekw

livid geode
#

wha

#

where is that from

shadow trench
#

cppreference

#

consistency

#

uses size_t for one count, u32 for the other

hot yarrow
#

@livid geode rex as in graphite's rex?

livid geode
#

didn't even know graphite had a project named rex

hot yarrow
#

ah

livid geode
#

rex is a to-be-renamed project of mine which i also posted here

hot yarrow
#

was before your time here

livid geode
#

what was it?

hot yarrow
#

an opengl engine πŸ™‚

#

actually, not just opengl

shadow trench
#

oh i rember that

hot yarrow
#

dx11 and gl iirc

#

while i was working on xacor

#

also a d3d11/gl thing πŸ˜„

short surge
shadow trench
#

yep dread

#

i would be fine with it if it showed any sign of life or plans to continue but its been empty for 9 months so

#

im making decent progress on writing bindings i think

#

its not a whole lot to do manually

#

then again nervous

#

that should be all the basic functions

#

now to do the backend

shadow trench
#

easy enough i guess?

#

its surprisingly not a lot

shadow trench
#

unsafe everywhere!

#

also wtf is happening on my pc

shadow trench
#

im setting -DCMAKE_BUILD_TYPE=Release why is it not building release

#

ah

#

for multi-config (vs) you need to pass the config in cmake --build

#

ok debug vs release has been fixed

#

ill figure out how to fix the vk related linker errors tomorrow

#

good night frogs

shadow trench
#

nervous thank god I spotted this

#

casting vkGetInstanceProcAddr to vkGetDeviceProcAddr will surely go well

#

it seems like fsr2 assumes i link to vk to call vkEnumerateDeviceExtensionProperties and other functions not related to the device

#

i guess ill modify it to pass in those function pointer s instead

#

of course they use both vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2

#

because consistency

#

not me writing a mini vk loader ish thing so i dont need to depend on ash for the fsr2 bindings

shadow trench
#

surely this will work

shadow trench
#

i despise people who build their examples by default in cmake

#

or dont even provide a flag to turn it off

#

at least it compiles

shadow trench
#

so uh, I can create the context fine with validation off NanaStare

livid geode
shadow trench
#

yes

#

This is such a cursed workaround lmfao

#

but it works

livid geode
#

ub frOK

shadow trench
#

idk if its ub or just validation being shit

#

it does throw some errors about features not being enabled so maybe ill fix those and see if i can remove the thread after that

#

apparently their shaders use int16 but its not documented that i have to enable that feature

#

oh yeah that fixed it lol

#

mfw validation would rather cause a stack overflow than tell me im missing a feature

shadow trench
#

currently stripping down the fsr2 library to its bare essentials to fit in the crates.io upload limit kekw

shadow trench
#

ok i had to completely delete dx12 support because they ship an 18mb binary with dxc

shadow trench
#

also, phobos is at >400 commits now NanaStare

shadow trench
#

fsr2 in phobos very soon

#

you better start learning kekw

shadow trench
#

i think i have the basic infrastructure done so I guess its time to start writing a sample

#

mostly to see if it works

livid geode
#

thank you for your work soldier 🫑

shadow trench
#

o7

#

yeah i was surprised too tbh

livid geode
#

you should post it in the gamedev rust discord

shadow trench
#

sure, why not yeah

livid geode
#

its bound to get a shitton of stars

#

post it as a thread on the crates channel

shadow trench
#

will do frogapprove

shadow trench
#

some of the fields are getting swapped around

#
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct FfxResourceDescription {
    pub ty: FfxResourceType,
    pub surface_format: FfxSurfaceFormat,
    pub width: u32,
    pub height: u32,
    pub depth: u32,
    pub mip_count: u32,
    pub flags: FfxResourceFlags,
}

#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct FfxResource {
    pub resource: *mut c_void,
    pub name: [wchar_t; 64],
    pub description: FfxResourceDescription,
    pub state: FfxResourceState,
    pub is_depth: bool,
    pub descriptor_data: u64,
}
/// A structure describing a resource.
typedef struct FfxResourceDescription {

    FfxResourceType                 type;                                   ///< The type of the resource.
    FfxSurfaceFormat                format;                                 ///< The surface format.
    uint32_t                        width;                                  ///< The width of the resource.
    uint32_t                        height;                                 ///< The height of the resource.
    uint32_t                        depth;                                  ///< The depth of the resource.
    uint32_t                        mipCount;                               ///< Number of mips (or 0 for full mipchain).
    FfxResourceFlags                flags;                                  ///< A set of <c><i>FfxResourceFlags</i></c> flags.
} FfxResourceDescription;

/// An outward facing structure containing a resource
typedef struct FfxResource {
    void*                           resource;                               ///< pointer to the resource.
    wchar_t                         name[64];
    FfxResourceDescription          description;
    FfxResourceStates               state;
    bool                            isDepth;
    uint64_t                        descriptorData;
} FfxResource;

compare time

shadow trench
#

i got trolled by the formatting lmao

wise viper
shadow trench
#

i blame amd programmers

wise viper
#

smh jaker not having his company in order

shadow trench
#

unbelievable πŸ™„

nimble solar
#

Clearly Jaker is to blame for all AMD problems as he is the CEO, CTO, Chief Programmer, Chief Designer, Chief Marketing Manager, Chief Relationships Manager, and whatever other title there is

shadow trench
#

exactly

polar otter
#

Project looking really good Penguin frogapprove

#

any future plans for water / grass rendering, or purely focusing on the terrain part for a while?

shadow trench
shadow trench
#

real fsr2

#

no validation errors though

hot yarrow
#

perfectly upscaled black

shadow trench
#

zero artifacts

shadow trench
#

ok i think all i need to do to get it working now is jitter and motion vectors

#

test scene is ready

shadow trench
#

that looks antialiased to me :)

livid geode
#

Yayyyy

#

In phobos too?

shadow trench
#

this is all in phobos yea

#

what do you mean I can use it below but not clone it and pass it along

#

ah i get it

#

meh

#

There we go

hot yarrow
#

hard to tell

#

you need an actual noisy scene

shadow trench
#

yeah true

#

but this is good to test if its not crashing completely kekw

#

and it seems to at least not be aliased

nimble solar
#

You seem to be having the same motion problem, hmm πŸ€”

shadow trench
#

i calculated motion vectors by doing the shrimplest thing i could find

#

FragMotion = PrevClipPos.xy / PrevClipPos.w - ClipPos.xy / ClipPos.w;

nimble solar
#

How do you do them

shadow trench
#

and then set motion vector scale to render w/h

nimble solar
#

I read frogmotion

shadow trench
nimble solar
#

The scale should be set to w / 2, h / 2

shadow trench
#

wtf

nimble solar
#

Because math @distant radish did

#

Oh shit, sorry

shadow trench
#

why does the readme say otherwise lmao

nimble solar
#

I have no idea

shadow trench
#

i copied this

#

worf a try

nimble solar
#

#1019779751600205955 message

#

This be the math

shadow trench
#

that makes sense

#

That seems alright

#

might be better yeah

livid geode
#

this mf really think we can see the difference from a gif

shadow trench
#

gifs do be trash

#

but im too lazy to open obs every time

shadow trench
#

im so stupid i figured out why its stack overflowing

#
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct FfxFsr2Context {
    pub data: [u32; FFX_FSR2_CONTEXT_SIZE],
}

i tried to keep this on the stack

#

i made it upscale with the Quality preset now and its definitely not perfect

#

maybe its better with infinite reverse depth as they said

#

wtf i forgot to enable depth write lmao

#

much better

shadow trench
#

FSR2 has been added

nimble solar
#

How does reverseZ make such a big difference wtf

shadow trench
#

Well a big part of that difference you see is because in the first screenshot I had depth writes off entirely KEKW

coarse yoke
#

sharex can do 60fps mp4s :)

#

question i actually came here for, do you store a copy of the terrain on the CPU? (i'm guessing not since you'd have to manage, but i guess i'm curious if you've considered whether you'll need to)

#

other questions, if i understand correctly, you store a normal map of the terrain? why?

#

obviously normals can add detail, but it doesn't feel realistic to me for a terrain editor to actually utilize it unless you're just exporting hi-res from houdini, at which point it's a bit okey

#

or maybe blending from brushes? but that too also feels messy

#

you also said you use deferred decal rendering to render the brush

#

why implement that over virtual texturing for the terrain? i.e. why not do it as a component of the terrain rendering, rather than in compositing? i would expect this to be a lot more powerful, given that with other stuff in the future, you can modify heights with it too

#

these may seem like suslik/nano/jasper/etc.. .. . . style questions where i'm challenging decisions, they are not, i am not knowledgable enough for these to not be curiosities

wispy ore
#

Any decal that is movong just increases bandwidth used there proportional to decal count

#

Say you're doing stochastic texture mapping etc.
You need to redo everything for the area then reapply the decal at the new pos

coarse yoke
#

so do you cache the sample in chunked textures with vtm then? i haven't implemented it

wispy ore
#

You cache it there yeah

coarse yoke
#

gotcha, i understood vtm as just taking the expensive sample every time when rendering the terrain

shadow trench
#

Sounds interesting, I can’t say I know enough to answer all those questions properly but it’s definitely worth looking at

nimble solar
shadow trench
#

The normals are mostly for adding detail while rendering, without it looks really quite flat which just is kinda ugly

nimble solar
#

I don't understand the math behind extracting planes from an infinite reverse projection 😦

shadow trench
shadow trench
#

anyway, time to integrate fsr2 in andromeda now

shadow trench
#

that's not right

#

why is it shaking

shadow trench
#

how is it all zero now

#

it wasnt 10 minutes ago

potent quest
shadow trench
#

fsr2-sys (the bindings lib) is a separate crate

#

but i made a fork of FSR2 thats stripped down to just the source and stuff needed for the vk backend

#

Because yes initially it didnt fit kekw

#

now fsr2-sys is like 5 mb or so

potent quest
#

OHHH

shadow trench
#

I also changed some stuff in the fork but its quite minimal

#

the biggest thing is I changed the vk backend api to take in function pointers stuff like vkEnumerateDeviceExtensionProperties

#

because it was calling those directly

potent quest
#

Never understood function pointers but sounds good

shadow trench
#

basically what it means is the bindings dont depend on vulkan being linked at all so it can use any loader potentially

potent quest
#

Ohhh so you can do stuff like test cases

shadow trench
#

possibly i suppose

#

but also i dont want to link vulkan directly kek

#

that would break with using the dynamic loader in ash for example

potent quest
#

Ohh

#

Wait there are multiple loaders for Vulkan?

shadow trench
#

even in c++ you can link statically or use volk

livid geode
shadow trench
#

right, of course

#

sorry sir

potent quest
#

hire a new one

#

clearly they arent fit enough for the job

shadow trench
#

when are you learning rust

hot yarrow
#

πŸ‡ΈπŸ‡΄ πŸ”› πŸ‡ΉπŸ‡²

potent quest
shadow trench
nimble solar
shadow trench
#

you can use vulkan easily with phobos ℒ️

#

also

#

cool lang

nimble solar
#

This is NIH land isn't it

shadow trench
#

naturally

nimble solar
#

I make my own bread

shadow trench
#

its like fwog but for vk

#

and in rust

#

it does a little more but thats the gist of it

#

i have this overview thingy of features

nimble solar
#

Looks cool, I'll use it as reference for my own thingy

#

Virtual resources are particularly attractive

shadow trench
#

admittedly it doesnt do any aliasing yet

#

but one day

#

some initial ideas are heavily inspired by vuk (martty's thing for c++)

#

but its nothing like current vuk

livid geode
shadow trench
#

no vuk does a lot more with fancy rendergraph combination thingies

potent quest
#

i am proud to present bad news

#

i got deferred from University of Toronto CS to their math department bleakekw

shrewd lynx
#

Sadge

potent quest
#

maybe living in a cardboard box isn't that bad

shadow trench
#

i dont know what that means

potent quest
#

the cardboard box?

#

or university

shadow trench
#

the university thing

potent quest
#

UoFT (university of toronto) is one of the most prestigous universities in Canada

#

if not the

#

but I got deferred from computer science (rejected) and instead got an offer to their maths

shadow trench
#

ooh I see

#

Yeah piece of advice dont go study maths

#

Just dont

potent quest
#

LMAOOO

#

is it that bad

#

i'm coping so hard rn

shadow trench
#

i take a minor in maths and its horrible

#

i mean

#

i quite like math but i didnt sign up for not getting my degree ever

potent quest
#

πŸ’€
The second option is a math offer from another uni

shadow trench
#

damn you really dont get to choose there

potent quest
#

it's math but i pay 20K or math, but no one knows about my university

shadow trench
#

πŸ’€

potent quest
#

the other option is CS, but no one knows about this uni and half of my high school is going there πŸ’€

shadow trench
#

yeah that sound even worse

potent quest
#

(i do not want to see my high school grade again)

#

yeah but from what i heard no one there tries so its easy to get 4.0 gpas πŸ’€

hot yarrow
potent quest
#

it's known within my province well

#

actually country, but if i were to fly out, it wouldn't really be known but tbf

#

trying to get a job outside of my home country is bleakekw

hot yarrow
#

is that a thing over there?

#

that you are only getting a job if you go to a place ppl know?

#

rather than what you can/have researched/have mastered in

potent quest
#

from what i heard from my techers

#

you use the co-op programs to help you get jobs?

shadow trench
#

that’s not usually how we eu frogs do it

#

But you can also generally attend (almost) any uni you like so it’s not as important

potent quest
#

huh

#

yeah co-op is usually the route most people go down

#

people can/do apply using degrees right out of grad

#

but co-op has become really big at least for se

#

as it's more or less how you connect to and from potential employers

shadow trench
#

Hmmm

hot yarrow
#

never heard of that before

#

you either studied an interesting topic or not

#

and then people hire you according to what you can do/sold yourself best with

#

not which university you went to

shadow trench
#

Yeah

hot yarrow
#

but that could be a cultural thing... ive seen that in south korea/india as well

#

us of freedom perhaps too to some degree

#

but anyway, im not judging, just wondering πŸ™‚

potent quest
#

tbf i am being completely over dramatic. both unis are perfectly fine and in truth, i'm aiming way too high for my caliber trying to get co-op at the top unis

#

πŸ’€

#

but i know for sure that co-op has been the primary route that my teachers at least

#

have been touting as the "this will land you a job"

#

however i am not being over dramatc in saying half of my grade is going there πŸ’€ I don't wana see them again

hot yarrow
#

just make sure you learn/study/research on something interesting

#

and when you get the chance to travel/see the world no matter how short it is... 3 weeks, 6 months, 2 days... do it

#

exchange programs or whatever

potent quest
#

I really wanna do an exchange program since I haven't travelled since I was a child

#

Wanna visit Europe one day fr

hot yarrow
#

if you can other cultures too, not just the cheese eaters, wine drinkers and beer brewers πŸ™‚

potent quest
#

lmaooooo ill try

shadow trench
#

im making some drastic changes to how in-frame resources are allocated and passed around

#

going to make it more streamlined with out of frame stuff

#

should also lead to major api simplifications

shadow trench
#

i was fully prepared for this to come crashing down burning but after fixing all the compiler errors it just works

#

epic

#

fences and scratch allocators are now globally pooled

#

as an added bonus you now no longer need to manually keep track of pipeline/descriptor caches or pass them to cmd buffers

shadow trench
#
frame.new_frame(..., || {
  // global_pool is a ResourcePool, you only really have one across the entire program
  let pool = LocalPool::new(global_pool)?;

  pool.allocate_scratch_ubo(...) // memory for this frame only
});
#

The nice thing about this is that it doesnt matter if this is inside a frame or not

nimble solar
#

How do you delete it?

shadow trench
#

i was just figuring that out

nimble solar
#

Rather, do you keep track of the GPU using the resource or do you just kill it after some fixed time has passed?

shadow trench
#

im thinking the cleanest way is to make SubmitBatch::submit_for_present() take ownership of the local pool

shadow trench
#

well

#

release back to the pool

nimble solar
#

Hmm

#

So for each queue submission, you keep track of the resources it uses and assign a fence to each?

shadow trench
#

not really

#

each queue submission has a single fence associated with it

#

But fences are a bit beefed up

#

They store a chain of cleanup functions called after wait() completes

#

I can move the local pool into such a cleanup function so it is kept alive until wait() is done