terrain updates

This commit is contained in:
Turánszki János
2024-05-26 05:42:43 +02:00
parent 345e0261bd
commit 02acde0f34
8 changed files with 50 additions and 29 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ Snow texture:
https://www.sharetextures.com/textures/ground/snow_ground_3/
Sand texture:
https://www.cgbookcase.com/textures/sandy-gravel-01/?source=3dassets.one
https://ambientcg.com/view?id=Ground033
Stone texture:
ambientCG (ambientCG.com)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1024 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

@@ -1382,7 +1382,13 @@ struct TerrainVirtualTexturePush
uint write_size;
float resolution_rcp;
int blendmap_buffer;
uint blendmap_buffer_offset;
int blendmap_texture;
uint blendmap_layers;
int output_texture;
int padding0;
};
struct VirtualTextureResidencyUpdateCB
{
@@ -4,19 +4,10 @@
PUSHCONSTANT(push, TerrainVirtualTexturePush);
Texture2DArray<float> blendmap : register(t0);
ByteAddressBuffer blendmap_buffer : register(t1);
#if !defined(UPDATE_NORMALMAP) && !defined(UPDATE_SURFACEMAP) && !defined(UPDATE_EMISSIVEMAP)
#define UPDATE_BASECOLORMAP
#endif
#if defined(UPDATE_BASECOLORMAP) || defined(UPDATE_EMISSIVEMAP)
RWTexture2D<uint2> output : register(u0);
#else
RWTexture2D<uint4> output : register(u0);
#endif
static const uint2 block_offsets[16] = {
uint2(0, 0), uint2(1, 0), uint2(2, 0), uint2(3, 0),
uint2(0, 1), uint2(1, 1), uint2(2, 1), uint2(3, 1),
@@ -30,9 +21,14 @@ void main(uint3 DTid : SV_DispatchThreadID)
if (DTid.x >= push.write_size || DTid.y >= push.write_size)
return;
uint2 dim;
uint array_size;
blendmap.GetDimensions(dim.x, dim.y, array_size);
Texture2DArray blendmap = bindless_textures2DArray[push.blendmap_texture];
ByteAddressBuffer blendmap_buffer = bindless_buffers[push.blendmap_buffer];
#if defined(UPDATE_BASECOLORMAP) || defined(UPDATE_EMISSIVEMAP)
RWTexture2D<uint2> output = bindless_rwtextures_uint2[push.output_texture];
#else
RWTexture2D<uint4> output = bindless_rwtextures_uint4[push.output_texture];
#endif
#ifdef UPDATE_BASECOLORMAP
float3 block_rgb[16];
@@ -63,9 +59,9 @@ void main(uint3 DTid : SV_DispatchThreadID)
float accumulation = 0;
// Note: blending is front-to back with early exit like decals
for(int blendmap_index = array_size - 1; blendmap_index >= 0; blendmap_index--)
for(int blendmap_index = push.blendmap_layers - 1; blendmap_index >= 0; blendmap_index--)
{
float weight = blendmap.SampleLevel(sampler_linear_clamp, float3(uv, blendmap_index), 0);
float weight = blendmap.SampleLevel(sampler_linear_clamp, float3(uv, blendmap_index), 0).r;
if(weight == 0)
continue;
+30 -12
View File
@@ -229,6 +229,7 @@ namespace wi::terrain
bool success = device->CreateTexture(&td, nullptr, &residencyMap);
assert(success);
device->SetName(&residencyMap, "VirtualTexture::residencyMap");
residency_cleared = false;
for (uint32_t i = 0; i < lod_count; ++i)
{
@@ -304,6 +305,7 @@ namespace wi::terrain
data_available_CPU[i] = false;
}
cpu_resource_id = 0;
residency_cleared = false;
}
void VirtualTexture::init(VirtualTextureAtlas& atlas, uint resolution)
@@ -1351,9 +1353,11 @@ namespace wi::terrain
bool success = device->CreateTexture(&desc, nullptr, &atlas.maps[map_type].texture);
assert(success);
device->SetName(&atlas.maps[map_type].texture, "VirtualTextureAtlas::texture");
success = device->CreateTexture(&desc_raw_block, nullptr, &atlas.maps[map_type].texture_raw_block);
assert(success);
device->SetName(&atlas.maps[map_type].texture_raw_block, "VirtualTextureAtlas::texture_raw_block");
assert(atlas.maps[map_type].texture.sparse_properties->total_tile_count == atlas.maps[map_type].texture_raw_block.sparse_properties->total_tile_count);
assert(atlas.maps[map_type].texture.sparse_page_size == atlas.maps[map_type].texture_raw_block.sparse_page_size);
@@ -1674,9 +1678,16 @@ namespace wi::terrain
device->ClearUAV(&vt->residency->feedbackMap, 0xFF, cmd);
device->ClearUAV(&vt->residency->requestBuffer, 0xFF, cmd);
device->ClearUAV(&vt->residency->allocationBuffer, 0, cmd);
if (!vt->residency->residency_cleared)
{
vt->residency->residency_cleared = true;
device->ClearUAV(&vt->residency->residencyMap, 0, cmd);
}
}
device->EventEnd(cmd);
device->Barrier(GPUBarrier::Memory(), cmd);
device->EventBegin("Update Residency Maps", cmd);
device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_VIRTUALTEXTURE_RESIDENCYUPDATE), cmd);
for (const VirtualTexture* vt : virtual_textures_in_use)
@@ -1719,28 +1730,37 @@ namespace wi::terrain
continue;
for (uint32_t map_type = 0; map_type < arraysize(atlas.maps); map_type++)
{
TerrainVirtualTexturePush push = {};
switch (map_type)
{
case MaterialComponent::BASECOLORMAP:
device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_BASECOLORMAP), cmd);
device->BindUAV(&atlas.maps[MaterialComponent::BASECOLORMAP].texture_raw_block, 0, cmd);
push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::BASECOLORMAP].texture_raw_block, SubresourceType::UAV);
break;
case MaterialComponent::NORMALMAP:
device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_NORMALMAP), cmd);
device->BindUAV(&atlas.maps[MaterialComponent::NORMALMAP].texture_raw_block, 0, cmd);
push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::NORMALMAP].texture_raw_block, SubresourceType::UAV);
break;
case MaterialComponent::SURFACEMAP:
device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_SURFACEMAP), cmd);
device->BindUAV(&atlas.maps[MaterialComponent::SURFACEMAP].texture_raw_block, 0, cmd);
push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::SURFACEMAP].texture_raw_block, SubresourceType::UAV);
break;
case MaterialComponent::EMISSIVEMAP:
device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_EMISSIVEMAP), cmd);
device->BindUAV(&atlas.maps[MaterialComponent::EMISSIVEMAP].texture_raw_block, 0, cmd);
push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::EMISSIVEMAP].texture_raw_block, SubresourceType::UAV);
break;
default:
assert(0);
break;
}
if (push.output_texture < 0)
continue;
push.blendmap_texture = device->GetDescriptorIndex(&vt->blendmap, SubresourceType::SRV);
push.blendmap_layers = vt->blendmap.desc.array_size;
if (push.blendmap_texture < 0)
continue;
auto mem = device->AllocateGPU(sizeof(uint) * vt->blendmap.desc.array_size, cmd);
const uint blendcount = std::min(vt->blendmap.desc.array_size, uint(materialEntities.size()));
@@ -1749,9 +1769,11 @@ namespace wi::terrain
const uint material_index = (uint)scene->materials.GetIndex(materialEntities[i]);
std::memcpy((uint*)mem.data + i, &material_index, sizeof(uint)); // force memcpy to avoid uncached write into GPU pointer!
}
const uint blendmap_buffer_offset = (uint)mem.offset;
device->BindResource(&vt->blendmap, 0, cmd);
device->BindResource(&mem.buffer, 1, cmd);
push.blendmap_buffer = device->GetDescriptorIndex(&mem.buffer, SubresourceType::SRV);
if (push.blendmap_buffer < 0)
continue;
push.blendmap_buffer_offset = (uint)mem.offset;
for (auto& request : vt->update_requests)
{
@@ -1761,17 +1783,14 @@ namespace wi::terrain
request.tile_y * SVT_TILE_SIZE_PADDED / 4
);
TerrainVirtualTexturePush push;
push.offset = int2(
int(request.x * SVT_TILE_SIZE) - int(SVT_TILE_BORDER),
int(request.y * SVT_TILE_SIZE) - int(SVT_TILE_BORDER)
);
push.blendmap_buffer_offset = blendmap_buffer_offset;
if (request_lod_resolution < SVT_TILE_SIZE)
{
// packed mips
uint32_t tail_mip_idx = 0;
while (request_lod_resolution >= 4u)
{
@@ -1866,8 +1885,7 @@ namespace wi::terrain
device->EventEnd(cmd);
}
GPUBarrier memory_barrier = GPUBarrier::Memory();
device->Barrier(&memory_barrier, 1, cmd);
device->Barrier(GPUBarrier::Memory(), cmd);
{
device->EventBegin("Tile Allocation Requests", cmd);
+2 -1
View File
@@ -97,6 +97,7 @@ namespace wi::terrain
bool data_available_CPU[wi::graphics::GraphicsDevice::GetBufferCount() + 1] = {};
int cpu_resource_id = 0;
uint32_t resolution = 0;
bool residency_cleared = false;
void init(uint32_t resolution);
void reset();
@@ -132,7 +133,7 @@ namespace wi::terrain
uint64_t get_tile_frames(const Tile& tile) const
{
if (!tile.IsValid())
return false;
return ~0ull;
return physical_tiles[tile.x + tile.y * physical_tile_count_x].free_frames;
}
std::shared_ptr<Residency> allocate_residency(uint32_t resolution)
+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 = 466;
const int revision = 467;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);