osgUtil.TangentSpaceGenerator
OSG(OpenSceneGraph)中的 osgUtil.TangentSpaceGenerator
用于生成切线空间。切线空间可以用于在渲染时进行法线映射、光照和阴影计算。在计算完顶点列表和法线列表之后,osgUtil.TangentSpaceGenerator
可以创建一个包含切线和副切线的新顶点列表,与法线列表一起传输到着色器中。
TangentSpaceGenerator(unsigned int tangentArrayIndex=6, unsigned int binormalArrayIndex=7, unsigned int normalArrayIndex=2);
构造函数,使用索引初始化切线、副切线和法线。
void generate(osg::Geometry& geometry);
计算一些几何参数,例如三角形的面积和周长,以及顶点的法线,并使用这些参数来计算三角形的切线和副切线。
void generate(osg::PrimitiveSet* geometry);
计算一些几何参数,例如三角形的面积和周长,以及顶点的法线,并使用这些参数来计算三角形的切线和副切线。
// 加载模型到场景图中
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("model.obj");
// 找到模型中的第一个几何体
osg::ref_ptr<osg::Geometry> geometry = dynamic_cast<osg::Geometry*>(model->getOrCreateStateSet()->getAttribute(osg::StateAttribute::Type::GEOMETRY)->asGeometry());
// 计算切线和副切线
osgUtil::TangentSpaceGenerator tsg;
tsg.generate(*geometry);
// 提取顶点数组和索引数组
osg::ref_ptr<osg::Vec3Array> vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
osg::ref_ptr<osg::UShortArray> indices = dynamic_cast<osg::UShortArray*>(geometry->getPrimitiveSet(0)->getIndices());
// 在着色器中使用切线和副切线
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(new osg::Shader(osg::Shader::Type::VERTEX, vertexShaderSource));
program->addShader(new osg::Shader(osg::Shader::Type::FRAGMENT, fragmentShaderSource));
program->setParameter(GL_GEOMETRY_VERTICES_OUT_EXT, 3);
program->setParameter(GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES);
program->setParameter(GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP);
program->setParameter(GL_GEOMETRY_OUTPUT_VERTEX_COUNT_EXT, 3);
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
stateSet->setAttributeAndModes(program.get());
stateSet->addUniform(new osg::Uniform("tangentArray", tsg.getTangentArrayIndex()));
stateSet->addUniform(new osg::Uniform("binormalArray", tsg.getBinormalArrayIndex()));
stateSet->addUniform(new osg::Uniform("normalArray", tsg.getNormalArrayIndex()));
stateSet->setTextureAttributeAndModes(tsg.getTangentArrayIndex(), tsg.getTangentTexture(), osg::StateAttribute::ON);
stateSet->setTextureAttributeAndModes(tsg.getBinormalArrayIndex(), tsg.getBinormalTexture(), osg::StateAttribute::ON);
stateSet->setTextureAttributeAndModes(tsg.getNormalArrayIndex(), tsg.getNormalTexture(), osg::StateAttribute::ON);
// 应用状态集
geometry->setStateSet(stateSet.get());