Configurable sampling per custom texture in material shaders

This commit is contained in:
RaveYard 2023-08-25 08:23:24 +02:00 committed by Magnus Norddahl
commit 97eaa46b69
9 changed files with 117 additions and 27 deletions

View file

@ -35,6 +35,14 @@ struct SpritePositioningInfo
};
enum class MaterialLayerSampling
{
Default = -1,
NearestMipLinear,
LinearMipLinear,
};
struct MaterialLayers
{
float Glossiness;
@ -46,6 +54,8 @@ struct MaterialLayers
FGameTexture* Roughness;
FGameTexture* AmbientOcclusion;
FGameTexture* CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES];
MaterialLayerSampling CustomShaderTextureSampling[MAX_CUSTOM_HW_SHADER_TEXTURES];
};
enum EGameTexFlags
@ -74,6 +84,8 @@ struct FMaterialLayers
RefCountedPtr<FTexture> Roughness; // Roughness texture for PBR
RefCountedPtr<FTexture> AmbientOcclusion; // Ambient occlusion texture for PBR
RefCountedPtr<FTexture> CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES]; // Custom texture maps for custom hardware shaders
MaterialLayerSampling CustomShaderTextureSampling[MAX_CUSTOM_HW_SHADER_TEXTURES];
};
// Refactoring helper to allow piece by piece adjustment of the API
@ -235,7 +247,11 @@ public:
if (lay.AmbientOcclusion) Layers->AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
{
if (lay.CustomShaderTextures[i]) Layers->CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
if (lay.CustomShaderTextures[i])
{
Layers->CustomShaderTextureSampling[i] = lay.CustomShaderTextureSampling[i];
Layers->CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
}
}
}
}

View file

@ -52,7 +52,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
mShaderIndex = SHADER_Default;
sourcetex = tx;
auto imgtex = tx->GetTexture();
mTextureLayers.Push({ imgtex, scaleflags, -1 });
mTextureLayers.Push({ imgtex, scaleflags, -1, MaterialLayerSampling::Default });
if (tx->GetUseType() == ETextureType::SWCanvas && static_cast<FWrapperTexture*>(imgtex)->GetColorFormat() == 0)
{
@ -83,7 +83,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
{
for (auto &texture : { tx->Layers->Normal.get(), tx->Layers->Specular.get() })
{
mTextureLayers.Push({ texture, 0, -1 });
mTextureLayers.Push({ texture, 0, -1, MaterialLayerSampling::Default });
}
mShaderIndex = SHADER_Specular;
}
@ -91,7 +91,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
{
for (auto &texture : { tx->Layers->Normal.get(), tx->Layers->Metallic.get(), tx->Layers->Roughness.get(), tx->Layers->AmbientOcclusion.get() })
{
mTextureLayers.Push({ texture, 0, -1 });
mTextureLayers.Push({ texture, 0, -1, MaterialLayerSampling::Default });
}
mShaderIndex = SHADER_PBR;
}
@ -101,30 +101,30 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
auto placeholder = TexMan.GameByIndex(1);
if (tx->Brightmap.get())
{
mTextureLayers.Push({ tx->Brightmap.get(), scaleflags, -1 });
mTextureLayers.Push({ tx->Brightmap.get(), scaleflags, -1, MaterialLayerSampling::Default });
mLayerFlags |= TEXF_Brightmap;
}
else
{
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1, MaterialLayerSampling::Default });
}
if (tx->Layers && tx->Layers->Detailmap.get())
{
mTextureLayers.Push({ tx->Layers->Detailmap.get(), 0, CLAMP_NONE });
mTextureLayers.Push({ tx->Layers->Detailmap.get(), 0, CLAMP_NONE, MaterialLayerSampling::Default });
mLayerFlags |= TEXF_Detailmap;
}
else
{
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1, MaterialLayerSampling::Default });
}
if (tx->Layers && tx->Layers->Glowmap.get())
{
mTextureLayers.Push({ tx->Layers->Glowmap.get(), scaleflags, -1 });
mTextureLayers.Push({ tx->Layers->Glowmap.get(), scaleflags, -1, MaterialLayerSampling::Default});
mLayerFlags |= TEXF_Glowmap;
}
else
{
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1, MaterialLayerSampling::Default });
}
auto index = tx->GetShaderIndex();
@ -137,10 +137,13 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
{
if (tx->Layers)
{
size_t index = 0;
for (auto& texture : tx->Layers->CustomShaderTextures)
{
if (texture == nullptr) continue;
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
if (texture != nullptr)
{
mTextureLayers.Push({ texture.get(), 0, -1, tx->Layers->CustomShaderTextureSampling[index++]}); // scalability should be user-definable.
}
}
}
mShaderIndex = index;

View file

@ -13,6 +13,7 @@ struct MaterialLayerInfo
FTexture* layerTexture;
int scaleFlags;
int clampflags;
MaterialLayerSampling layerFiltering;
};
//===========================================================================
@ -55,9 +56,9 @@ public:
mTextureLayers.Resize(1);
}
void AddTextureLayer(FTexture *tex, bool allowscale)
void AddTextureLayer(FTexture *tex, bool allowscale, MaterialLayerSampling filter)
{
mTextureLayers.Push({ tex, allowscale });
mTextureLayers.Push({ tex, allowscale, -1, filter });
}
int NumLayers() const
@ -66,7 +67,11 @@ public:
}
IHardwareTexture *GetLayer(int i, int translation, MaterialLayerInfo **pLayer = nullptr) const;
MaterialLayerSampling GetLayerFilter(int index) const
{
return mTextureLayers[index].layerFiltering;
}
static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true);
const TArray<MaterialLayerInfo> &GetLayerArray() const