From cd8c2537defd71f9cd880da98386f4747f679439 Mon Sep 17 00:00:00 2001 From: Pursche Date: Sat, 30 Sep 2023 22:36:00 +0200 Subject: [PATCH] Improve water rendering to correctly load textures --- Source/Game/Game/ECS/Singletons/LiquidDB.h | 19 ++ Source/Game/Game/Editor/MapEditor.cpp | 7 - .../Game/Loaders/ClientDB/ClientDBLoader.cpp | 32 ++- Source/Game/Game/Rendering/Canvas/Canvas.cpp | 4 +- .../Game/Rendering/Debug/DebugRenderer.cpp | 18 +- .../Game/Rendering/Terrain/TerrainLoader.cpp | 6 + .../Game/Game/Rendering/Water/WaterLoader.cpp | 9 +- .../Game/Rendering/Water/WaterRenderer.cpp | 182 ++++++++++++------ .../Game/Game/Rendering/Water/WaterRenderer.h | 17 +- Source/Shaders/Water/Draw.ps.hlsl | 22 +-- Submodules/Engine | 2 +- 11 files changed, 228 insertions(+), 90 deletions(-) create mode 100644 Source/Game/Game/ECS/Singletons/LiquidDB.h diff --git a/Source/Game/Game/ECS/Singletons/LiquidDB.h b/Source/Game/Game/ECS/Singletons/LiquidDB.h new file mode 100644 index 00000000..0c5c6c82 --- /dev/null +++ b/Source/Game/Game/ECS/Singletons/LiquidDB.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include + +#include +#include + +#include + +namespace ECS::Singletons +{ + struct LiquidDB + { + public: + LiquidDB() {} + + DB::Client::ClientDB liquidTypes; + }; +} \ No newline at end of file diff --git a/Source/Game/Game/Editor/MapEditor.cpp b/Source/Game/Game/Editor/MapEditor.cpp index 2f251ebe..185cea04 100644 --- a/Source/Game/Game/Editor/MapEditor.cpp +++ b/Source/Game/Game/Editor/MapEditor.cpp @@ -5,7 +5,6 @@ #include "Game/ECS/Util/MapDBUtil.h" #include "Game/Rendering/GameRenderer.h" #include "Game/Rendering/Terrain/TerrainLoader.h" -#include "Game/Rendering/Model/ModelLoader.h" #include "Game/Util/ServiceLocator.h" #include @@ -125,12 +124,6 @@ namespace Editor { if (DB::Client::Definitions::Map* map = ECS::Util::MapDB::GetMapFromName(*preview)) { - if (_hasLoadedMap) - { - ModelLoader* modelLoader = ServiceLocator::GetGameRenderer()->GetModelLoader(); - modelLoader->Clear(); - } - const std::string& mapInternalName = mapDB.entries.stringTable.GetString(map->internalName); TerrainLoader* terrainLoader = ServiceLocator::GetGameRenderer()->GetTerrainLoader(); diff --git a/Source/Game/Game/Loaders/ClientDB/ClientDBLoader.cpp b/Source/Game/Game/Loaders/ClientDB/ClientDBLoader.cpp index 7075d7fb..8a56b766 100644 --- a/Source/Game/Game/Loaders/ClientDB/ClientDBLoader.cpp +++ b/Source/Game/Game/Loaders/ClientDB/ClientDBLoader.cpp @@ -1,6 +1,7 @@ #include "Game/Loaders/LoaderSystem.h" #include "Game/Util/ServiceLocator.h" #include "Game/ECS/Singletons/MapDB.h" +#include "Game/ECS/Singletons/LiquidDB.h" #include "Game/Application/EnttRegistries.h" #include @@ -97,6 +98,7 @@ class ClientDBLoader : Loader void SetupSingletons(entt::registry::context& registryCtx) { registryCtx.emplace(); + registryCtx.emplace(); } bool LoadMapDB(entt::registry::context& registryCtx, std::shared_ptr& buffer, const ClientDBPair& pair) @@ -127,6 +129,8 @@ class ClientDBLoader : Loader continue; } + mapDB.entries.idToIndexMap[map.id] = i; + const std::string& mapName = stringTable.GetString(map.name); u32 mapNameHash = StringUtils::fnv1a_32(mapName.c_str(), mapName.length()); @@ -138,9 +142,35 @@ class ClientDBLoader : Loader return true; } + bool LoadLiquidTypeDB(entt::registry::context& registryCtx, std::shared_ptr& buffer, const ClientDBPair& pair) + { + auto& liquidDB = registryCtx.at(); + + // Clear, in case we already filled liquidDB + liquidDB.liquidTypes.data.clear(); + liquidDB.liquidTypes.stringTable.Clear(); + + if (!liquidDB.liquidTypes.Read(buffer)) + { + return false; + } + + u32 numRecords = static_cast(liquidDB.liquidTypes.data.size()); + + for (u32 i = 0; i < numRecords; i++) + { + const DB::Client::Definitions::LiquidType& type = liquidDB.liquidTypes.data[i]; + + liquidDB.liquidTypes.idToIndexMap[type.id] = i; + } + + return true; + } + robin_hood::unordered_map&, const ClientDBPair&)>> clientDBEntries = { - { "Map.cdb"_h, std::bind(&ClientDBLoader::LoadMapDB, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) } + { "Map.cdb"_h, std::bind(&ClientDBLoader::LoadMapDB, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) }, + { "LiquidType.cdb"_h, std::bind(&ClientDBLoader::LoadLiquidTypeDB, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) } }; }; diff --git a/Source/Game/Game/Rendering/Canvas/Canvas.cpp b/Source/Game/Game/Rendering/Canvas/Canvas.cpp index 68b963d4..8aa656d7 100644 --- a/Source/Game/Game/Rendering/Canvas/Canvas.cpp +++ b/Source/Game/Game/Rendering/Canvas/Canvas.cpp @@ -104,8 +104,8 @@ void Canvas::DrawText(Renderer::Font& font, const std::string& text, const vec2& // Add char draw data CanvasCharDrawData& charDrawData = charDrawDatas.emplace_back(); charDrawData.data.x = fontChar.textureIndex; - charDrawData.data.y = Color::White.ToU32(); - charDrawData.data.z = Color::Black.ToU32(); + charDrawData.data.y = Color::White.ToABGR32(); + charDrawData.data.z = Color::Black.ToABGR32(); f32 outlineWidth = 0.5f; charDrawData.data.w = *reinterpret_cast(&outlineWidth); diff --git a/Source/Game/Game/Rendering/Debug/DebugRenderer.cpp b/Source/Game/Game/Rendering/Debug/DebugRenderer.cpp index b20253bb..383ff78a 100644 --- a/Source/Game/Game/Rendering/Debug/DebugRenderer.cpp +++ b/Source/Game/Game/Rendering/Debug/DebugRenderer.cpp @@ -400,7 +400,7 @@ void DebugRenderer::DrawLine2D(const glm::vec2& from, const glm::vec2& to, Color { auto& vertices = _debugVertices2D.Get(); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); vertices.push_back({ from, colorInt }); vertices.push_back({ to, colorInt }); @@ -410,7 +410,7 @@ void DebugRenderer::DrawLine3D(const glm::vec3& from, const glm::vec3& to, Color { auto& vertices = _debugVertices3D.Get(); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); vertices.push_back({ from, colorInt }); vertices.push_back({ to, colorInt }); @@ -423,7 +423,7 @@ void DebugRenderer::DrawAABB3D(const vec3& center, const vec3& extents, Color co vec3 v0 = center - extents; vec3 v1 = center + extents; - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); // Bottom vertices.push_back({ { v0.x, v0.y, v0.z }, colorInt }); @@ -460,7 +460,7 @@ void DebugRenderer::DrawOBB3D(const vec3& center, const vec3& extents, const qua { auto& vertices = _debugVertices3D.Get(); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); vec3 corners[8] = { center + rotation * glm::vec3(-extents.x, -extents.y, -extents.z), @@ -522,7 +522,7 @@ void DebugRenderer::DrawCircle3D(const vec3& center, f32 radius, i32 resolution, { auto& vertices = _debugVertices3D.Get(); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); constexpr f32 PI = glm::pi(); constexpr f32 TAU = PI * 2.0f; @@ -587,7 +587,7 @@ void DebugRenderer::DrawMatrix(const mat4x4& matrix, f32 scale) void DebugRenderer::DrawLineSolid2D(const vec2& from, const vec2& to, Color color, bool shaded) { color.a = static_cast(shaded); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); auto& vertices = _debugVerticesSolid2D.Get(); @@ -611,7 +611,7 @@ void DebugRenderer::DrawAABBSolid3D(const vec3& center, const vec3& extents, Col vec3 rightNormal = { 1, 0, 0 }; color.a = static_cast(shaded); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); f32 colorFloat = *reinterpret_cast(&colorInt); // Bottom @@ -693,7 +693,7 @@ void DebugRenderer::DrawOBBSolid3D(const vec3& center, const vec3& extents, cons vec3 rightNormal = rotation * vec3(1, 0, 0); color.a = static_cast(shaded); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); f32 colorFloat = *reinterpret_cast(&colorInt); // Bottom @@ -767,7 +767,7 @@ void DebugRenderer::DrawTriangleSolid3D(const vec3& v0, const vec3& v1, const ve vec3 normal = glm::normalize(glm::cross(v1 - v0, v2 - v0)); color.a = static_cast(shaded); - u32 colorInt = color.ToU32(); + u32 colorInt = color.ToABGR32(); f32 colorFloat = *reinterpret_cast(&colorInt); vertices.push_back({ vec4(v0, 0.0f), vec4(normal, colorFloat ) }); diff --git a/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp b/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp index 569ecfbb..6c3babd9 100644 --- a/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp +++ b/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp @@ -516,6 +516,12 @@ void TerrainLoader::PrepareForChunks(LoadType loadType, u32 numChunks) { _terrainRenderer->ClearChunks(); + ModelLoader* modelLoader = ServiceLocator::GetGameRenderer()->GetModelLoader(); + modelLoader->Clear(); + + WaterLoader* waterLoader = ServiceLocator::GetGameRenderer()->GetWaterLoader(); + waterLoader->Clear(); + for (auto& pair : _chunkIDToBodyID) { JPH::BodyID id = static_cast(pair.second); diff --git a/Source/Game/Game/Rendering/Water/WaterLoader.cpp b/Source/Game/Game/Rendering/Water/WaterLoader.cpp index 3aaccd90..d1d3ffd5 100644 --- a/Source/Game/Game/Rendering/Water/WaterLoader.cpp +++ b/Source/Game/Game/Rendering/Water/WaterLoader.cpp @@ -28,7 +28,13 @@ void WaterLoader::Init() void WaterLoader::Clear() { + LoadRequestInternal dummyRequest; + while (_requests.try_dequeue(dummyRequest)) + { + // Just empty the queue + } + _waterRenderer->Clear(); } void WaterLoader::Update(f32 deltaTime) @@ -68,7 +74,7 @@ void WaterLoader::Update(f32 deltaTime) // Have WaterRenderer prepare all buffers for what we need to load _waterRenderer->Reserve(reserveInfo); -#if 1 +#if 0 for (u32 i = 0; i < numDequeued; i++) { LoadRequestInternal& request = _workingRequests[i]; @@ -209,7 +215,6 @@ void WaterLoader::LoadRequest(LoadRequestInternal& request) f32* heightMap = nullptr; u8* bitMap = nullptr; - //Terrain::LiquidUVMapEntry* uvEntries = nullptr; if (request.vertexData != nullptr && hasVertexData) { diff --git a/Source/Game/Game/Rendering/Water/WaterRenderer.cpp b/Source/Game/Game/Rendering/Water/WaterRenderer.cpp index 52237125..65aedba2 100644 --- a/Source/Game/Game/Rendering/Water/WaterRenderer.cpp +++ b/Source/Game/Game/Rendering/Water/WaterRenderer.cpp @@ -3,6 +3,7 @@ #include "Game/Rendering/Debug/DebugRenderer.h" #include "Game/Rendering/RenderUtils.h" #include "Game/Rendering/RenderResources.h" +#include "Game/ECS/Singletons/LiquidDB.h" #include #include @@ -15,7 +16,7 @@ AutoCVar_Int CVAR_WaterOcclusionCullingEnabled("waterRenderer.culling.occlusion" AutoCVar_Int CVAR_WaterDrawAABBs("waterRenderer.debug.drawAABBs", "if enabled, the culling pass will debug draw all AABBs", 0, CVarFlags::EditCheckbox); -AutoCVar_Float CVAR_WaterVisibilityRange("waterRenderer.visibilityRange", "How far underwater you should see", 3.0f, CVarFlags::EditFloatDrag); +AutoCVar_Float CVAR_WaterVisibilityRange("waterRenderer.visibilityRange", "How far underwater you should see", 500.0f, CVarFlags::EditFloatDrag); WaterRenderer::WaterRenderer(Renderer::Renderer* renderer, DebugRenderer* debugRenderer) : CulledRenderer(renderer, debugRenderer) @@ -35,6 +36,9 @@ void WaterRenderer::Update(f32 deltaTime) if (!CVAR_WaterRendererEnabled.Get()) return; + _constants.waterVisibilityRange = CVAR_WaterVisibilityRange.GetFloat(); + _constants.currentTime += deltaTime; + const bool cullingEnabled = CVAR_WaterCullingEnabled.Get(); _cullingResources.Update(deltaTime, cullingEnabled); @@ -43,10 +47,9 @@ void WaterRenderer::Update(f32 deltaTime) void WaterRenderer::Clear() { - _cullingResources.Clear(); - _cullingDatas.Clear(); + _cullingResources.Clear(); _instanceIndex.store(0); _vertices.Clear(); @@ -54,6 +57,8 @@ void WaterRenderer::Clear() _indices.Clear(); _indicesIndex.store(0); + + _renderer->UnloadTexturesInArray(_textures, 1); } void WaterRenderer::Reserve(ReserveInfo& info) @@ -102,22 +107,65 @@ void WaterRenderer::Load(LoadDesc& desc) DrawCallData& drawCallData = drawCallDatas[instanceOffset]; drawCallData.chunkID = desc.chunkID; drawCallData.cellID = desc.cellID; + drawCallData.textureStartIndex = 0; + drawCallData.textureCount = 1; + drawCallData.hasDepth = 0; + drawCallData.liquidType = 0; + drawCallData.uvAnim = hvec2(0, 0); + + // Load textures if they exist + entt::registry* registry = ServiceLocator::GetEnttRegistries()->gameRegistry; + entt::registry::context& ctx = registry->ctx(); - /*NDBC::LiquidType* liquidType = liquidTypesNDBC->GetRowById(liquidInstance.liquidTypeID); - const std::string& liquidTexture = liquidTypesStringTable->GetString(liquidType->texture); - u32 liquidTextureHash = liquidTypesStringTable->GetStringHash(liquidType->texture); + bool isLavaOrSlime = false; - u32 textureIndex; - if (!TryLoadTexture(liquidTexture, liquidTextureHash, liquidType->numTextureFrames, textureIndex)) + auto& liquidDB = ctx.at(); + if (liquidDB.liquidTypes.HasEntry(desc.typeID)) { - DebugHandler::PrintFatal("WaterRenderer::RegisterChunksToBeLoaded : failed to load texture %s", liquidTexture.c_str()); - }*/ + const DB::Client::Definitions::LiquidType& liquidType = liquidDB.liquidTypes.GetEntry(desc.typeID); + + u32 textureHash = liquidType.textures[0]; + const std::string& baseTextureName = liquidDB.liquidTypes.stringTable.GetString(textureHash); - drawCallData.textureStartIndex = 0;//static_cast(textureIndex); - drawCallData.textureCount = 0;//liquidType->numTextureFrames; - drawCallData.hasDepth = 0;//liquidType->hasDepthEnabled; - drawCallData.liquidType = 0;//liquidType->type; - drawCallData.uvAnim = hvec2(0, 0);//hvec2(liquidType->uvAnim); + u16 textureStartIndex = 0; + u32 textureCount = liquidType.frameCountTextures[0]; + + if (textureCount > std::numeric_limits().max()) + { + DebugHandler::PrintFatal("Tried to load a water texture with more than 255 frames!"); + } + + { + std::scoped_lock lock(_textureMutex); + + char textureBuffer[256]; + for (u32 i = 0; i < liquidType.frameCountTextures[0]; i++) + { + i32 length = StringUtils::FormatString(textureBuffer, 256, baseTextureName.c_str(), i + 1); + + Renderer::TextureDesc textureDesc; + textureDesc.path = "Data/Texture/" + std::string(textureBuffer, length); + + u32 index; + _renderer->LoadTextureIntoArray(textureDesc, _textures, index); + + if (i == 0) + { + textureStartIndex = static_cast(index); + } + } + } + + if (liquidType.soundBank == 2 || liquidType.soundBank == 3) + { + isLavaOrSlime = true; + } + + drawCallData.textureStartIndex = textureStartIndex; + drawCallData.textureCount = textureCount; + drawCallData.liquidType = liquidType.soundBank; // This is a workaround for now, but we don't want to rely on soundbank for knowing if this is water, lava or slime in the future + drawCallData.uvAnim = hvec2(0, 0); // TODO: Load this from Vertex format data + } vec3 min = vec3(100000, 100000, 100000); vec3 max = vec3(-100000, -100000, -100000); @@ -132,21 +180,23 @@ void WaterRenderer::Load(LoadDesc& desc) u8 xOffset = x + desc.posX; f32 offsetX = -(static_cast(xOffset) * Terrain::PATCH_SIZE); - f32 vertexHeight = desc.defaultHeight; + u32 vertexDataIndex = (8 - y) + (x * (desc.height + 1)); + f32 vertexHeight = desc.defaultHeight; if (desc.heightMap != nullptr) { - u32 vertexHeightIndex = (8 - y) + (x * (desc.height + 1)); - vertexHeight = desc.heightMap[vertexHeightIndex]; + vertexHeight = desc.heightMap[vertexDataIndex]; } + vec2 cellOffsetPos = vec2(yOffset * Terrain::PATCH_SIZE, xOffset * Terrain::PATCH_SIZE); + vec3 cellPos = vec3(desc.cellPos.x - cellOffsetPos.x, vertexHeight, desc.cellPos.y - cellOffsetPos.y); + vec2 uv = vec2(static_cast(-y) / 2.0f, static_cast(-x) / 2.0f); // These need to be inverted and swizzled - /*if (uvEntries) + if (isLavaOrSlime) { - Terrain::LiquidUVMapEntry* uvEntry = &uvEntries[vertexIndex]; - uv = vec2(uvEntry->x, uvEntry->y); // This one however should not be inverted and swizzled - }*/ + uv = vec2(cellPos.x * 0.06f, cellPos.z * 0.06f); + } u32 vertexIndex = x + (y * (desc.width + 1)); Vertex& vertex = vertices[vertexOffset + vertexIndex]; @@ -157,8 +207,25 @@ void WaterRenderer::Load(LoadDesc& desc) vertex.height = f16(vertexHeight); vertex.uv = hvec2(uv); - vec2 cellOffsetPos = vec2(yOffset * Terrain::PATCH_SIZE, xOffset * Terrain::PATCH_SIZE); - vec3 cellPos = vec3(desc.cellPos.x - cellOffsetPos.x, vertexHeight, desc.cellPos.y - cellOffsetPos.y); + if (yOffset >= desc.endY || xOffset >= desc.endX) + { + vec2 minWithoutHeight = glm::min(vec2(min.x, min.z), vec2(cellPos.x, cellPos.z)); + vec2 maxWithoutHeight = glm::max(vec2(max.x, max.z), vec2(cellPos.x, cellPos.z)); + + min = vec3(minWithoutHeight.x, min.y, minWithoutHeight.y); + max = vec3(maxWithoutHeight.x, max.y, maxWithoutHeight.y); + continue; + } + + // Check if this tile is used + if (desc.bitMap != nullptr) + { + i32 maskIndex = (xOffset - desc.startX) * (desc.endY - desc.startY) + ((7 - yOffset) - desc.startY); + bool exists = (desc.bitMap[maskIndex >> 3] >> ((maskIndex & 7))) & 1; + + if (!exists) + continue; + } min = glm::min(min, cellPos); max = glm::max(max, cellPos); @@ -204,19 +271,6 @@ void WaterRenderer::Load(LoadDesc& desc) cullingData.center = min; // TODO: Unfuck our AABB representations, we currently mix AABBs with min/max variables and ones with center/extents... cullingData.extents = max; cullingData.boundingSphereRadius = glm::distance(min, max); - - if (cullingData.boundingSphereRadius > 100.0f) - { - volatile int asd = 123; - } - if (cullingData.boundingSphereRadius > 1000.0f) - { - volatile int asdf = 123; - } - if (cullingData.boundingSphereRadius > 10000.0f) - { - volatile int asdg = 123; - } } void WaterRenderer::AddCullingPass(Renderer::RenderGraph* renderGraph, RenderResources& resources, u8 frameIndex) @@ -465,6 +519,41 @@ void WaterRenderer::CreatePermanentResources() initParams.materialPassDescriptorSet = nullptr; // Transparencies, we don't draw these in materialPass initParams.enableTwoStepCulling = false; _cullingResources.Init(initParams); + + _constants.shallowOceanColor = Color::FromBGR32(2635575); + _constants.deepOceanColor = Color::FromBGR32(1387070); + _constants.shallowRiverColor = Color::FromBGR32(1856070); + _constants.deepRiverColor = Color::FromBGR32(861477); + _constants.waterVisibilityRange = CVAR_WaterVisibilityRange.GetFloat(); + _constants.currentTime = 0; + + Renderer::DescriptorSet& geometrySet = _cullingResources.GetGeometryPassDescriptorSet(); + + Renderer::TextureArrayDesc textureArrayDesc; + textureArrayDesc.size = 512; + _textures = _renderer->CreateTextureArray(textureArrayDesc); + geometrySet.Bind("_textures"_h, _textures); + + Renderer::DataTextureDesc dataTextureDesc; + dataTextureDesc.width = 1; + dataTextureDesc.height = 1; + dataTextureDesc.format = Renderer::ImageFormat::R8G8B8A8_UNORM_SRGB; + dataTextureDesc.data = new u8[4]{ 0, 0, 0, 255 }; // Black color, because water textures are additive + dataTextureDesc.debugName = "WaterDebugTexture"; + + u32 arrayIndex = 0; + _renderer->CreateDataTextureIntoArray(dataTextureDesc, _textures, arrayIndex); + + Renderer::SamplerDesc samplerDesc; + samplerDesc.enabled = true; + samplerDesc.filter = Renderer::SamplerFilter::ANISOTROPIC; + samplerDesc.addressU = Renderer::TextureAddressMode::WRAP; + samplerDesc.addressV = Renderer::TextureAddressMode::WRAP; + samplerDesc.addressW = Renderer::TextureAddressMode::CLAMP; + samplerDesc.shaderVisibility = Renderer::ShaderVisibility::PIXEL; + samplerDesc.maxAnisotropy = 8; + _sampler = _renderer->CreateSampler(samplerDesc); + geometrySet.Bind("_sampler"_h, _sampler); } void WaterRenderer::SyncToGPU() @@ -553,24 +642,7 @@ void WaterRenderer::Draw(const RenderResources& resources, u8 frameIndex, Render commandList.BindDescriptorSet(Renderer::DescriptorSetSlot::GLOBAL, params.globalDescriptorSet, frameIndex); commandList.BindDescriptorSet(Renderer::DescriptorSetSlot::PER_PASS, params.drawDescriptorSet, frameIndex); - struct Constants - { - Color shallowOceanColor; - Color deepOceanColor; - Color shallowRiverColor; - Color deepRiverColor; - float waterVisibilityRange; - float currentTime; - }; - Constants* constants = graphResources.FrameNew(); - - constants->shallowOceanColor = Color(28.0f / 255.0f, 163.0f / 255.0f, 236.0f / 255.0f, 0.5f); - constants->deepOceanColor = Color(15.0f / 255.0f, 94.0f / 255.0f, 156.0f / 255.0f, 0.9f); - constants->shallowRiverColor = Color(116.0f / 255.0f, 204.0f / 255.0f, 244.0f / 255.0f, 0.5f); - constants->deepRiverColor = Color(35.0f / 255.0f, 137.0f / 255.0f, 218.0f / 255.0f, 0.9f); - constants->waterVisibilityRange = CVAR_WaterVisibilityRange.GetFloat(); - constants->currentTime = 0.0f; // TODO - commandList.PushConstant(constants, 0, sizeof(Constants)); + commandList.PushConstant(&_constants, 0, sizeof(Constants)); commandList.SetIndexBuffer(_indices.GetBuffer(), Renderer::IndexFormat::UInt16); diff --git a/Source/Game/Game/Rendering/Water/WaterRenderer.h b/Source/Game/Game/Rendering/Water/WaterRenderer.h index 19ea47fb..d42b9a42 100644 --- a/Source/Game/Game/Rendering/Water/WaterRenderer.h +++ b/Source/Game/Game/Rendering/Water/WaterRenderer.h @@ -41,6 +41,16 @@ class WaterRenderer : CulledRenderer u16 padding0; hvec2 uvAnim = hvec2(f16(1), f16(0)); // x seems to be scrolling, y seems to be rotation }; + + struct Constants + { + Color shallowOceanColor; + Color deepOceanColor; + Color shallowRiverColor; + Color deepRiverColor; + f32 waterVisibilityRange; + f32 currentTime; + }; #pragma pack(pop) public: @@ -95,10 +105,11 @@ class WaterRenderer : CulledRenderer DebugRenderer* _debugRenderer = nullptr; Renderer::DescriptorSet _copyDescriptorSet; - //Renderer::DescriptorSet _cullingDescriptorSet; - //Renderer::DescriptorSet _passDescriptorSet; + + Constants _constants; Renderer::SamplerID _sampler; + Renderer::TextureArrayID _textures; CullingResources _cullingResources; std::atomic _instanceIndex = 0; @@ -108,4 +119,6 @@ class WaterRenderer : CulledRenderer Renderer::GPUVector _indices; std::atomic _indicesIndex = 0; + + std::mutex _textureMutex; }; \ No newline at end of file diff --git a/Source/Shaders/Water/Draw.ps.hlsl b/Source/Shaders/Water/Draw.ps.hlsl index 8e10ab84..12d39fc4 100644 --- a/Source/Shaders/Water/Draw.ps.hlsl +++ b/Source/Shaders/Water/Draw.ps.hlsl @@ -53,8 +53,8 @@ DrawCallData LoadDrawCallData(uint drawCallID) } [[vk::binding(2, PER_PASS)]] Texture2D _depthRT; -//[[vk::binding(2, PER_PASS)]] SamplerState _sampler; -//[[vk::binding(4, PER_PASS)]] Texture2D _textures[1024]; +[[vk::binding(3, PER_PASS)]] SamplerState _sampler; +[[vk::binding(4, PER_PASS)]] Texture2D _textures[512]; struct PSInput { @@ -92,15 +92,12 @@ PSOutput main(PSInput input) if (drawCallData.liquidType == 2 || drawCallData.liquidType == 3) // Lava or Slime { - float textureUVX = input.textureUV.x / 102.0f; // Found these by trial and error, unless we find another spot that looks bad this is what we're gonna use - float textureUVY = input.textureUV.y / 102.0f; - - float2 textureUV = float2(textureUVX, textureUVY); + float2 textureUV = float2(input.textureUV.x, input.textureUV.y); // Add slow scrolling effect - textureUV += drawCallData.uvAnim * (_constants.currentTime); + textureUV += /*drawCallData.uvAnim*/ float2(0.0f, 1.0f) * (_constants.currentTime) * 0.05f; - color = float4(1, 0, 0, 1);//_textures[drawCallData.textureStartIndex + textureAnimationOffset].Sample(_sampler, textureUV); + color = _textures[drawCallData.textureStartIndex + textureAnimationOffset].Sample(_sampler, textureUV); } else { @@ -111,12 +108,15 @@ PSOutput main(PSInput input) float blendFactor = clamp(linearDepthDifference, 0.0f, _constants.waterVisibilityRange) / _constants.waterVisibilityRange; // Blend color - color = lerp(_constants.shallowRiverColor, _constants.deepRiverColor, blendFactor); + float4 shallowColor = lerp(_constants.shallowRiverColor, _constants.shallowOceanColor, drawCallData.liquidType); + float4 deepColor = lerp(_constants.deepRiverColor, _constants.deepOceanColor, drawCallData.liquidType); + + color = lerp(shallowColor, deepColor, blendFactor); // Animate the texture UV - float2 textureUV = Rot2(input.textureUV * drawCallData.uvAnim.x, drawCallData.uvAnim.y); + float2 textureUV = input.textureUV;//Rot2(input.textureUV * drawCallData.uvAnim.x, drawCallData.uvAnim.y); - float3 texture0 = float3(0, 0, 1);//_textures[drawCallData.textureStartIndex + textureAnimationOffset].Sample(_sampler, textureUV).rgb; + float3 texture0 = _textures[drawCallData.textureStartIndex + textureAnimationOffset].Sample(_sampler, textureUV).rgb; color.rgb = saturate(color.rgb + texture0); } diff --git a/Submodules/Engine b/Submodules/Engine index 431ebb81..503b7b63 160000 --- a/Submodules/Engine +++ b/Submodules/Engine @@ -1 +1 @@ -Subproject commit 431ebb81c7dcedc573e0dbdac172f172a71a3cf1 +Subproject commit 503b7b633f83a5afb2335cbe8f51a81cdaac0a2c