[osg-users] GLSL shaders and projective texturing

269 views
Skip to first unread message

Brad Colbert

unread,
Sep 27, 2011, 4:16:29 PM9/27/11
to osg-...@openscenegraph.org
Hi folks,

I'm looking for a complete example showing projective texturing with GLSL shaders in OSG. I'm simply trying to implement a spotlight just like the osgspotlight example. What I've found doesn't quite paint the whole picture for me. Anything would be helpful.

Cheers,
Brad

---
Brad Colbert
Renaissance Sciences Corporation
(480) 374-5073


_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Chris 'Xenon' Hanson

unread,
Sep 27, 2011, 4:43:55 PM9/27/11
to OpenSceneGraph Users
On 9/27/2011 2:16 PM, Brad Colbert wrote:
> Hi folks,
> I'm looking for a complete example showing projective texturing with GLSL shaders in OSG. I'm simply trying to implement a spotlight just like the osgspotlight example. What I've found doesn't quite paint the whole picture for me. Anything would be helpful.

This one seemed fairly complete.
http://www.jotschi.de/?p=378


Ping me if you need help on the project.


--
Chris 'Xenon' Hanson, omo sanza lettere. Xe...@AlphaPixel.com http://www.alphapixel.com/
Digital Imaging. OpenGL. Scene Graphs. GIS. GPS. Training. Consulting. Contracting.
"There is no Truth. There is only Perception. To Perceive is to Exist." - Xen

Brad Colbert

unread,
Sep 27, 2011, 6:08:51 PM9/27/11
to OpenSceneGraph Users

Hi Chris,

 

Thanks for the quick reply and the lead.  I'm still fumbling around with that example and I think I've found an issue with it.  It appears to be sensitive to the camera position (ie not the correct projection solution).  This little bit in the shader makes me feel that it's suspect (+vec2(0.5,0.5)):

 

"     vec4 color =  texture2D(projectionMap,dividedCoord.st+vec2(0.5,0.5)  );"

 

 

Do embedded images come across in these emails:

 

Startup:

 

 

Moving in slide to the right (projection moves to the far right):

 

 

-B

Brad Colbert

unread,
Sep 27, 2011, 8:36:47 PM9/27/11
to OpenSceneGraph Users, osg-...@openscenegraph.org
To add more to this:

I've adapted this to where the camera is the projector (ie the image is projected from the viewpoint, well, at least that is the idea):

http://www.jotschi.de/?p=378

and I would like to say I'm close, but I'm still a ways away from a solution.

I do see the "clock" projected onto my model, but the movement is not properly coordinated with my camera, and I'm quite sure I see the reverse projection at times.

I'm including my source below hoping someone can find what I've done wrong.

//
#include <osg/Version>
#include <osg/Camera>
#include <osg/NodeVisitor>
#include <osg/TexGenNode>
#include <osg/TexMat>

#include <osgSim/MultiSwitch>

#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/DatabasePager>

#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/CameraManipulator>


#include <iostream>
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
#include <osg/PositionAttitudeTransform>
#include <osg/Geometry>
#include <osgGA/TrackballManipulator>

#include <osg/Texture2D>
#include <osg/Geode>
#include <osg/LightSource>
#include <osg/TexGenNode>
#include <osg/TexMat>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>

using namespace std;

osgViewer::View* viewA = new osgViewer::View;
osg::TexMat* texMat = new osg::TexMat;
osg::Uniform* ViewMatInv = new osg::Uniform( osg::Uniform::FLOAT_MAT4,
"ViewMatInv" );


osg::ref_ptr<osg::Program> addShader()
{
osg::ref_ptr<osg::Program> projProg(new osg::Program);
osg::ref_ptr<osg::Shader> projvertexShader(osg::Shader::readShaderFile(
osg::Shader::VERTEX, "surface.main.vert.glsl"));
osg::ref_ptr<osg::Shader> projfragShader(osg::Shader::readShaderFile(
osg::Shader::FRAGMENT, "surface.main.frag.glsl"));

projProg->addShader(projvertexShader.get());
projProg->addShader(projfragShader.get());
return projProg;
}

void addProjectionInfoToState(osg::StateSet* stateset, string fn)
{

osg::Vec4 centerColour(1.0f,1.0f,1.0f,1.0f);
osg::Vec4 ambientColour(0.05f,0.05f,0.05f,1.0f);

/* 1. Load the texture that will be projected */
osg::Texture2D* texture = new osg::Texture2D();
texture->setImage( osgDB::readImageFile(fn) );//VTB::createSpotLightImage(centerColour, ambientColour, 64, 1.0));
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( (int)spotTUnit, texture, osg::StateAttribute::ON);

// set up tex gens
stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);
stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);
stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON);
stateset->setTextureMode((int)spotTUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON);

/* 3. Handover the texture to the fragment shader via uniform */
osg::Uniform* texUniform = new osg::Uniform(osg::Uniform::SAMPLER_2D,
"projectionMap");
texUniform->set( (int)spotTUnit );
stateset->addUniform(texUniform);

/* 4. set Texture matrix*/

//If you want to create the texture matrix by yourself you can do this like this way:
//osg::Vec3 projectorPos = osg::Vec3(0.0f, 0.0f, 324.0f);
//osg::Vec3 projectorDirection = osg::Vec3(osg::inDegrees(dirX),osg::inDegrees(dirY), osg::inDegrees(dirZ));
//osg::Vec3 up(0.0f, 1.0f, 0.0f);
//osg::Vec3 target = osg::Vec3(0.0f, 0.0f,0.0f);
//float projectorAngle = 80.f; //FOV
//mat = osg::Matrixd::lookAt(projectorPos, projectorPos*target ,up) * osg::Matrixd::perspective(projectorAngle, 1.0, 1.0, 10);

osg::Matrix mat = viewA->getCamera()->getViewMatrix()
* viewA->getCamera()->getProjectionMatrix();

texMat->setMatrix(mat);
stateset->setTextureAttributeAndModes((int)spotTUnit, texMat, osg::StateAttribute::ON);

stateset->addUniform( ViewMatInv );
}

osg::StateSet* createProjectorState()
{
osg::StateSet* stateset = new osg::StateSet;

osg::ref_ptr<osg::Program> prog = addShader();

addProjectionInfoToState(stateset, "C:\\Users\\bcolbert\\Desktop\\Work\\OpenSceneGraph-Data-3.0.0\\Images\\clockface.JPG");

stateset->setAttribute(prog.get());

return stateset;
}

/**
* Load some model, scale it and apply the shader
*/
osg::Node* createModel()
{
osg::Group* root = new osg::Group;

/* Load the terrain which will be the receiver of out projection */
osg::Node* terr = osgDB::readNodeFile("C:\\Users\\bcolbert\\Documents\\JOSHVILLE_new2.ive");

root->addChild( terr );

/* Enable projective texturing for all objects of this node */
root->setStateSet( createProjectorState() );
return root;
}

int main( int argc, char* argv[] )
{
// Set the output level
osg::setNotifyLevel( osg::WARN );

osg::ArgumentParser arguments(&argc, argv);

osg::ref_ptr<osg::Group> sceneA = new osg::Group;
osg::ref_ptr<osg::Group> sceneB = new osg::Group;
osg::ref_ptr<osg::Group> sceneC = new osg::Group;
sceneA->addChild(createModel());

osgViewer::CompositeViewer viewer(arguments);

viewer.addView(viewA);
viewA->setUpViewInWindow(10, 10, 640, 480);
viewA->setSceneData(sceneA.get());

//Add this to move the projector by mouse - you need to disable the set
//of the viewmatrix in the while loop below.
osgGA::TrackballManipulator* aManipulator = new osgGA::TrackballManipulator;
viewA->setCameraManipulator(aManipulator);

// Create a TexGenNode to automatically update the
// planes.
osg::TexGenNode* texgenNode = new osg::TexGenNode;
texgenNode->setTextureUnit( (int)spotTUnit );

osg::TexGen* texgen = texgenNode->getTexGen();
texgen->setMode( osg::TexGen::EYE_LINEAR );

osg::MatrixTransform* posTexGen = new osg::MatrixTransform;
posTexGen->addChild( texgenNode );

osg::Vec3 position(0.0f,0.0f,0.0f);
osg::Vec3 direction(0.0f,1.0f,0.0f);
osg::Vec3 up(0.0f,0.0f,1.0f);
up = (direction ^ up) ^ direction;
up.normalize();

texgen->setPlanesFromMatrix( osg::Matrixd::lookAt(position, position+direction, up)*
viewA->getCamera()->getProjectionMatrix() );
// osg::Matrixd::perspective(45.f,1.0,0.1,100));

sceneA->addChild( posTexGen );


while ( !viewer.done() )
{
osg::Matrixd viewMatInv( viewA->getCamera()->getInverseViewMatrix() );
ViewMatInv->set( viewMatInv );

// Position the TexGenNode in the world with the camera;
posTexGen->setMatrix( aManipulator->getInverseMatrix() );

viewer.frame();
}
return 0;
}


Vertex shader:

uniform mat4 ViewMatInv;

void main()
{
vec4 posEye = gl_ModelViewMatrix * gl_Vertex;
// vec4 posWorld = ViewMatInv * posEye;

gl_TexCoord[3].s = dot( posEye, gl_EyePlaneS[3] );
gl_TexCoord[3].t = dot( posEye, gl_EyePlaneT[3] );
gl_TexCoord[3].p = dot( posEye, gl_EyePlaneR[3] );
gl_TexCoord[3].q = dot( posEye, gl_EyePlaneQ[3] );

gl_Position = gl_ProjectionMatrix * posEye;
}


Fragment shader:

uniform sampler2D projectionMap;
varying vec4 projCoord;

void main()
{
gl_FragColor = texture2DProj( projectionMap, gl_TexCoord[3] );

#if TEST_FOR_REVERSE_PROJECTION
if ( gl_TexCoord[3].q > 0.0 )
gl_FragColor = texture2DProj( projectionMap, gl_TexCoord[3] );
else
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
#endif
}
-B

Brad Colbert

unread,
Sep 27, 2011, 9:11:44 PM9/27/11
to OpenSceneGraph Users, osg-...@openscenegraph.org

An update:

 

This is interesting.  If I "fix" the position of the TexGenNode I get something that is starting to make sense.

 

I commented out the code that updates the posTexGen (MatrixTransform) in the tight-loop and changed the initial state of the texgen position, direction and up:

 

    osg::Vec3 position(0.0f,0.0f,-75.0f);

    osg::Vec3 direction(0.0f,0.0f,1.0f);

    osg::Vec3 up(0.0f,1.0f,0.0f);

 

It's strange but the coordinate system does not appear to be Z up.  Any ideas on that one?

 

Anyway, here is some eye-candy:

 

Brad Colbert

unread,
Sep 27, 2011, 9:21:38 PM9/27/11
to OpenSceneGraph Users, osg-...@openscenegraph.org

I am closer!

 

By reversing the "direction" of the osg::Matrixd::lookAt call used in the setPlanesFromMatrix() and setting the matrix of the posTexGen with the actual matrix from the manipulator instead of the inverse matrix, It now looks like it's following (and projecting from) the camera position/orientation!  Strange thing though is that the projection is only in the upper right quandrant.  Any ideas on how to fix this?

 

Code updates:

 

    osg::Vec3 direction(0.f, 0.f, -1.0f);

 

...

 

        // Position the TexGenNode in the world with the camera;

        posTexGen->setMatrix( aManipulator->getMatrix() );

 

Eye candy:

 

 

-B

 

 

-----Original Message-----
From: osg-user...@lists.openscenegraph.org [mailto:osg-user...@lists.openscenegraph.org] On Behalf Of Brad Colbert

Sent: Tuesday, September 27, 2011 5:37 PM
To: 'OpenSceneGraph Users'; 'osg-...@openscenegraph.org'

Chris 'Xenon' Hanson

unread,
Sep 28, 2011, 6:31:01 PM9/28/11
to OpenSceneGraph Users
On 9/27/2011 7:21 PM, Brad Colbert wrote:
> I am closer!

Looks like the other example I have is FFP not GLSL. Here's a working GLSL
implementation (not OSG) that should be relatively easy to feed with OSG uniforms and such:

http://www.ozone3d.net/tutorials/glsl_texturing_p08.php#part_8

--
Chris 'Xenon' Hanson, omo sanza lettere. Xe...@AlphaPixel.com http://www.alphapixel.com/
Digital Imaging. OpenGL. Scene Graphs. GIS. GPS. Training. Consulting. Contracting.
"There is no Truth. There is only Perception. To Perceive is to Exist." - Xen

Brad Colbert

unread,
Sep 28, 2011, 7:34:19 PM9/28/11
to OpenSceneGraph Users
Hi Chris,

Thanks! I found that one too but it still doesn't help me figure out how to fix the coordinates so that my projected texture renders in the center of the projection frustum instead of the upper right quadrant. It's strange and I can't figure it out.

-B


-----Original Message-----
From: osg-user...@lists.openscenegraph.org [mailto:osg-user...@lists.openscenegraph.org] On Behalf Of Chris 'Xenon' Hanson
Sent: Wednesday, September 28, 2011 3:31 PM
To: OpenSceneGraph Users
Subject: Re: [osg-users] GLSL shaders and projective texturing

Glenn Waldron

unread,
Sep 28, 2011, 7:40:27 PM9/28/11
to OpenSceneGraph Users
Brad,
I once had the same issue; calcuating my texgen matrix like this worked:

texGenMat =
    modelViewMat *
    projectionMat *
    osg::Matrix::translate(1, 1, 1) *
    osg::Matrix::scale(0.5, 0.5, 0.5);

    
Glenn Waldron / Pelican Mapping / @glennwaldron

Brad Colbert

unread,
Sep 28, 2011, 7:59:51 PM9/28/11
to OpenSceneGraph Users

Glenn,

 

Bingo!  That was it.  I wasn’t quite sure that would work with TexGen but there you go!

 

Thanks!

 

 

-B

Per Nordqvist

unread,
Sep 29, 2011, 7:46:25 AM9/29/11
to OpenSceneGraph Users
I also struggled with this issue once and I believe osgspotlight suffers from exactly the same "quadrant defect" if you look closely.
Would be really nice if somebody submitted a fix.

/Per

J.P. Delport

unread,
Sep 29, 2011, 8:18:40 AM9/29/11
to OpenSceneGraph Users
I think Paul Martz did already.

http://thread.gmane.org/gmane.comp.graphics.openscenegraph.cvs/9237/focus=9304

jp

On 29/09/2011 13:46, Per Nordqvist wrote:
> I also struggled with this issue once and I believe osgspotlight suffers
> from exactly the same "quadrant defect" if you look closely.
> Would be really nice if somebody submitted a fix.
>
> /Per
>
> On 29 September 2011 01:59, Brad Colbert <bcol...@rscusa.com

> <mailto:bcol...@rscusa.com>> wrote:
>
> Glenn,____
>
> __ __


>
> Bingo! That was it. I wasn’t quite sure that would work with

> TexGen but there you go!____
>
> __ __
>
> Thanks!____
>
> __ __
>
> ____
>
> __ __
>
> -B____
>
> __ __
>
> *From:*osg-user...@lists.openscenegraph.org
> <mailto:osg-user...@lists.openscenegraph.org>
> [mailto:osg-user...@lists.openscenegraph.org
> <mailto:osg-user...@lists.openscenegraph.org>] *On Behalf Of
> *Glenn Waldron
> *Sent:* Wednesday, September 28, 2011 4:40 PM
>
>
> *To:* OpenSceneGraph Users
> *Subject:* Re: [osg-users] GLSL shaders and projective texturing____
>
> __ __
>
> Brad,____


>
> I once had the same issue; calcuating my texgen matrix like this

> worked:____
>
> __ __
>
> texGenMat =____
>
> modelViewMat *____
>
> projectionMat *____
>
> osg::Matrix::translate(1, 1, 1) *____
>
> osg::Matrix::scale(0.5, 0.5, 0.5);____
>
> __ __


>
>
> Glenn Waldron / Pelican Mapping / @glennwaldron
>

> ____


>
> On Wed, Sep 28, 2011 at 7:34 PM, Brad Colbert <bcol...@rscusa.com

> <mailto:bcol...@rscusa.com>> wrote:____


>
> Hi Chris,
>
> Thanks! I found that one too but it still doesn't help me figure
> out how to fix the coordinates so that my projected texture renders
> in the center of the projection frustum instead of the upper right
> quadrant. It's strange and I can't figure it out.
>

> -B____

> <mailto:osg-...@lists.openscenegraph.org>


> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> _______________________________________________
> osg-users mailing list
> osg-...@lists.openscenegraph.org

> <mailto:osg-...@lists.openscenegraph.org>
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org____
>
> __ __


>
>
> _______________________________________________
> osg-users mailing list
> osg-...@lists.openscenegraph.org

> <mailto:osg-...@lists.openscenegraph.org>

--
This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard.
The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.

This message has been scanned for viruses and dangerous content by MailScanner,
and is believed to be clean.

Brad Colbert

unread,
Sep 29, 2011, 12:54:47 PM9/29/11
to OpenSceneGraph Users
Funny, I should have changed my search to just "projective texture" and I think this would have popped up.

-B

Reply all
Reply to author
Forward
0 new messages