osg(osg中文社区)-osgEarth-osgViewer-基于OpenGL-开源三维渲染引擎-图形引擎-虚拟仿真工具-osg教程-osg仿真

Optimizer选项

当前位置:首页 > 关于osg > 使用指南 > 用户指南

Optimizer可以通过代码来打开与关闭,也可以使用环境变量OSG_OPTIMIZER来设置。osgViewer也支持使用命令行参数来打开。


FLATTEN_STATIC_TRANSFORMS

这个特性是指,当几何体结点上方存在移动结点时,会将移动结点消失,然后直接将移动的效果直接用修改Geometry的顶点位置来代替。我必须提醒这二者的区别,Transform是个逻辑结点,它并不会增大显卡上的坐标空间,而Geometry是几何结点,它会增大显卡上的坐标空间。坐标空间的增大导致坐标判别精度丢失,会导致闪烁。CPU上的坐标最终在显卡上都会被投射到0~1范围内,假如CPU上你的坐标范围为0~1000000,那么1000000被投到GPU是1,如果你的物体顶点一个是1一个是2,那么它们投到GPU上之后只相差0.0000001,GPU只支持浮点数精度,这个数值可能被忽略,因此物体的这两个顶点就花了。闪烁是个经典问题,希望大家都能找到自己的解决方案。--FreeSouth注。

基于上述描述,是不推荐使用FLATTEN_STATIC_TRANSFORMS的原因之一。

使用F_S_T特性需要将geometry的data variance设置为STATIC: setDataVariance(osg::Object::STATIC)

邮件列表里的例子:

///before optimization FLATTEN_STATIC_TRANSFORMS
///left out several properties for clarity
Group {
  DataVariance STATIC
  num_children 1
  PositionAttitudeTransform {
    DataVariance STATIC
    referenceFrame RELATIVE
    position 0 0 0
    attitude 0 0 0 1
    scale 1 5 10
    pivotPoint 0 0 0
    num_children 1
    Geode {
      DataVariance DYNAMIC
      num_drawables 1
      Geometry {
        DataVariance DYNAMIC
        useDisplayList TRUE
        useVertexBufferObjects FALSE
        PrimitiveSets 1
        {
          DrawArrays QUADS 0 4
        }
        VertexArray UniqueID Vec3Array_2 VA 4
        {
          0 -0.5 -0.5
          0 0.5 -0.5
          0 0.5 0.5
          0 -0.5 0.5
        }
      }
    }
  }
}
///after optimization FLATTEN_STATIC_TRANSFORMS
///left out several properties for clarity
Group {
  DataVariance STATIC
  num_children 1
  Group {
    DataVariance STATIC
    num_children 1
    Geode {
      DataVariance DYNAMIC
      num_drawables 1
      Geometry {
        DataVariance DYNAMIC
        useDisplayList TRUE
        useVertexBufferObjects FALSE
        PrimitiveSets 1
        {
          DrawArrays QUADS 0 4
        }
        VertexArray UniqueID Vec3Array_2 Vec3Array 4
        {
          0 -2.5 -5
          0 2.5 -5
          0 2.5 5
          0 -2.5 5
        }
      }
    }
  }
}


REMOVE_REDUNDANT_NODES

将空结点删除,比如:

  • 没有drawable的geode

  • 空的drawable

  • 没有孩子的group

删除冗余结点,比如:

  • 只有一个孩子的group

  • 基于单位矩阵的矩阵变换


REMOVE_LOADED_PROXY_NODES

删除代理结点,代理结点的意义是先设置个文件名,当距离合适需要加载模型时,从这个文件名中加载。如果模型已经读进去了,那么这个代理结点也不再需要了,若其上设置有回调,则将其优化为Group,否则直接删除,将已经加载的模型挂在其父下。


COMBINE_ADJACENT_LODS

组合相临的LOD。

如果一个组包含两个LOD(pagedLOD不在此列),它们的范围会被合并到一个LOD中。因为一个LOD可以定义多个范围。

//before optimization COMBINE_ADJACENT_LODS

Group {
  DataVariance DYNAMIC
   num_children 2
  LOD {
    DataVariance DYNAMIC
    Radius -1
    RangeMode DISTANCE_FROM_EYE_POINT
    RangeList 1 {
      0 1000
    }
    num_children 1
    Geode {
      //left out geode 1
      }
    }
  }
  LOD {
    DataVariance DYNAMIC
    Radius -1
    RangeMode DISTANCE_FROM_EYE_POINT
    RangeList 1 {
      1000 2000
    }
    num_children 1
    Geode {
      //left out geode 2
    }
  }
}

//after optimization COMBINE_ADJACENT_LODS
Group {
  DataVariance DYNAMIC
  num_children 1
  LOD {
    DataVariance DYNAMIC
    name "newLOD"
    Center 0 0 0
    Radius -1
    RangeMode DISTANCE_FROM_EYE_POINT
    RangeList 2 {
      0 1000
      1000 2000
    }
    num_children 2
    Geode {
      //left out geode 1
      }
    }
    Geode {
      //left out geode 2
    }
  }
}


SHARE_DUPLICATE_STATE

将重复的状态(state)进行合并,假如两个结点有着相同的state,比如都用了同一个shader等,任何地方都一样,则会将这两具state合并成一个。优化会遍历所有的state,对其中相同的,进行合并。


MERGE_GEOMETRY

把对geode进行合并,前提是这些geode没有共享顶点数组。合并后每个geode不超过1000个顶点,超过则另起一个geode。合并geode是必须的,一万个geode每个包含一个geometry比一个geode里包含一万个geometry效率要低很多。


SPATIALIZE_GROUPS

按照深度,把模型按照八叉树/四叉树进行排列,以方便拣选。


COPY_SHARED_NODES

如果有共享的结点,优化会深拷一份。


TRISTRIP_GEOMETRY

三角化。会把所有的非2D几何体(点线属2D几何体)转成三角带的方式。使用的是osgUtil::TriStripVisitor。这样能共享顶点,还有其它好处未知。


TESSELATE_GEOMETRY

把所有的POLYGONS都进行Tesselate。


OPTIMIZE_TEXTURE_SETTINGS

对纹理设置setUnRefImageDataAfterApply(true),这样CPU不需要存该image,只需要纹理引用就可以了,image也会被删除。


MERGE_GEODES

合并重复的geode。


FLATTEN_BILLBOARDS

如果billboard上面有matrix transform,但是mt又没有做移动和旋转操作,则该mt会被展开到geode(直接改顶点),而billboard会上升取代它。


CHECK_GEOMETRY

TODO


TEXTURE_ATLAS_BUILDER

类似纹理展开的功能,把很多纹理放在一张纹理上,这样节省纹理的空间。


STATIC_OBJECT_DETECTION

STATIC数据检测,因为STATIC没有任何的回调(设置了callback会被自动转为DYNAMIC),检测静态数据有利于其它的优化,比如状态合并等。


FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS

FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor 和 FlattenStaticTransformsVisitor 类似,主要功能都是展开位置移动结点直接到geometry,不同的是mt与geode会有复杂的共享关系,比如两个mt共享了一个geode,这样消除这两个mt就需要两个geode了。这样增加了数据量,需要仔细权衡哦。


INDEX_MESH

INDEX_MESH 是指将polygonal几何体转成共享顶点序列的三角索引方式。Quads, triangle strips, triangle fans, and polygons 都会被 triangles替代。这样就不再需要DrawElements了,这个优化可以减少MESH存储空间,把多个几何体合并成一个。


VERTEX_POSTTRANSFORM

Optimize the order of triangles in a DrawElements mesh to reduce cache misses in the GPU post-transform cache. This can significantly improve rendering time; see this blog entry for details.


VERTEX_PRETRANSFORM

Change the order of vertex attributes to reflect their first use in the triangles of a mesh so that vertices that are used in early triangles come first in the vertex attribute arrays. This optimizes cache misses in the GPU pre-transform cache. This optimization should usually be run together with VERTEX_POSTTRANSFORM.