查看: 1878|回复: 2

求教:有关shader

[复制链接]

该用户从未签到

发表于 2011-9-3 15:48:02 | 显示全部楼层 |阅读模式
我仿照osgshader的大理石做了一些效果,想请问那个噪声的纹理能否变个方向,譬如由横向变为纵向。因为模型的面数很多,难以一个个设置纹理坐标。由于对着色语言并不熟悉,我只能让那个动态纹理改变其运动方向,而并不能改变纹理本身的方向。求高手指教。

该用户从未签到

发表于 2011-9-5 08:58:36 | 显示全部楼层
您都没有给出shader的代码,我如何判断您该如何改进?

该用户从未签到

 楼主| 发表于 2011-9-17 07:30:45 | 显示全部楼层
回复 2# array


    static osg::ref_ptr<osg::Group> rootNode;
static osg:rogram* BlockyProgram;
static osg::Shader*  BlockyVertObj;
static osg::Shader*  BlockyFragObj;
static osg::Program* ErodedProgram;
static osg::Shader*  ErodedVertObj;
static osg::Shader*  ErodedFragObj;
static osg::Program* MarbleProgram;
static osg::Shader*  MarbleVertObj;
static osg::Shader*  MarbleFragObj;
#define TEXUNIT_SINE        1
#define TEXUNIT_NOISE        2
class GeodeVisitor:public osg::NodeVisitor
{
public:
GeodeVisitor::GeodeVisitor(const std::string &searchName1,const std::string &searchName2,const std::string &searchName3,const std::string &searchName4,const std::string &searchName5,const std::string &searchName6,const std::string &searchName7,const std::string &searchName8,const std::string &searchName9,const std::string &searchName10,const std::string &searchName11,const std::string &searchName12,const std::string &searchName13,const std::string &searchName14):
   osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),searchForName1(searchName1),searchForName2(searchName2),searchForName3(searchName3),searchForName4(searchName4),searchForName5(searchName5),searchForName6(searchName6),searchForName7(searchName7),searchForName8(searchName8),searchForName9(searchName9),searchForName10(searchName10),searchForName11(searchName11),searchForName12(searchName12),searchForName13(searchName13),searchForName14(searchName14)
{
}
void GeodeVisitor::apply(osg::Geode &searchNode)
{
  if(searchNode.getName()==searchForName1)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(3,"RenderBin");
  }
  if(searchNode.getName()==searchForName2)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName3)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName4)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName5)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName6)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName7)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName8)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName9)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName10)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName11)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName12)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName13)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(2,"RenderBin");
  }
  if(searchNode.getName()==searchForName14)
  {
   searchNode.getOrCreateStateSet()->setRenderBinDetails(-1,"RenderBin");
  }
  NodeVisitor::apply(searchNode);
}
void GeodeVisitor::setNameToFind(const std::string &searchName1,const std::string &searchName2,const std::string &searchName3,const std::string &searchName4,const std::string &searchName5,const std::string &searchName6,const std::string &searchName7,const std::string &searchName8,const std::string &searchName9,const std::string &searchName10,const std::string &searchName11,const std::string &searchName12,const std::string &searchName13,const std::string &searchName14)
{
  searchForName1=searchName1;
  searchForName2=searchName2;
  searchForName3=searchName3;
  searchForName4=searchName4;
  searchForName5=searchName5;
  searchForName6=searchName6;
  searchForName7=searchName7;
  searchForName8=searchName8;
  searchForName9=searchName9;
  searchForName10=searchName10;
  searchForName11=searchName11;
  searchForName12=searchName12;
  searchForName13=searchName13;
  searchForName14=searchName14;
  foundNodeList.clear();
}
osg::Node* GeodeVisitor::getFirst()
{
  return *(foundNodeList.begin());
}
typedef std::vector<osg::Node*> nodeListType;
private:
std::string searchForName1;
std::string searchForName2;
std::string searchForName3;
std::string searchForName4;
std::string searchForName5;
std::string searchForName6;
std::string searchForName7;
std::string searchForName8;
std::string searchForName9;
std::string searchForName10;
std::string searchForName11;
std::string searchForName12;
std::string searchForName13;
std::string searchForName14;
nodeListType foundNodeList;
};
static osg::Image*make3DNoiseImage(int texSize)//三维噪声贴图
{
    osg::Image* image = new osg::Image;
    image->setImage(texSize, texSize, texSize,
            4, GL_RGBA, GL_UNSIGNED_BYTE,
            new unsigned char[4 * texSize * texSize * texSize],
            osg::Image::USE_NEW_DELETE);
    const int startFrequency = 4;
    const int numOctaves = 4;
    int f, i, j, k, inc;
    double ni[3];
    double inci, incj, inck;
    int frequency = startFrequency;
    GLubyte *ptr;
    double amp = 0.5;
    osg::notify(osg::INFO) << "creating 3D noise texture... ";
    for (f = 0, inc = 0; f < numOctaves; ++f, frequency *= 2, ++inc, amp *= 0.5)
    {
        SetNoiseFrequency(frequency);
        ptr = image->data();
        ni[0] = ni[1] = ni[2] = 0;
        inci = 1.0 / (texSize / frequency);
        for (i = 0; i < texSize; ++i, ni[0] += inci)
        {
            incj = 1.0 / (texSize / frequency);
            for (j = 0; j < texSize; ++j, ni[1] += incj)
            {
                inck = 1.0 / (texSize / frequency);
                for (k = 0; k < texSize; ++k, ni[2] += inck, ptr += 4)
                {
                    *(ptr+inc) = (GLubyte) (((noise3(ni) + 1.0) * amp) * 128.0);
                }
            }
        }
    }
    osg::notify(osg::INFO) << "DONE" << std::endl;
    return image;        
}
static osg::Texture3D*make3DNoiseTexture(int texSize )//三维噪声纹理
{
    osg::Texture3D* noiseTexture = new osg::Texture3D;
    noiseTexture->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture3D:INEAR);
    noiseTexture->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture3D::LINEAR);
    noiseTexture->setWrap(osg::Texture3D::WRAP_S, osg::Texture3D::REPEAT);
    noiseTexture->setWrap(osg::Texture3D::WRAP_T, osg::Texture3D::REPEAT);
    noiseTexture->setWrap(osg::Texture3D::WRAP_R, osg::Texture3D::REPEAT);
    noiseTexture->setImage( make3DNoiseImage(texSize) );
    return noiseTexture;
}
static osg::Image*make1DSineImage( int texSize )//一维噪声贴图
{
    const float PI = 3.1415927;
    osg::Image* image = new osg::Image;
    image->setImage(texSize, 1, 1,
            4, GL_RGBA, GL_UNSIGNED_BYTE,
            new unsigned char[4 * texSize],
            osg::Image::USE_NEW_DELETE);
    GLubyte* ptr = image->data();
    float inc = 2* PI / (float)texSize;
    for(int i = 0; i < texSize; i++)
    {
        *ptr = (GLubyte)((sinf(i * inc) * 0.5 + 0.5) * 255.);//深浅不一的红色
  
   if (*ptr>40)
   {
    *ptr-=40;
   }
   else
    *ptr=0;
  ptr++;
        *ptr++ = 0;
        *ptr++ = 0;
        *ptr++ = 1;
    }
osgDB::writeImageFile(*image,"D:\\test.png");
    return image;        
}
static osg::Texture1D*make1DSineTexture( int texSize )//一维噪声纹理
{
    osg::Texture1D* sineTexture = new osg::Texture1D;
    sineTexture->setWrap(osg::Texture1D::WRAP_S, osg::Texture1D::REPEAT);
    sineTexture->setFilter(osg::Texture1D::MIN_FILTER, osg::Texture1D::LINEAR);
    sineTexture->setFilter(osg::Texture1D::MAG_FILTER, osg::Texture1D::LINEAR);
    sineTexture->setImage( make1DSineImage(texSize) );
    return sineTexture;
}
static const char *microshaderVertSource = {                  //顶点着色器
    "// microshader - colors a fragment based on its position\n"
    "varying vec4 color;\n"
    "void main(void)\n"
    "{\n"
    "    color = gl_Vertex;\n"
    "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
    "}\n"
};
static const char *microshaderFragSource = {                   //片元着色器
    "varying vec4 color;\n"
    "void main(void)\n"
    "{\n"
    "    gl_FragColor = clamp( color, 0.0, 1.0 );\n"
    "}\n"
};
static osg::Geode*CreateModel()//建立几何体
{
    osg::Geode* geode = new osg::Geode();
    geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),1.0f)));
    geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(2.2f,0.0f,-0.4f),0.9f,1.8f)));
    geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(4.4f,0.0f,0.0f),1.0f,1.4f)));
    return geode;
}
static osg::StateSet*ModelInstance()//确定几何体位置
{
    static float zvalue = 0.0f;
    static osg::Node* masterModel = CreateModel();
    osg::Node*glider=osgDB::readNodeFile("huo3jia4gou48.osg");
GeodeVisitor cow("Circle01-GEODE","Line12-GEODE","Line11-GEODE","Line10-GEODE","Line9-GEODE","Line8-GEODE","Line7-GEODE","Line6-GEODE","Line5-GEODE","Line4-GEODE","Line3-GEODE","Line2-GEODE","Line1-GEODE","Shape01-GEODE");
glider->accept(cow);
    rootNode->addChild(glider);
    return glider->getOrCreateStateSet();
}
static void LoadShaderSource( osg::Shader* shader, const std::string& fileName )
{
    std::string fqFileName = osgDB::findDataFile(fileName);
    if( fqFileName.length() != 0 )
    {
        shader->loadShaderSourceFromFile( fqFileName.c_str() );
    }
    else
    {
        osg::notify(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl;
    }
}
class AnimateCallback: public osg::Uniform::Callback//路径动画
{
    public:
        enum Operation
        {
            OFFSET,
        };
        AnimateCallback(Operation op) : _enabled(true),_operation(op) {}
        virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
        {
            if( _enabled )
            {
                float angle = 2.0 * nv->getFrameStamp()->getSimulationTime();
                float sine =  angle ;        // -1 -> 1
                float v01 = 0.5f * sine + 0.5f;        //  0 -> 1
                switch(_operation)
                {
                    case OFFSET : uniform->set( osg::Vec3(-0.8f*v01, 0, 0) ); break;
                }
            }
        }
   private:
        bool _enabled;
        Operation _operation;
};
osg::ref_ptr<osg::Group>GL2Scene::buildScene()//贴上四个纹理
{
    osg::Texture3D* noiseTexture = make3DNoiseTexture( 32 /*128*/ );
    osg::Texture1D* sineTexture = make1DSineTexture( 16 /*1024*/ );
    rootNode = new osg::Group;
osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile("ping2mian41.3DS");
osg::ref_ptr<osg::StateSet>frontsta=new osg::StateSet();
osg::ref_ptr<osg::Material>frontmat=new osg::Material();
osg::ref_ptr<osg::MatrixTransform> transnode1 = new osg::MatrixTransform ;
transnode1 ->setMatrix(osg::Matrix::translate(0, 0, 0.35)) ;
transnode1 ->addChild(node1.get()) ;
frontsta=node1->getOrCreateStateSet();
frontmat->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.9,0.5,0.7,0.0));
frontmat->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0.9,0.5,0.7,0.0));
frontmat->setShininess(osg::Material::FRONT,90.0f);
frontsta->setAttribute(frontmat.get());
frontsta->setRenderBinDetails(-2,"RenderBin");
frontsta->setMode(GL_BLEND,osg::StateAttribute::ON);
rootNode->addChild(transnode1);
    {
        osg::Uniform* OffsetUniform = new osg::Uniform( "Offset", osg::Vec3(0.0f, 0.0f, 0.0f) );
        OffsetUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::OFFSET));
        osg::StateSet* ss = rootNode->getOrCreateStateSet();
        ss->setMode(GL_LIGHTING,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
  ss->setMode(GL_BLEND,osg::StateAttribute::ON);
  ss->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
        ss->addUniform( OffsetUniform );
    }
    {
        osg::StateSet* ss = ModelInstance();
        ss->setTextureAttribute(TEXUNIT_NOISE, noiseTexture);
        ss->setTextureAttribute(TEXUNIT_SINE, sineTexture);
        MarbleProgram = new osg::Program;
        MarbleProgram->setName( "marble" );
        _programList.push_back( MarbleProgram );
        MarbleVertObj = new osg::Shader( osg::Shader::VERTEX );
        MarbleFragObj = new osg::Shader( osg::Shader::FRAGMENT );
        MarbleProgram->addShader( MarbleFragObj );
        MarbleProgram->addShader( MarbleVertObj );
        ss->setAttributeAndModes(MarbleProgram, osg::StateAttribute::ON);
        ss->addUniform( new osg::Uniform("NoiseTex", TEXUNIT_NOISE) );
        ss->addUniform( new osg::Uniform("SineTex", TEXUNIT_SINE) );
    }
    reloadShaderSource();
    return rootNode;
}
GL2Scene::GL2Scene()
{
    _rootNode = buildScene();
    _shadersEnabled = true;
}
GL2Scene::~GL2Scene()
{
}
void GL2Scene::reloadShaderSource()
{
    osg::notify(osg::INFO) << "reloadShaderSource()" << std::endl;
    LoadShaderSource( MarbleVertObj, "C:/tool/OpenSceneGraph-Data-2.8.0/OpenSceneGraph-Data-2.8.0/shaders/marble.vert" );
    LoadShaderSource( MarbleFragObj, "C:/tool/OpenSceneGraph-Data-2.8.0/OpenSceneGraph-Data-2.8.0/shaders/marble.frag" );
}
void GL2Scene::toggleShaderEnable()
{
    _shadersEnabled = ! _shadersEnabled;
    osg::notify(osg::WARN) << "shader enable = " <<
            ((_shadersEnabled) ? "ON" : "OFF") << std::endl;
    for( unsigned int i = 0; i < _programList.size(); i++ )
    {
        //_programList->enable( _shadersEnabled );
    }
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表