Skip to main content
Describe question in title
Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

Procedural Terrain How to add water material below sea level in Godotprocedural terrain?

Source Link

Procedural Terrain in Godot

I'm trying to create procedurally generated terrain, it works but it just uses simple textures. The lower area below sea level I want to add a water material instead of a simple texture. How can I achieve this? enter image description here I am using the following code to procedurally generate terrain:

class_name HTerrainGenerator # Import classes const HTerrain: Resource = preload("res://addons/zylann.hterrain/hterrain.gd") const HTerrainData: Resource = preload("res://addons/zylann.hterrain/hterrain_data.gd") const HTerrainTextureSet: Resource = preload("res://addons/zylann.hterrain/hterrain_texture_set.gd") var grass_texture: Resource = load("res://Levels/Textures/T_ground_forest_grass_03_BC_H.PNG") var sand_texture: Resource = load("res://Levels/Textures/T_ground_sand_03_BC_H.PNG") var mud_texture: Resource = load("res://Levels/Textures/t_mud_01_d_1k.PNG") var terrian_seed: int = randi_range(0, 999999999999999999) func generate_terrain() -> HTerrain: # Create terrain resource and give it a size. # It must be either 513, 1025, 2049 or 4097. var terrain_data: HTerrainData = HTerrainData.new() terrain_data.resize(513) var noise: FastNoiseLite = FastNoiseLite.new() noise.seed = terrian_seed var noise_multiplier = 10.0 # affects the height of the terrain # Get access to terrain maps var heightmap: Image = terrain_data.get_image(HTerrainData.CHANNEL_HEIGHT) var normalmap: Image = terrain_data.get_image(HTerrainData.CHANNEL_NORMAL) var splatmap: Image = terrain_data.get_image(HTerrainData.CHANNEL_SPLAT) # Generate terrain maps for z in heightmap.get_height(): for x in heightmap.get_width(): # Generate height var h = noise_multiplier * noise.get_noise_2d(x, z) # Getting normal by generating extra heights directly from noise, # so map borders won't have seams in case you stitch them var h_right = noise_multiplier * noise.get_noise_2d(x + 0.1, z) var h_forward = noise_multiplier * noise.get_noise_2d(x, z + 0.1) var normal: Vector3 = Vector3(h - h_right, 0.1, h_forward - h).normalized() # Generate texture amounts var splat: Color = splatmap.get_pixel(x, z) var slope: float = 4.0 * normal.dot(Vector3.UP) - 2.0 # Sand on the slopes the higher value the more sand shows var sand_amount: float = clamp(2.1 - slope, 0.0, 1.0) # Mud below sea level var mud_amount: float = clamp(0.0 - h, 0.0, 1.0) splat = splat.lerp(Color(0,1,0,0), sand_amount) splat = splat.lerp(Color(0,0,1,0), mud_amount) heightmap.set_pixel(x, z, Color(h, 0, 0)) normalmap.set_pixel(x, z, HTerrainData.encode_normal(normal)) splatmap.set_pixel(x, z, splat) # Commit modifications so they get uploaded to the graphics card var modified_region: Rect2 = Rect2(Vector2(), heightmap.get_size()) terrain_data.notify_region_change(modified_region, HTerrainData.CHANNEL_HEIGHT) terrain_data.notify_region_change(modified_region, HTerrainData.CHANNEL_NORMAL) terrain_data.notify_region_change(modified_region, HTerrainData.CHANNEL_SPLAT) # Create texture set var texture_set: HTerrainTextureSet = HTerrainTextureSet.new() texture_set.set_mode(HTerrainTextureSet.MODE_TEXTURES) texture_set.insert_slot(-1) texture_set.set_texture(0, HTerrainTextureSet.TYPE_ALBEDO_BUMP, grass_texture) texture_set.insert_slot(-1) texture_set.set_texture(1, HTerrainTextureSet.TYPE_ALBEDO_BUMP, sand_texture) texture_set.insert_slot(-1) texture_set.set_texture(2, HTerrainTextureSet.TYPE_ALBEDO_BUMP, mud_texture) # Create terrain node var terrain: HTerrain = HTerrain.new() terrain.set_shader_type(HTerrain.SHADER_CLASSIC4_LITE) terrain.set_data(terrain_data) terrain.set_texture_set(texture_set) terrain.position = Vector3(0, 0, 0) return terrain func reload(terrain: HTerrain): terrain.data.reload() terrain.update_collider()