Hi, when i'm using shaders instead of fixed functionality to create projective textures the resulting texture mapping is a tiny spot in the center of the terrain model.
[Image: http://www.jotschi.de/download/osg/projection_shader.jpg ] If i disable the shaders by removing the follwing line i get a correct projection as you can see in the image below. Code: /* 4. Enable this to see that the shader is not working :\ */ stateset->setAttribute(projProg.get()); [Image: http://www.jotschi.de/download/osg/projection_fixedfunctionality.jpg ] I belive i do something wrong about the texture matrix generation. My vertex shader just calculates the texture coordinate for the given vertex by using the texture matrix 1: Code: varying vec4 projCord; void main() { projCord= gl_TextureMatrix[1] * gl_Vertex; gl_Position = ftransform(); gl_FrontColor = gl_Color; } My fragment shader uses the given projCord texture coordinate to load the color data from the given projectionMap texture: Code: uniform sampler2D projectionMap; varying vec4 projCord; void main() { vec4 shadowCoordinateWdivide = projCord / projCord.w ; shadowCoordinateWdivide.z += 0.0015; vec4 color = texture2D(projectionMap,shadowCoordinateWdivide.st); gl_FragColor = color * gl_Color; } Code: #include <iostream> #include <osg/Notify> #include <osg/MatrixTransform> #include <osg/ShapeDrawable> #include <osg/PositionAttitudeTransform> #include <osg/Geometry> #include <osg/Texture2D> #include <osg/Geode> #include <osg/LightSource> #include <osg/TexGenNode> #include <osgUtil/Optimizer> #include <osgDB/Registry> #include <osgDB/ReadFile> #include <osgViewer/Viewer> osg::StateSet* createProjectorState() { osg::StateSet* stateset = new osg::StateSet; /* 1. Load the texture that will be projected */ osg::Texture2D* texture = new osg::Texture2D(); texture->setImage(osgDB::readImageFile("foo.jpg")); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER); texture->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER); stateset->setTextureAttributeAndModes(1, texture, osg::StateAttribute::ON); // set up tex gens stateset->setTextureMode(1, GL_TEXTURE_GEN_S, osg::StateAttribute::ON); stateset->setTextureMode(1, GL_TEXTURE_GEN_T, osg::StateAttribute::ON); stateset->setTextureMode(1, GL_TEXTURE_GEN_R, osg::StateAttribute::ON); stateset->setTextureMode(1, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON); /* 2. Load the Shaders */ osg::ref_ptr<osg::Program> projProg(new osg::Program); osg::ref_ptr<osg::Shader> projvertexShader(osg::Shader::readShaderFile( osg::Shader::VERTEX, "VertexShader.glsl")); osg::ref_ptr<osg::Shader> projfragShader(osg::Shader::readShaderFile( osg::Shader::FRAGMENT, "FragmentShader.glsl")); projProg->addShader(projvertexShader.get()); projProg->addShader(projfragShader.get()); /* 3. Handover the texture to the fragment shader via uniform */ osg::Uniform* texUniform = new osg::Uniform(osg::Uniform::SAMPLER_2D, "projectionMap"); texUniform->set(1); stateset->addUniform(texUniform); /* 4. Enable this to see that the shader is not working :\ */ stateset->setAttribute(projProg.get()); return stateset; } osg::Node* createModel() { /* 1. Setup projector parameters */ osg::Group* root = new osg::Group; osg::Vec3 projectorPos = osg::Vec3(0.0f, 0.0f, 324.0f); osg::Vec3 projectorDirection = osg::Vec3(osg::inDegrees(0.0f), osg::inDegrees(280.0f), osg::inDegrees(-460.0f)); float projectorAngle = 110; /* 2. create tex gen. for the texture unit 1*/ osg::Vec3 up(0.0f, 0.0f, 1.0f); //up = (projectorDirection ^ up) ^ projectorDirection; //up.normalize(); osg::TexGenNode* texgenNode = new osg::TexGenNode; /* As you can see texture unit 1 is assigned the texgenNode. Does this mean the texture matrix will be stored in: gl_TextureMatrix[1] ?*/ texgenNode->setTextureUnit(1); osg::TexGen* texgen = texgenNode->getTexGen(); texgen->setMode(osg::TexGen::EYE_LINEAR); texgen->setPlanesFromMatrix(osg::Matrixd::lookAt(projectorPos, projectorPos + projectorDirection, up) * osg::Matrixd::perspective( projectorAngle, 1.0, 0.1, 100)); root->addChild(texgenNode); /* 3. Load the terrain which will be the receiver of out projection */ osg::Node* terr = osgDB::readNodeFile("Terrain2.3ds"); osg::Matrix m; osg::ref_ptr<osg::MatrixTransform> mt =new osg::MatrixTransform; m.makeTranslate( 112.f, 410.f, -2.f ); m.makeScale(2.f,2.f,2.f); mt->setMatrix( m ); root->addChild( mt.get() ); mt->addChild( terr ); //root->addChild(terr); root->setStateSet(createProjectorState()); return root; } int main(int, char **) { osgViewer::Viewer viewer; viewer.setSceneData(createModel()); viewer.setUpViewInWindow(0, 0, 1024, 768); return viewer.run(); } The complete project can be downloaded here: http://www.jotschi.de/download/osg/OSG_ProjectiveTexturesExample.tgz Perhaps you have any tips according to my problem? Maybe i have missed a step according to the texture matrix generation? Thank you! Cheers, Johannes ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=13212#13212 _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org