Z buffer values are not linearly interpolated beetwen near and far. I did
similar things in the past and Z values often tend to occupy 0.9.. 1.0 range.
With 8 bit precision one may not notice any diferences in color. All Z values
may appear as 255 ie all white. Its good idea to use GL_DEPTH_COMPNENT as
texture internal format. See the web for discussion for Z buffer precision and
how Near to Far ratio affects Z values distibution.
Sorry for late answer, I was on sick leave for one week. let me know if you
still need suggestions. I may send you modified osgdepthshadow example which
displays shadow map in the HUD polygon.
Wojtek
----- Original Message -----
From: Mark W
To: osg users
Sent: Friday, March 02, 2007 4:51 AM
Subject: Re: [osg-users] Simple problem with multitexturing
I wasn't actually sending the texture as a uniform to the shader, but I think
I've fixed that now.
When I texture my model with the depth map that I have passed down, it comes
out pure white. If I display the depth map to the screen, I can see that it is
generated correctly. My model uses a single texture, and the texture
coordinates are spread out over most of the texture, so there should be some
spots on the model that are colored based on the depth map. Since the model is
completely white, I think I must still be doing something wrong.
Here is the osg code in question:
osg::Group* scene_root = new osg::Group;
osg::Node* model = osgDB::readNodeFile(filename);
if(!model)
{
// error code
}
// Set up our texture to be used as a depth map
osg::Texture2D* texture = new osg::Texture2D;
texture->setTextureSize(tex_width, tex_height);
texture->setInternalFormat(GL_RGB);
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_BORDER);
texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_BORDER);
texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
// set up the render to texture camera.
{
// create the camera
osg::CameraNode* camera = new osg::CameraNode;
camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
// set viewport
camera->setViewport(0,0,tex_width,tex_height);
// set the camera to render before the main camera.
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
// tell the camera to use OpenGL frame buffer object where supported.
camera->setRenderTargetImplementation(
osg::CameraNode::FRAME_BUFFER_OBJECT);
// attach the texture and use it as the color buffer.
camera->attach(osg::CameraNode::DEPTH_BUFFER, texture);
camera->addChild(model);
osg::StateSet* stateset = camera->getOrCreateStateSet();
scene_root->addChild(camera);
// Set the camera to point at the model it is rendering
osg::BoundingSphere bs;
for(unsigned int i=0; i< camera->getNumChildren(); ++i)
{
bs.expandBy(camera->getChild(i)->getBound());
}
if (!bs.valid())
{
// Error
}
osg::Vec3 position(45.0f, 0.0f, 0.0f );
float centerDistance = (position-bs.center()).length();
float znear = centerDistance-bs.radius();
float zfar = centerDistance+bs.radius();
float zNearRatio = 0.001f;
if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
float top = (bs.radius()/centerDistance)*znear;
float right = top;
camera->setReferenceFrame(osg::CameraNode::ABSOLUTE_RF);
camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
camera->setViewMatrixAsLookAt(position,bs.center(),
osg::Vec3(0.0f,1.0f,0.0f));
}
// Set the texture and pass it to the shader. (texture unit 2).
{
osg::StateSet* stateset = model->getOrCreateStateSet();
stateset->setTextureAttribute(2,texture);
stateset->addUniform( new osg::Uniform("depth", 2) );
}
//
// Create the shaders and assemble the scene
//
model_transform->addChild(model);
program = new osg::Program;
program->setName( "projective texture program" );
frag_shader = new osg::Shader( osg::Shader::FRAGMENT );
load_shader_source( frag_shader, "data/shaders/projective_texture.frag" );
program->addShader( frag_shader );
osg::StateSet* ss = get_target_stateset();
ss->setAttributeAndModes(program, osg::StateAttribute::ON);
unsigned int contextID = sceneView_ -> getState() -> getContextID() ;
frag_shader->compileShader(contextID);
scene_root->addChild(model_transform);
sceneView_->setSceneData(scene_root);
And here is the shader code. Right now I'm just trying to make sure the
depth map is passed into the shader correctly, so I'm just using it as my
texture.
uniform sampler2D tex, depth;
void main()
{
vec4 color = texture2D(depth,gl_TexCoord[0].st);
gl_FragColor = color;
}
Can anyone tell why my model just shows up pure white? It should have the
depth map pasted on it in some manner.
Wojciech Lewandowski <[EMAIL PROTECTED]> wrote:
> But then looking at the two lines together:
>
>
> stateset->setTextureAttributeAndModes(1,texture,osg::StateAttribute::ON);
>
> stateset->setTextureAttributeAndModes(1,texgen,osg::StateAttribute::ON);
>
>it would appear that both of these textures are being applied to texture
>unit 1, and are then being blended together by the osg::TexEnv that is
>defined (and also applied to >texture unit 1).
TexGen attribute is not a Texture. One cannot have two Textures active for
one stage. Second texture applied will override the first one.
Two lines above first set Texture for the stage 1 and then set automatic
tex
coord generation (TexGen) for the same stage. Only one texture "texture" is
applied, texgen auto generates texture coordinates for all vertices passed
and tex env blends texture with constant color defined (.3f,0.3f,0.3f,0.3f).
State method setTextureAttributeAndModes sets attribute for particular
Texture Stage. It does not only select specific Texture for the stage but
can set other texture attributes like TexGen, TexEnv, TexMat, PointSprite,
TexEnvFilter, TexEnvCombine.
As for the second texture on stage 2. There are other things that could
went
wrong. Possible errors may be texture on stage 2 not passed as uniform to
shader, texture coords not present, errors fragment shader code. Provide
some source code and we may be more helpful.
Cheers,
Wojtek Lewandowski
----- Original Message -----
From: Mark W
To: [email protected]
Sent: Thursday, March 01, 2007 8:08 AM
Subject: [osg-users] Simple problem with multitexturing
Hey everyone,
I'm writing a fragment shader to do projective texturing. I'm using an
osg::camera to render a depth map to a texture, and then I'd like to bind
that texture to my model so that I can access it from within my fragment
shader.
I looked at the osgmultitexture example, and the texture code is as follows:
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
osg::TexGen* texgen = new osg::TexGen;
texgen->setMode(osg::TexGen::SPHERE_MAP);
osg::TexEnv* texenv = new osg::TexEnv;
texenv->setMode(osg::TexEnv::BLEND);
texenv->setColor(osg::Vec4(0.3f,0.3f,0.3f,0.3f));
osg::StateSet* stateset = new osg::StateSet;
stateset->setTextureAttributeAndModes(1,texture,osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(1,texgen,osg::StateAttribute::ON);
stateset->setTextureAttribute(1,texenv);
rootnode->setStateSet(stateset);
From my understanding, the line:
stateset->setTextureAttributeAndModes(1,texture,osg::StateAttribute::ON);
binds "texture" to texture unit 1 and enables that texture. But then
looking at the two lines together:
stateset->setTextureAttributeAndModes(1,texture,osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(1,texgen,osg::StateAttribute::ON);
it would appear that both of these textures are being applied to texture
unit 1, and are then being blended together by the osg::TexEnv that is
defined (and also applied to texture unit 1).
My initial thought was that I would just take my model's stateset (the
model
is only using a single texture) and make a function call like:
osg::StateSet* stateset = model->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(2,my_texture,osg::StateAttribute::ON);
to bind a texture into texture unit 2 for that model. I tried this and it
doesn't seem to allow me to access the second texture in my fragment
shader.
I attempted to put the new texture in texture unit 1 (attempting to copy
the
example where both textures are put in the first texture unit) but I didn't
use an osg::TexEnv to blend or anything like that (I just want to be able
to
access both textures independently, I don't want them to be blended for me).
I realize this is a pretty elementary question, but it's had me stumped for
longer than I care to admit :). Thanks a bunch in advance for any help you
guys can offer!
Mark
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/
------------------------------------------------------------------------------
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/