Reputation: 3583
I'm working on procedural landscape in Godot 4. It works but at the moment it's just using simple textures. Below sea level I want to add a water material instead of the mud texture. How can I accomplish this?
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
Upvotes: 0
Views: 41