mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Adds PBR output texture to PostProc
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
This commit is contained in:
parent
25df2d8a02
commit
a7967d4ad9
8 changed files with 177 additions and 47 deletions
|
|
@ -97,6 +97,7 @@ X(color)
|
|||
X(colorAdd)
|
||||
X(colorMul)
|
||||
X(compute_rcas)
|
||||
X(compute_resolve_pbr)
|
||||
X(compute_skinning)
|
||||
X(compute_upscale_fsr)
|
||||
X(debug_line)
|
||||
|
|
@ -104,6 +105,7 @@ X(debug_overlay)
|
|||
X(delta)
|
||||
X(depthTex)
|
||||
X(dummy)
|
||||
X(exposure)
|
||||
X(foamTex)
|
||||
X(fogColor)
|
||||
X(fogParams)
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ void CPostprocManager::Cleanup()
|
|||
m_PingFramebuffer.reset();
|
||||
m_PongFramebuffer.reset();
|
||||
|
||||
m_PBROutputTexture.reset();
|
||||
m_ColorTex1.reset();
|
||||
m_ColorTex2.reset();
|
||||
m_DepthTex.reset();
|
||||
|
|
@ -147,6 +148,9 @@ void CPostprocManager::Initialize()
|
|||
if (m_IsInitialized)
|
||||
return;
|
||||
|
||||
if (g_ConfigDB.Get("pbr", false))
|
||||
InitializePBR();
|
||||
|
||||
const std::array<Renderer::Backend::SVertexAttributeFormat, 2> attributes{{
|
||||
{Renderer::Backend::VertexAttributeStream::POSITION,
|
||||
Renderer::Backend::Format::R32G32_SFLOAT, 0, sizeof(float) * 2,
|
||||
|
|
@ -183,6 +187,40 @@ void CPostprocManager::Initialize()
|
|||
m_DownscaleComputeTech = g_Renderer.GetShaderManager().LoadEffect(CStrIntern("compute_downscale"));
|
||||
}
|
||||
|
||||
void CPostprocManager::InitializePBR()
|
||||
{
|
||||
const bool PBRSupported{
|
||||
m_Device->GetCapabilities().computeShaders &&
|
||||
m_Device->IsFramebufferFormatSupported(Renderer::Backend::Format::R16G16B16A16_SFLOAT)};
|
||||
if (!PBRSupported)
|
||||
{
|
||||
m_PBREnabled = false;
|
||||
LOGWARNING("PBR is unsupported for the current renderer backend");
|
||||
return;
|
||||
}
|
||||
|
||||
m_FramebufferColorFormat = Renderer::Backend::Format::R16G16B16A16_SFLOAT;
|
||||
const std::string framebufferFormatName{g_ConfigDB.Get("pbr.framebufferformat", std::string{})};
|
||||
if (framebufferFormatName == "rgba32")
|
||||
{
|
||||
if (m_Device->IsFramebufferFormatSupported(Renderer::Backend::Format::R32G32B32A32_SFLOAT))
|
||||
m_FramebufferColorFormat = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
|
||||
else
|
||||
LOGWARNING("%s is unsupported", framebufferFormatName);
|
||||
}
|
||||
else if (framebufferFormatName == "r11g11b10")
|
||||
{
|
||||
if (m_Device->IsFramebufferFormatSupported(Renderer::Backend::Format::B10G11R11_UFLOAT))
|
||||
m_FramebufferColorFormat = Renderer::Backend::Format::B10G11R11_UFLOAT;
|
||||
else
|
||||
LOGWARNING("%s is unsupported", framebufferFormatName);
|
||||
}
|
||||
|
||||
m_ResolvePBRComputeTech = g_Renderer.GetShaderManager().LoadEffect(str_compute_resolve_pbr);
|
||||
if (m_ResolvePBRComputeTech)
|
||||
m_PBREnabled = true;
|
||||
}
|
||||
|
||||
void CPostprocManager::Resize()
|
||||
{
|
||||
RecalculateSize(g_Renderer.GetWidth(), g_Renderer.GetHeight());
|
||||
|
|
@ -196,21 +234,33 @@ void CPostprocManager::RecreateBuffers()
|
|||
{
|
||||
Cleanup();
|
||||
|
||||
#define GEN_BUFFER_RGBA(name, w, h) \
|
||||
name = m_Device->CreateTexture2D( \
|
||||
"PostProc" #name, \
|
||||
Renderer::Backend::ITexture::Usage::SAMPLED | \
|
||||
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT | \
|
||||
Renderer::Backend::ITexture::Usage::TRANSFER_SRC | \
|
||||
Renderer::Backend::ITexture::Usage::TRANSFER_DST, \
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM, w, h, \
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler( \
|
||||
Renderer::Backend::Sampler::Filter::LINEAR, \
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
|
||||
const auto defaultSampler{
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE)};
|
||||
const uint32_t colorTextureUsage{
|
||||
Renderer::Backend::ITexture::Usage::SAMPLED |
|
||||
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT |
|
||||
Renderer::Backend::ITexture::Usage::TRANSFER_SRC |
|
||||
Renderer::Backend::ITexture::Usage::TRANSFER_DST};
|
||||
|
||||
if (m_PBREnabled)
|
||||
{
|
||||
m_PBROutputTexture = m_Device->CreateTexture2D(
|
||||
"PostProcPBROutput", colorTextureUsage,
|
||||
m_FramebufferColorFormat,
|
||||
m_Width, m_Height, defaultSampler);
|
||||
}
|
||||
|
||||
// Two fullscreen ping-pong textures.
|
||||
GEN_BUFFER_RGBA(m_ColorTex1, m_Width, m_Height);
|
||||
GEN_BUFFER_RGBA(m_ColorTex2, m_Width, m_Height);
|
||||
m_ColorTex1 = m_Device->CreateTexture2D(
|
||||
"PostProcColor1", colorTextureUsage | (m_PBREnabled ? Renderer::Backend::ITexture::Usage::STORAGE : 0),
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM,
|
||||
m_Width, m_Height, defaultSampler);
|
||||
m_ColorTex2 = m_Device->CreateTexture2D(
|
||||
"PostProcColor2", colorTextureUsage | (m_PBREnabled ? Renderer::Backend::ITexture::Usage::STORAGE : 0),
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM,
|
||||
m_Width, m_Height, defaultSampler);
|
||||
|
||||
if (m_UnscaledWidth != m_Width && m_Device->GetCapabilities().computeShaders)
|
||||
{
|
||||
|
|
@ -257,7 +307,10 @@ void CPostprocManager::RecreateBuffers()
|
|||
{
|
||||
for (BlurScale::Step& step : scale.steps)
|
||||
{
|
||||
GEN_BUFFER_RGBA(step.texture, width, height);
|
||||
step.texture = m_Device->CreateTexture2D(
|
||||
"PostProcBlurStep", colorTextureUsage,
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM,
|
||||
width, height, defaultSampler);
|
||||
Renderer::Backend::SColorAttachment colorAttachment{};
|
||||
colorAttachment.texture = step.texture.get();
|
||||
colorAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::LOAD;
|
||||
|
|
@ -270,8 +323,6 @@ void CPostprocManager::RecreateBuffers()
|
|||
height = std::max(1u, height / 2);
|
||||
}
|
||||
|
||||
#undef GEN_BUFFER_RGBA
|
||||
|
||||
// Allocate the Depth/Stencil texture.
|
||||
m_DepthTex = m_Device->CreateTexture2D("PostProcDepthTexture",
|
||||
Renderer::Backend::ITexture::Usage::SAMPLED |
|
||||
|
|
@ -285,24 +336,14 @@ void CPostprocManager::RecreateBuffers()
|
|||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
|
||||
|
||||
RecreateCaptureFramebuffer();
|
||||
|
||||
// Set up the framebuffers with some initial textures.
|
||||
Renderer::Backend::SColorAttachment colorAttachment{};
|
||||
colorAttachment.texture = m_ColorTex1.get();
|
||||
colorAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::DONT_CARE;
|
||||
colorAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
|
||||
colorAttachment.clearColor = CColor{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
Renderer::Backend::SDepthStencilAttachment depthStencilAttachment{};
|
||||
depthStencilAttachment.texture = m_DepthTex.get();
|
||||
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
|
||||
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
|
||||
|
||||
m_CaptureFramebuffer = m_Device->CreateFramebuffer("PostprocCaptureFramebuffer",
|
||||
&colorAttachment, &depthStencilAttachment);
|
||||
|
||||
colorAttachment.texture = m_ColorTex1.get();
|
||||
colorAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::LOAD;
|
||||
colorAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
|
||||
colorAttachment.clearColor = CColor{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
m_PingFramebuffer = m_Device->CreateFramebuffer("PostprocPingFramebuffer",
|
||||
&colorAttachment, nullptr);
|
||||
|
||||
|
|
@ -310,7 +351,7 @@ void CPostprocManager::RecreateBuffers()
|
|||
m_PongFramebuffer = m_Device->CreateFramebuffer("PostprocPongFramebuffer",
|
||||
&colorAttachment, nullptr);
|
||||
|
||||
if (!m_CaptureFramebuffer || !m_PingFramebuffer || !m_PongFramebuffer)
|
||||
if (!m_PingFramebuffer || !m_PongFramebuffer)
|
||||
{
|
||||
LOGWARNING("Failed to create postproc framebuffers");
|
||||
g_RenderingOptions.SetPostProc(false);
|
||||
|
|
@ -323,6 +364,28 @@ void CPostprocManager::RecreateBuffers()
|
|||
}
|
||||
}
|
||||
|
||||
void CPostprocManager::RecreateCaptureFramebuffer()
|
||||
{
|
||||
Renderer::Backend::SColorAttachment colorAttachment{};
|
||||
colorAttachment.texture = m_PBREnabled ? m_PBROutputTexture.get() : m_ColorTex1.get();
|
||||
colorAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::DONT_CARE;
|
||||
colorAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
|
||||
colorAttachment.clearColor = CColor{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
Renderer::Backend::SDepthStencilAttachment depthStencilAttachment{};
|
||||
depthStencilAttachment.texture = m_DepthTex.get();
|
||||
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
|
||||
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
|
||||
|
||||
m_CaptureFramebuffer = m_Device->CreateFramebuffer("PostprocCaptureFramebuffer",
|
||||
&colorAttachment, m_UsingMultisampleBuffer ? nullptr : &depthStencilAttachment);
|
||||
|
||||
if (!m_CaptureFramebuffer)
|
||||
{
|
||||
LOGWARNING("Failed to create postproc capture framebuffer");
|
||||
g_RenderingOptions.SetPostProc(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CPostprocManager::ApplyBlurDownscale2x(
|
||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
|
||||
|
|
@ -698,17 +761,15 @@ void CPostprocManager::ApplyPostproc(
|
|||
{
|
||||
ENSURE(m_IsInitialized);
|
||||
|
||||
// Don't do anything if we are using the default effect and no AA.
|
||||
const bool hasEffects{m_PostProcEffect != L"default"};
|
||||
const bool hasAA{m_AATech};
|
||||
const bool hasSharp{m_SharpTech};
|
||||
if (!hasEffects && !hasAA && !hasSharp)
|
||||
return;
|
||||
|
||||
PROFILE3_GPU(deviceCommandContext, "Render postproc");
|
||||
GPU_SCOPED_LABEL(deviceCommandContext, "Render postproc");
|
||||
|
||||
if (hasEffects)
|
||||
if (m_PBREnabled)
|
||||
{
|
||||
ResolvePBR(deviceCommandContext);
|
||||
}
|
||||
|
||||
if (!m_PBREnabled && m_PostProcEffect != L"default")
|
||||
{
|
||||
// First render blur textures. Note that this only happens ONLY ONCE, before any effects are applied!
|
||||
// (This may need to change depending on future usage, however that will have a fps hit)
|
||||
|
|
@ -717,13 +778,13 @@ void CPostprocManager::ApplyPostproc(
|
|||
ApplyEffect(deviceCommandContext, m_PostProcTech, pass);
|
||||
}
|
||||
|
||||
if (hasAA)
|
||||
if (m_AATech)
|
||||
{
|
||||
for (int pass = 0; pass < m_AATech->GetNumPasses(); ++pass)
|
||||
ApplyEffect(deviceCommandContext, m_AATech, pass);
|
||||
}
|
||||
|
||||
if (hasSharp && !ShouldUpscale())
|
||||
if (m_SharpTech && !ShouldUpscale())
|
||||
{
|
||||
for (int pass = 0; pass < m_SharpTech->GetNumPasses(); ++pass)
|
||||
ApplyEffect(deviceCommandContext, m_SharpTech, pass);
|
||||
|
|
@ -815,6 +876,8 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
|
|||
m_UsingMultisampleBuffer = true;
|
||||
CreateMultisampleBuffer();
|
||||
}
|
||||
|
||||
RecreateCaptureFramebuffer();
|
||||
}
|
||||
|
||||
void CPostprocManager::UpdateSharpeningTechnique()
|
||||
|
|
@ -871,7 +934,7 @@ void CPostprocManager::CreateMultisampleBuffer()
|
|||
Renderer::Backend::ITexture::Type::TEXTURE_2D_MULTISAMPLE,
|
||||
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT |
|
||||
Renderer::Backend::ITexture::Usage::TRANSFER_SRC,
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM, m_Width, m_Height,
|
||||
m_FramebufferColorFormat, m_Width, m_Height,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, m_MultisampleCount);
|
||||
|
|
@ -935,7 +998,42 @@ void CPostprocManager::ResolveMultisampleFramebuffer(
|
|||
|
||||
GPU_SCOPED_LABEL(deviceCommandContext, "Resolve postproc multisample");
|
||||
deviceCommandContext->ResolveFramebuffer(
|
||||
m_MultisampleFramebuffer.get(), m_PingFramebuffer.get());
|
||||
m_MultisampleFramebuffer.get(),
|
||||
m_PBREnabled ? m_CaptureFramebuffer.get() : m_PingFramebuffer.get());
|
||||
}
|
||||
|
||||
void CPostprocManager::ResolvePBR(
|
||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
ENSURE(m_PBREnabled);
|
||||
ENSURE(m_ResolvePBRComputeTech);
|
||||
|
||||
GPU_SCOPED_LABEL(deviceCommandContext, "Resolve PBR");
|
||||
|
||||
Renderer::Backend::IShaderProgram* shaderProgram{m_ResolvePBRComputeTech->GetShader()};
|
||||
|
||||
Renderer::Backend::ITexture* source{m_PBROutputTexture.get()};
|
||||
Renderer::Backend::ITexture* destination{m_ColorTex1.get()};
|
||||
|
||||
const std::array<float, 4> screenSize{{
|
||||
static_cast<float>(m_Width), static_cast<float>(m_Height),
|
||||
1.0f / static_cast<float>(m_Width), 1.0f / static_cast<float>(m_Height)}};
|
||||
|
||||
constexpr uint32_t threadGroupWorkRegionDim{8};
|
||||
const uint32_t dispatchGroupCountX{DivideRoundUp(m_Width, threadGroupWorkRegionDim)};
|
||||
const uint32_t dispatchGroupCountY{DivideRoundUp(m_Height, threadGroupWorkRegionDim)};
|
||||
|
||||
deviceCommandContext->BeginComputePass();
|
||||
deviceCommandContext->SetComputePipelineState(
|
||||
m_ResolvePBRComputeTech->GetComputePipelineState());
|
||||
deviceCommandContext->SetUniform(shaderProgram->GetBindingSlot(str_screenSize), screenSize);
|
||||
// Mapping [0.0, 1.0] to [-2.0, 2.0].
|
||||
deviceCommandContext->SetUniform(shaderProgram->GetBindingSlot(str_exposure),
|
||||
std::exp2f((g_RenderingOptions.GetPBRBrightness() - 0.5f) * 4.0f));
|
||||
deviceCommandContext->SetTexture(shaderProgram->GetBindingSlot(str_inTex), source);
|
||||
deviceCommandContext->SetStorageTexture(shaderProgram->GetBindingSlot(str_outTex), destination);
|
||||
deviceCommandContext->Dispatch(dispatchGroupCountX, dispatchGroupCountY, 1);
|
||||
deviceCommandContext->EndComputePass();
|
||||
}
|
||||
|
||||
void CPostprocManager::RecalculateSize(const uint32_t width, const uint32_t height)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -95,9 +95,16 @@ public:
|
|||
|
||||
float GetScale() const { return m_Scale; }
|
||||
|
||||
bool IsPBREnabled() const { return m_PBREnabled; }
|
||||
|
||||
Renderer::Backend::Format GetFramebufferColorFormat() const { return m_FramebufferColorFormat; }
|
||||
|
||||
private:
|
||||
void CreateMultisampleBuffer();
|
||||
void DestroyMultisampleBuffer();
|
||||
void RecreateCaptureFramebuffer();
|
||||
|
||||
void InitializePBR();
|
||||
|
||||
void RecalculateSize(const uint32_t width, const uint32_t height);
|
||||
|
||||
|
|
@ -127,8 +134,20 @@ private:
|
|||
Renderer::Backend::ITexture* source,
|
||||
Renderer::Backend::ITexture* destination);
|
||||
|
||||
/**
|
||||
* Resolve PBR HDR output to SDR one.
|
||||
*/
|
||||
void ResolvePBR(
|
||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
Renderer::Backend::IDevice* m_Device = nullptr;
|
||||
|
||||
Renderer::Backend::Format m_FramebufferColorFormat{
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM};
|
||||
|
||||
bool m_PBREnabled{false};
|
||||
std::unique_ptr<Renderer::Backend::ITexture> m_PBROutputTexture;
|
||||
|
||||
std::unique_ptr<Renderer::Backend::IFramebuffer> m_CaptureFramebuffer;
|
||||
|
||||
// Two framebuffers, that we flip between at each shader pass.
|
||||
|
|
@ -170,6 +189,8 @@ private:
|
|||
CStrW m_PostProcEffect;
|
||||
CShaderTechniquePtr m_PostProcTech;
|
||||
|
||||
CShaderTechniquePtr m_ResolvePBRComputeTech;
|
||||
|
||||
CStr m_SharpName;
|
||||
CShaderTechniquePtr m_SharpTech;
|
||||
float m_Sharpness;
|
||||
|
|
|
|||
|
|
@ -271,6 +271,8 @@ void CRenderingOptions::ReadConfigAndSetupHooks()
|
|||
if (CRenderer::IsInitialised())
|
||||
g_Renderer.GetTextureManager().OnQualityChanged();
|
||||
});
|
||||
|
||||
m_ConfigHooks->Setup("pbr.brightness", m_PBRBrightness);
|
||||
}
|
||||
|
||||
void CRenderingOptions::ClearHooks()
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ OPTION_CUSTOM_SETTER(NAME, TYPE); OPTION_GETTER(NAME, TYPE); OPTION_DEF(NAME, TY
|
|||
OPTION(DisplayFrustum, bool);
|
||||
OPTION(DisplayShadowsFrustum, bool);
|
||||
|
||||
OPTION(PBRBrightness, float);
|
||||
|
||||
// Cutscene Mode: while active, (most) visual overlays aren't rendered in order to give the scene a more "pure"
|
||||
// and real feel, like a movie.
|
||||
// The idea is for it to be inactive during normal gameplay, but enabled while playing cinema paths and
|
||||
|
|
|
|||
|
|
@ -260,6 +260,11 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
|
|||
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
|
||||
true, false);
|
||||
|
||||
Renderer::Backend::Format framebufferColorFormat{
|
||||
g_Renderer.GetPostprocManager().IsEnabled()
|
||||
? g_Renderer.GetPostprocManager().GetFramebufferColorFormat()
|
||||
: Renderer::Backend::Format::R8G8B8A8_UNORM};
|
||||
|
||||
// Create reflection textures.
|
||||
const bool needsReflectionTextures =
|
||||
g_RenderingOptions.GetWaterEffects() &&
|
||||
|
|
@ -269,7 +274,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
|
|||
m_ReflectionTexture = m_Device->CreateTexture2D("WaterReflectionTexture",
|
||||
Renderer::Backend::ITexture::Usage::SAMPLED |
|
||||
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT,
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM, m_RefTextureSize, m_RefTextureSize,
|
||||
framebufferColorFormat, m_RefTextureSize, m_RefTextureSize,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::MIRRORED_REPEAT));
|
||||
|
|
@ -312,7 +317,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
|
|||
m_RefractionTexture = m_Device->CreateTexture2D("WaterRefractionTexture",
|
||||
Renderer::Backend::ITexture::Usage::SAMPLED |
|
||||
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT,
|
||||
Renderer::Backend::Format::R8G8B8A8_UNORM, m_RefTextureSize, m_RefTextureSize,
|
||||
framebufferColorFormat, m_RefTextureSize, m_RefTextureSize,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::MIRRORED_REPEAT));
|
||||
|
|
|
|||
|
|
@ -968,7 +968,7 @@ bool CDevice::IsTextureFormatSupported(const Format format) const
|
|||
|
||||
case Format::R16G16B16A16_SFLOAT:
|
||||
case Format::R32G32B32A32_SFLOAT:
|
||||
supported = m_Capabilities.computeShaders && m_Capabilities.storage && ogl_HaveExtension("GL_ARB_texture_float");
|
||||
supported = m_Capabilities.computeShaders && m_Capabilities.storage && GLAD_GL_ARB_texture_float;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
|
|||
Loading…
Reference in a new issue