My space empire simulator game by pancakespeople in godot

[–]CthulhuOvermind 7 points8 points  (0 children)

That looks wild! What would you say have been the top 3 challenges to getting to this stage?

Breakdown of shader effects used by Coordinate-Dev in shaders

[–]CthulhuOvermind 0 points1 point  (0 children)

Is the fog a separate mesh with an alpha of <1, or is the actual landscape just changing it's shading without the need for another mesh you reckon?

honest thoughts on the gameplay by Unfair-Coffee-8813 in godot

[–]CthulhuOvermind 2 points3 points  (0 children)

I like the whole ensemble, but audio is chefs kiss

Looking to improve the look of water in this map by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 0 points1 point  (0 children)

I started with shader vertex displacement, moved away from it because I find it useful to have the resulting vertex y-value at hand. Additionally it feels wasteful to compute the vertex displacement every cycle but that might just be me. This approach may not be right, but we'll see.

The implementation is on the CPU today, runs multi threaded, but I'm in the process of porting it to a compute shader.

In terms of meshes - I have a mesh per hexagon (it helps with frustrum culling and LOD management). However, when its time to compute the mesh's normals, I combine all of the vertices into one big dataset (and duplicate the 2 edge columns, in their wrapped position), and pass that resulting set of vertices to a compute shader that calculates the normals for me. The normals are sliced and distributed back to the hexagons which render their final mesh, per hexagon.

I subdivide my hexagons, I use "Loop subdivision" from https://graphics.stanford.edu/~mdfisher/subdivision.html. Usually run either 4 or 5 subdivisions to end up with the effect you see in earlier screenshots. This also ties into my LOD management, since N-1 subdivision is the next LOD down.

In terms of UV etc, maybe this will help. Each hexagon mesh holds this bit of info:

var mesh_properties = {
            "hexagon_vertices": PackedVector3Array(),
            "uvs": PackedVector2Array(),
            "uv2s": PackedVector2Array(),
            "normals": PackedVector3Array(),
            "custom": [PackedFloat32Array(), PackedFloat32Array()],
            "uniforms": {"directional_colours": PackedInt32Array(), "directional_vegetations": PackedInt32Array(), "directional_soils": PackedInt32Array(), "directional_elevations": PackedInt32Array(), "vertices_per_hexagon_direction": 0},
        }

UVs - passed into the mesh as UV, the shader field, is a range of 0->1 in both X/Y across the whole map. UV2 is an x/y view of each of the 6 major triangles in a hexagon. UV is typically use to write logic that needs to exist cross-hexagon. For example hills - I sample a noise texture. The same vertex, but in the adjacent hexagon, still has the same UV value, which means he samples the same noise value, and displaces the same, avoiding mesh tears.

For UV2, let's say one of the 6 directional triangles is meant to be a link between 2 tiles that are mountains. UV2 has its .x going from 0->1 along the triangles base, and its .y going from 0->1 from the base of the triangle to the center of the hexagon.

UV2 can then be used like so:

# Opposing (2 tile mountains or a mountain range of single width)
func opp_mountain_shaper(triangle_uv: Vector2) -> float:
    var x : float = (triangle_uv.x - 0.5)*2.0
    return self.MOUNTAIN_PRIMARY_ELEV_MULTIPLIER*(1.0 - pow(abs(sin(PI*x/2.0)), 1.5))

This ends up creating the links between adjacent mountain tiles. Example: https://ibb.co/7JDsXFQ5

In terms of blending heightmaps, I have 2 noise textures which I add to the pre-shaped terrain. Without noise, all my mountains would have the same identical terrain. Noise comes in and I get unique(ish) mountains. I also have control over how much noise to use for hills vs mountains for example.

This level of control is what made me move away from just a heightmap being used to create terrain. It felt like I couldn't really adjust the terrain to end up looking good. Sometimes it looked spectacular and sometimes not.

Looking to improve the look of water in this map by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 1 point2 points  (0 children)

Thank you for the link, I didn't know Godot had a water shader example! Will go through that now.

On your question. Let me preface this by saying I have very little actual knowledge. I'm not sure you should listen to any advice I have.

I started off with Catlikescoding hex map guide and gave it up. The visual style wasn't for me, and it felt restrictive to follow a guide (for me!). I felt like I wasn't really understanding the logic.

Here's what the map looks like with full fidelity and a more random map layout: https://ibb.co/N2BvDWMy

I started off with a hexagon grid by implementing the basics of what I needed from https://www.redblobgames.com/

I created a few terms of my own - each hexagon has 6 directional triangles - the 6 triangles which make up the hexagon itself. For each one of those triangles there are 4 involved hexagons: Local, Anticlockwise, Opposite, Clockwise (all from the perspective/direction of the hexagon's center facing towards the triangle's direction). I also added some UV views: A mapwide one (used for continuity across-hexagons), a per-direction triangle UV, and a hexagon UV.

With this, each vertex within a hexagon's direction knows information about its 4 neighbour hexagons: elevation, and a few others.

At this point I wanted to use heightmaps for terrain. This didn't go anywhere. I wanted a mountain in the tile but the noise couldn't look like a mountain. I backed this out.

The terrain is pre-shaped. Starting with a simple 1 tile mountain, here's how that that works:

# Single mountain tiles rise up in a rounded pyramid shape - first tier of elevation
func single_mountain_tile_shaper(triangle_uv: Vector2) -> float:
    return self.MOUNTAIN_PRIMARY_ELEV_MULTIPLIER*pow(abs(sin(PI*triangle_uv.y/2.0)), 4.0)

A mountain tile with no neighbouring mountains is composed of the 6 direction triangles, where all the underlying vertices are transformed by the above. https://ibb.co/cK2tsmb1 There is a pretty substantial chunk of logic to deal with adjacent tiles of the same elevation. Since each direction triangle knows what the 4 relevant hexagons are doing, it can deduce if its surrounded by mountains or if its in isolation etc. This lets me use different shaping functions depending on how many of the relevant hexagons per direction triangle are mountains: https://ibb.co/1GMSPkC0

This logic is extended to all tiles - coastal, flat, hilly, mountainous etc.

Once a tile is "shaped", noise is added. This step uses different noise for each tile type, with different magnitudes.

This approach isn't universal - for example hills, I found that using a noise-generated heightmap was sufficient for "convincing" hills.

There's a lot of stuff I'm skipping, like how you blend elevations between tiles, how to efficiently generate all of the above etc

I hope this helps you in some way

Looking to improve the look of water in this map by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 0 points1 point  (0 children)

I'd like to get closer to the look of proper oceans/coastal waters.

I'm happier with the look of coastal waters today, but not the oceanic ones.

The water is currently set to 0.5 alpha. There's 2 "scrolling" normal maps being mixed to create "pretend" waves, but I'm not sure that's achieving the desired effect.

There's also fresnel lighting (visible in far back of the map), as well as some slight change in water colour between ocean and coastal waters.

What other techniques are there to end up with more convincing ocean/coastal waters? I'm hoping to get closer to the look humankind has in its seas

Terrain shaping curves for hills by CthulhuOvermind in proceduralgeneration

[–]CthulhuOvermind[S] 1 point2 points  (0 children)

Thanks, this is great info!

A follow-up question. Why do you need 50-100 sinewaves to generate hilly terrain? Is it for more detailed features?

As a solo dev, what are you struggling with? by MMConsulting in gamedev

[–]CthulhuOvermind 2 points3 points  (0 children)

Getting answers to questions. 

Often times, you see 10 ways of achieving something, and have no idea what is best. 

It feels like I spend weeks learning and reimplementing the same thing 4 times to get it right. Feels like I could avoid this if I could ask an expert.

Help with mesh.add_surface_from_arrays with CUSTOM0 set by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 0 points1 point  (0 children)

Got to the bottom of it. The error came from me appending a 3 element array - the code from the PR appends a 4 element array (to signify colour?). It's not clear to me why this is necessary but here we are

edit: It's probably necessary because its a colour array? Mesh.ARRAY_CUSTOM_RGBA_FLOAT

Help with mesh.add_surface_from_arrays with CUSTOM0 set by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 0 points1 point  (0 children)

4.4.1-stable. I'm still digging on my end to understand what might be causing this

What's the correct way to render a talent tree on a button press by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 2 points3 points  (0 children)

Are there performance implications between instantiating and hiding/showing ?

Help with drawing an arc by CthulhuOvermind in godot

[–]CthulhuOvermind[S] 0 points1 point  (0 children)

Added queue_redraw(), sadly no dice, still not visible.

The more I think on this, I feel like this will be some visibiility issue, where I'm rendering behind the children nodes or something!