diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index f96ddffa..aba5212a 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -3032,6 +3032,12 @@ void opengl33_renderer::Render_Instanced( TModel3d *Model, std::vectorMaterial() != nullptr ? Instances.front()->Material()->replacable_skins : nullptr }; + bool castsshadow { m_renderpass.draw_mode != rendermode::shadows }; m_instance_lodbounds.clear(); m_instance_lodpending.clear(); m_instance_lodpending.push_back( Model->Root ); @@ -3041,9 +3047,14 @@ void opengl33_renderer::Render_Instanced( TModel3d *Model, std::vectorfSquareMinDist > 0.f ) { m_instance_lodbounds.emplace_back( submodel->fSquareMinDist ); } if( submodel->fSquareMaxDist < std::numeric_limits::max() ) { m_instance_lodbounds.emplace_back( submodel->fSquareMaxDist ); } + if( ( false == castsshadow ) && ( submodel->eType < TP_ROTATOR ) ) { + auto const material { submodel->m_material >= 0 ? submodel->m_material : ( skins != nullptr ? skins[ -submodel->m_material ] : null_handle ) }; + castsshadow = ( Material( material ).shadow_rank <= Global.gfx_shadow_rank_cutoff ); + } m_instance_lodpending.push_back( submodel->Child ); m_instance_lodpending.push_back( submodel->Next ); } + if( false == castsshadow ) { return; } std::sort( m_instance_lodbounds.begin(), m_instance_lodbounds.end() ); m_instance_lodbounds.erase( std::unique( m_instance_lodbounds.begin(), m_instance_lodbounds.end() ), m_instance_lodbounds.end() ); auto const bandcount { m_instance_lodbounds.size() + 1 }; @@ -3064,6 +3075,7 @@ void opengl33_renderer::Render_Instanced( TModel3d *Model, std::vectorlocation() - m_renderpass.pass_camera.position() ), 1.f ); auto const distance { static_cast( distancesquared ) }; + farthest_distancesquared = std::max( farthest_distancesquared, distance ); m_instance_survivors.push_back( { view_matrix * root, distance, @@ -3120,16 +3133,25 @@ void opengl33_renderer::Render_Instanced( TModel3d *Model, std::vector::max() ); - for( auto const &survivor : m_instance_survivors ) { - ++m_instance_bandstarts[ survivor.band + 1 ]; + for( auto &survivor : m_instance_survivors ) { m_instance_banddistances[ survivor.band ] = std::min( m_instance_banddistances[ survivor.band ], survivor.distancesquared ); + auto const slot { std::min( distanceslots - 1, static_cast( std::sqrt( survivor.distancesquared ) * slotscale ) ) }; + survivor.band = static_cast( survivor.band * distanceslots + slot ); // from now on it's the sort key + ++m_instance_bandstarts[ survivor.band + 1 ]; } - for( std::size_t band = 1; band <= bandcount; ++band ) { - m_instance_bandstarts[ band ] += m_instance_bandstarts[ band - 1 ]; + for( std::size_t key = 1; key <= keycount; ++key ) { + m_instance_bandstarts[ key ] += m_instance_bandstarts[ key - 1 ]; } m_instance_bandcursors.assign( m_instance_bandstarts.begin(), m_instance_bandstarts.end() - 1 ); m_instance_modelviews.resize( m_instance_survivors.size() ); @@ -3145,8 +3167,8 @@ void opengl33_renderer::Render_Instanced( TModel3d *Model, std::vector( band_end - offset_idx, gl::MAX_INSTANCES_PER_BATCH ); diff --git a/rendering/opengl33renderer.h b/rendering/opengl33renderer.h index 2f86117f..43cd24b0 100644 --- a/rendering/opengl33renderer.h +++ b/rendering/opengl33renderer.h @@ -436,7 +436,8 @@ class opengl33_renderer : public gfx_renderer { std::vector m_instance_survivors; std::vector m_instance_lodbounds; std::vector m_instance_lodpending; - // per lod band: first index in m_instance_modelviews (with end sentinel), fill cursor, nearest distance + // per sort key (lod band and distance slot): first index in m_instance_modelviews (with end sentinel) + // and fill cursor; per lod band: nearest distance std::vector m_instance_bandstarts; std::vector m_instance_bandcursors; std::vector m_instance_banddistances;