From 454df4872a1ac09534e6449f1380f04a74bad3b9 Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Thu, 26 Mar 2020 22:09:04 +0000 Subject: [PATCH] Reduce shader attribute usage by packing floats Previously we required 6 shader attributes to pass in all the required information for the building shader. By using packing techniques this has been reduced to 4. This should improve support for integrated graphics cards. --- simgear/scene/tgdb/SGBuildingBin.cxx | 49 +++++++++++++++++++--------- simgear/scene/tgdb/SGBuildingBin.hxx | 8 ++--- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/simgear/scene/tgdb/SGBuildingBin.cxx b/simgear/scene/tgdb/SGBuildingBin.cxx index 2a56f309..dd2b66a1 100644 --- a/simgear/scene/tgdb/SGBuildingBin.cxx +++ b/simgear/scene/tgdb/SGBuildingBin.cxx @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -329,10 +330,8 @@ struct MakeBuildingLeaf geom->setVertexAttribArray(BUILDING_POSITION_ATTR, new osg::Vec3Array, Array::BIND_PER_VERTEX); geom->setVertexAttribArray(BUILDING_SCALE_ATTR, new osg::Vec3Array, Array::BIND_PER_VERTEX); - geom->setVertexAttribArray(BUILDING_ROT_PITCH_TEX0X_ATTR, new osg::Vec3Array, Array::BIND_PER_VERTEX); - geom->setVertexAttribArray(BUILDING_TEX0Y_TEX1X_TEX1Y_ATTR, new osg::Vec3Array, Array::BIND_PER_VERTEX); - geom->setVertexAttribArray(BUILDING_RTEX0X_RTEX0Y_ATTR, new osg::Vec3Array, Array::BIND_PER_VERTEX); - geom->setVertexAttribArray(BUILDING_ROFFTOPSCALE_ATTR, new osg::Vec3Array, Array::BIND_PER_VERTEX); + geom->setVertexAttribArray(BUILDING_ATTR1, new osg::Vec3Array, Array::BIND_PER_VERTEX); + geom->setVertexAttribArray(BUILDING_ATTR2, new osg::Vec3Array, Array::BIND_PER_VERTEX); //geom->addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 48, 0) ); geom->addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 52, 0) ); @@ -344,10 +343,8 @@ struct MakeBuildingLeaf StateSet* ss = geode->getOrCreateStateSet(); ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_POSITION_ATTR, 1)); ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_SCALE_ATTR, 1)); - ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_ROT_PITCH_TEX0X_ATTR, 1)); - ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_TEX0Y_TEX1X_TEX1Y_ATTR, 1)); - ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_RTEX0X_RTEX0Y_ATTR, 1)); - ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_ROFFTOPSCALE_ATTR, 1)); + ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_ATTR1, 1)); + ss->setAttributeAndModes(new osg::VertexAttribDivisor(BUILDING_ATTR2, 1)); LOD* result = new LOD; result->addChild(geode, 0, _range); @@ -359,6 +356,15 @@ struct MakeBuildingLeaf bool _fade_out; }; +const float pack_precision = 128.0; +const float pack_precision1 = pack_precision+1.0; + +float pack8bit(float a, float b, float c) { + return floor(a * pack_precision + 0.5) + + floor(b * pack_precision + 0.5) * pack_precision1 + + floor(c * pack_precision + 0.5) * pack_precision1 * pack_precision1; +}; + struct AddBuildingLeafObject { void operator() (LOD* lod, const SGBuildingBin::BuildingInstance building) const @@ -370,18 +376,29 @@ struct AddBuildingLeafObject osg::Vec3Array* positions = static_cast (geom->getVertexAttribArray(BUILDING_POSITION_ATTR)); // (x,y,z) osg::Vec3Array* scale = static_cast (geom->getVertexAttribArray(BUILDING_SCALE_ATTR)); // (width, depth, height) - osg::Vec3Array* rot = static_cast (geom->getVertexAttribArray(BUILDING_ROT_PITCH_TEX0X_ATTR)); // (rotation, pitch height, wall texture x0) - osg::Vec3Array* tex = static_cast (geom->getVertexAttribArray(BUILDING_TEX0Y_TEX1X_TEX1Y_ATTR)); // (wall texture y0, front/roof texture x1, front/side/roof texture y1) - osg::Vec3Array* rtex = static_cast (geom->getVertexAttribArray(BUILDING_RTEX0X_RTEX0Y_ATTR)); // (roof texture x0, roof texture y0, side texture x1) - osg::Vec3Array* rooftops = static_cast (geom->getVertexAttribArray(BUILDING_ROFFTOPSCALE_ATTR)); // (rooftop scale x, rooftop scale y, unused) + osg::Vec3Array* attrib1 = static_cast (geom->getVertexAttribArray(BUILDING_ATTR1)); + osg::Vec3Array* attrib2 = static_cast (geom->getVertexAttribArray(BUILDING_ATTR2)); positions->push_back(building.position); // Depth is the x-axis, width is the y-axis scale->push_back(osg::Vec3f(building.depth, building.width, building.height)); - rot->push_back(osg::Vec3f(building.rotation, building.pitch_height, building.walltex0.x())); - tex->push_back(osg::Vec3f(building.walltex0.y(), building.tex1.x(), building.tex1.y())); - rtex->push_back(osg::Vec3f(building.rooftex0.x(), building.rooftex0.y(), building.tex1.z())); - rooftops->push_back(osg::Vec3f(building.rooftop_scale.x(), building.rooftop_scale.y(), 0.0f)); + attrib1->push_back(osg::Vec3d( + pack8bit(building.rotation, // attr1 in shader + building.walltex0.x(), + building.walltex0.y()), + building.pitch_height, + pack8bit(building.tex1.x(), // attr2 in shader + building.tex1.y(), + building.rooftex0.x()) + )); + attrib2->push_back(osg::Vec3f( + pack8bit( // attr3 in shader + building.rooftex0.y(), + building.tex1.z(), + building.rooftop_scale.x()), + building.rooftop_scale.y(), + 0.0f + )); DrawArrays* primSet = static_cast(geom->getPrimitiveSet(0)); primSet->setNumInstances(positions->size()); diff --git a/simgear/scene/tgdb/SGBuildingBin.hxx b/simgear/scene/tgdb/SGBuildingBin.hxx index 6e99d45b..d19dbc1d 100644 --- a/simgear/scene/tgdb/SGBuildingBin.hxx +++ b/simgear/scene/tgdb/SGBuildingBin.hxx @@ -54,10 +54,10 @@ // these correspond to building.eff const int BUILDING_POSITION_ATTR = 10; // (x,y,z) const int BUILDING_SCALE_ATTR = 11; // (width, depth, height) -const int BUILDING_ROT_PITCH_TEX0X_ATTR = 12; // (rotation, pitch height, wall texture x offset) -const int BUILDING_TEX0Y_TEX1X_TEX1Y_ATTR = 13; // (wall texture y offset, texture x gain, texture y gain) -const int BUILDING_RTEX0X_RTEX0Y_ATTR = 14; // (roof texture x offset, roof texture y offset, unused) -const int BUILDING_ROFFTOPSCALE_ATTR = 15; // (roof texture x offset, roof texture y offset, unused) +const int BUILDING_ATTR1 = 12; +const int BUILDING_ATTR2 = 13; +const int BUILDING_ATTR3 = 14; +const int BUILDING_ATTR4 = 15; using namespace osg;