osg模型调整

osg模型调整光照以及模型闪烁问题[z-lighting]

0 模型闪烁原因推测

  • 1 关于模型闪烁的问题,很可能是由于坐标的值的有效位数超过了7位,目前的opengl的gpu渲染(老一点的显卡以及gl)都是以单精度来渲染点的位置的,所以如果坐标很大,很可能导致单精度无法精确表示有效位数超过7位的数据,然后发生截断。
  • 2 关于z-lighting的问题,尝试了网上大多数的方法:可以使用osg封装的polygonOffset来避免重叠面片交替出现的问题,当然最好的方案是找的模型本身重叠面片就少

1 meshlab手动调模型

filters->Normals,curve,orientations->transform…

2 使用osg降低模型的点的坐标大小

	osg::Vec3f center1 = TerrainM1->getBound().center();
	float radius1 = TerrainM1->getBound().radius();
	osg::Vec3f center2 = TerrainM2->getBound().center();
	float radius2 = TerrainM2->getBound().radius();
	TerrainM1->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z()) *
		osg::Matrix::rotate(osg::DegreesToRadians(180.0), 1, 0, 0) *
		osg::Matrix::translate(center1.x(), center1.y(), center1.z()) *
		osg::Matrix::translate(0, 0, radius2 * 0.80 + radius1)
	);
	
	// to modify the model's points render value
	mRoot->getChild(0)->asTransform()->asMatrixTransform()->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z())
	);
	osgDB::writeNodeFile(*(mRoot->getChild(0)->asNode()), "sc.obj");

3 关于材质,光照,以及模型读写旋转平移的例子

关于材料的颜色光照等可以参考https://learnopengl-cn.readthedocs.io/zh/latest/02%20Lighting/03%20Materials/

  // mRoot是一个osg::ref_ptr<osg::Group>
	auto TerrainM1 = new osg::MatrixTransform;
	auto terrain1 = new osg::PositionAttitudeTransform;

	auto TerrainM2 = new osg::MatrixTransform;
	auto terrain2 = new osg::PositionAttitudeTransform;
	osgDB::Options  *a = new osgDB::Options(std::string("noRotation")); // 关掉模型优化绘制(OSG在加载obj模型的时候,会默认将模型绕x轴逆时针旋转90度,此处设置不旋转)

	// setting material
	osg::Material *material = new osg::Material;
	material->setDiffuse(osg::Material::FRONT, osg::Vec4(0.75, 0.80, 0.75, 1.0));
	material->setAmbient(osg::Material::FRONT, osg::Vec4(0.75, 0.80, 0.75, 1.0));
	// material->setShininess(osg::Material::FRONT, 90.0);
	
	// turn off light effect
	auto Model1 = osgDB::readNodeFile(part1Path, a);
	auto pState1 = Model1->getOrCreateStateSet();
	pState1->setMode(GL_LIGHTING, osg::StateAttribute::ON);
	pState1->setAttribute(material);
	// pState1->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
    // pState1->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
    // set polygon offset
	osg::ref_ptr<osg::PolygonOffset> polyOff = new osg::PolygonOffset();
	float mFactor = 1.0, mUnits = 1.0;
	polyOff->setFactor(mFactor);
	polyOff->setUnits(mUnits);
	pState1->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute::ON);
	material->setEmission(osg::Material::FRONT, osg::Vec4(0.75, 0.80, 0.75, 1.0));
	// pState1->setAttributeAndModes(polyOff.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

	// auto pGeom1 = Model1->asGeode()->asGeometry();
	// pGeom1->getOrCreateStateSet()->setMode(GL_NV_framebuffer_multisample_coverage, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
	TerrainM1->addChild(Model1);
	TerrainM1->setName(modelPrefix + "1");


	auto Model2 = osgDB::readNodeFile(part2Path, a);
	auto pState2 = Model2->getOrCreateStateSet();
	pState2->setMode(GL_LIGHTING, osg::StateAttribute::ON);
	pState2->setAttribute(material);
	
	pState2->setMode(GL_BLEND, osg::StateAttribute::ON);
	TerrainM2->addChild(Model2);
	TerrainM2->setName(modelPrefix + "2");

	

	// rotate to make sure the building is standing on the ground
	osg::Vec3f center1 = TerrainM1->getBound().center();
	float radius1 = TerrainM1->getBound().radius();
	osg::Vec3f center2 = TerrainM2->getBound().center();
	float radius2 = TerrainM2->getBound().radius();
	TerrainM1->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z()) *
		osg::Matrix::rotate(osg::DegreesToRadians(180.0), 1, 0, 0) *
		osg::Matrix::translate(center1.x(), center1.y(), center1.z()) *
		osg::Matrix::translate(0, 0, radius2 * 0.80 + radius1)
	);
	mRoot->addChild(TerrainM1);
	TerrainM2->setMatrix(
		osg::Matrix::translate(-center2.x(), -center2.y(), -center2.z()) *
		osg::Matrix::rotate(osg::DegreesToRadians(180.0), 1, 0, 0) *
		osg::Matrix::translate(center2.x(), center2.y(), center2.z()) *
		osg::Matrix::translate(0, 0, 0.5 * radius2)
	);
	mRoot->addChild(TerrainM2);

	// to modify the model's points render value
	mRoot->getChild(0)->asTransform()->asMatrixTransform()->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z())
	);
	mRoot->getChild(1)->asTransform()->asMatrixTransform()->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z())
	);
	mRoot->getChild(4)->asTransform()->asMatrixTransform()->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z())
	);
	mRoot->getChild(5)->asTransform()->asMatrixTransform()->setMatrix(
		osg::Matrix::translate(-center1.x(), -center1.y(), -center1.z())
	);


	osgDB::writeNodeFile(*(mRoot->getChild(0)->asNode()), "sc.obj");
	osgDB::writeNodeFile(*(mRoot->getChild(1)->asNode()), "de.obj");
	osgDB::writeNodeFile(*(mRoot->getChild(4)->asNode()), "par1.obj");
	osgDB::writeNodeFile(*(mRoot->getChild(5)->asNode()), "par2.obj");

Guess you like

Origin blog.csdn.net/cxy_hust/article/details/117065444