diff --git a/res/shaders/TerrainPass.slang b/res/shaders/TerrainPass.slang index aa98028..233f02b 100644 --- a/res/shaders/TerrainPass.slang +++ b/res/shaders/TerrainPass.slang @@ -30,6 +30,7 @@ struct TerrainData { StructuredBuffer tiles; Texture2D displacement; + Texture2D colorMap; SamplerState sampler; }; ParameterBlock pTerrainData; @@ -44,7 +45,24 @@ void taskMain( GroupMemoryBarrierWithGroupSync(); AABB bounding; bounding.minCorner = float3(tile.location.x, tile.height, tile.location.y) * tile.extent; - bounding.maxCorner = float3(tile.location.x + 1, tile.height, tile.location.y + 1) * tile.extent; + bounding.maxCorner = float3(tile.location.x + tile.extent, tile.height, tile.location.y + tile.extent) * tile.extent; + float3 origin = viewToWorld(float4(0, 0, 0, 1)).xyz; + const float offset = 0.0f; + float3 corners[4] = { + screenToWorld(float4(offset, offset, -1.0f, 1.0f)).xyz, + screenToWorld(float4(pViewParams.c.screenDimensions.x - offset, offset, -1.0f, 1.0f)).xyz, + screenToWorld(float4(offset, pViewParams.c.screenDimensions.y - offset, -1.0f, 1.0f)).xyz, + screenToWorld(float4(pViewParams.c.screenDimensions - float2(offset, offset), -1.0f, 1.0f)).xyz + }; + Frustum viewFrustum; + viewFrustum.sides[0] = computePlane(origin, corners[2], corners[0]); + viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]); + viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]); + viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]); + if(!bounding.insideFrustum(viewFrustum)) + { + return; + } float3 median = (bounding.minCorner + bounding.maxCorner) / 2; float distance = distance(median, pViewParams.c.cameraPos_WS.xyz); float tileDistance = distance / tile.extent; @@ -151,7 +169,7 @@ void meshMain( // float3 displacement2 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(worldPos.xz * pWaterMaterial.tile2, 1)).xyz * pWaterMaterial.contributeDisplacement2; // float3 displacement3 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(worldPos.xz * pWaterMaterial.tile3, 2)).xyz * pWaterMaterial.contributeDisplacement3; // float3 displacement4 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(worldPos.xz * pWaterMaterial.tile4, 3)).xyz * pWaterMaterial.contributeDisplacement4; - float displacement = pTerrainData.displacement.SampleLevel(pTerrainData.sampler, worldPos.xz, 0); + float displacement = pTerrainData.displacement.SampleLevel(pTerrainData.sampler, worldPos.xz / 1000, 0) * 10; float4 clipPos = mul(vp, float4(worldPos, 1)); float ndcDepth = clipPos.z / clipPos.w; @@ -160,7 +178,7 @@ void meshMain( // displacement = lerp(0.0f, displacement, pow(saturate(depth), pTerrainData.displacementDepthAttenuation)); - worldPos += displacement; + worldPos.y += displacement; worldPos.y += lodDisplacement; TerrainVertex v; @@ -176,5 +194,5 @@ void meshMain( [shader("pixel")] float4 fragmentMain(TerrainVertex vertex) { - return float4(0, 1, 0, 1); + return float4(pTerrainData.colorMap.Sample(pTerrainData.sampler, vertex.position_WS.xz / 1000), 1); } \ No newline at end of file diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index fb2d290..e5e099a 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -72,6 +72,9 @@ int main() { AssetImporter::importTexture(TextureImportArgs{ .filePath = sourcePath / "import/textures/azeroth.png", }); + AssetImporter::importTexture(TextureImportArgs{ + .filePath = sourcePath / "import/textures/azeroth_height.png", + }); // AssetImporter::importMesh(MeshImportArgs{ // .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", // .importPath = "Whitechapel", diff --git a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp index cf9ac2e..503fd3c 100644 --- a/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/TerrainRenderer.cpp @@ -8,23 +8,36 @@ using namespace Seele; TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescriptorLayout viewParamsLayout) : graphics(graphics), scene(scene) { + struct TerrainTile { + IVector2 offset; + float extent; + float height; + }; + Array payloads; + for (int32 y = -100; y < 100; ++y) { + for (int32 x = -100; x < 100; ++x) { + payloads.add(TerrainTile{ + .offset = IVector2(x, y), + .extent = Component::TerrainTile::DIMENSIONS, + .height = 0, + }); + } + } tilesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .sourceData = + { + .size = sizeof(TerrainTile) * payloads.size(), + .data = (uint8*)payloads.data(), + }, + .numElements = payloads.size(), .dynamic = true, .name = "TilesBuffer", }); - float displacementData = 0; - displacementMap = graphics->createTexture2D(TextureCreateInfo{ - .sourceData = - { - .size = sizeof(float), - .data = (uint8*)&displacementData, - }, - .format = Gfx::SE_FORMAT_R32_SFLOAT, - .width = 1, - .height = 1, - .depth = 1, - .name = "TerrainDisplacement", - }); + tilesBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, + Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT); + colorMap = AssetRegistry::findTexture("", "azeroth")->getTexture(); + displacementMap = AssetRegistry::findTexture("", "azeroth_height")->getTexture(); + sampler = graphics->createSampler(SamplerCreateInfo{}); layout = graphics->createDescriptorLayout("pTerrainData"); layout->addDescriptorBinding(Gfx::DescriptorBinding{ @@ -37,6 +50,10 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe }); layout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + }); + layout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER, }); layout->create(); @@ -65,30 +82,11 @@ TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDe TerrainRenderer::~TerrainRenderer() {} void TerrainRenderer::beginFrame() { - struct TerrainTile { - IVector2 offset; - float extent; - float height; - }; - Array payloads; - scene->view([&](Component::TerrainTile& tile) { - payloads.add(TerrainTile{ - .offset = IVector2(tile.location), - .extent = Component::TerrainTile::DIMENSIONS, - .height = tile.height, - }); - }); - if (payloads.size() == 0) - return; - tilesBuffer->rotateBuffer(sizeof(TerrainTile) * payloads.size()); - tilesBuffer->updateContents(0, sizeof(TerrainTile) * payloads.size(), payloads.data()); - tilesBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, - Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT); - set = layout->allocateDescriptorSet(); set->updateBuffer(0, 0, tilesBuffer); - set->updateTexture(1, 0, Gfx::PTexture2D(displacementMap)); - set->updateSampler(2, 0, sampler); + set->updateTexture(1, 0, displacementMap); + set->updateTexture(2, 0, colorMap); + set->updateSampler(3, 0, sampler); set->writeChanges(); } @@ -97,7 +95,7 @@ Gfx::ORenderCommand TerrainRenderer::render(Gfx::PDescriptorSet viewParamsSet) { command->setViewport(viewport); command->bindPipeline(pipeline); command->bindDescriptor({viewParamsSet, set}); - command->drawMesh(400, 4, 1); + command->drawMesh(tilesBuffer->getNumElements(), 4, 1); return command; } diff --git a/src/Engine/Graphics/RenderPass/TerrainRenderer.h b/src/Engine/Graphics/RenderPass/TerrainRenderer.h index dcbbbc0..b593c4d 100644 --- a/src/Engine/Graphics/RenderPass/TerrainRenderer.h +++ b/src/Engine/Graphics/RenderPass/TerrainRenderer.h @@ -22,7 +22,8 @@ class TerrainRenderer { Gfx::PGraphicsPipeline pipeline; Gfx::PViewport viewport; Gfx::OShaderBuffer tilesBuffer; - Gfx::OTexture2D displacementMap; + Gfx::PTexture2D displacementMap; + Gfx::PTexture2D colorMap; Gfx::OSampler sampler; }; DEFINE_REF(TerrainRenderer); diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index 029cb15..960e4db 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -28,7 +28,7 @@ Matrix4 Viewport::getProjectionMatrix() const { // 0, 0, a, b, // 0, 0, 1, 0 //); - return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 10000.0f); + return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 1000.0f); } else { return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f); }