#Vertexture: revisiting an old school project

135 messages · Page 1 of 1 (latest)

left pagoda
#

https://youtu.be/Ms6xotuRfBE little project I made in 8 days back in school - project statement attached - recently templated my engine so that I can have these different applications inherit from some base engine class that has the basic functionality implemented, anyways, porting some of my older projects into this structure and taking the time to go through and rewrite this one because it's, ah, 4 years old and I have gotten a lot better at graphics stuff and just generally better at writing code since then

jb

longer game of vertexture: 100, 100, 45, 18 ( good guys, bad guys, trees, boxes )

▶ Play video
#

some brainstorming, I think I want to render from a second view and do shadowmaps

#

redoing how the points are distributed for the trees, and I'm going to extend this sphere rendering method a little bit more, it maps a small heightmap of a sphere onto the square covered by graphics API points

#

was quite pleased with the water in this one, but those sideskirt things need work, I can see the holes a lot more because this was done on a 1366x768 display and now on a 1440p one

#

potentially trying some methods to do lit volumetrics, as well

left pagoda
#

potentially move the computation for the particles to the GPU and see what we can do with that

left pagoda
#

this was called Vertexture, because it displaces the vertices, and as it happens, basically everything else, by a texture in the vertex shader

#

scoring is offscreen, it's in the terminal, so that's another thing, just a little scroll with my text renderer

#

orthographic projection lets you get away with murder

#

Vertexture: revisiting an old project

left pagoda
#

Vertexture: revisiting an old school project

#

couple very easy optimizations to do, the trees repel the little guys - instead of iterating the whole list every update, I can precompute distance and direction to closest tree into some kind of cache so that's something possible to refer to quickly - I can extend that a bit and do variable radius trees - currently all the trees have a static arrangement of points and it's repeated for each one - I think that could be a lot cooler with some variation added

#

another aspect here which is not really super apparent is a color-based selection scheme, where I map the world x,y to a color and pick from a buffer on click events - this means that even with the offset height, you have good picking, easy masking for the areas that are under water

#

trees and guys have their position as a vertex attribute and refer to the same heightmap that's used to displace the vertices + bounce ( randomizing this phase/frequency will be big ) + random jitter each update + offset towards closest box

#

some random variation in point size would go a long way, I think - I found glEnable( GL_PROGRAM_POINT_SIZE ), which lets you set it from the vertex shader

#

since that scales the UV I'm getting in the fragment shader, that'll all work out, each of the sphere/point/whatevers just need to know a radius

#

and doing it orthographic, that can stay super straightforward

#

correct depth I think is going to be one of the more difficult parts - unless I render to two buffers, one depth and one heightmap/radius to determine an offset... but that wouldn't work because the z won't be correct

#

I think it would have to write to the API depth in the fragment shader

#

but again, orthographic perspective would be your friend there as well just do everything as simply as possible with that

#

I know that has some performance implications but we'll have to see how significant that actually ends up being

left pagoda
#

does go to 255 there on the sphere as well, it's, I guess normalized is the easiest terminology - so that's good to go, this is the texture I was using

#

I have it in a higher res as well but that's totally overkill

#

actually kind of a mess at the top end

#

some kind of compression artifacts or dithering or something

#

anyway probably not super important right now

#

and then this is the texture that's being used as a heightmap + a shitty normal map that even after smoothing was kinda shit so I don't actually use it anywhere

#

apparently my water textures are too explicit

#

interesting

#

that takes, ayways

#

I have normals and height, but I don't think they match and I'm not thinking that they're actually being used anywhere

#

anyways, that's what the small one looks like

#

and that's sufficient for even quite large spheres before starting to show pixels

#

and hopefully this can serve two purposes, discard for black pixels, and also inform the offsetting of depth value - with knowledge of radius, this is just a scalar on that value, since this hemisphere is in [0..1] or I guess [0..255]

#

I'm really curious to see what kind of implications there are to writing to the depth buffer, because I only have anecdotal evidence on that one

left pagoda
#

getting position/normal in the fragment shader is easy with that gl_PointCoord thing, because that gives you an XY to start on and then you get the z value from the texture read

#

probably not super hard to figure out

left pagoda
#

another random thought, the method for the trees could easily be extended to do various ground cover, rocks, moss, these types of things, with smaller / greater number of points - this program is by no means GPU bound, it's a single threaded update ( more on that later ) - I can mark obstacles the same way as trees, too, so I can do rocks as occluders - depending on how performant the point rendering is I might be able to do a pretty significant amount of detail, I haven't profiled it really at all https://youtu.be/M8eed7NBJRQ anyways it starts slowing down single threaded around 10k guys in there in the current implementation

jb

longer run of Vertexture - 5000 5000 60 45 ( good, bad, trees, boxes )

I like the flow of the stuff around the trees - I'm making use of some broken state that you can get into where you actually place the box outside the area in which the points can access - that leads to a situation where it can never be captured and the target just stays as ...

▶ Play video
#

and I think there's a bug, potential intentional bias towards the good guys, you can see towards the end ( ~26:00 ) the blue guys preferentially go for the closest active box while the red / bad guys go towards the least recently placed active

left pagoda
#

got the new one rendering the subdivided plane, displacing the vertices in the fragment shader with the heightmap

left pagoda
#

no apparent penalty for directly writing depth, this may yet be as easy as it seems

#

so it "just works", apparently

left pagoda
left pagoda
left pagoda
#

one million points at 60fps, not too bad

left pagoda
#

quite a bit faster with smaller points

left pagoda
#

interesting

#

easy to get worldspace position and normals for the fragments on the spheres

left pagoda
#

need to figure out what I'm doing wrong with the normals, can't seem to get them to look right in worldspace

left pagoda
#

clearly i’m going to have to do the movement logic on the GPU, being able to render this many points, it just don’t make sense not to

#

keep state in an SSBO, cache distance and direction to nearest obstacle into a texture, should be pretty straightforward

left pagoda
#

so there’s going to be a static set of points placed with obstacles at the program start - this might be either cpu or gpu, tbd - use the locations to get the cached informational maps for the dudes - nearest goal point, nearest obstacle, compute shader updates position based on samples - this will enable some stuff I’m thinking about it, or maybe each one does an atomic write to a buffer, so we kind of get a value for how trampled areas are, maybe try and do grass rendering, some thing where these guys would have trails, but it’s not just on off, you have a lot of dynamic range, in terms of how trampled areas were…

#

maybe they pick up water when they’re in the water, and then there’s a similar water deposition map, for ground to look wet

left pagoda
#

or grass etc

#

and I can do height fade with point radius kind of thing

#

and what's nice about that is that it will work if I eventually swap out this static texture for like a diamond square + erosion kind of deal

#

doing GPU sim for the little guys moving around, will be able to do 10s of thousands of them easily

#

was thinking, how much state to keep for the simulation there, and it can be like, a significant amount without worrying too much - like, use 16 floats or whatever, it's not a big deal, even with 10k of them you're not even using megabytes of memory

#

SSBO for that would the move

left pagoda
left pagoda
#

don't put trees in the water

left pagoda
#

progress on the sideskirts - this had previously been done with a vertex shader, but now I'm just using a single quad per side and doing different logic on the front and back faces

#

what's cool is that I can look at the height and the height of the water, so on the kind of "outward" face, which is the API backface, we can see areas where it's in water or in the ground, or discarded when it's above that

#

and then on the back face we can see the green area, that's area that's above the ground based on that same logic, and I can draw something there if I want or I guess just discard, whatever makes the most sense for the application

left pagoda
#

per-point color

#

tree trunks

left pagoda
left pagoda
left pagoda
#

points now avoiding trees/obstacles - they're moving based on the logic in this compute shader, it has a couple of influences, here some constant direction + random jitter + away from nearest tree if it's too close

#

precomputes the distances and directions into a buffer, then each point reads from that

#

also looking at a "steepness/height" map

#

red channel is high when there's a large difference between lowest and highest point - green just has distance, was testing something

#

was thinking this would scale movement speed

#

basically just takes a dozen random height reads in a disk for each pixel, and keeps the difference between the enountered minimums and maximums

#

interesting view from below

left pagoda
#

2.5m points running in a compute shader updating positions every frame, and displaying in realtime

left pagoda
left pagoda
#

using normals

left pagoda
#

orbiting light, doing very simple directional diffuse lighting calcs with no shadowing ( shadowmapping is next ) - directional lights correspond to ortho perspective in the shadowmap, again just for the sake of simplicity

left pagoda
left pagoda
#

So right now the dude movement comes from a constant direction+random offset+bump away from trees below some distance threshold all times some steepness parameter, which makes it go slower on steep slopes... Kind of strange for downhill, but it doesn't look super weird in practice

left pagoda
#

Thinking about adding another "crowding" map so I can have like an indicator of how many dudes are at any point on the map - channels of this can be used for e.g. densities per team, can read from CPU at goal positions to see who got there first, first nonzero channel sample encountered

#

This crowding map would also allow me to adjust z to kind of make them look like they're "piling up" in dense areas, and maybe act as some indication of footsteps for e.g. trampled grass

#

Where it could fade out over time like the renderer for point drop, my boids impl, the physarum thing

#

Gaussian blur, multiply result by some attenuation factor, lower factor fades faster

#

I like the idea of being able to have some kind of simulation here where there's feedback with simulation elements and the environment, e.g. height map could be manipulated by the sim, and it would show in the display

#

Will also be adding ( potentially much more ) state to the dudes, they currently have position and color, plus radius in position.a, so it's 8 floats ( 32 bytes ) apiece but there's only a couple million in play so we have a lot of headroom ( kb of state would be possible, if for some reason that became desirable )

#

Thinking, then, about the physarum, how it did the simulation agent update logic by sampling areas around the agent, this might be a method to do something similar with the data maps in this project - but potentially keeping memory, and more samples... What would/could that be used for?

#

I'm thinking about some way to do plant growth and compensation for occlusion in that setting - e.g. id value per tree, render the leaves and the fragment shader can add to some value if it somehow knows it receives sunlight, whether that is the fact that the shader runs, or a check to a shadowmap

#

There's a paper I saw at SIGGRAPH 2019, synthetic silviculture, it dealt with some similar ideas

#

But that could be a way to add CPU feedback, if it knows ok X plant got Y units of energy last frame

left pagoda
left pagoda
#

another thought, potentially performance improvement - I have a little bit of a limitation for writing the depth, that it will be less than the depth of the primitive, since the point primitive is being placed at the point center - but - what if you kind of pre-compensate for that in the vertex shader - that's probably the move

#

because previously, in order to get correct depths, it would have to subtract from gl_FragCoord.z, by the radius

#

if I set it to that much closer to the screen in the vertex shader, then it can be an addition by one minus what I was offsetting it with before

#

so at the center of the sphere, with a height read of 1, it is just gl_FragCoord.z

left pagoda
#

and that worked out pretty well - need to see how much better the perf is on my laptop, I expect at least a bit of an improvement

#

yeah lol same settings we're looking at about 20x longer execution time rendering all the points vs my desktop - that's not too crazy, though, given it's an older intel integrated graphics chip in an x270

#

specifying layout( depth_greater ) out float gl_FragDepth;

#

looks like about 30% perf improvement on the desktop, interesting

#

holy shit

#

it actually scales like

#

a lot better

#

I can do almost 40m points now at 60fps

#

just kidding, math was wrong, it's actually 25m

#

still, radically better

left pagoda