Hi Nan,

could you explain why here you used texCoord1?

because of we setting '1' here?
        sset->setTextureAttributeAndModes(1,tex2D,osg::StateAttribute::ON);
        sset->addUniform(new osg::Uniform("tex",1));

i dont think so ...

Generally, there will be a correspondence between 3 things:

1. The texture unit the texture is set to, i.e.
    const unsigned int TEXTURE_UNIT = 1;
    stateSet->setTextureAttributeAndModes(TEXTURE_UNIT, texture,
                                          osg::StateAttribute::ON);

2. The sampler used to access the texture in the shader, i.e.
    // Note that this is shorthand for:
    //  osg::Uniform* samplerUniform =
    //      new osg::Uniform(osg::Uniform::SAMPLER_2D, "SamplerName);
    //  samplerUniform->set(TEXTURE_UNIT);
    //  stateSet->addUniform(samplerUniform);
    // because the GLSL compiler can interpret a uniform of type
    // unsigned int as type sampler2D interchangeably. Be careful if
    // you use an inline number in the line below though, some
    // compilers will interpret that as int instead of unsigned int
    // which can't be used as a sampler2D type so you'll either get
    // errors or your texture will show up as all black.
    stateSet->addUniform(new osg::Uniform("SamplerName", TEXTURE_UNIT));

   and in the fragment shader:
    uniform sampler2D SamplerName;

3. The texture coordinate array used to sample the texture, i.e.
    geometry->setTexCoordArray(TEXTURE_UNIT, texCoordArray.get());

   and in the vertex shader:
    gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;

   and in the fragment shader:
    vec4 textureColor = texture2D(SamplerName, gl_TexCoord[1].st);

To be able to access the texture at all in the shader, the first two must match, meaning the texture unit you've set the texture on in the stateset (setTextureAttributeAndModes(TEXTURE_UNIT, ...) ) must match the unsigned integer you've set in the uniform, and then you have to use that same name in your shader as a uniform sampler2D type variable.

The one that can be relaxed is the third one. You aren't forced to sample your texture using the same texture coordinate unit number as the texture uses, in fact you could calculate texture coordinates in other ways, for example have some correspondence of world space to texture coordinates, or projection of the texture.

But in the case of normal mapping, in general, the normal map texture has the same form as the diffuse (color) texture (in fact it's often generated from some tool that interprets the shading in the diffuse texture as bumps), so you can use the same texture coordinates (i.e. texture coordinate array 0 in general) to sample the normal map. So if that is the case, you don't need to create a texture coordinate array for unit 1 in your geometry object, and in the shader you just use:

    vec4 normalMapValue = texture2D(SamplerName, gl_TexCoord[0].st);

Hope this clears things up,

J-S
--
______________________________________________________
Jean-Sebastien Guay    jean-sebastien.g...@cm-labs.com
                               http://www.cm-labs.com/
                    http://whitestar02.dyndns-web.com/
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to