Pbr的间接光用到立方体贴图,所以,先用shader进行立方体贴图。
 立方体贴图很简单,就是用方向向量(不一定是单位向量)采样cubeMap的颜色。
 也就是在片元着色器中传递。
"float x = outPos.r;\n"
"float y = outPos.g;\n"
"float z = outPos.b;\n"
"vec3 dir = vec3(x,y,z);\n"
"gl_FragColor = texture(tex0,dir);\n"
 
也就是需要把位置数组传递到shader中,可以用个NodeVisitor
 class MyNodeVisitor : public osg::NodeVisitor
 {
 public:
 MyNodeVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
 {
}
void apply(osg::Geode& geode)
{
	int count = geode.getNumDrawables();
	for (int i = 0; i < count; i++)
	{
		osg::ref_ptr<osg::Geometry> geometry = geode.getDrawable(i)->asGeometry();
		if (!geometry.valid())
		{
			continue;
		}
		osg::Array* vertexArray = geometry->getVertexArray();
		geometry->setVertexAttribArray(1, vertexArray);//这里传递位置数组。
	}
	traverse(geode);
}
 
};
cubeMap需要把六个面的图片都加上,即。
 osg::ref_ptrosg::TextureCubeMap tcm = new osg::TextureCubeMap;
 tcm->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
 tcm->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
 tcm->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
 tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
 tcm->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
 tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);
随便贴到一个Osg::box就行。
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, tcm, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
 
接下来在shader的c++端传递位置数组和纹理
program1->addBindAttribLocation("aPos", 1);
osg::ref_ptr<osg::Uniform> tex0Uniform = new osg::Uniform("tex0", 0);
stateset->addUniform(tex0Uniform);
 
如下图所示
 
 完整代码如下:
 #include <osg/TextureCubeMap>
 #include <osg/TexGen>
 #include <osg/TexEnvCombine>
 #include <osgUtil/ReflectionMapGenerator>
 #include <osgDB/ReadFile>
 #include <osgViewer/Viewer>
 #include <osg/NodeVisitor>
 #include <osg/ShapeDrawable>
static const char * vertexShader =
 {
 “in vec3 aPos;\n”
 “varying vec3 outPos;”
 “void main(void)\n”
 “{\n”
 “outPos = aPos;\n”
 " gl_Position = ftransform();\n"
 “}\n”
 };
static const char *psShader =
 {
 “varying vec3 outPos;”
 “uniform samplerCube tex0;”
 “void main(void)\n”
 “{\n”
 “float x = outPos.r;\n”
 “float y = outPos.g;\n”
 “float z = outPos.b;\n”
 “vec3 dir = vec3(x,y,z);\n”
 “gl_FragColor = texture(tex0,dir);\n”
 “}\n”
 };
 class MyNodeVisitor : public osg::NodeVisitor
 {
 public:
 MyNodeVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
 {
}
void apply(osg::Geode& geode)
{
	int count = geode.getNumDrawables();
	for (int i = 0; i < count; i++)
	{
		osg::ref_ptr<osg::Geometry> geometry = geode.getDrawable(i)->asGeometry();
		if (!geometry.valid())
		{
			continue;
		}
		osg::Array* vertexArray = geometry->getVertexArray();
		geometry->setVertexAttribArray(1, vertexArray);
	}
	traverse(geode);
}
 
};
int main()
 {
 osg::ref_ptrosg::TextureCubeMap tcm = new osg::TextureCubeMap;
 tcm->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
 tcm->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
 tcm->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP);
std::string strImagePosX = "D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/Cubemap_axis/posx.bmp";
osg::ref_ptr<osg::Image> imagePosX = osgDB::readImageFile(strImagePosX);
tcm->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
std::string strImageNegX = "D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/Cubemap_axis/negx.bmp";
osg::ref_ptr<osg::Image> imageNegX = osgDB::readImageFile(strImageNegX);
tcm->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
std::string strImagePosY = "D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/Cubemap_axis/posy.bmp";
osg::ref_ptr<osg::Image> imagePosY = osgDB::readImageFile(strImagePosY);
tcm->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
std::string strImageNegY = "D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/Cubemap_axis/negY.bmp";
osg::ref_ptr<osg::Image> imageNegY = osgDB::readImageFile(strImageNegY);
tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
std::string strImagePosZ = "D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/Cubemap_axis/posZ.bmp";
osg::ref_ptr<osg::Image> imagePosZ = osgDB::readImageFile(strImagePosZ);
tcm->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
std::string strImageNegZ = "D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/Cubemap_axis/negZ.bmp";
osg::ref_ptr<osg::Image> imageNegZ = osgDB::readImageFile(strImageNegZ);
tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);
osg::ref_ptr<osg::Box> box = new osg::Box(osg::Vec3(0, 0, 0), 1);
osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(box);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(drawable);
MyNodeVisitor nv;
geode->accept(nv);
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, tcm, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
//shader
osg::ref_ptr<osg::Shader> vs1 = new osg::Shader(osg::Shader::VERTEX, vertexShader);
osg::ref_ptr<osg::Shader> ps1 = new osg::Shader(osg::Shader::FRAGMENT, psShader);
osg::ref_ptr<osg::Program> program1 = new osg::Program;
program1->addShader(vs1);
program1->addShader(ps1);
program1->addBindAttribLocation("aPos", 1);
osg::ref_ptr<osg::Uniform> tex0Uniform = new osg::Uniform("tex0", 0);
stateset->addUniform(tex0Uniform);
stateset->setAttribute(program1, osg::StateAttribute::ON);
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(geode);
viewer->realize();
return viewer->run();
 
}


















