IsoSurface Demo - Dev blog experiment... (released)

Well, I already did it, in a raw form - no calculation optimizations, just compatibility. Next thing is to find why sometimes it produces ugly artefacts with shorts and no such things with floats - due to mesher or due to worldgen. I bet it’s worldgen and will check it today.

Converting float to short feels like data loss, not optimisation.

Did you think about serializing your chunks to seed + diff stack? It works well for heighmapped, but it’s surely more complex with iso surfaces.

Ultimately, what really matters is the grid corners and the edges between them, more or less. Essentially, you need enough resolution at the corners to put 0 somewhere between the corners which as much resolution as you desire. The edges aren’t very long so I guess not much resolution is required. Even +/- 127 (a byte) might give you enough… that’s ~256 places the surface could intersect that particular edge.

In RAM, floats are much easier to deal with but the surface functions should still be possible to write in reference to byte or other. And actually, once you’ve decided on a range, they could convert to float on the fly to return the corners in float.
byte corner = …
return corner * RANGE

…or whatever.

1 Like

Looks like I did a wrong turn somewhere :chimpanzee_closedlaugh:

edit:

Got weird stuff here - for test purposes I made simplest terrain possible, consisting from one meter wide pillar at 0; 0 and horizontal plane. And then I noticed that pillar is really not on 0; 0 coordinates, or at least debug overlay thinks so. Will investigate if it’s due to my changes or not.

edit:
Fixed that offset thing, it looks like it’s marching cubes implementation “feature”, but thankfully @pspeed already implemented possibility to offset density volume for zones/chunks so I just added “-1” offset to every axis and everything is perfectly in sync now. Well, not everything actually - had to remove all “+1” offsets from collision calculations as well.

So it’s finally a time to move to more interesting things - adapting worldgen to a new reality and to my likings. :chimpanzee_cool:

1 Like

Man, sometimes I’m surprised how well that edging algorithm works even when presented with really bizarre terrain. :slight_smile:

1 Like

Hm… Looks like I’m a bit misunderstanding some principles behind internal grid and density field management here. Don’t treat anything I already said about internals of IsoSurface library as confirmed truth - just to avoid confusion if my assumptions were incorrect. :chimpanzee_nogood:

From the other hand, to make terrain really editable it’s unavoidable to implement my main misunderstanding as real code - right now density field is cached only for physics and other post-generation routines and that’s what made me think the same is true for other parts, while terrain mesh generation in reality uses density field provided directly by worldgen without data caching.

Maybe it’s time to start my own thread and stop spamming here.

I am trying the demo, the vegetation texture, tall grass and trees are very good! Atmospherics too!
I wonder we could easily add flowers and fruit plants into the vegetation spreading algorithm?

The disconnected terrain patches (levitating ones) are detectable?
The weak-connected terrain patches are detectable also?
I would like to texture them as rocks, or let them fall to the ground as new rock geometries, may be to be reintegrated into the terrain.

The terrain seems to be a matrix like the block world, or it has connections in angles other than a cube can provide? The mesh suggests that.
Also, there was an old code at JME tests called MetaBalls ScalarField. Is the world skinned by something like that? if it is, I wonder if bigger radius/weight could create more smoothed terrain surfaces?

EDIT: SimArboreal editor is very very cool hehe! I wonder if we can tweak the wind option to provide more randomic tree movement?

Yeah, it shouldn’t be too bad… you could even just inject a flower texture or two into the grass atlas for a cheap version.

It all depends on what algorithm generates the terrain. Any 3D noise-based function is likely to have these sort of floaters. For Dragonfly Odyssey, I used a different algorithm for terrain generation that didn’t have this issue. (It was the same height-mapped fractal I used for Mythruna’s base terrain, actually.)

That’s basically what isosurfaces are. In this case, it’s seeded from a grid of ‘strength’ values. You should probably read nVidia’s original article that I used as inspiration.

http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html

The wind is random… you can make it more random by tweaking the shader. Or you can adjust the wind strength parameter dynamically.

It’s just sample code and open source… you can extend it however you need to.

2 Likes

Don’t mean to revive an old topic, I’m trying to add a Dual Contouring mesher to the existing IsoSurface project. I was wondering how the MarchingCubesMeshGenerator works in relation to coordinates in the worldspace rather than in the chunkspace. Is there a way that I can convert the chunkspace coordinates to world space coordinates?

Honestly, I don’t remember without looking at the code. If chunk space is scaled from world space then it will be through some kind of wrapper that you could always leave out. Check the main grid setup code I guess.

Dead download links…

Am i able to sell a game based on your library?

Yes. but… manually.

If you have the world space, use bitshifting to reduce it. Easier in code to explain:

we presume your chunk_xz and chunk_y is 64 (default i believe in the demo)

Vector3f worldspace = ../// your worldspace co-ordinate.

// get the grid location. octrees..
int gridlocationX = worldspace.x >> 6;
int gridLocationY = worldspace.y >> 6; // it does support vertical paging!
int gridLocationZ = worldspace.z >> 6;

// now get the local chunk location by subtraction.

// shift it back down so we get the world position of the chunk.
int chunkLocX = gridLocationX << 6;
int chunkLocY = gridLocationY << 6;
int chunkLocZ = gridLocationZ << 6;


// now remove the chunkLoc from the worldspace, and you end up with what you want.

int resultX = worldspace.x - chunkLocX;
int resultY = worldspace.y - chunkLocY;
int resultZ = worldspace.z - chunkLocZ;

The number 6 is significant. Take a look at bitshifting and octrees if you aren’t sure what it does.

It sounded like he was trying to hook into a different place.

At any rate, given that the rest of the code is written to deal with multiple grid sizes (as I recall) then manually calculating this with bit shifts might be dangerous unless you’ve already turned all of that constant.

There also should be a way to get what you want somehow… after all the local geometry must get mapped to world space somehow when the surface is queried. Also things like grass layers are already sampling into world space from local space. There must be a way.

Anyway, the grid models are there and they should allow you to go back and forth, I though. I don’t have the code in front of me right now, though.

Hi
I am a bit in doubt of how the collision checking should work with the terrain.

(Sorry if this question seems stupid)

Can we check collision on IsoSurface terrain with a way other than ray casting to terrain mesh ?
Can we do with similar approach to HEIGHTFIELD_COLLISION_SHAPE ?

I believe I already do this for walking around. As I recall, I do it by querying the distance function directly and finding the normals from that.

I’m not sure I added the code to the demo but there is definitely some version that you can walk around on the ground. I had another version (99% sure I did not commit) that you could fire blue balls and have them roll around.

I don’t know how you’d integrate that with Bullet but for simple physics it wasn’t really a problem.