17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 07:29:20 +02:00

feat(track): the texture of a shared running surface blends into the texture of the rail it lies on: 2 cm on each side of the boundary both are drawn in tinted variants of their materials that fade per vertex into the mean colour of the two treads, sampled from the texture files, so the edge of the wheels of the other track leaves a soft band instead of a line

This commit is contained in:
maj00r
2026-10-14 00:01:20 +02:00
parent 1219dde073
commit 592d1687d5
9 changed files with 168 additions and 35 deletions

View File

@@ -662,6 +662,29 @@ material_manager::create_from_text( std::string const &Name, std::string const &
return materialhandle;
}
namespace {
opengl_material
variant_of( opengl_material const &Source, std::string const &Suffix ) {
opengl_material variant;
variant.textures = Source.textures;
variant.texture_variants = Source.texture_variants;
variant.params = Source.params;
variant.params_state = Source.params_state;
variant.shader = Source.shader;
variant.opacity = Source.opacity;
variant.selfillum = Source.selfillum;
variant.shadow_rank = Source.shadow_rank;
variant.name = Source.name + Suffix;
variant.size = Source.size;
variant.is_good = Source.is_good;
variant.path = Source.path;
return variant;
}
} // namespace
material_handle
material_manager::create_matte( material_handle const Material ) {
@@ -672,21 +695,8 @@ material_manager::create_matte( material_handle const Material ) {
if( lookup != m_mattes.end() ) {
return lookup->second;
}
auto const &source { m_materials[ Material ] };
opengl_material matte;
matte.textures = source.textures;
matte.texture_variants = source.texture_variants;
matte.params = source.params;
matte.params_state = source.params_state;
matte.shader = source.shader;
matte.opacity = source.opacity;
matte.selfillum = source.selfillum;
auto matte { variant_of( m_materials[ Material ], ":matte" ) };
matte.glossiness = 0.1f;
matte.shadow_rank = source.shadow_rank;
matte.name = source.name + ":matte";
matte.size = source.size;
matte.is_good = source.is_good;
matte.path = source.path;
if( matte.shader ) {
for( auto const &[ key, value ] : std::vector<std::pair<std::string, glm::vec4>>{ { "weathering", glm::vec4{ 1.f } } } ) {
auto const entry { matte.shader->param_conf.find( key ) };
@@ -710,6 +720,42 @@ material_manager::create_matte( material_handle const Material ) {
return mattehandle;
}
material_handle
material_manager::create_tinted( material_handle const Material, glm::vec3 const &Colour ) {
if( Material == null_handle || Material >= m_materials.size() || !m_materials[ Material ].shader ) {
return Material;
}
auto const key { std::make_tuple( Material, Colour.r, Colour.g, Colour.b ) };
if( auto const lookup { m_tints.find( key ) }; lookup != m_tints.end() ) {
return lookup->second;
}
auto const &conf { m_materials[ Material ].shader->param_conf };
auto const weathering { conf.find( "weathering" ) };
if( weathering == conf.end()
|| weathering->second.offset != 3
|| std::any_of(
std::begin( conf ), std::end( conf ),
[&]( auto const &Entry ) {
return Entry.first != weathering->first && Entry.second.location == weathering->second.location; } ) ) {
return Material;
}
auto tinted { variant_of( m_materials[ Material ], ":tinted" ) };
tinted.glossiness = m_materials[ Material ].glossiness;
auto const location { weathering->second.location };
tinted.params[ location ] = glm::vec4{ Colour, -1.f };
tinted.params_state.erase(
std::remove_if(
std::begin( tinted.params_state ), std::end( tinted.params_state ),
[&]( gl::shader::param_entry const &State ) {
return State.location == location; } ),
std::end( tinted.params_state ) );
auto const tintedhandle { static_cast<material_handle>( m_materials.size() ) };
m_materials.emplace_back( std::move( tinted ) );
m_tints.emplace( key, tintedhandle );
return tintedhandle;
}
void
material_manager::on_weather_change() {