• osg着色器uniform回调实现高亮部分闪烁效果的实例分析


    效果:牛身上圈圈里的颜色在闪烁

    代码:

     1 #include <osg/Program>
     2 #include <osgDB/ReadFile>
     3 #include <osgViewer/Viewer>
     4 
     5 static const char* vertSource = {
     6     "varying vec3 normal;
    "//易变量 用于着色器之间的传值
     7     "void main()
    "
     8     "{
    "
     9     "    normal = normalize(gl_NormalMatrix * gl_Normal);
    " //把法线向量从物体空间转化到视觉空间。
    10     "    gl_Position = ftransform();
    " //相当于 gl_Position = ModelViewProjectionMatrix * gl_Vertex,
    11                                                 //模型视图投影矩阵与空间顶点位置相乘,得到裁剪空间顶点位置。
    12     "}
    "
    13 };
    14 
    15 static const char* fragSource = {
    16     "uniform vec4 mainColor;
    "  //外面程序输入的颜色
    17     "varying vec3 normal;
    "    //上面的顶点着色器传的法线
    18     "void main()
    "
    19     "{
    "
    20     "    float intensity = dot(vec3(gl_LightSource[0].position), normal);
    " //计算光照位置与法线的点积,为什么这么做,知道的朋友不吝赐教下。
    21                                                                             //按照我的理解就是计算了一下亮度值。
    22     //给输出的颜色赋值
    23     "    if (intensity > 0.95) gl_FragColor = mainColor;
    " //如果这个值大于0.95,则输出颜色为mainColor,而uniform回调中每帧在来回改这个值,所
    24                                                             //以这一部分会出现闪烁的效果。
    25     "    else if (intensity > 0.5) gl_FragColor = vec4(0.6,0.3,0.3,1.0);
    "
    26     "    else if (intensity > 0.25) gl_FragColor = vec4(0.4,0.2,0.2,1.0);
    "
    27     "    else gl_FragColor = vec4(0.2,0.1,0.1,1.0);
    "
    28     "}
    "
    29 };
    30 
    31 
    32 /* 一直变量uniform回调类,主要用于每帧更新着色器中的用户数据,从而改变渲染的行为和输出结果。     */
    33 
    34 
    35 class ColorCallback : public osg::Uniform::Callback
    36 {
    37 public:
    38     ColorCallback() : _incRed(false) {}
    39     
    40     virtual void operator()( osg::Uniform* uniform, osg::NodeVisitor* nv )
    41     {
    42         if ( !uniform ) return;
    43         
    44         osg::Vec4 color;
    45         uniform->get( color );//获取通过uniform 设置进去的值mainColor
    46         
    47         if ( _incRed==true )//3、如果r减到0呢,就给他一直加。
    48         {
    49             if ( color.x()<1.0 ) color.x() += 0.1;
    50             else _incRed = false;//4、如果加到1就给他再减。
    51         }
    52         else
    53         {
    54             if ( color.x()>0.0 ) color.x() -= 0.1;//1、如果RGB中的r分量大于0,则一直减小。
    55             else _incRed = true;// 2、r减到0了。
    56         }
    57         uniform->set( color );
    58     }
    59 
    60 protected:
    61     bool _incRed;
    62 };
    63 
    64 void createShaders( osg::StateSet& ss )
    65 {
    66     osg::ref_ptr<osg::Shader> vertShader = new osg::Shader( osg::Shader::VERTEX, vertSource );
    67     osg::ref_ptr<osg::Shader> fragShader = new osg::Shader( osg::Shader::FRAGMENT, fragSource );
    68     
    69     osg::ref_ptr<osg::Program> program = new osg::Program;
    70     program->addShader( vertShader.get() );
    71     program->addShader( fragShader.get() );
    72     
    73     osg::ref_ptr<osg::Uniform> mainColor = new osg::Uniform( "mainColor", osg::Vec4(0.5,0.5,0.5,1.0) );//这个部分的颜色是闪烁部分的颜色值。
    74     mainColor->setUpdateCallback( new ColorCallback );
    75     
    76     ss.addUniform( mainColor.get() );
    77     ss.setAttributeAndModes( program.get() );
    78 }
    79 
    80 int main( int argc, char** argv )
    81 {
    82     osg::ArgumentParser arguments( &argc, argv );
    83     osg::Node* model = osgDB::readNodeFiles( arguments );
    84     if ( !model ) model = osgDB::readNodeFile( "cow.osg" );
    85     
    86     createShaders( *(model->getOrCreateStateSet()) );
    87     
    88     osgViewer::Viewer viewer;
    89     viewer.setSceneData( model );
    90     viewer.setUpViewInWindow(20,20,600,600);
    91     return viewer.run();
    92 }
  • 相关阅读:
    ntpdate
    动态查看日志
    eclipse proxy
    远程调试
    pe and elf
    03scikit-learn非监督学习
    15管家婆小项目
    02scikit-learn模型训练
    01scikit-learn数据集下载
    scikit-learn中文api
  • 原文地址:https://www.cnblogs.com/airduce/p/10033286.html
Copyright © 2020-2023  润新知