Skip to content

Commit

Permalink
Added multipass generator demo
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Nov 4, 2023
1 parent ae01557 commit 2147d81
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 0 deletions.
35 changes: 35 additions & 0 deletions project/multipass_generator/blocky_library.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[gd_resource type="VoxelBlockyLibrary" load_steps=6 format=3 uid="uid://5nm1ee5xpocl"]

[ext_resource type="Material" uid="uid://l26jp5hcwveg" path="res://multipass_generator/opaque_material.tres" id="1_xlckp"]

[sub_resource type="VoxelBlockyModelEmpty" id="VoxelBlockyModelEmpty_7i052"]

[sub_resource type="VoxelBlockyModelCube" id="VoxelBlockyModelCube_hrrub"]
resource_name = "stone"
material_override_0 = ExtResource("1_xlckp")
atlas_size_in_tiles = Vector2i(8, 8)

[sub_resource type="VoxelBlockyModelCube" id="VoxelBlockyModelCube_fehag"]
resource_name = "log"
material_override_0 = ExtResource("1_xlckp")
atlas_size_in_tiles = Vector2i(8, 8)
tile_left = Vector2i(2, 0)
tile_right = Vector2i(2, 0)
tile_bottom = Vector2i(3, 0)
tile_top = Vector2i(3, 0)
tile_back = Vector2i(2, 0)
tile_front = Vector2i(2, 0)

[sub_resource type="VoxelBlockyModelCube" id="VoxelBlockyModelCube_7mjab"]
resource_name = "leaves"
material_override_0 = ExtResource("1_xlckp")
atlas_size_in_tiles = Vector2i(8, 8)
tile_left = Vector2i(0, 2)
tile_right = Vector2i(0, 2)
tile_bottom = Vector2i(0, 2)
tile_top = Vector2i(0, 2)
tile_back = Vector2i(0, 2)
tile_front = Vector2i(0, 2)

[resource]
models = Array[VoxelBlockyModel]([SubResource("VoxelBlockyModelEmpty_7i052"), SubResource("VoxelBlockyModelCube_hrrub"), SubResource("VoxelBlockyModelCube_fehag"), SubResource("VoxelBlockyModelCube_7mjab")])
6 changes: 6 additions & 0 deletions project/multipass_generator/blocky_mesher.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[gd_resource type="VoxelMesherBlocky" load_steps=2 format=3 uid="uid://m85p22yb1ft0"]

[ext_resource type="VoxelBlockyLibrary" uid="uid://5nm1ee5xpocl" path="res://multipass_generator/blocky_library.tres" id="1_djp1m"]

[resource]
library = ExtResource("1_djp1m")
36 changes: 36 additions & 0 deletions project/multipass_generator/multipass_demo.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[gd_scene load_steps=7 format=3 uid="uid://d0dodvwrj0biu"]

[ext_resource type="VoxelGeneratorMultipassCB" uid="uid://dqgjcqp0m4ae2" path="res://multipass_generator/multipass_generator.tres" id="1_bubjg"]
[ext_resource type="VoxelMesherBlocky" uid="uid://m85p22yb1ft0" path="res://multipass_generator/blocky_mesher.tres" id="2_pgkoq"]
[ext_resource type="PackedScene" uid="uid://dljqckrx50m8t" path="res://common/spectator_avatar.tscn" id="3_tecxx"]

[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_8h45h"]
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)

[sub_resource type="Sky" id="Sky_rv3jx"]
sky_material = SubResource("ProceduralSkyMaterial_8h45h")

[sub_resource type="Environment" id="Environment_vdnyq"]
background_mode = 2
sky = SubResource("Sky_rv3jx")
tonemap_mode = 2
glow_enabled = true

[node name="Node" type="Node"]

[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_vdnyq")

[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
shadow_enabled = true

[node name="VoxelTerrain" type="VoxelTerrain" parent="."]
generator = ExtResource("1_bubjg")
mesher = ExtResource("2_pgkoq")
generate_collisions = false
run_stream_in_editor = false

[node name="SpectatorAvatar" parent="." instance=ExtResource("3_tecxx")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 15.1602, 0)
62 changes: 62 additions & 0 deletions project/multipass_generator/multipass_demo_single_column.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

# Test generating a single column without using threads

extends Node

# TODO Can't preload script: https://github.com/godotengine/godot/issues/83125
#const TestGenerator = preload("./multipass_generator.gd")
const GeneratorResource = preload("./multipass_generator.tres")
const BlockyMesher = preload("./blocky_mesher.tres")


func _ready():
var generator := GeneratorResource

var column = generator.debug_generate_test_column(Vector2i(2,1))

# TODO Need to preload script...
var channel := 0#TestGenerator.CHANNEL

var mesher := BlockyMesher
mesher.library.bake()
var materials : Array[Material] = mesher.library.get_materials()

var origin_in_voxels := Vector3(0, generator.column_base_y_blocks * 16, 0)

for rby in column.size():
var block : VoxelBuffer = column[rby]

var padded_voxels := VoxelBuffer.new()
var bs := block.get_size()
padded_voxels.create(bs.x + 2, bs.y + 2, bs.z + 2)
padded_voxels.copy_channel_from_area(block, Vector3i(), bs, Vector3i(1, 1, 1), channel)

if rby > 0:
var bottom_block : VoxelBuffer = column[rby - 1]
padded_voxels.copy_channel_from_area(bottom_block,
Vector3i(0, bs.y - 1, 0), bs, Vector3i(1, 0, 1), channel)

if rby + 1 < column.size():
var top_block : VoxelBuffer = column[rby + 1]
padded_voxels.copy_channel_from_area(top_block,
Vector3i(), Vector3i(bs.x, 1, bs.z), Vector3i(1, bs.y + 1, 1), channel)

# print("---- Block ", rby)
# for z in [8]:
# var ds := ""
# for x in block.get_size().x:
# for y in block.get_size().y:
# ds += str(block.get_voxel(x, y, z, 0), " ")
# ds += "\n"
# print("Z ", z)
# print(ds)

var mesh := mesher.build_mesh(padded_voxels, materials)

var mi := MeshInstance3D.new()
mi.mesh = mesh
mi.position = origin_in_voxels
add_child(mi)

origin_in_voxels.y += bs.y

29 changes: 29 additions & 0 deletions project/multipass_generator/multipass_demo_single_column.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[gd_scene load_steps=5 format=3 uid="uid://c1axjmomlc7hv"]

[ext_resource type="Script" path="res://multipass_generator/multipass_demo_single_column.gd" id="1_0w0kl"]

[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_rd8xx"]
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)

[sub_resource type="Sky" id="Sky_gyxt2"]
sky_material = SubResource("ProceduralSkyMaterial_rd8xx")

[sub_resource type="Environment" id="Environment_fngcp"]
background_mode = 2
sky = SubResource("Sky_gyxt2")
tonemap_mode = 2
glow_enabled = true

[node name="Node" type="Node"]
script = ExtResource("1_0w0kl")

[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
shadow_enabled = true

[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_fngcp")

[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(-0.48255, 0.449767, -0.751568, 0, 0.858084, 0.51351, 0.875869, 0.247794, -0.414068, -33.3619, 27.9191, -17.7105)
127 changes: 127 additions & 0 deletions project/multipass_generator/multipass_generator.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
extends VoxelGeneratorMultipassCB

const CHANNEL = VoxelBuffer.CHANNEL_TYPE

const AIR = 0
const STONE = 1
const LOG = 2
const LEAVES = 3

const SEED = 1337

var _noise : FastNoiseLite


func _init():
_noise = FastNoiseLite.new()
_noise.frequency = 1.0 / 128.0
_noise.seed = SEED


func _generate_pass(voxel_tool: VoxelToolMultipassGenerator, pass_index: int):
voxel_tool.channel = CHANNEL

var min_pos := voxel_tool.get_main_area_min()
var max_pos := voxel_tool.get_main_area_max()
# print("pass ", pass_index, ", min_pos: ", min_pos, ", max_pos: ", max_pos)

if pass_index == 0:
for gz in range(min_pos.z, max_pos.z):
for gx in range(min_pos.x, max_pos.x):
var height := 20.0 * _noise.get_noise_2d(gx, gz)
voxel_tool.value = STONE
voxel_tool.do_box(Vector3i(gx, min_pos.y, gz), Vector3i(gx, height, gz))

# This is just for testing do_path, also creating overhangs that show how tree generation
# benefits from multipass. In practice it's quite slow without checking boundaries.
generate_spiral(voxel_tool)

elif pass_index == 1:
var rng := RandomNumberGenerator.new()
rng.seed = hash(Vector2i(min_pos.x, min_pos.z)) + SEED

var tree_count := 3#rng.randi_range(0, 3)

for tree_index in tree_count:
try_plant_tree(voxel_tool, rng)


static func generate_spiral(voxel_tool: VoxelToolMultipassGenerator):
var positions := PackedVector3Array()
var radii := PackedFloat32Array()

var point_count := 100
var length := 100.0
var begin_position := Vector3(-40.0, 20.0, 20.0)
var radius := 15.0
var twist := 25.0

for i in point_count:
var t := i / float(point_count)
positions.append(begin_position + Vector3(
t * length, # X
radius * cos(t * twist), # Y
radius * sin(t * twist) # Z
))
radii.append(lerpf(2.0, 4.0, 0.5 + 0.5 * sin(t * 100.0)))

voxel_tool.do_path(positions, radii)


static func try_plant_tree(voxel_tool: VoxelToolMultipassGenerator, rng: RandomNumberGenerator):
var min_pos := voxel_tool.get_main_area_min()
var max_pos := voxel_tool.get_main_area_max()
var chunk_size = max_pos - min_pos

var tree_rpos := Vector3i(
rng.randi_range(0, chunk_size.x), 0,
rng.randi_range(0, chunk_size.z)
)
# print("Trying to plant a tree at ", tree_rpos)

var tree_pos := min_pos + tree_rpos
tree_pos.y = max_pos.y - 1

var found_ground := false
while tree_pos.y >= min_pos.y:
var v := voxel_tool.get_voxel(tree_pos)
# Note, we could also find tree blocks that were placed earlier!
if v == STONE:
found_ground = true
break
tree_pos.y -= 1

if not found_ground:
# print("Ground not found")
return

# Plant tree
var trunk_height := rng.randi_range(8, 15)
var leaves_min_y := 3 * trunk_height / 2
var leaves_max_y := trunk_height + 2
var leaves_min_radius := 2
var leaves_max_radius := 5

if tree_pos.y + leaves_max_y + leaves_max_radius >= max_pos.y:
# Too high
# print("Too high")
return

voxel_tool.value = LEAVES
for i in 5:
var center := tree_pos + Vector3i(0, rng.randi_range(leaves_min_y, leaves_max_y), 0)
var radius := rng.randf_range(leaves_min_radius, leaves_max_radius)
voxel_tool.do_sphere(center, radius)

voxel_tool.value = LOG
voxel_tool.do_box(tree_pos, tree_pos + Vector3i(0, trunk_height, 0))


func _generate_block_fallback(out_buffer: VoxelBuffer, origin_in_voxels: Vector3i):
pass


func _get_used_channels_mask() -> int:
return 1 << CHANNEL


9 changes: 9 additions & 0 deletions project/multipass_generator/multipass_generator.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[gd_resource type="VoxelGeneratorMultipassCB" load_steps=2 format=3 uid="uid://dqgjcqp0m4ae2"]

[ext_resource type="Script" path="res://multipass_generator/multipass_generator.gd" id="1_jgwux"]

[resource]
pass_count = 3
pass_1_extent = 1
pass_2_extent = 1
script = ExtResource("1_jgwux")
8 changes: 8 additions & 0 deletions project/multipass_generator/opaque_material.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://l26jp5hcwveg"]

[ext_resource type="Texture2D" uid="uid://bgxqjxpjjrbug" path="res://multipass_generator/terrain.png" id="1_2tubt"]

[resource]
vertex_color_use_as_albedo = true
albedo_texture = ExtResource("1_2tubt")
texture_filter = 0
Binary file added project/multipass_generator/terrain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions project/multipass_generator/terrain.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://bgxqjxpjjrbug"
path.s3tc="res://.godot/imported/terrain.png-1a8a53d00d70a507f028e21c793ee320.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}

[deps]

source_file="res://multipass_generator/terrain.png"
dest_files=["res://.godot/imported/terrain.png-1a8a53d00d70a507f028e21c793ee320.s3tc.ctex"]

[params]

compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

0 comments on commit 2147d81

Please sign in to comment.