Adjust sampler and LOD bias logic for texture replacements

This commit is contained in:
Luke Street
2026-05-29 18:00:20 -06:00
parent 4622fea2ef
commit ac72f79d1d
2 changed files with 23 additions and 10 deletions
+15 -5
View File
@@ -993,18 +993,28 @@ static u16 wgpu_aniso(GXAnisotropy aniso) {
wgpu::SamplerDescriptor aurora::gfx::TextureBind::get_descriptor() const noexcept {
auto [minFilter, mipFilter] = wgpu_filter_mode(texObj.min_filter());
const auto [magFilter, _] = wgpu_filter_mode(texObj.mag_filter());
auto [magFilter, _] = wgpu_filter_mode(texObj.mag_filter());
const bool mipsEnabled = mipFilter != wgpu::MipmapFilterMode::Undefined;
float minLod = texObj.min_lod();
float maxLod = texObj.max_lod();
u16 maxAnisotropy = wgpu_aniso(texObj.max_aniso());
if (ref && ref->isReplacement) {
minFilter = wgpu::FilterMode::Linear;
mipFilter = wgpu::MipmapFilterMode::Linear;
minLod = 0.f;
maxLod = static_cast<float>(std::max(ref->mipCount, 1u) - 1u);
maxLod = 1000.f;
if (!mipsEnabled) {
mipFilter = wgpu::MipmapFilterMode::Nearest;
}
} else if (mipFilter == wgpu::MipmapFilterMode::Undefined) {
minLod = 0.f;
maxLod = 0.f;
}
if ((ref && ref->hasArbitraryMips) || !mipsEnabled) {
maxAnisotropy = 1;
} else if (maxAnisotropy > 1) {
magFilter = wgpu::FilterMode::Linear;
minFilter = wgpu::FilterMode::Linear;
mipFilter = wgpu::MipmapFilterMode::Linear;
}
return {
.label = "Generated Filtering Sampler",
.addressModeU = wgpu_address_mode(texObj.wrap_s()),
@@ -1015,6 +1025,6 @@ wgpu::SamplerDescriptor aurora::gfx::TextureBind::get_descriptor() const noexcep
.mipmapFilter = mipFilter,
.lodMinClamp = minLod,
.lodMaxClamp = maxLod,
.maxAnisotropy = wgpu_aniso(texObj.max_aniso()),
.maxAnisotropy = maxAnisotropy,
};
} // namespace aurora::gx
+8 -5
View File
@@ -16,11 +16,14 @@ bool is_alpha_bump_channel(GXChannelID id) { return id == GX_ALPHA_BUMP || id ==
Vec4<float> texture_size_bias(const gfx::TextureBind& tex) {
auto width = static_cast<float>(tex.texObj.width());
auto height = static_cast<float>(tex.texObj.height());
const auto vpBias =
enableLodBias && tex.ref && tex.ref->hasArbitraryMips
? log2(std::min(g_gxState.renderViewport.width / std::max(g_gxState.logicalViewport.width, 1.f),
g_gxState.renderViewport.height / std::max(g_gxState.logicalViewport.height, 1.f)))
: 0.f;
float vpBias = 0.f;
if (enableLodBias && tex.ref && tex.ref->hasArbitraryMips) {
const float viewportScale =
std::min(g_gxState.renderViewport.width / std::max(g_gxState.logicalViewport.width, 1.f),
g_gxState.renderViewport.height / std::max(g_gxState.logicalViewport.height, 1.f));
const float replacementScale = static_cast<float>(tex.ref->size.width) / std::max(width, 1.f);
vpBias = std::log2(viewportScale / std::max(replacementScale, 0.001f));
}
return {width, height, tex.texObj.lod_bias() + vpBias, 0.0f};
}