zoukankan      html  css  js  c++  java
  • osg内置shader变量

    uniform int osg_FrameNumber:当前OSG程序运行的帧数;
    uniform float osg_FrameTime:当前OSG程序的运行总时间;
    uniform float osg_DeltaFrameTime:当前OSG程序运行每帧的间隔时间;
    uniform mat4 osg_ViewMatrix:当前OSG摄像机的观察矩阵;
    uniform mat4 osg_ViewMatrixInverse:当前OSG摄像机观察矩阵的逆矩阵。
    uniform mat4 osg_ModelViewMatrix:内置gl_ModelViewMatrix
    uniform mat4 osg_ModelViewProjectionMatrix:内置gl_ModelViewProjectionMatrix
    uniform mat4 osg_ProjectionMatrix:内置gl_ProjectionMatrix
    uniform mat3 osg_NormalMatrix:内置gl_NormalMatrix
    • attribute:应用程序与顶点着色器的接口,使用顶点属性定义函数进行定义;
    • uniform:应用程序与所有着色器的接口,定义不随顶点变化的“一致变量”;
    • varying:着色器之间的“易变变量”接口,用于传递插值得到的顶点数据;
    • const:用于声明常量数据;
    • in:作为函数形参进行传递,函数返回时不保留改变,只保留传入值;
    • out:作为函数形参进行传递,本身未定义,函数返回时保留改变值;
    • inout:作为函数形参进行传递,可以定义传入值,也会保留返回时的改变值。
    • uniform mat4 gl_NormalMatrix:法线变换矩阵;
    • uniform mat4 gl_ModelViewMatrix:模型视点变换矩阵;
    • attribute vec4 gl_Vertex:顶点坐标属性;
    • attribute vec4 gl_MultiTexCoord0:纹理单元0的纹理坐标属性;
    • varying vec4 gl_TexCoord[0]:纹理单元0的实际纹理坐标。
    • 实现片元着色器的一段示例代码如下:
      uniform sampler2D texture;
      varying vec3 tangent;
      void main( void )
      {
      gl_FragColor = texture2D( texture, gl_TexCoord[0] );
      }

      着色器一致变量的接口类。对于OpenGL着色语言而言,一致变量(uniform)是用户应用程序与着色器的主要交互接口。Uniform类支持绑定多种类型的一致变量,并使用set()和setArray()更新变量或变量数组的值。而为了实现一致变量的每帧变化,进而达到顶点和片元的各种动画特效,Uniform类还提供了相应的回调工具:使用setUpdateCallback设置自定义的回调类,并在其中更新这个一致变量的值,以实现所需的效果。

    #include <osgViewer/Viewer>
    
    #include <osg/ShapeDrawable>
    #include <osg/Geode>
    #include <osg/Vec3>
    
    #include <osg/Program>
    #include <osg/Shader>
    #include <osg/Uniform>
    
    using namespace osg;
    
    ///////////////////////////////////////////////////////////////////////////
    // in-line GLSL source code
    
    static const char *blockyVertSource = {
        "// blocky.vert - an GLSL vertex shader with animation
    "
        "// the App updates uniforms "slowly" (eg once per frame) for animation.
    "
        "uniform float Sine;
    "
        "const vec3 LightPosition = vec3(0.0, 0.0, 4.0);
    "
        "const float BlockScale = 0.30;
    "
        "// varyings are written by vert shader, interpolated, and read by frag shader.
    "
        "varying float LightIntensity;
    "
        "varying vec2  BlockPosition;
    "
        "void main(void)
    "
        "{
    "
        "    // per-vertex diffuse lighting
    "
        "    vec4 ecPosition    = gl_ModelViewMatrix * gl_Vertex;
    "
        "    vec3 tnorm         = normalize(gl_NormalMatrix * gl_Normal);
    "
        "    vec3 lightVec      = normalize(LightPosition - vec3 (ecPosition));
    "
        "    LightIntensity     = max(dot(lightVec, tnorm), 0.0);
    "
        "    // blocks will be determined by fragment's position on the XZ plane.
    "
        "    BlockPosition  = gl_Vertex.xz / BlockScale;
    "
        "    // scale the geometry based on an animation variable.
    "
        "    vec4 vertex    = gl_Vertex;
    "
        "    vertex.w       = 1.0 + 0.4 * (Sine + 1.0);
    "
        "    gl_Position    = gl_ModelViewProjectionMatrix * vertex;
    "
        "}
    "
    };
    
    static const char *blockyFragSource = {
        "// blocky.frag - an GLSL fragment shader with animation
    "
        "// the App updates uniforms "slowly" (eg once per frame) for animation.
    "
        "uniform float Sine;
    "
        "const vec3 Color1 = vec3(1.0, 1.0, 1.0);
    "
        "const vec3 Color2 = vec3(0.0, 0.0, 0.0);
    "
        "// varyings are written by vert shader, interpolated, and read by frag shader.
    "
        "varying vec2  BlockPosition;
    "
        "varying float LightIntensity;
    "
        "void main(void)
    "
        "{
    "
        "    vec3 color;
    "
        "    float ss, tt, w, h;
    "
        "    ss = BlockPosition.x;
    "
        "    tt = BlockPosition.y;
    "
        "    if (fract(tt * 0.5) > 0.5)
    "
        "        ss += 0.5;
    "
        "    ss = fract(ss);
    "
        "    tt = fract(tt);
    "
        "    // animate the proportion of block to mortar
    "
        "    float blockFract = (Sine + 1.1) * 0.4;
    "
        "    w = step(ss, blockFract);
    "
        "    h = step(tt, blockFract);
    "
        "    color = mix(Color2, Color1, w * h) * LightIntensity;
    "
        "    gl_FragColor = vec4 (color, 1.0);
    "
        "}
    "
    };
    
    ///////////////////////////////////////////////////////////////////////////
    // callback for animating various Uniforms (currently only the SIN uniform)
    
    class AnimateCallback : public osg::UniformCallback
    {
    public:
        enum Operation { SIN };
        AnimateCallback(Operation op) : _operation(op) {}
        virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv)
        {
            float angle = 2.0 * nv->getFrameStamp()->getSimulationTime();
            float sine = sinf(angle);            // -1 -> 1
            switch (_operation) {
            case SIN: uniform->set(sine); break;
            }
        }
    private:
        Operation _operation;
    };
    
    int main(int, char **)
    {
        // construct the viewer.
        osgViewer::Viewer viewer;
    
        // use a geode with a Box ShapeDrawable
        osg::Geode* basicModel = new osg::Geode();
        basicModel->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f)));
    
        // create the "blocky" shader, a simple animation test
        osg::StateSet *ss = basicModel->getOrCreateStateSet();
        osg::Program* program = new osg::Program;
        program->setName("blocky");
        //program->addShader(new osg::Shader(osg::Shader::VERTEX, blockyVertSource));
        //program->addShader(new osg::Shader(osg::Shader::FRAGMENT, blockyFragSource));
        program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, "blocky.vert"));
        program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, "blocky.frag"));
        ss->setAttributeAndModes(program, osg::StateAttribute::ON);
    
        // attach some animated Uniform variable to the state set
        osg::Uniform* SineUniform = new osg::Uniform("Sine", 0.0f);
        ss->addUniform(SineUniform);
        SineUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::SIN));
    
        // run the osg::Viewer using our model
        viewer.setSceneData(basicModel);
        return viewer.run();
    }
    
    /*EOF*/
  • 相关阅读:
    Java分享笔记:关于Java反射机制
    Java分享笔记:自定义枚举类 & 使用enum关键字定义枚举类
    Java分享笔记:RandomAccessFile流 & 在文件指定位置插入内容
    Spark-源码-SparkContext的初始化
    Spark-源码-Spark-StartAll Master Worler启动流程
    Spark-源码-Spark-Submit 任务提交
    Hadoop2学习路程-HDFS
    JavaSE 第二次学习随笔(五)
    JavaSE 第二次学习随笔(四)
    JavaSE 第二次学习随笔(三)
  • 原文地址:https://www.cnblogs.com/coolbear/p/7662976.html
Copyright © 2011-2022 走看看