osg环境映射

来源:互联网 发布:京东756网络交易平台 编辑:程序博客网 时间:2024/05/22 05:15

看了几个环境映射的例子,一个是把天空盒挂上,我不同意这种观点。以车身为例,因为环境映射是车身自身反射的内容,而与环境无关。

即:输入只与视点位置有关,反射向量碰到哪个物体了就用哪个物体的像素颜色。


挂代码:

天空盒不变

#ifndefSKYBOX_H

#define SKYBOX_H


#include <osg/TextureCubeMap>


#include <osg/Transform>


class SkyBox : public osg::Transform


{


public:


    SkyBox();


    SkyBox( const SkyBox& copy, osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY )


    : osg::Transform(copy, copyop) {}


    META_Node( osg, SkyBox )


    void setEnvironmentMap( unsigned int unit, osg::Image* posX, osg::Image* negX,


                            osg::Image* posY, osg::Image* negY, osg::Image* posZ, osg::Image* negZ );


    virtual bool computeLocalToWorldMatrix( osg::Matrix& matrix, osg::NodeVisitor* nv ) const;


    virtual bool computeWorldToLocalMatrix( osg::Matrix& matrix, osg::NodeVisitor* nv ) const;


protected:


    virtual ~SkyBox() {}


};


#endif // SKYBOX_H


#include <osg/Depth>
#include <osgUtil/CullVisitor>
#include "skybox.h"
#include <QDebug>
SkyBox::SkyBox()
{
    setReferenceFrame( osg::Transform::ABSOLUTE_RF );
    setCullingActive( false );
    osg::StateSet* ss = getOrCreateStateSet();
    ss->setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL, 1.0f, 1.0f) );
    ss->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
    ss->setMode( GL_CULL_FACE, osg::StateAttribute::OFF );
    ss->setRenderBinDetails( 5, "RenderBin" );
}
void SkyBox::setEnvironmentMap( unsigned int unit, osg::Image* posX, osg::Image* negX,
                                osg::Image* posY, osg::Image* negY, osg::Image* posZ, osg::Image* negZ )
{
    if ( posX && posY && posZ && negX && negY && negZ )
    {
        qDebug() << "6imageok!";
        osg::ref_ptr<osg::TextureCubeMap> cubemap = new osg::TextureCubeMap;
        cubemap->setImage( osg::TextureCubeMap::POSITIVE_X, posX );
        cubemap->setImage( osg::TextureCubeMap::NEGATIVE_X, negX );
        cubemap->setImage( osg::TextureCubeMap::POSITIVE_Y, posY );
        cubemap->setImage( osg::TextureCubeMap::NEGATIVE_Y, negY );
        cubemap->setImage( osg::TextureCubeMap::POSITIVE_Z, posZ );
        cubemap->setImage( osg::TextureCubeMap::NEGATIVE_Z, negZ );
        cubemap->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE );
        cubemap->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE );
        cubemap->setWrap( osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE );
        cubemap->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
        cubemap->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
        cubemap->setResizeNonPowerOfTwoHint( false );
        getOrCreateStateSet()->setTextureAttributeAndModes( unit, cubemap.get() );
    }
}
bool SkyBox::computeLocalToWorldMatrix( osg::Matrix& matrix, osg::NodeVisitor* nv ) const
{
    if ( nv && nv->getVisitorType()==osg::NodeVisitor::CULL_VISITOR )
    {
        osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>( nv );
        matrix.preMult( osg::Matrix::translate(cv->getEyeLocal()) );
        return true;
    }
    else
        return osg::Transform::computeLocalToWorldMatrix( matrix, nv );
}
bool SkyBox::computeWorldToLocalMatrix( osg::Matrix& matrix, osg::NodeVisitor* nv ) const
{
    if ( nv && nv->getVisitorType()==osg::NodeVisitor::CULL_VISITOR )
    {
        osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>( nv );
        matrix.postMult( osg::Matrix::translate(-cv->getEyeLocal()) );
        return true;
    }
    else
        return osg::Transform::computeWorldToLocalMatrix( matrix, nv );
}
顶点着色器,
uniform vec3 eyepos;varying vec3 reflectvec; void main(void){   vec4 pos = normalize(gl_ModelViewMatrix * gl_Vertex);   pos = pos / pos.w;      vec3 eyevec = normalize(eyepos - pos.xyz);   vec3 norm = normalize(gl_NormalMatrix * gl_Normal);      reflectvec = reflect(-eyevec, norm);      gl_Position = ftransform();}片元着色器
uniform samplerCube cubemap;varying vec3 reflectvec; void main(void){   vec4 texcolor = textureCube(cubemap, reflectvec);      gl_FragColor = texcolor;     //gl_FragColor = float4(1.0,0.0,0.0,1.0);  }
关键在于调用时,

    osg::ref_ptr<SkyBox> theSky = new SkyBox;
    theSky->getOrCreateStateSet()->setTextureAttributeAndModes( 0, new osg::TexGen );
    theSky->setEnvironmentMap( 0,
                               osgDB::readImageFile("E:/cubemap/pos_x.jpg"),
                               osgDB::readImageFile("E:/cubemap/neg_x.jpg"),
                               osgDB::readImageFile("E:/cubemap/pos_y.jpg"),
                               osgDB::readImageFile("E:/cubemap/neg_y.jpg"),
                               osgDB::readImageFile("E:/cubemap/pos_z.jpg"),
                               osgDB::readImageFile("E:/cubemap/neg_z.jpg") );
    //theSky->addChild(geode.get());
    root->addChild(theSky);
    qDebug() << "天空盒位置:"<<theSky->getBound().center().x()<<","
             <<theSky->getBound().center().y()<<","
            <<theSky->getBound().center().z();
    //环境映射物体
    _nodeEnvMapping = osgDB::readNodeFile("E:/glider.osg");
    root->addChild(_nodeEnvMapping);
    osg::StateSet * stateEnv = _nodeEnvMapping->getOrCreateStateSet();
    osg::ref_ptr<osg::Program> programEnv = new osg::Program;
    osg::ref_ptr<osg::Shader> vertexShaderEnv = new osg::Shader( osg::Shader::VERTEX );
    osg::ref_ptr<osg::Shader> fragShaderEnv = new osg::Shader( osg::Shader::FRAGMENT );
    vertexShaderEnv->loadShaderSourceFromFile("E:/vertexEnv.txt");
    fragShaderEnv->loadShaderSourceFromFile("E:/fragEnv.txt");
    programEnv->addShader( vertexShaderEnv );
    programEnv->addShader( fragShaderEnv );
    stateEnv->setAttributeAndModes( programEnv,osg::StateAttribute::ON );
    //传递视点坐标
    viewer->setCameraManipulator(NULL);
    //获取相机参数
    osg::Vec3f eye, center, up;
    viewer->getCamera()->getViewMatrixAsLookAt(eye,center,up);
    eye = osg::Vec3(100,100,100);
    _uniEyePos = new osg::Uniform("eyepos", eye);
    stateEnv->addUniform( _uniEyePos );
如果周围没天空盒时,即为黑色的,因为反射法线碰不到物体
加上天空盒后,滑翔机显示天空盒

原创粉丝点击