terrain updates
This commit is contained in:
@@ -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
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user