Great video. At 1:45 you describe sampling the terrain normal to place decorations parallel with the normal, however plants orient themselves to gravity and point up, not sideways. Your features will appear more natural if they point towards world up, not the surface normal.
While you are correct, aligning with the normal can provide some desired stylized results. I think smaller objects (grass, bushes) look better when aligned with the terrain normal. In my implementation I added a boolean to toggle aligning a particular feature with either the terrain normal or world up. For large objects, such as the tall pine trees, aligning them perfectly vertical looks more natural indeed!
Trees point mostly upwards. In nature they can lean a bit. Some are just crooked, some point slightly away from other trees (to get more sun and less shadow), some had lose soil and tilted because of that. But details like that are easy to implement.
I care about exact detail positions. I tried several tools in unity having to do with indirect rendering. It drove me crazy if a moved or rotated, that things were not in the same position. I put effort into my density and seed, placement logic, to curate the "margin" spaces. I wanted a good look, so it doesn't distract. A curated ambience. Some tools had little interference, but conflicted in other ways, others completely changed my curation. Even though I could render and cull by offloading to GPU, limit range, number of instances, optimized meshes and materials. I could not continuously replicate the aesthetics, because it became GPU bottleneck, rather than a mix of CPU and gpu using GPU instanceing. The solution was finding a balance with aestheticlly pleasing and minimal. Alternate ways to mimic a nice ambience. Less trees, less grass, baked lighting, some dynamic lighting, juice.
Its certainly a hard problem! I love computer graphics as it combines almost all interesting parts of computer science (math, algorithms, data and parallel processing). I did not cover this, but I kind of do keep detail positions! I use a deterministic pseudorandom number function seeded with vectors that remains constant, such as vertex positions of the triangle we are currently placing features on. Moreover, I use noise based 2d masks sampled using a global-position to remove details at points where the value is under a threshold. These methods actually make it consistent enough for my needs, without having to store upwards of millions of grass positions. Also, I want to look into more GPU processing at some point, but I run nearly everything on the CPU currently as the overhead caused by memory transfer between CPU & GPU became too large. GPU collisions among other things are out of the scope of my project, which is why I rely on having mostly everything in regular RAM.
Nice dutch accent! (Very subtle though). Trees don't grow along the normal of the surface, they grow towards the sun, up. With a bit of variety :p Looking forward to see updates on this. It looks very nice, optimized and I like your approach :)
Thanks ;) Yeah true! I like aligning along the normal for smaller things like bushes and grass. More importantly, I use the normal to ensure that trees aren't placed on steep areas, I should've mentioned that!
Looks great. What I do for detail generation is check the mesh bounds height. The shorter the more it aligns with terrain normal. Taller, the more it goes toward world vertical. Lerp/Slerp makes it easy.
You may benefit from billboarding your grass if you arent already. Although the visuals are great, the pop in as you travel is very noticeable. If all the grass are models that could be a large part of the performance impact. Alternatively finding a way to populate a larger area at a time may also help with that. Good luck!
Grass billboards (can) suffer from a huge amount of overdraw, which is can slow down the engine too! I agree that the grass rendering is not optimal in its current form, I was thinking of implementing GPU frustum culling or something similar. I could also easily push the grass rendering quite a bit more, its running at around 200 to 300 FPS on my computer! It is something fun to experiment with, my terrain supports many details, and It might be interesting to use a hybrid solution to render dense and more volumetric looking grass! (I'm not sure if I have ever seen that before)
It looks a little odd to have the trees perpendicular to the terrain like that. Usually trees roughly grow straight up because of gravity and the sun, so it might look more natural to at least balance it more towards gravity while retaining some of the terrain normal. I could see how this may be an issue though if the bottom of the tree model begins rising out of the side of terrain
Do you use compute shaders for the terrain or you do it on CPU? Funnily enough I want to do the same idea, but in bevy - I want to create a community project that is similar to Terraria and that requires a lot of entities - also I found flying edges, another algorithm for extracting mesh from a scalarfield.
I don't actually! the terrain generation is executed on about 8 cpu threads. Before I played around with GPU marching cubes, with a CPU octree and CPU collisions. The primary bottleneck was memory transfer, so I decided to go for an all CPU implementation for now.
You should be able to! Unity is very powerful in its own right, and it might be easier to write high performance code thanks to the Entity Component System for instance. I aim to be as engine/tool agnostic with my techniques. For instance, nothing I covered in this video is exclusive to Godot.
I know it's more related to the firt episode of this voxel series of yours. But did you use GDextension to achieve that in Godot or did you make changes in the source code. And also did you used compute shaders or is it only relying on cpu multithreading?
The implementation is purely multithreaded c# at the moment, I have been thinking of creating a c++ gdextension but i'm honestly doubtful that it would increase performance much (i'd say at best 10 to 20%, at the cost of more difficult development)
@@thecodejar Oh I completly forgot about C# 😅 Even though I personally started my journey with gamedev with it (and Unity..) Anyway you are making good stuff and the fact that you used Godot for that is even more incredible. In UE people probably would compare something like that to others' work in asset marketplace, but since Godot have small but nice community people like you have chance to shine. So please keep doing what you feel good with ;) (Even outside of Godot)
The grass falls under the detail category I discuss in the video. The key idea is to iterate through the polygons in relevant chunks and to use pseudorandom number generators to place the grass at seemingly random but mostly deterministic positions. We can use barycentric coordinates to sample the normal and position of a point on a triangle using two numbers.
Are you sure you want trees to be alligned with the terrain normals? Shouldnt trees always be practically vertical? Maybe you could have them vertical but lean a bit towards the normal.(But not fully alligned with the terrain)
It looks nice for some smaller ones but you're right! I primarily use the normal to ensure trees do not grow on parts of the terrain that are very steep :)
I have been thinking about this! I tested out baking navigation maps in real time using Godot's native navigation mesh system, but this is slow, and slows down the game dramatically because it is not trivial to move all computations to an alternate thread. I'm thinking about creating a custom algorithm that does rough pathfinding from a larger distance to the target, and more accurate pathfinding when closer or stuck in a local minima. I will have to do more research on what's best, and also think about use cases. (many agent pathfinding could be accelerated by sharing paths, almost turning it into a dynamic programming problem)
I not understand properly how you put trees down, i'am making a game as well, but 2D one, and are struggling to make a nice looking florest like ambient, and i not understand your way to explain how you make it, but i need to study more and solve my question LOL. Godot rocks!
@viniciusschadeck4992 the core idea is the poisson disk sampling in a horizontal plane, then raycasting/raymarching from those positions down to get a position on the ground. Additionally, I use noise masks to visually group objects, as points are deleted where values in the mask are under a threshold.
@@thecodejar understood now, the key point is this poisson dis sampling, the rest is pure logic, because if you get a sky point and shot a raycast downwards it will eventually hits the ground... but this poisson disk sample are the stuff i have to learn better and implement on my code, i already did generate islands and path using seed and some code, but for trees and rocks i need other type of code, i guess is this one, because making any object placement with perlin or simplex noise are really odd, at least the way i tried LOL
Dude, rotating the assets to be orthogonal to the surface normal triggers me so hard. That's not how plants work, my guy. Please use a global up vector instead lol
Haha sorry for that ;) It's intended for smaller assets such as grass/bushes (which imo do look better this way), I otherwise primarily use the surface normal to delete assets on steep terrain.
Such a dutch person thing to make the trees align to the surface normal. Clearly never seen a tree on a mountain before haha
I thought mountains are purely fictional :)
Great video. At 1:45 you describe sampling the terrain normal to place decorations parallel with the normal, however plants orient themselves to gravity and point up, not sideways. Your features will appear more natural if they point towards world up, not the surface normal.
While you are correct, aligning with the normal can provide some desired stylized results. I think smaller objects (grass, bushes) look better when aligned with the terrain normal. In my implementation I added a boolean to toggle aligning a particular feature with either the terrain normal or world up. For large objects, such as the tall pine trees, aligning them perfectly vertical looks more natural indeed!
@@thecodejar Imo it's not just the tall pine trees, but *all* the trees, which need to be pointing upward to look normal.
@@delphicdescant Fair! I also use the normal to ensure trees don't grow on parts of the terrain that are too steep.
Trees point mostly upwards. In nature they can lean a bit. Some are just crooked, some point slightly away from other trees (to get more sun and less shadow), some had lose soil and tilted because of that.
But details like that are easy to implement.
@@sasjadevries It might be interesting to implement some more natural generation rules later :)
I care about exact detail positions.
I tried several tools in unity having to do with indirect rendering. It drove me crazy if a moved or rotated, that things were not in the same position.
I put effort into my density and seed, placement logic, to curate the "margin" spaces. I wanted a good look, so it doesn't distract. A curated ambience.
Some tools had little interference, but conflicted in other ways, others completely changed my curation.
Even though I could render and cull by offloading to GPU, limit range, number of instances, optimized meshes and materials. I could not continuously replicate the aesthetics, because it became GPU bottleneck, rather than a mix of CPU and gpu using GPU instanceing.
The solution was finding a balance with aestheticlly pleasing and minimal. Alternate ways to mimic a nice ambience. Less trees, less grass, baked lighting, some dynamic lighting, juice.
Its certainly a hard problem! I love computer graphics as it combines almost all interesting parts of computer science (math, algorithms, data and parallel processing).
I did not cover this, but I kind of do keep detail positions!
I use a deterministic pseudorandom number function seeded with vectors that remains constant, such as vertex positions of the triangle we are currently placing features on. Moreover, I use noise based 2d masks sampled using a global-position to remove details at points where the value is under a threshold.
These methods actually make it consistent enough for my needs, without having to store upwards of millions of grass positions.
Also, I want to look into more GPU processing at some point, but I run nearly everything on the CPU currently as the overhead caused by memory transfer between CPU & GPU became too large. GPU collisions among other things are out of the scope of my project, which is why I rely on having mostly everything in regular RAM.
Man its the most beautiful and best thing I have seen in Godot with C#.
Thank you!
Nice dutch accent! (Very subtle though). Trees don't grow along the normal of the surface, they grow towards the sun, up. With a bit of variety :p
Looking forward to see updates on this. It looks very nice, optimized and I like your approach :)
Thanks ;) Yeah true! I like aligning along the normal for smaller things like bushes and grass. More importantly, I use the normal to ensure that trees aren't placed on steep areas, I should've mentioned that!
Looks great. What I do for detail generation is check the mesh bounds height. The shorter the more it aligns with terrain normal. Taller, the more it goes toward world vertical. Lerp/Slerp makes it easy.
awesome idea!
It looks great, but you have to change the grass colour, different from the ground colour.
Visuals are not my priority currently but I might play around with it :)
You may benefit from billboarding your grass if you arent already. Although the visuals are great, the pop in as you travel is very noticeable. If all the grass are models that could be a large part of the performance impact. Alternatively finding a way to populate a larger area at a time may also help with that. Good luck!
Grass billboards (can) suffer from a huge amount of overdraw, which is can slow down the engine too! I agree that the grass rendering is not optimal in its current form, I was thinking of implementing GPU frustum culling or something similar. I could also easily push the grass rendering quite a bit more, its running at around 200 to 300 FPS on my computer!
It is something fun to experiment with, my terrain supports many details, and It might be interesting to use a hybrid solution to render dense and more volumetric looking grass! (I'm not sure if I have ever seen that before)
Unreal Engine 4: Trees
Unreal Engine 5: Forests
@@M.N.9 and this was made in godot 🤯
@@thecodejar!!!
It looks a little odd to have the trees perpendicular to the terrain like that. Usually trees roughly grow straight up because of gravity and the sun, so it might look more natural to at least balance it more towards gravity while retaining some of the terrain normal. I could see how this may be an issue though if the bottom of the tree model begins rising out of the side of terrain
I suppose it could be interesting to write a vertex shader to achieve this!
awesome very cool!
Do you use compute shaders for the terrain or you do it on CPU? Funnily enough I want to do the same idea, but in bevy - I want to create a community project that is similar to Terraria and that requires a lot of entities - also I found flying edges, another algorithm for extracting mesh from a scalarfield.
I don't actually! the terrain generation is executed on about 8 cpu threads. Before I played around with GPU marching cubes, with a CPU octree and CPU collisions. The primary bottleneck was memory transfer, so I decided to go for an all CPU implementation for now.
you should add bigger structures that get generated
Its on the to do list! It might take a while though :)
this is impressive
thank you :D
@@thecodejar i wish i could do this in unity 😞😞
You should be able to! Unity is very powerful in its own right, and it might be easier to write high performance code thanks to the Entity Component System for instance. I aim to be as engine/tool agnostic with my techniques. For instance, nothing I covered in this video is exclusive to Godot.
@@thecodejar ok
Lets goooo
I know it's more related to the firt episode of this voxel series of yours. But did you use GDextension to achieve that in Godot or did you make changes in the source code. And also did you used compute shaders or is it only relying on cpu multithreading?
The implementation is purely multithreaded c# at the moment, I have been thinking of creating a c++ gdextension but i'm honestly doubtful that it would increase performance much (i'd say at best 10 to 20%, at the cost of more difficult development)
@@thecodejar Oh I completly forgot about C# 😅 Even though I personally started my journey with gamedev with it (and Unity..) Anyway you are making good stuff and the fact that you used Godot for that is even more incredible. In UE people probably would compare something like that to others' work in asset marketplace, but since Godot have small but nice community people like you have chance to shine. So please keep doing what you feel good with ;) (Even outside of Godot)
How do you figure out how to place the grass to match the surface height and angle?
The grass falls under the detail category I discuss in the video. The key idea is to iterate through the polygons in relevant chunks and to use pseudorandom number generators to place the grass at seemingly random but mostly deterministic positions. We can use barycentric coordinates to sample the normal and position of a point on a triangle using two numbers.
damn! do you plan on releasing the source code?
I'm not sure yet... I think I might release (part of) it if demand is high enough :)
Are you sure you want trees to be alligned with the terrain normals?
Shouldnt trees always be practically vertical? Maybe you could have them vertical but lean a bit towards the normal.(But not fully alligned with the terrain)
It looks nice for some smaller ones but you're right! I primarily use the normal to ensure trees do not grow on parts of the terrain that are very steep :)
How would you aproach AI navigation on such a terrain?
I have been thinking about this!
I tested out baking navigation maps in real time using Godot's native navigation mesh system, but this is slow, and slows down the game dramatically because it is not trivial to move all computations to an alternate thread. I'm thinking about creating a custom algorithm that does rough pathfinding from a larger distance to the target, and more accurate pathfinding when closer or stuck in a local minima. I will have to do more research on what's best, and also think about use cases. (many agent pathfinding could be accelerated by sharing paths, almost turning it into a dynamic programming problem)
Jarjar!!??
just jar ;)
I not understand properly how you put trees down, i'am making a game as well, but 2D one, and are struggling to make a nice looking florest like ambient, and i not understand your way to explain how you make it, but i need to study more and solve my question LOL. Godot rocks!
@viniciusschadeck4992 the core idea is the poisson disk sampling in a horizontal plane, then raycasting/raymarching from those positions down to get a position on the ground. Additionally, I use noise masks to visually group objects, as points are deleted where values in the mask are under a threshold.
@@thecodejar understood now, the key point is this poisson dis sampling, the rest is pure logic, because if you get a sky point and shot a raycast downwards it will eventually hits the ground... but this poisson disk sample are the stuff i have to learn better and implement on my code, i already did generate islands and path using seed and some code, but for trees and rocks i need other type of code, i guess is this one, because making any object placement with perlin or simplex noise are really odd, at least the way i tried LOL
woah :3
wow
Can we play the demo.
I have not thought about releasing a demo! It could be fun to create one down the line :)
actually, trees should not be perpendicular to the ground. they grow vertically regardless of the angle of the slope
True! I mostly use the normal to ensure trees do not generate on steep terrain.
Dude, rotating the assets to be orthogonal to the surface normal triggers me so hard. That's not how plants work, my guy. Please use a global up vector instead lol
Haha sorry for that ;) It's intended for smaller assets such as grass/bushes (which imo do look better this way), I otherwise primarily use the surface normal to delete assets on steep terrain.
@@thecodejar Yeah makes sense. For some scatter like rocks too maybe. Plants, especially trees, do grow upwards though lol.