terrain generator: grass length, texture target resolution

This commit is contained in:
Turánszki János
2022-09-27 19:26:54 +02:00
parent feeb4e2bbe
commit 3a9bee53e1
7 changed files with 68 additions and 28 deletions
+39 -14
View File
@@ -274,7 +274,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
ClearTransform();
wi::gui::Window::Create(ICON_TERRAIN " Terrain", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE);
SetSize(XMFLOAT2(420, 860));
SetSize(XMFLOAT2(420, 900));
closeButton.SetTooltip("Delete Terrain.\nThis will bake generated virtual textures to static textures which could take a while!");
OnClose([=](wi::gui::EventArgs args) {
@@ -303,11 +303,13 @@ void TerrainWindow::Create(EditorComponent* _editor)
terrain->SetGrassEnabled(grassCheckBox.GetCheck());
terrain->lod_multiplier = lodSlider.GetValue();
terrain->texlod = texlodSlider.GetValue();
terrain->target_texture_resolution = (uint32_t)texResolutionSlider.GetValue();
terrain->generation = (int)generationSlider.GetValue();
terrain->prop_generation = (int)propGenerationSlider.GetValue();
terrain->physics_generation = (int)physicsGenerationSlider.GetValue();
terrain->prop_density = propDensitySlider.GetValue();
terrain->grass_density = grassDensitySlider.GetValue();
terrain->grass_length = grassLengthSlider.GetValue();
terrain->chunk_scale = scaleSlider.GetValue();
terrain->seed = (uint32_t)seedSlider.GetValue();
terrain->bottomLevel = bottomLevelSlider.GetValue();
@@ -390,6 +392,15 @@ void TerrainWindow::Create(EditorComponent* _editor)
});
AddWidget(&texlodSlider);
texResolutionSlider.Create(256, 4096, 1024, 4096 - 256, "Tex Resolution: ");
texResolutionSlider.SetTooltip("Virtual texture target resolution for most detailed chunk.\nNote: if chunk resolution is bigger than texture resolution, texture scaling will be applied to those chunks.");
texResolutionSlider.SetSize(XMFLOAT2(wid, hei));
texResolutionSlider.SetPos(XMFLOAT2(x, y += step));
texResolutionSlider.OnSlide([this](wi::gui::EventArgs args) {
terrain->target_texture_resolution = (uint32_t)args.iValue;
});
AddWidget(&texResolutionSlider);
generationSlider.Create(0, 16, 12, 16, "Generation Distance: ");
generationSlider.SetTooltip("How far out chunks will be generated (value is in number of chunks)");
generationSlider.SetSize(XMFLOAT2(wid, hei));
@@ -426,7 +437,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
});
AddWidget(&propDensitySlider);
grassDensitySlider.Create(0, 4, 1, 1000, "Grass Density: ");
grassDensitySlider.Create(0, 4, 2, 1000, "Grass Density: ");
grassDensitySlider.SetTooltip("Modifies overall grass density.");
grassDensitySlider.SetSize(XMFLOAT2(wid, hei));
grassDensitySlider.SetPos(XMFLOAT2(x, y += step));
@@ -435,6 +446,15 @@ void TerrainWindow::Create(EditorComponent* _editor)
});
AddWidget(&grassDensitySlider);
grassLengthSlider.Create(0, 8, 2, 1000, "Grass Length: ");
grassLengthSlider.SetTooltip("Modifies overall grass length.");
grassLengthSlider.SetSize(XMFLOAT2(wid, hei));
grassLengthSlider.SetPos(XMFLOAT2(x, y += step));
grassLengthSlider.OnSlide([this](wi::gui::EventArgs args) {
terrain->grass_properties.length = args.fValue;
});
AddWidget(&grassLengthSlider);
presetCombo.Create("Preset: ");
presetCombo.SetTooltip("Select a terrain preset");
presetCombo.SetSize(XMFLOAT2(wid, hei));
@@ -769,10 +789,13 @@ void TerrainWindow::SetEntity(Entity entity)
physicsCheckBox.SetCheck(terrain->IsPhysicsEnabled());
lodSlider.SetValue(terrain->lod_multiplier);
texlodSlider.SetValue(terrain->texlod);
texResolutionSlider.SetValue((float)terrain->target_texture_resolution);
generationSlider.SetValue((float)terrain->generation);
propGenerationSlider.SetValue((float)terrain->prop_generation);
physicsGenerationSlider.SetValue((float)terrain->physics_generation);
propDensitySlider.SetValue(terrain->prop_density);
grassDensitySlider.SetValue(terrain->grass_density);
grassLengthSlider.SetValue(terrain->grass_properties.length);
scaleSlider.SetValue(terrain->chunk_scale);
seedSlider.SetValue((float)terrain->seed);
bottomLevelSlider.SetValue(terrain->bottomLevel);
@@ -847,7 +870,7 @@ void TerrainWindow::SetupAssets()
terrain_preset.material_HighAltitude.textures[MaterialComponent::NORMALMAP].name = "terrain/high_altitude_nor.jpg";
terrain_preset.material_GrassParticle.textures[MaterialComponent::BASECOLORMAP].name = "terrain/grassparticle.png";
terrain_preset.material_GrassParticle.alphaRef = 0.75f;
terrain_preset.grass_properties.length = 5;
terrain_preset.grass_properties.length = 2;
terrain_preset.grass_properties.frameCount = 2;
terrain_preset.grass_properties.framesX = 1;
terrain_preset.grass_properties.framesY = 2;
@@ -866,16 +889,16 @@ void TerrainWindow::SetupAssets()
{
wi::terrain::Prop& prop = terrain_preset.props.emplace_back();
prop.min_count_per_chunk = 0;
prop.max_count_per_chunk = 10;
prop.max_count_per_chunk = 20;
prop.region = 0;
prop.region_power = 2;
prop.noise_frequency = 0.1f;
prop.noise_power = 1;
prop.threshold = 0.4f;
prop.min_size = 2.0f;
prop.max_size = 8.0f;
prop.min_y_offset = -0.5f;
prop.max_y_offset = -0.5f;
prop.min_size = 1.0f;
prop.max_size = 4.0f;
prop.min_y_offset = -0.25f;
prop.max_y_offset = -0.25f;
Entity mesh_entity = props_scene.Entity_FindByName("tree_mesh");
props_scene.impostors.Create(mesh_entity).swapInDistance = 200;
Entity object_entity = props_scene.Entity_FindByName("tree_object");
@@ -908,9 +931,9 @@ void TerrainWindow::SetupAssets()
prop.noise_power = 2;
prop.threshold = 0.5f;
prop.min_size = 0.02f;
prop.max_size = 4.0f;
prop.min_y_offset = -2;
prop.max_y_offset = 0.5f;
prop.max_size = 2.0f;
prop.min_y_offset = -1;
prop.max_y_offset = 0.25f;
Entity mesh_entity = props_scene.Entity_FindByName("rock_mesh");
Entity object_entity = props_scene.Entity_FindByName("rock_object");
ObjectComponent* object = props_scene.objects.GetComponent(object_entity);
@@ -942,9 +965,9 @@ void TerrainWindow::SetupAssets()
prop.noise_frequency = 0.01f;
prop.noise_power = 4;
prop.threshold = 0.1f;
prop.min_size = 0.1f;
prop.max_size = 1.5f;
prop.min_y_offset = -1;
prop.min_size = 0.05f;
prop.max_size = 0.5f;
prop.min_y_offset = -0.25;
prop.max_y_offset = 0;
Entity mesh_entity = props_scene.Entity_FindByName("bush_mesh");
Entity object_entity = props_scene.Entity_FindByName("bush_object");
@@ -1032,11 +1055,13 @@ void TerrainWindow::ResizeLayout()
physicsCheckBox.SetPos(XMFLOAT2(grassCheckBox.GetPos().x - 100, grassCheckBox.GetPos().y));
add(lodSlider);
add(texlodSlider);
add(texResolutionSlider);
add(generationSlider);
add(propGenerationSlider);
add(physicsGenerationSlider);
add(propDensitySlider);
add(grassDensitySlider);
add(grassLengthSlider);
add(presetCombo);
add(scaleSlider);
add(seedSlider);
+2
View File
@@ -58,11 +58,13 @@ public:
wi::gui::CheckBox physicsCheckBox;
wi::gui::Slider lodSlider;
wi::gui::Slider texlodSlider;
wi::gui::Slider texResolutionSlider;
wi::gui::Slider generationSlider;
wi::gui::Slider propGenerationSlider;
wi::gui::Slider physicsGenerationSlider;
wi::gui::Slider propDensitySlider;
wi::gui::Slider grassDensitySlider;
wi::gui::Slider grassLengthSlider;
wi::gui::ComboBox presetCombo;
wi::gui::Slider scaleSlider;
wi::gui::Slider seedSlider;
@@ -42,7 +42,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
tex.GetDimensions(dim.x, dim.y);
float2 diff = dim / output_dim;
float lod = log2(max(diff.x, diff.y));
float4 baseColorMap = tex.SampleLevel(sampler_linear_clamp, uv, lod);
float2 overscale = lod < 0 ? diff : 1;
float4 baseColorMap = tex.SampleLevel(sampler_linear_wrap, uv / overscale, lod);
baseColor *= baseColorMap;
}
total_baseColor += baseColor * weight;
@@ -56,7 +57,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
tex.GetDimensions(dim.x, dim.y);
float2 diff = dim / output_dim;
float lod = log2(max(diff.x, diff.y));
float4 surfaceMap = tex.SampleLevel(sampler_linear_clamp, uv, lod);
float2 overscale = lod < 0 ? diff : 1;
float4 surfaceMap = tex.SampleLevel(sampler_linear_wrap, uv / overscale, lod);
surface *= surfaceMap;
}
total_surface += surface * weight;
@@ -70,7 +72,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
tex.GetDimensions(dim.x, dim.y);
float2 diff = dim / output_dim;
float lod = log2(max(diff.x, diff.y));
float2 normalMap = tex.SampleLevel(sampler_linear_clamp, uv, lod).rg;
float2 overscale = lod < 0 ? diff : 1;
float2 normalMap = tex.SampleLevel(sampler_linear_wrap, uv / overscale, lod).rg;
normal = normalMap;
}
total_normal += normal * weight;
+1 -1
View File
@@ -51,7 +51,7 @@ namespace wi::scene
wi::ecs::ComponentManager<ScriptComponent>& scripts = componentLibrary.Register<ScriptComponent>("wi::scene::Scene::scripts");
wi::ecs::ComponentManager<ExpressionComponent>& expressions = componentLibrary.Register<ExpressionComponent>("wi::scene::Scene::expressions");
wi::ecs::ComponentManager<HumanoidComponent>& humanoids = componentLibrary.Register<HumanoidComponent>("wi::scene::Scene::humanoids");
wi::ecs::ComponentManager<wi::terrain::Terrain>& terrains = componentLibrary.Register<wi::terrain::Terrain>("wi::scene::Scene::terrains", 1); // version = 1
wi::ecs::ComponentManager<wi::terrain::Terrain>& terrains = componentLibrary.Register<wi::terrain::Terrain>("wi::scene::Scene::terrains", 2); // version = 2
// Non-serialized attributes:
float dt = 0;
+17 -9
View File
@@ -308,7 +308,7 @@ namespace wi::terrain
virtual_texture_barriers_end.clear();
// Check whether there are any materials that would write to virtual textures:
uint32_t max_texture_resolution = 0;
bool virtual_texture_any = false;
bool virtual_texture_available[MaterialComponent::TEXTURESLOT_COUNT] = {};
virtual_texture_available[MaterialComponent::SURFACEMAP] = true; // this is always needed to bake individual material properties
MaterialComponent* virtual_materials[4] = {
@@ -329,9 +329,7 @@ namespace wi::terrain
if (material->textures[i].resource.IsValid())
{
virtual_texture_available[i] = true;
const TextureDesc& desc = material->textures[i].resource.GetTexture().GetDesc();
max_texture_resolution = std::max(max_texture_resolution, desc.width);
max_texture_resolution = std::max(max_texture_resolution, desc.height);
virtual_texture_any = true;
}
break;
default:
@@ -384,14 +382,15 @@ namespace wi::terrain
}
}
// Grass density modification:
if (chunk_data.grass_entity != INVALID_ENTITY && std::abs(chunk_data.grass_density_current - grass_density) > std::numeric_limits<float>::epsilon())
// Grass property update:
if (chunk_data.grass_entity != INVALID_ENTITY)
{
wi::HairParticleSystem* grass = scene->hairs.GetComponent(chunk_data.grass_entity);
if (grass != nullptr)
{
chunk_data.grass_density_current = grass_density;
grass->strandCount = uint32_t(chunk_data.grass.strandCount * chunk_data.grass_density_current);
grass->length = grass_properties.length;
}
}
@@ -442,7 +441,7 @@ namespace wi::terrain
}
// Collect virtual texture update requests:
if (max_texture_resolution > 0)
if (virtual_texture_any)
{
uint32_t texture_lod = 0;
const float distsq = wi::math::DistanceSquared(camera.Eye, chunk_data.sphere.center);
@@ -459,7 +458,8 @@ namespace wi::terrain
texture_lod = uint32_t(dist_to_sphere * texlodMultiplier);
}
chunk_data.required_texture_resolution = uint32_t(max_texture_resolution / std::pow(2.0f, (float)std::max(0u, texture_lod)));
chunk_data.required_texture_resolution = uint32_t(target_texture_resolution / std::pow(2.0f, (float)std::max(0u, texture_lod)));
chunk_data.required_texture_resolution = AlignTo(chunk_data.required_texture_resolution, 8u);
chunk_data.required_texture_resolution = std::max(8u, chunk_data.required_texture_resolution);
MaterialComponent* material = scene->materials.GetComponent(chunk_data.entity);
@@ -935,7 +935,7 @@ namespace wi::terrain
case MaterialComponent::BASECOLORMAP:
case MaterialComponent::SURFACEMAP:
case MaterialComponent::NORMALMAP:
if (!tex.name.empty() && tex.GetGPUResource() != nullptr)
if (tex.GetGPUResource() != nullptr)
{
wi::vector<uint8_t> filedata;
if (wi::helper::saveTextureToMemory(tex.resource.GetTexture(), filedata))
@@ -1032,6 +1032,10 @@ namespace wi::terrain
{
archive >> physics_generation;
}
if (seri.GetVersion() >= 2)
{
archive >> target_texture_resolution;
}
size_t count = 0;
archive >> count;
@@ -1180,6 +1184,10 @@ namespace wi::terrain
{
archive << physics_generation;
}
if (seri.GetVersion() >= 2)
{
archive << target_texture_resolution;
}
archive << props.size();
for (size_t i = 0; i < props.size(); ++i)
+2
View File
@@ -140,6 +140,7 @@ namespace wi::terrain
int physics_generation = 3;
float prop_density = 1;
float grass_density = 1;
float grass_length = 1;
float chunk_scale = 1;
uint32_t seed = 3926;
float bottomLevel = -60;
@@ -147,6 +148,7 @@ namespace wi::terrain
float region1 = 1;
float region2 = 2;
float region3 = 8;
uint32_t target_texture_resolution = 1024;
wi::vector<std::shared_ptr<Modifier>> modifiers;
wi::vector<Modifier*> modifiers_to_remove;
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 55;
const int revision = 56;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);