From 881bc4d629affa07575600f22186fd0e96395d85 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 24 Apr 2026 12:20:32 +0200 Subject: [PATCH 1/2] Fix crash on Vulkan when constant buffer is missing --- Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp | 9 ++++++++- Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 4 +--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index 6c1b076fa..3bdccd2e1 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -604,7 +604,14 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des VkDeviceSize offset = 0, range = 0; uint32 dynamicOffset = 0; if (!handle) - handle = (GPUConstantBufferVulkan*)_device->HelperResources.GetDummyConstantBuffer(); + { + auto cb = (GPUConstantBufferVulkan*)_device->HelperResources.GetDummyConstantBuffer(); + // TODO: cache this allocation within a frame + const auto allocation = _device->UniformBufferUploader->Allocate(cb->GetSize(), 0, this); + Platform::MemoryClear(allocation.CPUAddress, allocation.Size); + cb->Allocation = allocation; + handle = cb; + } handle->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset); needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset, index); break; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index 112a64bf3..f63d2182f 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -946,9 +946,7 @@ GPUBufferVulkan* HelperResourcesVulkan::GetDummyVertexBuffer() GPUConstantBuffer* HelperResourcesVulkan::GetDummyConstantBuffer() { if (!_dummyCB) - { - _dummyCB = _device->CreateConstantBuffer(256, TEXT("DummyConstantBuffer")); - } + _dummyCB = _device->CreateConstantBuffer(1024, TEXT("DummyConstantBuffer")); return _dummyCB; } From e6c0836b0901713199d4309c64a922bb201bd55a Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 25 Apr 2026 10:31:21 +0200 Subject: [PATCH 2/2] Revert "Fix Blend Mode on Terrain materials to be unenviable due to not implemented" This reverts commit 641f70d4acb8986c794b7310958ca72a07ebc04b. Transparent material on terrain is used by terrain brushes and terrain highlight tools in editor. --- Source/Editor/Windows/Assets/MaterialWindow.cs | 11 +---------- .../Graphics/Materials/TerrainMaterialShader.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Source/Editor/Windows/Assets/MaterialWindow.cs b/Source/Editor/Windows/Assets/MaterialWindow.cs index b051542a1..934cd6594 100644 --- a/Source/Editor/Windows/Assets/MaterialWindow.cs +++ b/Source/Editor/Windows/Assets/MaterialWindow.cs @@ -57,7 +57,7 @@ namespace FlaxEditor.Windows.Assets [EditorOrder(20), VisibleIf(nameof(IsStandard)), EditorDisplay("General"), Tooltip("Defines how material inputs and properties are combined to result the final surface color.")] public MaterialShadingModel ShadingModel; - [EditorOrder(30), VisibleIf(nameof(ShowBlendMode)), EditorDisplay("General"), Tooltip("Determinates how materials' color should be blended with the background colors.")] + [EditorOrder(30), VisibleIf(nameof(IsStandard)), EditorDisplay("General"), Tooltip("Determinates how materials' color should be blended with the background colors.")] public MaterialBlendMode BlendMode; // Rendering @@ -145,7 +145,6 @@ namespace FlaxEditor.Windows.Assets // Visibility conditionals - private bool ShowBlendMode => Domain != MaterialDomain.Terrain; private bool IsPostProcess => Domain == MaterialDomain.PostProcess; private bool IsDecal => Domain == MaterialDomain.Decal; private bool IsGUI => Domain == MaterialDomain.GUI; @@ -188,14 +187,6 @@ namespace FlaxEditor.Windows.Assets // Link Window = window; - - // [Deprecated in 1.12] - // Fix old terrain materials to go back into opaque - if (Domain == MaterialDomain.Terrain && BlendMode != MaterialBlendMode.Opaque) - { - BlendMode = MaterialBlendMode.Opaque; - FlaxEngine.Scripting.InvokeOnUpdate(Window.MarkAsEdited); - } } /// diff --git a/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp b/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp index 4db4acda1..bb0796234 100644 --- a/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/TerrainMaterialShader.cpp @@ -150,6 +150,21 @@ bool TerrainMaterialShader::Load() } #endif + // Support blending but then use only emissive channel + switch (_info.BlendMode) + { + case MaterialBlendMode::Transparent: + psDesc.BlendMode = BlendingMode::AlphaBlend; + break; + case MaterialBlendMode::Additive: + psDesc.BlendMode = BlendingMode::Additive; + break; + case MaterialBlendMode::Multiply: + psDesc.BlendMode = BlendingMode::Multiply; + break; + default: ; + } + // GBuffer Pass psDesc.VS = _shader->GetVS("VS"); psDesc.PS = _shader->GetPS("PS_GBuffer"); @@ -170,6 +185,7 @@ bool TerrainMaterialShader::Load() // Depth Pass psDesc.CullMode = CullMode::TwoSided; + psDesc.BlendMode = BlendingMode::Opaque; psDesc.DepthClipEnable = false; psDesc.DepthWriteEnable = true; psDesc.DepthEnable = true;