diff --git a/Editor/ModelImporter_GLTF.cpp b/Editor/ModelImporter_GLTF.cpp index 0bba82f9e..b03fae984 100644 --- a/Editor/ModelImporter_GLTF.cpp +++ b/Editor/ModelImporter_GLTF.cpp @@ -138,7 +138,7 @@ std::shared_ptr RegisterTexture(tinygltf::Image *image, const string if (tex != nullptr) { - wiRenderer::AddDeferredMIPGen(tex); + wiRenderer::AddDeferredMIPGen(tex, true); if (image->uri.empty()) { diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index 991925390..7c2dc2892 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -583,7 +583,9 @@ void RenderPath3D::RenderSceneMIPChain(const Texture& srcSceneRT, CommandList cm device->RenderPassEnd(cmd); - wiRenderer::GenerateMipChain(rtSceneCopy, wiRenderer::MIPGENFILTER_GAUSSIAN, cmd, -1, &rtSceneCopy_tmp); + wiRenderer::MIPGEN_OPTIONS mipopt; + mipopt.gaussian_temp = &rtSceneCopy_tmp; + wiRenderer::GenerateMipChain(rtSceneCopy, wiRenderer::MIPGENFILTER_GAUSSIAN, cmd, mipopt); device->EventEnd(cmd); wiProfiler::EndRange(range); diff --git a/WickedEngine/ShaderInterop_Utility.h b/WickedEngine/ShaderInterop_Utility.h index f02058066..2b86bc521 100644 --- a/WickedEngine/ShaderInterop_Utility.h +++ b/WickedEngine/ShaderInterop_Utility.h @@ -12,8 +12,9 @@ CBUFFER(GenerateMIPChainCB, CBSLOT_RENDERER_UTILITY) uint3 outputResolution; uint arrayIndex; float3 outputResolution_rcp; - uint padding_mipgenCB; + uint mipgen_options; }; +static const uint MIPGEN_OPTION_BIT_PRESERVE_COVERAGE = 1 << 0; CBUFFER(FilterEnvmapCB, CBSLOT_RENDERER_UTILITY) { diff --git a/WickedEngine/generateMIPChain2D_float4_SimpleFilterCS.hlsl b/WickedEngine/generateMIPChain2D_float4_SimpleFilterCS.hlsl index fe6c6cf52..aebcc8582 100644 --- a/WickedEngine/generateMIPChain2D_float4_SimpleFilterCS.hlsl +++ b/WickedEngine/generateMIPChain2D_float4_SimpleFilterCS.hlsl @@ -15,6 +15,16 @@ void main(uint3 DTid : SV_DispatchThreadID) { if (DTid.x < outputResolution.x && DTid.y < outputResolution.y) { - output[DTid.xy] = input.SampleLevel(customsampler, ((float2)DTid.xy + 0.5f) * (float2)outputResolution_rcp.xy, 0); + float2 uv = ((float2)DTid.xy + 0.5f) * (float2)outputResolution_rcp.xy; + float4 color = input.SampleLevel(customsampler, uv, 0); + + [branch] + if (mipgen_options & MIPGEN_OPTION_BIT_PRESERVE_COVERAGE) + { + float4 alphas = input.GatherAlpha(customsampler, uv, 0); + color.a = max(alphas.x, max(alphas.y, max(alphas.z, alphas.w))); + } + + output[DTid.xy] = color; } } \ No newline at end of file diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 2b4c4426c..197afc76d 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -167,7 +167,7 @@ std::vector paintrads; XMFLOAT4 waterPlane = XMFLOAT4(0, 1, 0, 0); wiSpinLock deferredMIPGenLock; -unordered_set deferredMIPGens; +std::vector> deferredMIPGens; wiGPUBVH sceneBVH; @@ -4019,7 +4019,9 @@ void UpdateRenderData(CommandList cmd) deferredMIPGenLock.lock(); for (auto& it : deferredMIPGens) { - GenerateMipChain(*it, MIPGENFILTER_LINEAR, cmd); + MIPGEN_OPTIONS mipopt; + mipopt.preserve_coverage = it.second; + GenerateMipChain(*it.first, MIPGENFILTER_LINEAR, cmd, mipopt); } deferredMIPGens.clear(); deferredMIPGenLock.unlock(); @@ -6764,7 +6766,9 @@ void RefreshEnvProbes(CommandList cmd) device->RenderPassEnd(cmd); - GenerateMipChain(textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY], MIPGENFILTER_LINEAR, cmd, probe.textureIndex); + MIPGEN_OPTIONS mipopt; + mipopt.arrayIndex = probe.textureIndex; + GenerateMipChain(textures[TEXTYPE_CUBEARRAY_ENVMAPARRAY], MIPGENFILTER_LINEAR, cmd, mipopt); // Filter the enviroment map mip chain according to BRDF: // A bit similar to MIP chain generation, but its input is the MIP-mapped texture, @@ -7422,7 +7426,7 @@ void DownsampleDepthBuffer(const wiGraphics::Texture& src, wiGraphics::CommandLi device->EventEnd(cmd); } -void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList cmd, int arrayIndex, const Texture* gaussian_temp) +void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList cmd, const MIPGEN_OPTIONS& options) { GraphicsDevice* device = GetDevice(); TextureDesc desc = texture.GetDesc(); @@ -7480,7 +7484,8 @@ void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList c cb.outputResolution.y = desc.Height; cb.outputResolution_rcp.x = 1.0f / cb.outputResolution.x; cb.outputResolution_rcp.y = 1.0f / cb.outputResolution.y; - cb.arrayIndex = arrayIndex; + cb.arrayIndex = options.arrayIndex; + cb.mipgen_options = 0; device->UpdateBuffer(&constantBuffers[CBTYPE_MIPGEN], &cb, cmd); device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_MIPGEN], CB_GETBINDSLOT(GenerateMIPChainCB), cmd); @@ -7526,6 +7531,7 @@ void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList c cb.outputResolution_rcp.x = 1.0f / cb.outputResolution.x; cb.outputResolution_rcp.y = 1.0f / cb.outputResolution.y; cb.arrayIndex = 0; + cb.mipgen_options = 0; device->UpdateBuffer(&constantBuffers[CBTYPE_MIPGEN], &cb, cmd); device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_MIPGEN], CB_GETBINDSLOT(GenerateMIPChainCB), cmd); @@ -7562,7 +7568,7 @@ void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList c // Gaussian filter is a bit different as we do it in a separable way: for (uint32_t i = 0; i < desc.MipLevels - 1; ++i) { - Postprocess_Blur_Gaussian(texture, *gaussian_temp, texture, cmd, i, i + 1); + Postprocess_Blur_Gaussian(texture, *options.gaussian_temp, texture, cmd, i, i + 1); } device->EventEnd(cmd); return; @@ -7589,7 +7595,12 @@ void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList c cb.outputResolution.y = desc.Height; cb.outputResolution_rcp.x = 1.0f / cb.outputResolution.x; cb.outputResolution_rcp.y = 1.0f / cb.outputResolution.y; - cb.arrayIndex = arrayIndex >= 0 ? (uint)arrayIndex : 0; + cb.arrayIndex = options.arrayIndex >= 0 ? (uint)options.arrayIndex : 0; + cb.mipgen_options = 0; + if (options.preserve_coverage) + { + cb.mipgen_options |= MIPGEN_OPTION_BIT_PRESERVE_COVERAGE; + } device->UpdateBuffer(&constantBuffers[CBTYPE_MIPGEN], &cb, cmd); device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_MIPGEN], CB_GETBINDSLOT(GenerateMIPChainCB), cmd); @@ -7642,7 +7653,8 @@ void GenerateMipChain(const Texture& texture, MIPGENFILTER filter, CommandList c cb.outputResolution_rcp.x = 1.0f / cb.outputResolution.x; cb.outputResolution_rcp.y = 1.0f / cb.outputResolution.y; cb.outputResolution_rcp.z = 1.0f / cb.outputResolution.z; - cb.arrayIndex = arrayIndex >= 0 ? (uint)arrayIndex : 0; + cb.arrayIndex = options.arrayIndex >= 0 ? (uint)options.arrayIndex : 0; + cb.mipgen_options = 0; device->UpdateBuffer(&constantBuffers[CBTYPE_MIPGEN], &cb, cmd); device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_MIPGEN], CB_GETBINDSLOT(GenerateMIPChainCB), cmd); @@ -10627,7 +10639,9 @@ void Postprocess_Bloom( } device->EventBegin("Bloom Mipchain", cmd); - wiRenderer::GenerateMipChain(bloom, wiRenderer::MIPGENFILTER_GAUSSIAN, cmd, -1, &bloom_tmp); + MIPGEN_OPTIONS mipopt; + mipopt.gaussian_temp = &bloom_tmp; + GenerateMipChain(bloom, wiRenderer::MIPGENFILTER_GAUSSIAN, cmd, mipopt); device->EventEnd(cmd); // Combine image with bloom @@ -11130,10 +11144,10 @@ void DrawPaintRadius(const PaintRadius& paintrad) paintrads.push_back(paintrad); } -void AddDeferredMIPGen(const Texture* tex) +void AddDeferredMIPGen(const Texture* tex, bool preserve_coverage) { deferredMIPGenLock.lock(); - deferredMIPGens.insert(tex); + deferredMIPGens.push_back(std::make_pair(tex, preserve_coverage)); deferredMIPGenLock.unlock(); } diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index bfe360bce..dede30f0f 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -359,7 +359,13 @@ namespace wiRenderer MIPGENFILTER_GAUSSIAN, MIPGENFILTER_BICUBIC, }; - void GenerateMipChain(const wiGraphics::Texture& texture, MIPGENFILTER filter, wiGraphics::CommandList cmd, int arrayIndex = -1, const wiGraphics::Texture* gaussian_temp = nullptr); + struct MIPGEN_OPTIONS + { + int arrayIndex = -1; + const wiGraphics::Texture* gaussian_temp = nullptr; + bool preserve_coverage = false; + }; + void GenerateMipChain(const wiGraphics::Texture& texture, MIPGENFILTER filter, wiGraphics::CommandList cmd, const MIPGEN_OPTIONS& options = {}); enum BORDEREXPANDSTYLE { @@ -530,7 +536,7 @@ namespace wiRenderer void DrawPaintRadius(const PaintRadius& paintrad); // Add a texture that should be mipmapped whenever it is feasible to do so - void AddDeferredMIPGen(const wiGraphics::Texture* tex); + void AddDeferredMIPGen(const wiGraphics::Texture* tex, bool preserve_coverage = false); struct CustomShader { diff --git a/WickedEngine/wiResourceManager.cpp b/WickedEngine/wiResourceManager.cpp index a983414cf..24b1663de 100644 --- a/WickedEngine/wiResourceManager.cpp +++ b/WickedEngine/wiResourceManager.cpp @@ -268,7 +268,7 @@ namespace wiResourceManager if (image != nullptr && image->GetDesc().MipLevels > 1) { - wiRenderer::AddDeferredMIPGen(image); + wiRenderer::AddDeferredMIPGen(image, true); } success = image; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 4f1f4fd1c..d3887ac98 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 39; // minor bug fixes, alterations, refactors, updates - const int revision = 54; + const int revision = 55; long GetVersion()