feat: scale village queries and enrich Jajce center

This commit is contained in:
Rijad Zuzo
2026-07-16 23:51:08 +02:00
parent 4be72639d8
commit 2c88ed6ea8
48 changed files with 2059 additions and 280 deletions
+69 -19
View File
@@ -1,33 +1,83 @@
[gd_scene load_steps=5 format=3]
[gd_scene load_steps=9 format=3]
[sub_resource type="StandardMaterial3D" id="Material_deck"]
albedo_color = Color(0.62, 0.55, 0.44, 1)
roughness = 0.8
albedo_color = Color(0.61, 0.53, 0.42, 1)
roughness = 0.94
[sub_resource type="BoxMesh" id="Mesh_deck"]
material = SubResource("Material_deck")
size = Vector3(8, 0.2, 3)
size = Vector3(15.2, 0.32, 3.15)
[sub_resource type="StandardMaterial3D" id="Material_support"]
albedo_color = Color(0.45, 0.42, 0.38, 1)
roughness = 0.85
[sub_resource type="StandardMaterial3D" id="Material_stone"]
albedo_color = Color(0.48, 0.47, 0.41, 1)
roughness = 0.98
[sub_resource type="CylinderMesh" id="Mesh_support"]
material = SubResource("Material_support")
top_radius = 0.2
bottom_radius = 0.2
height = 1.0
[sub_resource type="BoxMesh" id="Mesh_abutment"]
material = SubResource("Material_stone")
size = Vector3(2.25, 1.45, 4.2)
[sub_resource type="BoxMesh" id="Mesh_pier"]
material = SubResource("Material_stone")
size = Vector3(1.05, 1.65, 3.7)
[sub_resource type="StandardMaterial3D" id="Material_rail"]
albedo_color = Color(0.2, 0.115, 0.055, 1)
roughness = 0.92
[sub_resource type="BoxMesh" id="Mesh_rail"]
material = SubResource("Material_rail")
size = Vector3(15.0, 0.16, 0.16)
[sub_resource type="BoxMesh" id="Mesh_post"]
material = SubResource("Material_rail")
size = Vector3(0.18, 1.25, 0.18)
[node name="BridgeBlockout" type="Node3D"]
[node name="Deck" type="MeshInstance3D" parent="."]
position = Vector3(0, 0.6, 0)
position = Vector3(0, 1.08, 0)
mesh = SubResource("Mesh_deck")
[node name="SupportL" type="MeshInstance3D" parent="."]
position = Vector3(-3.2, 0, 0)
mesh = SubResource("Mesh_support")
[node name="WestAbutment" type="MeshInstance3D" parent="."]
position = Vector3(-6.75, 0.15, 0)
mesh = SubResource("Mesh_abutment")
[node name="SupportR" type="MeshInstance3D" parent="."]
position = Vector3(3.2, 0, 0)
mesh = SubResource("Mesh_support")
[node name="EastAbutment" type="MeshInstance3D" parent="."]
position = Vector3(6.75, 0.15, 0)
mesh = SubResource("Mesh_abutment")
[node name="CenterPier" type="MeshInstance3D" parent="."]
position = Vector3(0, 0.05, 0)
mesh = SubResource("Mesh_pier")
[node name="NorthRail" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.76, -1.45)
mesh = SubResource("Mesh_rail")
[node name="SouthRail" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.76, 1.45)
mesh = SubResource("Mesh_rail")
[node name="PostNorthWest" type="MeshInstance3D" parent="."]
position = Vector3(-6.1, 1.48, -1.45)
mesh = SubResource("Mesh_post")
[node name="PostNorthCenter" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.48, -1.45)
mesh = SubResource("Mesh_post")
[node name="PostNorthEast" type="MeshInstance3D" parent="."]
position = Vector3(6.1, 1.48, -1.45)
mesh = SubResource("Mesh_post")
[node name="PostSouthWest" type="MeshInstance3D" parent="."]
position = Vector3(-6.1, 1.48, 1.45)
mesh = SubResource("Mesh_post")
[node name="PostSouthCenter" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.48, 1.45)
mesh = SubResource("Mesh_post")
[node name="PostSouthEast" type="MeshInstance3D" parent="."]
position = Vector3(6.1, 1.48, 1.45)
mesh = SubResource("Mesh_post")
+34
View File
@@ -0,0 +1,34 @@
extends Node3D
@export var orbit_radius := 1.2
@export var orbit_speed := 0.45
@export var bob_height := 0.35
@export var phase := 0.0
@onready var left_wing: MeshInstance3D = $LeftWing
@onready var right_wing: MeshInstance3D = $RightWing
var _center := Vector3.ZERO
var _elapsed := 0.0
func _ready() -> void:
_center = position
_elapsed = phase
func _process(delta: float) -> void:
_elapsed += delta
var angle := _elapsed * orbit_speed
position = (
_center
+ Vector3(
cos(angle) * orbit_radius,
sin(_elapsed * 1.7) * bob_height,
sin(angle) * orbit_radius * 0.65
)
)
rotation.y = -angle + PI * 0.5
var flap := 22.0 + sin(_elapsed * 10.0) * 34.0
left_wing.rotation_degrees.z = flap
right_wing.rotation_degrees.z = -flap
+1
View File
@@ -0,0 +1 @@
uid://di3mr7j4bdna3
+45
View File
@@ -0,0 +1,45 @@
[gd_scene load_steps=6 format=3]
[ext_resource type="Script" path="res://world/jajce/CozyButterfly.gd" id="1_script"]
[sub_resource type="StandardMaterial3D" id="Material_body"]
albedo_color = Color(0.18, 0.1, 0.06, 1)
roughness = 0.85
[sub_resource type="CapsuleMesh" id="Mesh_body"]
material = SubResource("Material_body")
radius = 0.08
height = 0.42
radial_segments = 8
rings = 3
[sub_resource type="StandardMaterial3D" id="Material_wing"]
albedo_color = Color(0.94, 0.53, 0.19, 1)
roughness = 0.72
emission_enabled = true
emission = Color(0.32, 0.08, 0.01, 1)
emission_energy_multiplier = 0.18
[sub_resource type="SphereMesh" id="Mesh_wing"]
material = SubResource("Material_wing")
radius = 0.42
height = 0.7
radial_segments = 12
rings = 6
[node name="CozyButterfly" type="Node3D"]
script = ExtResource("1_script")
[node name="Body" type="MeshInstance3D" parent="."]
rotation_degrees = Vector3(90, 0, 0)
mesh = SubResource("Mesh_body")
[node name="LeftWing" type="MeshInstance3D" parent="."]
position = Vector3(-0.3, 0, 0)
scale = Vector3(1, 0.12, 0.72)
mesh = SubResource("Mesh_wing")
[node name="RightWing" type="MeshInstance3D" parent="."]
position = Vector3(0.3, 0, 0)
scale = Vector3(1, 0.12, 0.72)
mesh = SubResource("Mesh_wing")
+189 -70
View File
@@ -1,119 +1,238 @@
[gd_scene load_steps=12 format=3]
[gd_scene load_steps=19 format=3]
[sub_resource type="StandardMaterial3D" id="Material_keep"]
albedo_color = Color(0.45, 0.42, 0.38, 1)
roughness = 0.85
[sub_resource type="StandardMaterial3D" id="Material_rock"]
albedo_color = Color(0.25, 0.27, 0.24, 1)
roughness = 1.0
[sub_resource type="CylinderMesh" id="Mesh_rock_plinth"]
material = SubResource("Material_rock")
top_radius = 8.4
bottom_radius = 10.2
height = 3.2
radial_segments = 9
[sub_resource type="StandardMaterial3D" id="Material_stone"]
albedo_color = Color(0.47, 0.47, 0.43, 1)
roughness = 0.96
[sub_resource type="StandardMaterial3D" id="Material_stone_light"]
albedo_color = Color(0.57, 0.56, 0.51, 1)
roughness = 0.95
[sub_resource type="BoxMesh" id="Mesh_keep"]
material = SubResource("Material_keep")
size = Vector3(7, 6, 9)
material = SubResource("Material_stone_light")
size = Vector3(7.4, 7.8, 8.6)
[sub_resource type="StandardMaterial3D" id="Material_parapet"]
albedo_color = Color(0.42, 0.39, 0.35, 1)
roughness = 0.85
[sub_resource type="BoxMesh" id="Mesh_wall_long"]
material = SubResource("Material_stone")
size = Vector3(13.8, 3.3, 1.15)
[sub_resource type="BoxMesh" id="Mesh_parapet"]
material = SubResource("Material_parapet")
size = Vector3(6.6, 1.5, 7.8)
[sub_resource type="BoxMesh" id="Mesh_wall_short"]
material = SubResource("Material_stone")
size = Vector3(1.15, 3.3, 11.8)
[sub_resource type="StandardMaterial3D" id="Material_turret"]
albedo_color = Color(0.45, 0.42, 0.38, 1)
roughness = 0.85
[sub_resource type="CylinderMesh" id="Mesh_tower"]
material = SubResource("Material_stone_light")
top_radius = 1.65
bottom_radius = 1.95
height = 6.0
radial_segments = 10
[sub_resource type="CylinderMesh" id="Mesh_turret"]
material = SubResource("Material_turret")
top_radius = 0.6
bottom_radius = 0.7
height = 4.0
[sub_resource type="CylinderMesh" id="Mesh_tower_cap"]
material = SubResource("Material_stone")
top_radius = 1.9
bottom_radius = 1.9
height = 0.65
radial_segments = 10
[sub_resource type="BoxMesh" id="Mesh_crenellation"]
material = SubResource("Material_parapet")
size = Vector3(0.55, 0.9, 0.7)
material = SubResource("Material_stone_light")
size = Vector3(0.72, 0.92, 0.82)
[sub_resource type="StandardMaterial3D" id="Material_pole"]
albedo_color = Color(0.24, 0.13, 0.07, 1)
roughness = 0.82
[sub_resource type="BoxMesh" id="Mesh_gate_post"]
material = SubResource("Material_stone_light")
size = Vector3(1.25, 3.7, 1.7)
[sub_resource type="BoxMesh" id="Mesh_gate_lintel"]
material = SubResource("Material_stone_light")
size = Vector3(4.6, 1.05, 1.7)
[sub_resource type="StandardMaterial3D" id="Material_gate"]
albedo_color = Color(0.18, 0.11, 0.065, 1)
roughness = 0.9
[sub_resource type="BoxMesh" id="Mesh_gate"]
material = SubResource("Material_gate")
size = Vector3(2.2, 2.8, 0.22)
[sub_resource type="CylinderMesh" id="Mesh_pole"]
material = SubResource("Material_pole")
top_radius = 0.08
bottom_radius = 0.1
height = 3.5
material = SubResource("Material_gate")
top_radius = 0.07
bottom_radius = 0.09
height = 4.2
radial_segments = 8
[sub_resource type="StandardMaterial3D" id="Material_banner"]
albedo_color = Color(0.68, 0.12, 0.1, 1)
roughness = 0.65
albedo_color = Color(0.58, 0.1, 0.08, 1)
roughness = 0.76
[sub_resource type="BoxMesh" id="Mesh_banner"]
material = SubResource("Material_banner")
size = Vector3(0.14, 2.0, 1.25)
size = Vector3(0.12, 2.2, 1.35)
[sub_resource type="StandardMaterial3D" id="Material_window_slit"]
albedo_color = Color(0.12, 0.14, 0.13, 1)
roughness = 0.98
[sub_resource type="BoxMesh" id="Mesh_window_slit"]
material = SubResource("Material_window_slit")
size = Vector3(0.38, 1.25, 0.14)
[node name="FortressBlockout" type="Node3D"]
[node name="Keep" type="MeshInstance3D" parent="."]
position = Vector3(0, 3, 0)
[node name="RockyCitadelHill" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.35, 0)
scale = Vector3(1.22, 1, 1)
mesh = SubResource("Mesh_rock_plinth")
[node name="CitadelKeep" type="MeshInstance3D" parent="."]
position = Vector3(-0.8, 7.05, 0.35)
rotation_degrees = Vector3(0, -4, 0)
mesh = SubResource("Mesh_keep")
[node name="Parapet" type="MeshInstance3D" parent="."]
position = Vector3(0, 6.75, 0)
mesh = SubResource("Mesh_parapet")
[node name="KeepWindowSouthLeft" type="MeshInstance3D" parent="."]
position = Vector3(-2.55, 7.0, 4.72)
rotation_degrees = Vector3(0, -4, 0)
mesh = SubResource("Mesh_window_slit")
[node name="Crenellation_01" type="MeshInstance3D" parent="."]
position = Vector3(-2.8, 7.7, -3.1)
[node name="KeepWindowSouthRight" type="MeshInstance3D" parent="."]
position = Vector3(0.85, 7.0, 4.72)
rotation_degrees = Vector3(0, -4, 0)
mesh = SubResource("Mesh_window_slit")
[node name="KeepWindowEast" type="MeshInstance3D" parent="."]
position = Vector3(2.95, 7.45, 1.45)
rotation_degrees = Vector3(0, 86, 0)
mesh = SubResource("Mesh_window_slit")
[node name="NorthRampart" type="MeshInstance3D" parent="."]
position = Vector3(0, 4.05, -5.55)
rotation_degrees = Vector3(0, -2, 0)
mesh = SubResource("Mesh_wall_long")
[node name="SouthRampart" type="MeshInstance3D" parent="."]
position = Vector3(-1.1, 4.0, 5.75)
rotation_degrees = Vector3(0, 4, 0)
mesh = SubResource("Mesh_wall_long")
[node name="WestRampart" type="MeshInstance3D" parent="."]
position = Vector3(-6.55, 4.0, 0)
mesh = SubResource("Mesh_wall_short")
[node name="EastRampart" type="MeshInstance3D" parent="."]
position = Vector3(6.55, 4.0, 0)
mesh = SubResource("Mesh_wall_short")
[node name="DescendingWallEast" type="MeshInstance3D" parent="."]
position = Vector3(9.5, 2.8, 2.7)
rotation_degrees = Vector3(0, 23, -7)
scale = Vector3(0.65, 0.7, 1)
mesh = SubResource("Mesh_wall_short")
[node name="DescendingWallSouth" type="MeshInstance3D" parent="."]
position = Vector3(4.8, 2.7, 8.1)
rotation_degrees = Vector3(0, 38, 5)
scale = Vector3(0.72, 0.7, 1)
mesh = SubResource("Mesh_wall_short")
[node name="TowerNorthWest" type="MeshInstance3D" parent="."]
position = Vector3(-6.5, 4.2, -5.5)
mesh = SubResource("Mesh_tower")
[node name="TowerNorthWestCap" type="MeshInstance3D" parent="."]
position = Vector3(-6.5, 7.28, -5.5)
mesh = SubResource("Mesh_tower_cap")
[node name="TowerNorthEast" type="MeshInstance3D" parent="."]
position = Vector3(6.5, 4.2, -5.5)
mesh = SubResource("Mesh_tower")
[node name="TowerNorthEastCap" type="MeshInstance3D" parent="."]
position = Vector3(6.5, 7.28, -5.5)
mesh = SubResource("Mesh_tower_cap")
[node name="TowerSouthWest" type="MeshInstance3D" parent="."]
position = Vector3(-6.5, 4.2, 5.5)
mesh = SubResource("Mesh_tower")
[node name="TowerSouthWestCap" type="MeshInstance3D" parent="."]
position = Vector3(-6.5, 7.28, 5.5)
mesh = SubResource("Mesh_tower_cap")
[node name="GatePostLeft" type="MeshInstance3D" parent="."]
position = Vector3(4.45, 4.1, 5.62)
mesh = SubResource("Mesh_gate_post")
[node name="GatePostRight" type="MeshInstance3D" parent="."]
position = Vector3(7.15, 4.1, 5.62)
mesh = SubResource("Mesh_gate_post")
[node name="GateLintel" type="MeshInstance3D" parent="."]
position = Vector3(5.8, 6.35, 5.62)
mesh = SubResource("Mesh_gate_lintel")
[node name="GateDoor" type="MeshInstance3D" parent="."]
position = Vector3(5.8, 3.65, 6.22)
mesh = SubResource("Mesh_gate")
[node name="CrenellationNorth01" type="MeshInstance3D" parent="."]
position = Vector3(-5.2, 6.12, -5.55)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_02" type="MeshInstance3D" parent="."]
position = Vector3(-1.4, 7.7, -3.1)
[node name="CrenellationNorth02" type="MeshInstance3D" parent="."]
position = Vector3(-2.6, 6.12, -5.55)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_03" type="MeshInstance3D" parent="."]
position = Vector3(0, 7.7, -3.1)
[node name="CrenellationNorth03" type="MeshInstance3D" parent="."]
position = Vector3(0, 6.12, -5.55)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_04" type="MeshInstance3D" parent="."]
position = Vector3(1.4, 7.7, -3.1)
[node name="CrenellationNorth04" type="MeshInstance3D" parent="."]
position = Vector3(2.6, 6.12, -5.55)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_05" type="MeshInstance3D" parent="."]
position = Vector3(2.8, 7.7, -3.1)
[node name="CrenellationNorth05" type="MeshInstance3D" parent="."]
position = Vector3(5.2, 6.12, -5.55)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_06" type="MeshInstance3D" parent="."]
position = Vector3(-2.8, 7.7, 3.1)
[node name="CrenellationSouth01" type="MeshInstance3D" parent="."]
position = Vector3(-5.2, 6.08, 5.75)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_07" type="MeshInstance3D" parent="."]
position = Vector3(-1.4, 7.7, 3.1)
[node name="CrenellationSouth02" type="MeshInstance3D" parent="."]
position = Vector3(-2.6, 6.08, 5.75)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_08" type="MeshInstance3D" parent="."]
position = Vector3(0, 7.7, 3.1)
[node name="CrenellationSouth03" type="MeshInstance3D" parent="."]
position = Vector3(0, 6.08, 5.75)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_09" type="MeshInstance3D" parent="."]
position = Vector3(1.4, 7.7, 3.1)
[node name="KeepCrenellationLeft" type="MeshInstance3D" parent="."]
position = Vector3(-3.5, 11.35, 3.8)
mesh = SubResource("Mesh_crenellation")
[node name="Crenellation_10" type="MeshInstance3D" parent="."]
position = Vector3(2.8, 7.7, 3.1)
[node name="KeepCrenellationCenter" type="MeshInstance3D" parent="."]
position = Vector3(-0.8, 11.35, 3.8)
mesh = SubResource("Mesh_crenellation")
[node name="Turret_A" type="MeshInstance3D" parent="."]
position = Vector3(-3.2, 2.0, -4)
mesh = SubResource("Mesh_turret")
[node name="Turret_B" type="MeshInstance3D" parent="."]
position = Vector3(3.2, 2.0, -4)
mesh = SubResource("Mesh_turret")
[node name="Turret_C" type="MeshInstance3D" parent="."]
position = Vector3(3.2, 2.0, 4)
mesh = SubResource("Mesh_turret")
[node name="KeepCrenellationRight" type="MeshInstance3D" parent="."]
position = Vector3(1.9, 11.35, 3.8)
mesh = SubResource("Mesh_crenellation")
[node name="RidgeBannerPole" type="MeshInstance3D" parent="."]
position = Vector3(0, 8.4, 3.8)
position = Vector3(-0.8, 13.1, 3.45)
mesh = SubResource("Mesh_pole")
[node name="RidgeBanner" type="MeshInstance3D" parent="."]
position = Vector3(0, 9.2, 4.45)
position = Vector3(-0.8, 13.75, 4.12)
mesh = SubResource("Mesh_banner")
+51
View File
@@ -0,0 +1,51 @@
extends Node
const SHADER_INTERACTOR_LIMIT := 8
@export var grass_material: ShaderMaterial
@export_range(1, SHADER_INTERACTOR_LIMIT, 1) var max_interactors := 8
@export_range(0.02, 0.5, 0.01) var update_interval := 0.08
var _elapsed := 0.0
func _ready() -> void:
_refresh_interactors()
func _process(delta: float) -> void:
_elapsed += delta
if _elapsed < update_interval:
return
_elapsed = 0.0
_refresh_interactors()
func _refresh_interactors() -> void:
if grass_material == null:
return
var camera := get_viewport().get_camera_3d()
var origin := camera.global_position if camera != null else Vector3.ZERO
var nearest: Array[Node3D] = []
for value in get_tree().get_nodes_in_group("grass_interactors"):
var candidate := value as Node3D
if candidate == null:
continue
var insert_at := nearest.size()
var candidate_distance := origin.distance_squared_to(candidate.global_position)
for index in nearest.size():
if candidate_distance < origin.distance_squared_to(nearest[index].global_position):
insert_at = index
break
nearest.insert(insert_at, candidate)
if nearest.size() > max_interactors:
nearest.pop_back()
var positions := PackedVector3Array()
positions.resize(SHADER_INTERACTOR_LIMIT)
for index in SHADER_INTERACTOR_LIMIT:
positions[index] = Vector3(0.0, -1000.0, 0.0)
for index in nearest.size():
positions[index] = nearest[index].global_position
grass_material.set_shader_parameter("interactor_count", nearest.size())
grass_material.set_shader_parameter("interactor_positions", positions)
@@ -0,0 +1 @@
uid://3py86vi5qjwy
+123 -6
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=50 format=3]
[gd_scene load_steps=57 format=3]
[ext_resource type="Terrain3DAssets" path="res://terrain/jajce/assets.tres" id="1_assets"]
[ext_resource type="PackedScene" path="res://world/resource_nodes/ResourceNode.tscn" id="2_resource"]
@@ -18,6 +18,13 @@
[ext_resource type="NavigationMesh" path="res://world/jajce/JajceNavigationMesh.tres" id="16_nav"]
[ext_resource type="PackedScene" path="res://world/jajce/vfx/WindGustField.tscn" id="17_wind_gust"]
[ext_resource type="Script" path="res://world/storage/PantryStockVisual.gd" id="18_pantry_visual"]
[ext_resource type="PackedScene" path="res://addons/terrain_3d/extras/particle_example/Terrain3DParticles.tscn" id="19_terrain_particles"]
[ext_resource type="Material" path="res://world/jajce/materials/cozy_grass_material.tres" id="20_grass_material"]
[ext_resource type="Script" path="res://world/jajce/GrassInteractionController.gd" id="21_grass_controller"]
[ext_resource type="PackedScene" path="res://assets/foliage/tree.glb" id="22_conifer"]
[ext_resource type="PackedScene" path="res://assets/foliage/tree-high.glb" id="23_conifer_high"]
[ext_resource type="PackedScene" path="res://world/jajce/CozyButterfly.tscn" id="24_butterfly"]
[ext_resource type="Material" path="res://world/jajce/materials/cozy_grass_process_material.tres" id="25_grass_process"]
[sub_resource type="Terrain3DMaterial" id="Terrain3DMaterial_jajce"]
_shader_parameters = {
@@ -193,16 +200,16 @@ fog_height_density = 0.08
fog_aerial_perspective = 0.35
fog_sky_affect = 0.28
volumetric_fog_enabled = true
volumetric_fog_density = 0.006
volumetric_fog_albedo = Color(0.94, 0.88, 0.75, 1)
volumetric_fog_emission = Color(0.1, 0.07, 0.04, 1)
volumetric_fog_emission_energy = 0.22
volumetric_fog_density = 0.0035
volumetric_fog_albedo = Color(0.82, 0.9, 0.82, 1)
volumetric_fog_emission = Color(0.06, 0.09, 0.07, 1)
volumetric_fog_emission_energy = 0.12
volumetric_fog_length = 96.0
volumetric_fog_detail_spread = 1.6
adjustment_enabled = true
adjustment_brightness = 1.08
adjustment_contrast = 1.04
adjustment_saturation = 1.25
adjustment_saturation = 1.08
[sub_resource type="StandardMaterial3D" id="Material_guard"]
albedo_color = Color(0.55, 0.45, 0.35, 1)
@@ -246,10 +253,28 @@ collision_mask = 3
collision_mode = 1
top_level = true
[node name="CozyGrassField" parent="TerrainRoot/Terrain3D" instance=ExtResource("19_terrain_particles")]
instance_spacing = 0.703125
cell_width = 24.0
grid_width = 3
rows = 34
amount = 1156
process_fixed_fps = 24
process_material = ExtResource("25_grass_process")
shadow_mode = 0
mesh_material_override = ExtResource("20_grass_material")
min_draw_distance = 36.0
particle_count = 10404
[node name="GrassInteractionController" type="Node" parent="TerrainRoot"]
script = ExtResource("21_grass_controller")
grass_material = ExtResource("20_grass_material")
[node name="FortressBlockout" type="Node3D" parent="."]
position = Vector3(-25, 7, 9)
[node name="Keep" parent="FortressBlockout" instance=ExtResource("5_fortress")]
scale = Vector3(1.06, 1.06, 1.06)
[node name="WaterRoot" type="Node3D" parent="."]
@@ -263,22 +288,58 @@ position = Vector3(-25, 7, 9)
[node name="House_01" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-15, 2, 7)
rotation_degrees = Vector3(0, 8, 0)
[node name="Smoke" parent="VillageRoot/House_01" instance=ExtResource("12_smoke")]
position = Vector3(0, 4.5, 0)
[node name="House_02" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-8, 2, 2)
rotation_degrees = Vector3(0, -12, 0)
scale = Vector3(0.92, 0.92, 0.92)
[node name="Smoke" parent="VillageRoot/House_02" instance=ExtResource("12_smoke")]
position = Vector3(0, 4.5, 0)
[node name="House_03" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-15, 2, -4)
rotation_degrees = Vector3(0, 18, 0)
scale = Vector3(0.88, 0.88, 0.88)
[node name="Smoke" parent="VillageRoot/House_03" instance=ExtResource("12_smoke")]
position = Vector3(0, 4.5, 0)
[node name="House_04" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-19, 0, 15)
rotation_degrees = Vector3(0, -19, 0)
scale = Vector3(0.82, 0.82, 0.82)
[node name="Smoke" parent="VillageRoot/House_04" instance=ExtResource("12_smoke")]
position = Vector3(0, 4.5, 0)
[node name="House_05" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-10, 0, 13)
rotation_degrees = Vector3(0, 15, 0)
scale = Vector3(0.76, 0.76, 0.76)
[node name="Smoke" parent="VillageRoot/House_05" instance=ExtResource("12_smoke")]
position = Vector3(0, 4.5, 0)
[node name="House_06" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-7, 0, -13)
rotation_degrees = Vector3(0, 31, 0)
scale = Vector3(0.9, 0.9, 0.9)
[node name="House_07" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(2, 0, 12)
rotation_degrees = Vector3(0, -24, 0)
scale = Vector3(0.8, 0.8, 0.8)
[node name="House_08" parent="VillageRoot" instance=ExtResource("6_house")]
position = Vector3(-22, 0, -9)
rotation_degrees = Vector3(0, 36, 0)
scale = Vector3(0.78, 0.78, 0.78)
[node name="Mill" parent="VillageRoot" instance=ExtResource("7_mill")]
position = Vector3(19, 2, 7)
@@ -353,6 +414,62 @@ scale = Vector3(0.9, 0.9, 0.9)
position = Vector3(31, 0, 14)
scale = Vector3(1.25, 1.25, 1.25)
[node name="Conifer_Citadel_01" parent="FoliageRoot" instance=ExtResource("23_conifer_high")]
position = Vector3(-39, 0, 13)
rotation_degrees = Vector3(0, 18, 0)
scale = Vector3(2.4, 2.4, 2.4)
[node name="Conifer_Citadel_02" parent="FoliageRoot" instance=ExtResource("22_conifer")]
position = Vector3(-34, 0, 22)
rotation_degrees = Vector3(0, -35, 0)
scale = Vector3(2.8, 2.8, 2.8)
[node name="Conifer_Citadel_03" parent="FoliageRoot" instance=ExtResource("23_conifer_high")]
position = Vector3(-43, 0, 3)
rotation_degrees = Vector3(0, 62, 0)
scale = Vector3(2.15, 2.15, 2.15)
[node name="Conifer_Falls_01" parent="FoliageRoot" instance=ExtResource("23_conifer_high")]
position = Vector3(36, 0, -17)
rotation_degrees = Vector3(0, -18, 0)
scale = Vector3(2.35, 2.35, 2.35)
[node name="Conifer_Falls_02" parent="FoliageRoot" instance=ExtResource("22_conifer")]
position = Vector3(38, 0, -8)
rotation_degrees = Vector3(0, 28, 0)
scale = Vector3(2.7, 2.7, 2.7)
[node name="Conifer_River_01" parent="FoliageRoot" instance=ExtResource("22_conifer")]
position = Vector3(38, 0, 20)
rotation_degrees = Vector3(0, -51, 0)
scale = Vector3(2.55, 2.55, 2.55)
[node name="Conifer_South_01" parent="FoliageRoot" instance=ExtResource("23_conifer_high")]
position = Vector3(-21, 0, -29)
rotation_degrees = Vector3(0, 44, 0)
scale = Vector3(2.25, 2.25, 2.25)
[node name="Conifer_South_02" parent="FoliageRoot" instance=ExtResource("22_conifer")]
position = Vector3(8, 0, -31)
rotation_degrees = Vector3(0, -20, 0)
scale = Vector3(2.65, 2.65, 2.65)
[node name="WildlifeRoot" type="Node3D" parent="."]
[node name="Butterfly_Meadow_01" parent="WildlifeRoot" instance=ExtResource("24_butterfly")]
position = Vector3(-3, 3.1, -5)
phase = 0.4
[node name="Butterfly_Houses_01" parent="WildlifeRoot" instance=ExtResource("24_butterfly")]
position = Vector3(-11, 4.2, 8)
scale = Vector3(0.9, 0.9, 0.9)
phase = 2.3
[node name="Butterfly_River_01" parent="WildlifeRoot" instance=ExtResource("24_butterfly")]
position = Vector3(10, 3.6, 5)
scale = Vector3(1.12, 1.12, 1.12)
phase = 4.4
[node name="WorldObjects" type="Node3D" parent="."]
[node name="ResourceNodes" type="Node3D" parent="WorldObjects"]
+92 -16
View File
@@ -1,40 +1,116 @@
[gd_scene load_steps=7 format=3]
[gd_scene load_steps=15 format=3]
[sub_resource type="StandardMaterial3D" id="Material_foundation"]
albedo_color = Color(0.43, 0.42, 0.36, 1)
roughness = 0.98
[sub_resource type="BoxMesh" id="Mesh_foundation"]
material = SubResource("Material_foundation")
size = Vector3(4.35, 0.65, 5.35)
[sub_resource type="StandardMaterial3D" id="Material_walls"]
albedo_color = Color(0.72, 0.65, 0.52, 1)
roughness = 0.85
albedo_color = Color(0.78, 0.7, 0.56, 1)
roughness = 0.94
[sub_resource type="BoxMesh" id="Mesh_walls"]
material = SubResource("Material_walls")
size = Vector3(4, 2.5, 5)
size = Vector3(4, 2.75, 5)
[sub_resource type="StandardMaterial3D" id="Material_roof"]
albedo_color = Color(0.55, 0.30, 0.18, 1)
roughness = 0.75
albedo_color = Color(0.48, 0.2, 0.12, 1)
roughness = 0.9
[sub_resource type="PrismMesh" id="Mesh_roof"]
material = SubResource("Material_roof")
size = Vector3(4.2, 1.5, 5.2)
size = Vector3(4.65, 1.7, 5.65)
left_to_right = 0.5
[sub_resource type="StandardMaterial3D" id="Material_door"]
albedo_color = Color(0.20, 0.12, 0.06, 1)
roughness = 0.7
[sub_resource type="StandardMaterial3D" id="Material_timber"]
albedo_color = Color(0.2, 0.105, 0.05, 1)
roughness = 0.92
[sub_resource type="BoxMesh" id="Mesh_beam_vertical"]
material = SubResource("Material_timber")
size = Vector3(0.17, 2.7, 0.16)
[sub_resource type="BoxMesh" id="Mesh_beam_horizontal"]
material = SubResource("Material_timber")
size = Vector3(4.15, 0.16, 0.16)
[sub_resource type="BoxMesh" id="Mesh_door"]
material = SubResource("Material_door")
size = Vector3(0.8, 1.4, 0.1)
material = SubResource("Material_timber")
size = Vector3(0.92, 1.65, 0.14)
[sub_resource type="StandardMaterial3D" id="Material_window"]
albedo_color = Color(0.9, 0.62, 0.25, 1)
roughness = 0.55
emission_enabled = true
emission = Color(0.72, 0.31, 0.08, 1)
emission_energy_multiplier = 0.35
[sub_resource type="BoxMesh" id="Mesh_window"]
material = SubResource("Material_window")
size = Vector3(0.72, 0.72, 0.12)
[sub_resource type="BoxMesh" id="Mesh_window_cross_vertical"]
material = SubResource("Material_timber")
size = Vector3(0.08, 0.82, 0.08)
[sub_resource type="BoxMesh" id="Mesh_window_cross_horizontal"]
material = SubResource("Material_timber")
size = Vector3(0.82, 0.08, 0.08)
[sub_resource type="BoxMesh" id="Mesh_chimney"]
material = SubResource("Material_foundation")
size = Vector3(0.62, 1.65, 0.62)
[node name="StylizedHouse" type="Node3D"]
[node name="Walls" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.25, 0)
[node name="StoneFoundation" type="MeshInstance3D" parent="."]
position = Vector3(0, 0.32, 0)
mesh = SubResource("Mesh_foundation")
[node name="PlasterWalls" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.85, 0)
mesh = SubResource("Mesh_walls")
[node name="Roof" type="MeshInstance3D" parent="."]
position = Vector3(0, 3.25, 0)
position = Vector3(0, 4.08, 0)
mesh = SubResource("Mesh_roof")
[node name="FrontBeamLeft" type="MeshInstance3D" parent="."]
position = Vector3(-1.78, 1.9, 2.56)
mesh = SubResource("Mesh_beam_vertical")
[node name="FrontBeamRight" type="MeshInstance3D" parent="."]
position = Vector3(1.78, 1.9, 2.56)
mesh = SubResource("Mesh_beam_vertical")
[node name="FrontBeamTop" type="MeshInstance3D" parent="."]
position = Vector3(0, 3.0, 2.56)
mesh = SubResource("Mesh_beam_horizontal")
[node name="FrontBeamMiddle" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.62, 2.56)
mesh = SubResource("Mesh_beam_horizontal")
[node name="Door" type="MeshInstance3D" parent="."]
position = Vector3(0, 1.0, 2.55)
position = Vector3(-0.72, 1.15, 2.59)
mesh = SubResource("Mesh_door")
[node name="Window" type="MeshInstance3D" parent="."]
position = Vector3(0.92, 2.1, 2.6)
mesh = SubResource("Mesh_window")
[node name="WindowCrossVertical" type="MeshInstance3D" parent="."]
position = Vector3(0.92, 2.1, 2.69)
mesh = SubResource("Mesh_window_cross_vertical")
[node name="WindowCrossHorizontal" type="MeshInstance3D" parent="."]
position = Vector3(0.92, 2.1, 2.69)
mesh = SubResource("Mesh_window_cross_horizontal")
[node name="Chimney" type="MeshInstance3D" parent="."]
position = Vector3(1.25, 4.45, -0.65)
rotation_degrees = Vector3(0, 0, 2)
mesh = SubResource("Mesh_chimney")
+84 -20
View File
@@ -7,9 +7,9 @@ enum CanopyVariant {
}
const COLORS := {
CanopyVariant.GREEN: Color(0.19, 0.38, 0.17),
CanopyVariant.DARK_GREEN: Color(0.12, 0.30, 0.12),
CanopyVariant.YELLOW_GREEN: Color(0.30, 0.42, 0.15),
CanopyVariant.GREEN: Color(0.18, 0.39, 0.16),
CanopyVariant.DARK_GREEN: Color(0.10, 0.28, 0.12),
CanopyVariant.YELLOW_GREEN: Color(0.34, 0.47, 0.16),
}
const WIND_SHADER := preload("res://world/jajce/materials/wind.gdshader")
@@ -25,13 +25,14 @@ func _ready() -> void:
var rng := RandomNumberGenerator.new()
rng.seed = hash_seed
var canopy_variant := rng.randi() % COLORS.size() as CanopyVariant
var canopy_radius := 1.0 + rng.randf() * 0.8
var canopy_radius := 1.0 + rng.randf() * 0.55
var wind_phase := rng.randf_range(0.0, TAU)
var trunk_mesh := CylinderMesh.new()
trunk_mesh.top_radius = 0.22
trunk_mesh.bottom_radius = 0.32
trunk_mesh.height = 2.8
trunk_mesh.height = 3.4
trunk_mesh.radial_segments = 9
var trunk_mat := StandardMaterial3D.new()
trunk_mat.albedo_color = Color(0.27, 0.16, 0.09)
@@ -41,24 +42,87 @@ func _ready() -> void:
var trunk := MeshInstance3D.new()
trunk.name = "Trunk"
trunk.mesh = trunk_mesh
trunk.position = Vector3(0, 1.4, 0)
trunk.position = Vector3(0, 1.7, 0)
add_child(trunk)
var canopy_mesh := SphereMesh.new()
canopy_mesh.radius = canopy_radius
canopy_mesh.height = 2.4
_add_branch(Vector3(-0.18, 2.45, 0.0), Vector3(0.0, 0.0, 42.0), 1.45, trunk_mat)
_add_branch(Vector3(0.2, 2.6, 0.08), Vector3(24.0, 0.0, -38.0), 1.25, trunk_mat)
var canopy_mat := ShaderMaterial.new()
canopy_mat.shader = WIND_SHADER
canopy_mat.set_shader_parameter("albedo", COLORS[canopy_variant])
canopy_mat.set_shader_parameter("roughness", 0.9)
canopy_mat.set_shader_parameter("wind_strength", WIND_STRENGTH)
canopy_mat.set_shader_parameter("wind_speed", WIND_SPEED)
canopy_mat.set_shader_parameter("wind_phase", wind_phase)
canopy_mesh.material = canopy_mat
var canopy_color: Color = COLORS[canopy_variant]
var crown_height := 3.7 + (canopy_radius - 1.2) * 0.45
_add_canopy(
"Canopy",
Vector3(0.0, crown_height, 0.0),
Vector3(canopy_radius * 1.12, canopy_radius, canopy_radius),
canopy_color,
wind_phase
)
_add_canopy(
"CanopyLeft",
Vector3(-0.82, crown_height - 0.15, 0.1),
Vector3(canopy_radius * 0.78, canopy_radius * 0.72, canopy_radius * 0.76),
canopy_color.lightened(0.05),
wind_phase + 0.12
)
_add_canopy(
"CanopyRight",
Vector3(0.78, crown_height - 0.05, -0.12),
Vector3(canopy_radius * 0.74, canopy_radius * 0.68, canopy_radius * 0.72),
canopy_color.darkened(0.04),
wind_phase - 0.1
)
_add_canopy(
"CanopyTop",
Vector3(0.08, crown_height + 0.72, 0.04),
Vector3(canopy_radius * 0.72, canopy_radius * 0.66, canopy_radius * 0.7),
canopy_color.lightened(0.08),
wind_phase + 0.05
)
func _add_branch(
branch_position: Vector3,
branch_rotation_degrees: Vector3,
branch_height: float,
material: StandardMaterial3D
) -> void:
var mesh := CylinderMesh.new()
mesh.top_radius = 0.08
mesh.bottom_radius = 0.14
mesh.height = branch_height
mesh.radial_segments = 7
mesh.material = material
var branch := MeshInstance3D.new()
branch.name = "Branch"
branch.mesh = mesh
branch.position = branch_position
branch.rotation_degrees = branch_rotation_degrees
add_child(branch)
func _add_canopy(
canopy_name: String,
canopy_position: Vector3,
canopy_scale: Vector3,
canopy_color: Color,
wind_phase: float
) -> void:
var mesh := SphereMesh.new()
mesh.radius = 1.0
mesh.height = 2.0
mesh.radial_segments = 12
mesh.rings = 6
var material := ShaderMaterial.new()
material.shader = WIND_SHADER
material.set_shader_parameter("albedo", canopy_color)
material.set_shader_parameter("roughness", 0.9)
material.set_shader_parameter("wind_strength", WIND_STRENGTH)
material.set_shader_parameter("wind_speed", WIND_SPEED)
material.set_shader_parameter("wind_phase", wind_phase)
mesh.material = material
var canopy := MeshInstance3D.new()
canopy.name = "Canopy"
canopy.mesh = canopy_mesh
canopy.position = Vector3(0, 3.2 + (canopy_radius - 1.35) * 0.5, 0)
canopy.name = canopy_name
canopy.mesh = mesh
canopy.position = canopy_position
canopy.scale = canopy_scale
add_child(canopy)
+82
View File
@@ -0,0 +1,82 @@
extends Node3D
@export var terrain_path := NodePath("../../TerrainRoot/Terrain3D")
@export var river_material: Material
@export_range(6.0, 20.0, 0.5) var river_width := 8.0
@export_range(2, 12, 1) var width_segments := 6
@export_range(8, 96, 1) var length_segments := 36
@export var local_start_z := -25.0
@export var local_end_z := 40.0
@export_range(0.05, 0.5, 0.01) var water_offset := 0.18
@onready var river_ribbon: MeshInstance3D = $RiverRibbon
func _ready() -> void:
call_deferred("_build_terrain_ribbon")
func _build_terrain_ribbon() -> void:
var terrain := get_node_or_null(terrain_path) as Terrain3D
if terrain == null or terrain.data == null or river_material == null:
push_warning("TerrainRiverRibbon: terrain or material is unavailable")
return
var vertices := PackedVector3Array()
var normals := PackedVector3Array()
var uvs := PackedVector2Array()
var indices := PackedInt32Array()
var row_size := width_segments + 1
for z_index in length_segments + 1:
var progress := float(z_index) / float(length_segments)
var local_z := lerpf(local_start_z, local_end_z, progress)
var downstream_curve := smoothstep(0.58, 1.0, progress) * 12.0
var center_offset := sin(progress * TAU) * 1.4 + downstream_curve
var downstream_taper := lerpf(1.0, 0.45, smoothstep(0.65, 1.0, progress))
var half_width := river_width * lerpf(0.52, 0.45, progress) * downstream_taper
for x_index in width_segments + 1:
var across := float(x_index) / float(width_segments)
var local_x := center_offset + lerpf(-half_width, half_width, across)
var world_sample := to_global(Vector3(local_x, 0.0, local_z))
var terrain_height := terrain.data.get_height(world_sample)
if is_nan(terrain_height):
terrain_height = global_position.y
vertices.append(
to_local(Vector3(world_sample.x, terrain_height + water_offset, world_sample.z))
)
normals.append(Vector3.UP)
uvs.append(Vector2(across, progress))
for z_index in length_segments:
for x_index in width_segments:
var top_left := z_index * row_size + x_index
var top_right := top_left + 1
var bottom_left := top_left + row_size
var bottom_right := bottom_left + 1
indices.append_array(
[top_left, bottom_left, top_right, top_right, bottom_left, bottom_right]
)
var arrays := []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = vertices
arrays[Mesh.ARRAY_NORMAL] = normals
arrays[Mesh.ARRAY_TEX_UV] = uvs
arrays[Mesh.ARRAY_INDEX] = indices
var mesh := ArrayMesh.new()
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
mesh.surface_set_material(0, river_material)
river_ribbon.mesh = mesh
_align_pool_to_terrain(terrain)
func _align_pool_to_terrain(terrain: Terrain3D) -> void:
var pool := $PlungePool as MeshInstance3D
var pool_sample := to_global(Vector3(pool.position.x, 0.0, pool.position.z))
var pool_height := terrain.data.get_height(pool_sample)
if is_nan(pool_height):
return
var local_surface := to_local(Vector3(pool_sample.x, pool_height + water_offset, pool_sample.z))
for node_name in [&"PlungePool", &"FoamRing", &"FoamAtFall"]:
var surface := get_node(NodePath(node_name)) as MeshInstance3D
surface.position.y = local_surface.y
+1
View File
@@ -0,0 +1 @@
uid://gri4c7mt0rmo
+51 -6
View File
@@ -1,16 +1,61 @@
[gd_scene load_steps=4 format=3]
[gd_scene load_steps=8 format=3]
[ext_resource type="Shader" path="res://world/jajce/materials/water.gdshader" id="1_water_shader"]
[ext_resource type="Script" path="res://world/jajce/TerrainRiverRibbon.gd" id="2_river_script"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_water"]
shader = ExtResource("1_water_shader")
[sub_resource type="BoxMesh" id="Mesh_water_body"]
[sub_resource type="CylinderMesh" id="Mesh_plunge_pool"]
material = SubResource("ShaderMaterial_water")
size = Vector3(8, 0.08, 58)
top_radius = 7.6
bottom_radius = 7.6
height = 0.08
radial_segments = 32
rings = 2
[sub_resource type="StandardMaterial3D" id="Material_foam"]
transparency = 1
shading_mode = 0
albedo_color = Color(0.8, 0.93, 0.86, 0.46)
emission_enabled = true
emission = Color(0.34, 0.56, 0.48, 1)
emission_energy_multiplier = 0.18
roughness = 0.74
[sub_resource type="TorusMesh" id="Mesh_foam_ring"]
material = SubResource("Material_foam")
inner_radius = 4.8
outer_radius = 5.65
rings = 28
ring_segments = 10
[sub_resource type="PlaneMesh" id="Mesh_foam_patch"]
material = SubResource("Material_foam")
size = Vector2(10.5, 2.2)
subdivide_width = 8
subdivide_depth = 2
[node name="WaterBody" type="Node3D"]
position = Vector3(25, 0.08, 0)
position = Vector3(25, 0.1, 1)
script = ExtResource("2_river_script")
river_material = SubResource("ShaderMaterial_water")
[node name="Mesh" type="MeshInstance3D" parent="."]
mesh = SubResource("Mesh_water_body")
[node name="RiverRibbon" type="MeshInstance3D" parent="."]
cast_shadow = 0
[node name="PlungePool" type="MeshInstance3D" parent="."]
position = Vector3(0, -0.02, -25)
scale = Vector3(1.25, 1, 0.82)
mesh = SubResource("Mesh_plunge_pool")
[node name="FoamRing" type="MeshInstance3D" parent="."]
position = Vector3(0, 0.09, -25)
scale = Vector3(1.25, 0.12, 0.82)
cast_shadow = 0
mesh = SubResource("Mesh_foam_ring")
[node name="FoamAtFall" type="MeshInstance3D" parent="."]
position = Vector3(0, 0.12, -25.8)
cast_shadow = 0
mesh = SubResource("Mesh_foam_patch")
+70 -5
View File
@@ -1,16 +1,81 @@
[gd_scene load_steps=4 format=3]
[gd_scene load_steps=10 format=3]
[ext_resource type="Shader" path="res://world/jajce/materials/waterfall.gdshader" id="1_waterfall_shader"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_waterfall"]
shader = ExtResource("1_waterfall_shader")
[sub_resource type="BoxMesh" id="Mesh_waterfall_body"]
[sub_resource type="QuadMesh" id="Mesh_waterfall_body"]
material = SubResource("ShaderMaterial_waterfall")
size = Vector3(8, 12, 0.5)
size = Vector2(10.8, 14)
subdivide_width = 18
subdivide_depth = 28
[sub_resource type="StandardMaterial3D" id="Material_rock_dark"]
albedo_color = Color(0.32, 0.36, 0.3, 1)
roughness = 1.0
[sub_resource type="StandardMaterial3D" id="Material_rock_moss"]
albedo_color = Color(0.3, 0.4, 0.23, 1)
roughness = 1.0
[sub_resource type="CylinderMesh" id="Mesh_cliff_side"]
material = SubResource("Material_rock_dark")
top_radius = 2.05
bottom_radius = 3.15
height = 14.5
radial_segments = 7
[sub_resource type="BoxMesh" id="Mesh_rock_lobe"]
material = SubResource("Material_rock_dark")
size = Vector3(4.8, 5.5, 3.4)
[sub_resource type="BoxMesh" id="Mesh_lip"]
material = SubResource("Material_rock_moss")
size = Vector3(11.6, 0.7, 3.2)
[node name="WaterfallBody" type="Node3D"]
position = Vector3(25, 6, -24)
position = Vector3(25, 8.9, -24)
[node name="Mesh" type="MeshInstance3D" parent="."]
[node name="RockFrame" type="Node3D" parent="."]
[node name="WestCliff" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(-7.2, -0.45, -1)
rotation_degrees = Vector3(0, 8, -3)
mesh = SubResource("Mesh_cliff_side")
[node name="EastCliff" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(7.2, -0.25, -1.2)
rotation_degrees = Vector3(0, -7, 4)
mesh = SubResource("Mesh_cliff_side")
[node name="WestCrownRock" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(-5.0, 7.45, -1.25)
rotation_degrees = Vector3(8, -14, -11)
scale = Vector3(0.85, 0.62, 0.9)
mesh = SubResource("Mesh_rock_lobe")
[node name="EastCrownRock" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(5.1, 7.55, -1.4)
rotation_degrees = Vector3(-6, 12, 9)
scale = Vector3(0.82, 0.6, 0.86)
mesh = SubResource("Mesh_rock_lobe")
[node name="WestLowerRock" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(-5.9, -4.8, 0.1)
rotation_degrees = Vector3(7, 14, 12)
mesh = SubResource("Mesh_rock_lobe")
[node name="EastLowerRock" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(6.0, -4.4, 0)
rotation_degrees = Vector3(-4, -12, -9)
mesh = SubResource("Mesh_rock_lobe")
[node name="RiverLip" type="MeshInstance3D" parent="RockFrame"]
position = Vector3(0, 7.05, 0.2)
mesh = SubResource("Mesh_lip")
[node name="FallingWater" type="MeshInstance3D" parent="."]
position = Vector3(0, 0, 1.05)
cast_shadow = 0
mesh = SubResource("Mesh_waterfall_body")
+3 -3
View File
@@ -10,7 +10,7 @@ scale_min = 0.08
scale_max = 2.0
color = Color(0.82, 0.94, 0.96, 0.35)
emission_shape = 1
emission_box_extents = Vector3(4.5, 1.5, 1.0)
emission_box_extents = Vector3(5.8, 1.5, 1.35)
[sub_resource type="StandardMaterial3D" id="Material_mist"]
albedo_color = Color(0.82, 0.94, 0.96, 0.28)
@@ -24,9 +24,9 @@ material = SubResource("Material_mist")
size = Vector2(1.8, 1.8)
[node name="WaterfallMist" type="GPUParticles3D"]
position = Vector3(25, 0.8, -24)
position = Vector3(25, 2.05, -24)
emitting = true
amount = 72
amount = 96
lifetime = 3.0
one_shot = false
preprocess = 1.5
+70
View File
@@ -0,0 +1,70 @@
// Adapted for The Steward from the bundled Terrain3D particle-grass example.
shader_type spatial;
render_mode skip_vertex_transform, cull_disabled, blend_mix;
const int MAX_INTERACTORS = 8;
uniform vec2 wind_direction = vec2(1.0, 0.7);
uniform vec3 base_color : source_color = vec3(0.16, 0.31, 0.08);
uniform vec3 tip_color : source_color = vec3(0.54, 0.68, 0.24);
uniform float wind_amount : hint_range(0.0, 1.0) = 0.34;
uniform int interactor_count : hint_range(0, 8) = 0;
uniform vec3 interactor_positions[MAX_INTERACTORS];
uniform float interaction_radius : hint_range(0.25, 4.0) = 1.8;
uniform float interaction_strength : hint_range(0.0, 2.0) = 0.75;
varying vec4 grass_data;
varying float pressed_weight;
void vertex() {
grass_data[2] = VERTEX.y + 0.55;
grass_data[2] *= grass_data[2];
VERTEX.xz *= 1.0 - grass_data[2];
COLOR = mix(COLOR, vec4(1.0), smoothstep(0.9, 1.0, grass_data[2]));
COLOR *= INSTANCE_CUSTOM[3] < 0.35 ? 1.0 : mix(1.0, 0.75, smoothstep(0.35, 0.0, grass_data[2]));
grass_data.rg = INSTANCE_CUSTOM.rg;
vec3 world_vertex = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
float scale = pow(INSTANCE_CUSTOM[3] * INSTANCE_CUSTOM[3], 0.707);
float force = INSTANCE_CUSTOM[2] * grass_data[2] * scale * wind_amount;
force -= fract(force * 256.0) * force * 0.05;
force = pow(max(force, 0.0), 0.707);
float lateral_wobble = sin(TIME * 2.0 * (1.0 + grass_data.r + grass_data.g)) * 0.2 * (1.0 - INSTANCE_CUSTOM[2]);
vec2 direction = normalize(wind_direction);
world_vertex.xz -= (vec2(-direction.y, direction.x) * lateral_wobble + direction) * force;
world_vertex.y -= INSTANCE_CUSTOM[2] * force * grass_data[2];
grass_data[3] = force;
pressed_weight = 0.0;
for (int index = 0; index < MAX_INTERACTORS; index++) {
if (index >= interactor_count) {
break;
}
vec2 offset = world_vertex.xz - interactor_positions[index].xz;
float distance_to_actor = length(offset);
float influence = 1.0 - smoothstep(0.25, interaction_radius, distance_to_actor);
vec2 away = offset / max(distance_to_actor, 0.08);
world_vertex.xz += away * influence * interaction_strength * grass_data[2];
world_vertex.y -= influence * 0.28 * grass_data[2];
pressed_weight = max(pressed_weight, influence);
}
VERTEX = (VIEW_MATRIX * vec4(world_vertex, 1.0)).xyz;
NORMAL = MODELVIEW_NORMAL_MATRIX * NORMAL;
BINORMAL = MODELVIEW_NORMAL_MATRIX * BINORMAL;
TANGENT = MODELVIEW_NORMAL_MATRIX * TANGENT;
}
void fragment() {
vec3 color = mix(base_color, tip_color, grass_data[2] * 0.62);
color.rg *= grass_data.rg * 0.18 + 0.91;
color *= pow(COLOR.rgb, vec3(2.2));
ALBEDO = mix(color, base_color * 0.72, pressed_weight * 0.42);
float specular_roughness = clamp(max(grass_data[2], grass_data[3]), 0.0, 1.0);
ROUGHNESS = 1.0 - specular_roughness * 0.22;
SPECULAR = clamp(specular_roughness * 0.2, 0.0, 0.12);
BACKLIGHT = tip_color * 0.24;
}
@@ -0,0 +1 @@
uid://3ayekivfakfr
@@ -0,0 +1,14 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3]
[ext_resource type="Shader" path="res://world/jajce/materials/cozy_grass.gdshader" id="1_grass"]
[resource]
render_priority = 0
shader = ExtResource("1_grass")
shader_parameter/wind_direction = Vector2(1, 0.7)
shader_parameter/base_color = Vector3(0.16, 0.31, 0.08)
shader_parameter/tip_color = Vector3(0.54, 0.68, 0.24)
shader_parameter/wind_amount = 0.34
shader_parameter/interactor_count = 0
shader_parameter/interaction_radius = 1.8
shader_parameter/interaction_strength = 0.75
@@ -0,0 +1,47 @@
[gd_resource type="ShaderMaterial" load_steps=4 format=3]
[ext_resource type="Shader" path="res://addons/terrain_3d/extras/particle_example/particles.gdshader" id="1_process_shader"]
[sub_resource type="FastNoiseLite" id="FastNoise_grass"]
noise_type = 2
frequency = 0.018
cellular_return_type = 4
[sub_resource type="NoiseTexture2D" id="NoiseTexture_grass"]
seamless = true
noise = SubResource("FastNoise_grass")
[resource]
shader = ExtResource("1_process_shader")
shader_parameter/main_noise = SubResource("NoiseTexture_grass")
shader_parameter/main_noise_scale = 0.012
shader_parameter/position_offset = Vector3(0, 0.22, 0)
shader_parameter/align_to_normal = true
shader_parameter/normal_strength = 0.22
shader_parameter/random_rotation = true
shader_parameter/random_spacing = 0.72
shader_parameter/min_scale = Vector3(0.09, 0.22, 0.09)
shader_parameter/max_scale = Vector3(0.13, 0.48, 0.13)
shader_parameter/noise_scale = 0.0041
shader_parameter/wind_speed = 0.022
shader_parameter/wind_strength = 0.6
shader_parameter/wind_dithering = 4.0
shader_parameter/wind_direction = Vector2(1, 0.7)
shader_parameter/clod_scale_boost = 0.18
shader_parameter/clod_min_threshold = 0.32
shader_parameter/clod_max_threshold = 0.78
shader_parameter/patch_min_threshold = 0.08
shader_parameter/patch_max_threshold = 0.42
shader_parameter/condition_dither_range = 0.18
shader_parameter/surface_slope_min = 0.88
shader_parameter/distance_fade_ammount = 0.7
shader_parameter/max_dist = 1.0
shader_parameter/camera_position = Vector3(0, 0, 0)
shader_parameter/instance_rows = 1
shader_parameter/instance_spacing = 0.703125
shader_parameter/_background_mode = 0
shader_parameter/_vertex_spacing = 1.0
shader_parameter/_vertex_density = 1.0
shader_parameter/_region_size = 1024.0
shader_parameter/_region_texel_size = 0.000976563
shader_parameter/_region_map_size = 32
+30 -42
View File
@@ -1,54 +1,42 @@
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
render_mode blend_mix, depth_prepass_alpha, cull_disabled, diffuse_burley, specular_schlick_ggx;
uniform float wave_strength : hint_range(0.0, 0.5) = 0.08;
uniform float wave_speed : hint_range(0.0, 5.0) = 0.8;
uniform float flow_speed : hint_range(0.0, 3.0) = 0.6;
uniform vec3 deep_color : source_color = vec3(0.06, 0.24, 0.38);
uniform vec3 shallow_color : source_color = vec3(0.18, 0.44, 0.58);
uniform vec3 foam_color : source_color = vec3(0.82, 0.88, 0.86);
uniform float rim_power : hint_range(0.5, 5.0) = 2.5;
uniform float sparkle_strength : hint_range(0.0, 1.0) = 0.12;
uniform float wave_strength : hint_range(0.0, 0.3) = 0.055;
uniform float wave_speed : hint_range(0.0, 3.0) = 0.72;
uniform float flow_speed : hint_range(0.0, 2.0) = 0.46;
uniform vec3 deep_color : source_color = vec3(0.03, 0.39, 0.45);
uniform vec3 shallow_color : source_color = vec3(0.07, 0.67, 0.64);
uniform vec3 sunlit_color : source_color = vec3(0.55, 0.95, 0.78);
uniform vec3 foam_color : source_color = vec3(0.82, 0.94, 0.84);
uniform vec3 sun_direction = vec3(0.4, 0.8, 0.4);
void vertex() {
vec3 pos = VERTEX;
float wave_a = sin(pos.x * 0.35 + pos.z * 0.25 + TIME * wave_speed) * wave_strength;
float wave_b = cos(pos.x * 0.45 - pos.z * 0.55 + TIME * wave_speed * 0.7) * wave_strength * 0.6;
float wave_c = sin(pos.z * 0.7 + TIME * wave_speed * 1.3) * wave_strength * 0.35;
pos.y += wave_a + wave_b + wave_c;
VERTEX = pos;
float broad_wave = sin(VERTEX.x * 0.42 + VERTEX.z * 0.18 + TIME * wave_speed);
float crossing_wave = cos(VERTEX.x * 0.7 - VERTEX.z * 0.31 + TIME * wave_speed * 0.73);
VERTEX.y += (broad_wave + crossing_wave * 0.45) * wave_strength;
}
void fragment() {
vec3 view_dir = VIEW;
vec3 normal = NORMAL;
vec3 view_norm = normalize(view_dir);
vec2 flowing_uv = UV * vec2(7.0, 10.0);
flowing_uv.y -= TIME * flow_speed;
float ribbon_a = sin(flowing_uv.y + sin(flowing_uv.x * 0.72) * 1.25) * 0.5 + 0.5;
float ribbon_b = sin(flowing_uv.y * 1.7 - flowing_uv.x * 0.55 + TIME * 0.23) * 0.5 + 0.5;
float quiet_ripple = smoothstep(0.72, 0.98, ribbon_a * 0.62 + ribbon_b * 0.38);
float fresnel = pow(1.0 - clamp(dot(normalize(NORMAL), normalize(VIEW)), 0.0, 1.0), 2.4);
float bank_distance = min(UV.x, 1.0 - UV.x);
float bank_foam = 1.0 - smoothstep(0.0, 0.07, bank_distance);
bank_foam *= 0.72 + sin(UV.y * 52.0 + TIME * 0.35) * 0.12;
float rim = 1.0 - abs(dot(normal, view_norm));
rim = pow(rim, rim_power);
rim = smoothstep(0.15, 0.7, rim);
vec2 uv = UV;
uv.x += TIME * flow_speed * 0.4;
uv.y += TIME * flow_speed * 0.3;
float flow_a = sin(uv.x * 8.0 + uv.y * 5.0) * 0.5 + 0.5;
float flow_b = cos(uv.y * 6.0 - uv.x * 4.0 + TIME * 0.25) * 0.5 + 0.5;
float flow = mix(flow_a, flow_b, 0.5);
vec3 water_color = mix(deep_color, shallow_color, flow * 0.6 + 0.2);
water_color = mix(water_color, foam_color, rim * 0.65);
vec3 half_vec = normalize(view_norm + normalize(sun_direction));
float specular = pow(max(dot(normal, half_vec), 0.0), 120.0);
specular *= smoothstep(0.4, 0.85, rim);
float sparkle = specular * sparkle_strength;
vec3 water_color = mix(deep_color, shallow_color, ribbon_a * 0.2 + 0.48);
water_color = mix(water_color, sunlit_color, fresnel * 0.42);
water_color = mix(water_color, foam_color, quiet_ripple * 0.05);
water_color = mix(water_color, foam_color, bank_foam * 0.3);
ALBEDO = water_color;
METALLIC = 0.08;
ROUGHNESS = 0.22;
EMISSION = water_color * 0.04 + foam_color * sparkle;
ALPHA = 0.76;
ALPHA_SCISSOR_THRESHOLD = 0.0;
ROUGHNESS = mix(0.34, 0.5, ribbon_b);
SPECULAR = 0.38;
EMISSION = water_color * 0.12 + sunlit_color * (quiet_ripple * 0.05 + fresnel * 0.03);
EMISSION += foam_color * bank_foam * 0.025;
ALPHA = mix(0.94, 0.99, fresnel);
}
+27 -39
View File
@@ -1,50 +1,38 @@
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
render_mode blend_mix, depth_prepass_alpha, cull_disabled, diffuse_burley, specular_schlick_ggx;
uniform float scroll_speed : hint_range(0.0, 4.0) = 1.35;
uniform vec3 shadow_color : source_color = vec3(0.075, 0.33, 0.34);
uniform vec3 water_color : source_color = vec3(0.31, 0.68, 0.64);
uniform vec3 light_color : source_color = vec3(0.78, 0.94, 0.83);
uniform vec3 foam_color : source_color = vec3(0.91, 0.97, 0.9);
uniform float scroll_speed : hint_range(0.0, 5.0) = 1.8;
uniform vec3 deep_color : source_color = vec3(0.1, 0.45, 0.55);
uniform vec3 mid_color : source_color = vec3(0.45, 0.78, 0.82);
uniform vec3 foam_color : source_color = vec3(0.9, 0.95, 0.95);
uniform float foam_contrast : hint_range(0.5, 4.0) = 2.2;
uniform float sparkle_strength : hint_range(0.0, 0.8) = 0.25;
void vertex() {
float edge_weight = 1.0 - abs(UV.x * 2.0 - 1.0);
float curtain_wobble = sin(UV.y * 13.0 - TIME * 2.2 + UV.x * 8.0) * 0.05;
VERTEX.z += curtain_wobble * edge_weight;
}
void fragment() {
vec2 uv = UV;
uv.y += TIME * scroll_speed;
vec2 flow_uv = UV;
flow_uv.y += TIME * scroll_speed;
float long_thread = sin(flow_uv.x * 32.0 + sin(flow_uv.y * 3.1) * 2.4) * 0.5 + 0.5;
float soft_thread = sin(flow_uv.x * 13.0 - flow_uv.y * 7.0) * 0.5 + 0.5;
float falling_detail = sin(flow_uv.y * 27.0 + flow_uv.x * 7.0) * 0.5 + 0.5;
float thread = smoothstep(0.36, 0.9, long_thread * 0.6 + soft_thread * 0.4);
float broken_foam = smoothstep(0.72, 0.98, falling_detail * thread);
float base_foam = smoothstep(0.58, 1.0, UV.y);
float edge_fade = smoothstep(0.0, 0.08, UV.x) * smoothstep(1.0, 0.92, UV.x);
float band_a = fract(uv.y * 5.0 + sin(uv.x * 2.0) * 0.15);
band_a = smoothstep(0.2, 0.55, band_a) * smoothstep(0.8, 0.45, band_a);
float band_b = fract(uv.y * 3.5 + cos(uv.x * 2.5 + TIME * 0.3) * 0.12);
band_b = smoothstep(0.1, 0.5, band_b) * smoothstep(0.85, 0.4, band_b);
float foam_a = fract(uv.y * 4.0);
foam_a = pow(smoothstep(0.0, 0.12, foam_a) * smoothstep(0.3, 0.15, foam_a), foam_contrast);
float foam_b = fract(uv.y * 6.0 + uv.x * 1.5);
foam_b = pow(smoothstep(0.5, 0.58, foam_b) * smoothstep(0.7, 0.6, foam_b), foam_contrast * 0.8);
float foam = foam_a * 0.7 + foam_b * 0.3;
vec3 base = mix(deep_color, mid_color, band_a * 0.5 + band_b * 0.3);
vec3 color = mix(base, foam_color, foam);
float sparkle = pow(foam_a, 3.0) * sparkle_strength;
float highlight = band_a * band_b * 0.35;
float emission_value = sparkle + highlight * 0.3;
vec3 color = mix(shadow_color, water_color, 0.5 + thread * 0.35);
color = mix(color, light_color, broken_foam * 0.5);
color = mix(color, foam_color, base_foam * (0.38 + broken_foam * 0.42));
ALBEDO = color;
ALPHA = mix(0.25, 0.78, foam * 0.7 + 0.15);
EMISSION = color * emission_value;
METALLIC = 0.05;
ROUGHNESS = 0.15;
vec3 normal = NORMAL;
vec3 view_dir = VIEW;
vec3 view_norm = normalize(view_dir);
float rim = 1.0 - abs(dot(normal, view_norm));
ALPHA = mix(ALPHA, ALPHA * 0.5, rim * 0.6);
ROUGHNESS = mix(0.16, 0.32, broken_foam);
SPECULAR = 0.65;
EMISSION = light_color * (broken_foam * 0.07 + base_foam * 0.04);
ALPHA = edge_fade * mix(0.62, 0.9, thread * 0.56 + base_foam * 0.3);
}