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

feat(renderer): a matte variant of a material for the parts of rails no wheel rolls on: it lights the same maps as weathered steel, with the weathering scaled per vertex by userdata, so a polished running surface fades into unused steel without a bright stripe; the cut faces of rails are drawn in it in an extra pass

This commit is contained in:
maj00r
2026-10-13 18:30:16 +02:00
parent c7f9796387
commit 7e1b2c553c
7 changed files with 133 additions and 0 deletions

View File

@@ -2225,6 +2225,12 @@ material_handle opengl33_renderer::Fetch_Material(std::string const &Filename, b
return m_materials.create(Filename, Loadnow);
}
material_handle opengl33_renderer::Matte_Material(material_handle const Material)
{
return m_materials.create_matte(Material);
}
std::shared_ptr<gl::program> opengl33_renderer::Fetch_Shader(const std::string &name)
{
auto it = m_shaders.find(name);
@@ -4476,6 +4482,39 @@ void opengl33_renderer::Render(scene::basic_cell::path_sequence::const_iterator
}
flush_batch();
// cut faces of rails, in matte variants of the rail materials
if ((m_renderpass.draw_mode == rendermode::color) || (m_renderpass.draw_mode == rendermode::reflections))
{
for (auto first{First}; first != Last; ++first)
{
auto const track{*first};
if (false == track->m_visible)
{
continue;
}
for (auto const &cuts : {std::make_pair(track->m_materialcut1, &track->GeometryCut1), std::make_pair(track->m_materialcut2, &track->GeometryCut2)})
{
if ((cuts.first == null_handle) || cuts.second->empty())
{
continue;
}
if (track->eEnvironment != e_flat)
{
flush_batch();
setup_environment_light(track->eEnvironment);
Bind_Material(cuts.first);
draw(std::begin(*cuts.second), std::end(*cuts.second));
setup_environment_light();
continue;
}
begin_batch(cuts.first);
m_pathbatch.insert(std::end(m_pathbatch), std::begin(*cuts.second), std::end(*cuts.second));
}
}
flush_batch();
}
// fourth pass: per-track sleeper models (sleepermodel optional directive).
// drawn after rails/trackbeds so depth pre-pass culling is favourable, and only in passes
// where Render_Sleepers actually does work (it gates itself on draw mode / distance).

View File

@@ -78,6 +78,8 @@ class opengl33_renderer : public gfx_renderer {
// material methods
material_handle
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
material_handle
Matte_Material( material_handle const Material ) override;
void
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override;
IMaterial const *

View File

@@ -3327,6 +3327,32 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
}
}
}
// cut faces of rails
if( ( m_renderpass.draw_mode == rendermode::color )
|| ( m_renderpass.draw_mode == rendermode::reflections ) ) {
for( auto first { First }; first != Last; ++first ) {
auto const track { *first };
if( false == track->m_visible ) {
continue;
}
for( auto const &cuts : { std::make_pair( track->m_materialcut1, &track->GeometryCut1 ), std::make_pair( track->m_materialcut2, &track->GeometryCut2 ) } ) {
if( ( cuts.first == null_handle )
|| ( cuts.second->empty() ) ) {
continue;
}
if( track->eEnvironment != e_flat ) {
setup_environment_light( track->eEnvironment );
}
Bind_Material( cuts.first );
m_geometry.draw( std::begin( *cuts.second ), std::end( *cuts.second ) );
if( track->eEnvironment != e_flat ) {
setup_environment_light();
}
}
}
}
// post-render reset
switch( m_renderpass.draw_mode ) {
case rendermode::shadows:

View File

@@ -69,6 +69,8 @@ public:
virtual auto Fetch_Material( std::string const &Filename, bool const Loadnow = true ) -> material_handle = 0;
virtual void Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) = 0;
virtual auto Material( material_handle const Material ) const -> IMaterial const * = 0;
// the same material with its highlights damped, for faces which aren't polished like the surfaces they are cut from. backends which can't make one give back the material itself
virtual auto Matte_Material( material_handle const Material ) -> material_handle { return Material; }
// heightmap terrain: material of a chunk blending the materials of up to 8 layers by their weights.
// Weights: (Samples + 1)^2 values per layer, planar, rows of growing z, the weights of a sample adding up to 255; null with a single layer.
// Placement: corner of the chunk (x, z) in the texture coordinates of its mesh, and the size of the chunk.