@@moritzfechtner5245 if it's a square plane it would be like a donut actually. It's an interesting concept and something I wish there was a tutorial on
@@stayathomedevbut it is fake water for underwater like in minecraft which you can find water in below. But you using fake water, how to make real water
If your player moves too far from the origin you will start to run into floating point errors with this system. If you want to make it truly infinite, you could make the noise tile over a long distance. Then whenever the player reaches the edge of the tile you teleport them back to the opposite edge. The player shouldn't notice because the noise there would be identical to the noise of the opposite edge. I don't know if any of this applies to your eventual implementation, but I hope this might help someone who reads this.
Very true! There's a terrain version on here that addresses that issue by doing what you propose. You could just teleport back to origin once you were at the tiling point.
Well, you only really need to tile at the overflow threshold. If you want to put unique things _really_ far out that don't repeat on a closed/looping map, you can convert the global coordinates to a local one, then add in details _relative_ to it. Floating point errors are defeated.
Absolutely incredible i followed the first tutorial for water shaders and it was awesome! but this one blew me away completely! nice work with the seams!
Awesome content! I loved the way you resolved the seams issue by averaging the values of the edges…I was looking for something similar to my terrain shader… Keep going man!
Thanks! Found that technique through terrain LODs. Once I could isolate the vertices, it made more sense. I'm sure there is a more elegant method but it worked well enough!
Thank you for your tutorials, now I know how to write shaders. This has also pushed me to figure out how gerstner waves ACTUALLY work. Basically every point of the water is moving in circles. The y component is in function of sin() and the x component is in function of cos()
In Godot 4.1.1, all the instances seem to share mesh data, so adjusting the subdivs sets them all to 0 at the end of the for loop. You need to go to the Mesh dropdown and select "Make Unique" for them all to have different subdivs That aside, I'm getting some noticeable seams between the layer 2 and layer 3 tiles, with the height changing drastically between the two layers
⚠Text version of tutorial: stayathomedev.com/tutorials/making-an-infinite-ocean-in-godot-4? ⬇Project files available for free to download at: ✅ Website - stayathomedev.com/? 📣 Twitter - twitter.com/StayAtHomeDev 🎮 Discord Server - discord.gg/dmYbvFYQRQ 💛 Patreon - patreon.com/stayathomedev
Not so sure why, but the shallow depth colour of the water is visible when viewing the ocean at a higher altitude, which only happens when there is a sea floor underneath the mesh.
I'm sure to have completely followed the tutorial, but when each tiles are created, the mesh subdivision is shared between each tile making all mesh having a 0 subdivision which is obviously not what we want. I'm not 100% sure if it is an option I missed or there has been some changes between the version of Godot you were using while making the video (4.0 beta3), and the 4.0.1 I use. I found that mesh may need to be duplicated so parameters would not be shared, probalby not the most pretty way, but after calling the instantiate method, I added that line: instance.mesh = instance.mesh.duplicate(); and it seems to have solve the issue.
The tutorial is amazing as always and it's such a great result! Unfortunately it's not working on 4.3 or anything above 4.0, I tried doing the fix by adding these lines: uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap; uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; but the shader gets really messed up and nothing is working properly. Do you think you can take a look and fix it? Thanks a lot!
// Time calculations for wave (normal map) movement vec2 time = (TIME * wave_direction) * time_scale; // Movement rate of first wave vec2 time2 = (TIME * wave_direction2) * time_scale; // Movement rate of second wave
// Blend normal maps into one vec3 normal_blend = mix(texture(texture_normal,world_pos.xz + time).rgb, texture(texture_normal2,world_pos.xz + time2).rgb, 0.5);
Hey, just a random question, but shouldn't you move said ocean by fixed steps? You don't see it now I guess, but if you stop the wave noise motion and move, your waves will be changing shape per frame even though they are technically frozen in time. PS: saw a few vids, liking the channel so far, great work :)
Thanks! Glad you are enjoying it! Possibly...the noise motion is set by world position so they would remain static if they had no underlying motion and the player moved...would look like sand or snow or something I guess...but the floating point issue the further away you are is an issue with just getting futher away from the world origin. You could teleport back if needed and had the noise matched up.
@@stayathomedev I've had that issue once with terrain. It's not as obvious on moving waves, but if you pause your world origin noise from changing, your sea will be static. However, as soon as your ship starts moving, the sea will start to shimmer. You are sampling the noise - and the position of your sample is your vertex. Because you move your ocean, you move said vertex to a different place (obviously), but you don't sample the same place again by a different vertex. You have different samples of the same noise => different mesh. You can prevent that by moving the grid so that the sampling locations won't change. As in, your ship is more than a vertex distance from the origin, so you move your grid by a vertex distance.
Just FYI the shader is outdated and does not work with Godot 4.1 despite the download page saying it does. line 98 needs to use hint_depth_texture i patched it for 4.1 but its still isn't working the tiling isn't working in my project.. when i import the standalone project it seems to work but when i try to deploy it in my project i only get one (broken) water tile.. i suspect its the grid resource isn't being read properly *shrugs*
Great tutorial. No problem making it work...standalone. I'm trying to figure it out for a headless multiplayer server...ugh...not having much success. Thoughts?
yo, if you plan to update this to godot 4.3, could you show how to render the player above the waves? like how sea of thieves or physics mod in minecraft does, they make the gpu render the player (or boat) above the waves while the cpu just see it as flat water
I want to make a game like GTA vicety with a test of gta 4 (not graphics demanding but huge place)... Right now I am makeing all of my assets and modular pack. I really want o usr godot but its doesnot have a terrain editor. so its very hard to set up a scene. How would you set up this kind of big scalable scene , specially the ground / terrain part.? (using godot 4)
@@stayathomedev I was using godot 3, where you have Hterrain plugs. which is a life saver... Like, i placed a house, then using Hterrain i can level the ground under the house... How ever godot 3 is pretty week for big scene.... Where comes godot 4 with its autolod and Ccclusion Culling and Frastam culling. How can I setup my scene, How in old day they did it... I want a proper pipeline. I am just asking... If you can show me some link or made 2-3 min video... describing just the processes. Thank you.
The center and 2nd level should have no seams. The 3rd level should not because the height effect is reduced to 0 at that distance. Check the overall scale of the system and if the distance letp is working. Can also msg on discord with a screenshot!
Would love to get buoyancy and have objects affect the water height...the ocean shader also needs some life for sure (foam, particles, better variation)
It's funny... while I could just download your water shader and infinite ocean script and call it a day... that kinda feels like cheating, so instead I will painstakingly recreate it! 😆
Your solution reminds me of this one… m.ruclips.net/video/rcsIMlet7Fw/видео.html Yours is easier to follow… it seems he snaps the player back to the center of the mesh… maybe I’m wrong? Hard to follow him. I think he does it so he doesn’t move away from the world origin… which effects accuracy.
Oh yeah @devmar is great. Moving further away from origin does affect accuracy...so if you can snap back then that works. I don't know at exactly what point that becomes an issue. I wanna say with Outer Wilds they just moved everything but the player??
there is a simpler way to avoid the gaps between the meshes. Just think in 4D. watching you stitch meshes was painful. do the largest tiles rendered on the bottom 3d layer. do not leave a gap in the middle, literally do all 9 tiles (3x3). same again for the middle tiles, do all 9 (3x3) but rendered one 3D layer on top of the larger tiles. then for your smallest tile around the player, render that on the 3D layer above the middle tiles. remember, when rendering 3D layers, the tiles are in the same 3D space, but the rendering order means the lowest 3D layer will always be rendered behind the 3D layers above it, regardless of 3D position. a simple way to think of it is like layering 2d photos of objects on top of each other. it doesn't matter how close or far each object is in the photo, the photos on top will always cover the photos underneath. i think they're called "canvas layers" in godot(?)
Understand your reasoning. Mesh stitching is pretty standard for tile based landscapes or water, etc. Though my technique may not be. The layering would work but I'd be hesitant to overdrawn unnecessarily. Though your tradeoff would be no stitching. Worth testing
As a member of the flat earth society I am offended for you not adding a icewall on the edges of the ocean. Jokes aside i find this really impressive
Thanks! Haha. No joke tho, I think a flat earth tutorial with a waterfall or something on the edges would be a great video haha
*writes that down*
maybe it wraps around like on a ball...
@@moritzfechtner5245 if it's a square plane it would be like a donut actually. It's an interesting concept and something I wish there was a tutorial on
@@stayathomedevbut it is fake water for underwater like in minecraft which you can find water in below. But you using fake water, how to make real water
If your player moves too far from the origin you will start to run into floating point errors with this system. If you want to make it truly infinite, you could make the noise tile over a long distance. Then whenever the player reaches the edge of the tile you teleport them back to the opposite edge. The player shouldn't notice because the noise there would be identical to the noise of the opposite edge. I don't know if any of this applies to your eventual implementation, but I hope this might help someone who reads this.
Very true! There's a terrain version on here that addresses that issue by doing what you propose. You could just teleport back to origin once you were at the tiling point.
Well, you only really need to tile at the overflow threshold.
If you want to put unique things _really_ far out that don't repeat on a closed/looping map, you can convert the global coordinates to a local one, then add in details _relative_ to it. Floating point errors are defeated.
Absolutely incredible i followed the first tutorial for water
shaders and it was awesome! but this one blew me away completely! nice work with the seams!
Thanks! Lot to.improve yet but progress
Awesome content! I loved the way you resolved the seams issue by averaging the values of the edges…I was looking for something similar to my terrain shader…
Keep going man!
Thanks! Found that technique through terrain LODs. Once I could isolate the vertices, it made more sense. I'm sure there is a more elegant method but it worked well enough!
This is very informative mate, amazing work.
Awesome! Glad you found it helpful. Project files are available if needed!
Thank you for your tutorials, now I know how to write shaders.
This has also pushed me to figure out how gerstner waves ACTUALLY work.
Basically every point of the water is moving in circles. The y component is in function of sin() and the x component is in function of cos()
This is super cool. Excited to see those additional waves you mentioned!
Thank you so much!! I can't believe you're making this so available for people. You're helping me realize my dream of making my own sailing game.
Secret in infinite flat words: they move with imstead of being really infinite.
Amazing tutorial, thank you! Will definitely come back to watch it again once I will be implementing the ocean.
Great! Thanks for watching!
Wow this looks really great!
Thanks!
This is awesome work!
Thanks! Lot of fun to create.
Really cool!
Thanks!
In Godot 4.1.1, all the instances seem to share mesh data, so adjusting the subdivs sets them all to 0 at the end of the for loop.
You need to go to the Mesh dropdown and select "Make Unique" for them all to have different subdivs
That aside, I'm getting some noticeable seams between the layer 2 and layer 3 tiles, with the height changing drastically between the two layers
⚠Text version of tutorial: stayathomedev.com/tutorials/making-an-infinite-ocean-in-godot-4?
⬇Project files available for free to download at:
✅ Website - stayathomedev.com/?
📣 Twitter - twitter.com/StayAtHomeDev
🎮 Discord Server - discord.gg/dmYbvFYQRQ
💛 Patreon - patreon.com/stayathomedev
Not so sure why, but the shallow depth colour of the water is visible when viewing the ocean at a higher altitude, which only happens when there is a sea floor underneath the mesh.
Worked great, the written post played a bigger role this time. But nicely done
I'm sure to have completely followed the tutorial, but when each tiles are created, the mesh subdivision is shared between each tile making all mesh having a 0 subdivision which is obviously not what we want.
I'm not 100% sure if it is an option I missed or there has been some changes between the version of Godot you were using while making the video (4.0 beta3), and the 4.0.1 I use.
I found that mesh may need to be duplicated so parameters would not be shared, probalby not the most pretty way, but after calling the instantiate method, I added that line:
instance.mesh = instance.mesh.duplicate();
and it seems to have solve the issue.
It's the duplication...they end up sharing the settings. I think i set to unique but I honestly would have to go back and check
I mean, how smart you are bro...
The tutorial is amazing as always and it's such a great result! Unfortunately it's not working on 4.3 or anything above 4.0, I tried doing the fix by adding these lines:
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
but the shader gets really messed up and nothing is working properly. Do you think you can take a look and fix it?
Thanks a lot!
I saw some tips on the previous video, here is the what I have and works well on 4.3 thanks to them.
shader_type spatial;
uniform vec3 albedo : source_color;
uniform vec3 albedo2 : source_color;
uniform float metallic : hint_range(0.0, 1.0) = 0;
uniform float roughness : hint_range(0.0, 1.0) = 0.02;
uniform sampler2D wave;
uniform sampler2D texture_normal;
uniform sampler2D texture_normal2;
uniform vec2 wave_direction = vec2(2.0,0.0); // Direction of wave 1
uniform vec2 wave_direction2 = vec2(0.0,1.0); // Direction of wave 2
uniform float time_scale : hint_range(0.0, 0.2, 0.005) = 0.025; // Rate of movement multiplied by TIME
uniform float noise_scale = 10.0;
uniform float height_scale = 0.15;
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap; // Fixes the DEPTH_TEXTURE error
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; // Fixes the SCREEN_TEXTURE error
uniform vec4 color_deep : source_color;
uniform vec4 color_shallow : source_color;
uniform float beers_law = 2.0; // Beer's law = attenuation of light
uniform float depth_offset = -0.75;
uniform float edge_scale = 0.1;
uniform float near = 1.0;
uniform float far = 100.0;
uniform vec3 edge_color : source_color;
// Varying variables
varying float height;
varying vec3 world_pos;
float fresnel(float amount, vec3 normal, vec3 view)
{
return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0 )), amount);
}
float edge(float depth){
depth = 1.0 - 2.0 * depth;
return near * far / (far + depth * (near - far));
}
void vertex() {
world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
height = texture(wave, world_pos.xz / noise_scale + TIME * time_scale).r;
VERTEX.y += height * height_scale;
}
void fragment() {
// Depth variables and calc
float depth_texture_x = texture(DEPTH_TEXTURE, SCREEN_UV).x;
vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth_texture_x);
vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view.xyz /= view.w;
float depth_blend = exp((-view.z+VERTEX.z + depth_offset) * -beers_law);
depth_blend = clamp(1.0 - depth_blend, 0.0, 1.0);
float depth_blend_power = clamp(pow(depth_blend, 2.5), 0.0, 1.0);
// Retrieving depth color and applying the deep and shallow colors
vec3 screen_color = textureLod(SCREEN_TEXTURE, SCREEN_UV, depth_blend_power * 2.5).rgb;
vec3 depth_color = mix(color_shallow.rgb, color_deep.rgb, depth_blend_power);
vec3 color = mix(screen_color * depth_color, depth_color * 0.25, depth_blend_power * 0.5);
// Getting edge depth calc
float z_depth = edge(texture(DEPTH_TEXTURE, SCREEN_UV).x);
float z_pos = edge(FRAGCOORD.z);
float z_dif = z_depth - z_pos;
// Time calculations for wave (normal map) movement
vec2 time = (TIME * wave_direction) * time_scale; // Movement rate of first wave
vec2 time2 = (TIME * wave_direction2) * time_scale; // Movement rate of second wave
// Blend normal maps into one
vec3 normal_blend = mix(texture(texture_normal,world_pos.xz + time).rgb, texture(texture_normal2,world_pos.xz + time2).rgb, 0.5);
// Calculate Fresnel
float fresnel = fresnel(5.0, NORMAL, VIEW);
vec3 surface_color = mix(albedo, albedo2, fresnel); // Interpolate albedo values by frensel
vec3 depth_color_adj = mix(edge_color, color, step(edge_scale, z_dif));
ALBEDO = clamp(surface_color + depth_color_adj,vec3(0.0),vec3(1.0));
METALLIC = metallic;
ROUGHNESS = roughness;
NORMAL_MAP = normal_blend;
}
Hey, just a random question, but shouldn't you move said ocean by fixed steps? You don't see it now I guess, but if you stop the wave noise motion and move, your waves will be changing shape per frame even though they are technically frozen in time.
PS: saw a few vids, liking the channel so far, great work :)
Thanks! Glad you are enjoying it!
Possibly...the noise motion is set by world position so they would remain static if they had no underlying motion and the player moved...would look like sand or snow or something I guess...but the floating point issue the further away you are is an issue with just getting futher away from the world origin. You could teleport back if needed and had the noise matched up.
@@stayathomedev I've had that issue once with terrain. It's not as obvious on moving waves, but if you pause your world origin noise from changing, your sea will be static. However, as soon as your ship starts moving, the sea will start to shimmer.
You are sampling the noise - and the position of your sample is your vertex. Because you move your ocean, you move said vertex to a different place (obviously), but you don't sample the same place again by a different vertex. You have different samples of the same noise => different mesh.
You can prevent that by moving the grid so that the sampling locations won't change. As in, your ship is more than a vertex distance from the origin, so you move your grid by a vertex distance.
what if for LOD, you project a subdivided quad from the camera to the y=0 plane instead of using LOD based on spatial distance?
Just FYI the shader is outdated and does not work with Godot 4.1 despite the download page saying it does. line 98 needs to use hint_depth_texture i patched it for 4.1 but its still isn't working the tiling isn't working in my project.. when i import the standalone project it seems
to work but when i try to deploy it in my project i only get one (broken) water tile.. i suspect its the grid resource isn't being read properly *shrugs*
Same. Please update...
Great tutorial. No problem making it work...standalone. I'm trying to figure it out for a headless multiplayer server...ugh...not having much success. Thoughts?
Please port it to 4.2.2 version...
yo, if you plan to update this to godot 4.3, could you show how to render the player above the waves? like how sea of thieves or physics mod in minecraft does, they make the gpu render the player (or boat) above the waves while the cpu just see it as flat water
I want to make a game like GTA vicety with a test of gta 4 (not graphics demanding but huge place)... Right now I am makeing all of my assets and modular pack. I really want o usr godot but its doesnot have a terrain editor. so its very hard to set up a scene.
How would you set up this kind of big scalable scene , specially the ground / terrain part.? (using godot 4)
It would take some work...but doable. You essentially need to chunk your map so it loads as needed.
@@stayathomedev I was using godot 3, where you have Hterrain plugs. which is a life saver... Like, i placed a house, then using Hterrain i can level the ground under the house... How ever godot 3 is pretty week for big scene.... Where comes godot 4 with its autolod and Ccclusion Culling and Frastam culling.
How can I setup my scene, How in old day they did it... I want a proper pipeline.
I am just asking... If you can show me some link or made 2-3 min video... describing just the processes. Thank you.
What program do you use to make the animations of the video? Can godot be used for that?
Hi, tell me how to apply water to a spherical world, for example Voxel planet
I downlaoded this project but the sea is just grey. No waves. What am I missing? (The files have no instructions)
What version of Godot are you using? The water shader may need to updated with the new DEPTH_TEXTURE code
I'm still getting a noticeable seam between meshes,
The center and 2nd level should have no seams. The 3rd level should not because the height effect is reduced to 0 at that distance. Check the overall scale of the system and if the distance letp is working. Can also msg on discord with a screenshot!
bro is going to create sea of thieves 2
Hello
I want to make car simulator game with realstic graphics
Which engine is good unity unreal or godot plz sugest
Te recomiendo unreal engine pero es muy duro de aprender es mejor que lo hagas en godot por qué en unity las políticas de privacidad son muy malas
The problem now is the physics I guess
Would love to get buoyancy and have objects affect the water height...the ocean shader also needs some life for sure (foam, particles, better variation)
🌊🌊🌊♥🌊🌊🌊
need boats ,ripple , buoyant effect , etch,,,,,,,,,,,,,,
What about collisions
PS: not necessarily collisions, you can do anything to objects in order to simulate the water
Like buoyancy?
@@stayathomedev yeah, exactly.
Like this one : ruclips.net/video/_R2KDcAp1YQ/видео.html
It's funny... while I could just download your water shader and infinite ocean script and call it a day... that kinda feels like cheating, so instead I will painstakingly recreate it! 😆
Your solution reminds me of this one… m.ruclips.net/video/rcsIMlet7Fw/видео.html
Yours is easier to follow… it seems he snaps the player back to the center of the mesh… maybe I’m wrong? Hard to follow him. I think he does it so he doesn’t move away from the world origin… which effects accuracy.
Oh yeah @devmar is great. Moving further away from origin does affect accuracy...so if you can snap back then that works. I don't know at exactly what point that becomes an issue. I wanna say with Outer Wilds they just moved everything but the player??
there is a simpler way to avoid the gaps between the meshes. Just think in 4D. watching you stitch meshes was painful.
do the largest tiles rendered on the bottom 3d layer. do not leave a gap in the middle, literally do all 9 tiles (3x3).
same again for the middle tiles, do all 9 (3x3) but rendered one 3D layer on top of the larger tiles.
then for your smallest tile around the player, render that on the 3D layer above the middle tiles.
remember, when rendering 3D layers, the tiles are in the same 3D space, but the rendering order means the lowest 3D layer will always be rendered behind the 3D layers above it, regardless of 3D position. a simple way to think of it is like layering 2d photos of objects on top of each other. it doesn't matter how close or far each object is in the photo, the photos on top will always cover the photos underneath.
i think they're called "canvas layers" in godot(?)
Understand your reasoning. Mesh stitching is pretty standard for tile based landscapes or water, etc. Though my technique may not be. The layering would work but I'd be hesitant to overdrawn unnecessarily. Though your tradeoff would be no stitching. Worth testing
Great tutorial. Could do without the jazz