http://blog.sina.com.cn/s/blog_78ea87380101eixi.html

此文实现一个简单地水面倒影效果,通过rtt相机 获取倒影纹理, 水的基本实现方法(参考前一博文:osg通过glsl实现一个平面的水效果(法线贴图)),具体代码如下:

 
vertex定点着色器:

varying vec3 lightdir;           //切线空间灯光向量;

varying vec3 eyedir;             //切线空间眼点向量;

varying vec4 ambient, diffuse, specular;

attribute vec3 tangent;          //顶点切线;

uniform float time;                       //时间更新;

uniform vec3  lightPos;         //灯光的位置;

void main()

{

vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);

vec3 L = normalize(lightPos - vVertex);                 //定点到光源向量;

vec3 E = normalize(-vVertex);                                     //定点到眼点向量;

vec3 N = normalize(gl_NormalMatrix * gl_Normal);

vec3 H = normalize(L + E);

//获取漫反射, 镜面反射量;

ambient = vec4(1.0,1.0,1.0,1.0);

diffuse = vec4(1.0,1.0,1.0,1.0);

specular = vec4(1.0,1.0,1.0,1.0);

float _diffuse = max(dot(L, N), 0.0);

if(_diffuse > 0.0)

{

diffuse = diffuse * _diffuse;

float _specular = max(dot(H,N),0.0);

specular = specular * pow(_specular , 64.0);

}

//计算切线空间量;

vec3 T = normalize(vec3(gl_NormalMatrix * tangent));

vec3 B = normalize(cross(N,T));

lightdir.x = dot(L,T);

lightdir.y = dot(L,B);

lightdir.z = dot(L,N);

lightdir = normalize(lightdir);

eyedir.x = dot(E,T);

eyedir.y = dot(E,B);

eyedir.z = dot(E,N);

lightdir = normalize(eyedir);

gl_TexCoord[0] = gl_MultiTexCoord0;

gl_TexCoord[0].x = 1.0 - gl_TexCoord[0].x;

//根据时间获取法线纹理位置;

gl_TexCoord[1].x = gl_TexCoord[0].x + time * 0.05;

gl_TexCoord[1].y = gl_TexCoord[0].y + time * 0.05;

gl_Position  = ftransform();

}

fragment像素着色器:

 
varying vec3 lightdir;
varying vec3 eyedir;
varying vec4 ambient, diffuse, specular;

uniform sampler2D baseTex;
uniform sampler2D normTex;

void main()
{
         vec3 L = normalize(lightdir);
         vec3 E = normalize(eyedir);

         vec4 _baseColor = texture2D(baseTex, gl_TexCoord[0].xy);
         vec3 _normColor = texture2D(normTex, gl_TexCoord[1].xy).xyz;
        
         _baseColor = texture2D(baseTex, gl_TexCoord[0].xy + _normColor * 0.05); //调制底面纹理波动;
         _normColor = texture2D(normTex, gl_TexCoord[1].xy + _normColor * 0.02).xyz;

         vec3 N = normalize(_normColor * 2.0 - vec3(1.0));     //将法线转到[-1,1]范围;

         float _diff = max(dot(L,N),0.0);
         float _spec = max(dot(E,N),0.0);

         if(_diff > 0.0)
         {
                 _spec = pow(_spec, 64.0);
         }
 
 gl_FragColor = vec4(ambient.xyz * _baseColor.xyz + diffuse.xyz * _diff * _baseColor.xyz + specular * _spec, 1.0);
}

osg主程序:

osg::ref_ptr createHalfSphere(osg::Image *img, float radius)
{
         osg::ref_ptr geode = new osg::Geode;
         osg::ref_ptr geom = new osg::Geometry;

         //压入顶点;
         osg::ref_ptr veArr = new osg::Vec3Array;
         std::vector> veVertext;

         //纹理坐标;
         osg::ref_ptr texArr = new osg::Vec2Array;
         std::vector> texVertex;

         for(int i=0; i<=90; i+=10)
         {
                 std::vector veTmp;
                 std::vector _texTmp;
                 for(int j=0; j<=360; j += 10)
                 {
                      double x = radius * cos(osg::DegreesToRadians((float)i)) * cos(osg::DegreesToRadians((float)j));
                      double y = radius * cos(osg::DegreesToRadians((float)i)) * sin(osg::DegreesToRadians((float)j));
                          double z = radius * sin(osg::DegreesToRadians((float)i));
                          veTmp.push_back(osg::Vec3(x,y,z));
                          _texTmp.push_back(osg::Vec2((float)j/370.0+0.01,(float)i/100.0+0.01));
                 }
                 veVertext.push_back(veTmp);
                 texVertex.push_back(_texTmp);
         }

         //重新组织点;
         //法线数组;
         osg::ref_ptr norArr = new osg::Vec3Array;

         std::vector>::iterator it = veVertext.begin();
         for(; it != veVertext.end(); )
         {
                 std::vector _tmp = *it;
                 it++;
                 if(it == veVertext.end())
                          break;

                 int count = (*it).size();
                 for(int i=0; i < count;  ++i)
                 {
                          veArr->push_back(_tmp.at(i));
                          veArr->push_back(it->at(i));
                          norArr->push_back(osg::Vec3(0,0,0) - _tmp.at(i));
                          norArr->push_back(osg::Vec3(0,0,0) - it->at(i));
                 }
         }
         geom->setVertexArray(veArr);

 
         std::vector>::iterator itt = texVertex.begin();
         for(; itt != texVertex.end(); )
         {
                 std::vector _tmp = *itt;
                 itt++;
                 if(itt == texVertex.end())
                          break;

                 int count = (*itt).size();
                 for(int i=0; i
                 {
                          texArr->push_back(_tmp.at(i));
                          texArr->push_back(itt->at(i));
                 }
         }

         geom->setTexCoordArray(0,texArr);

         //法线;
         geom->setNormalArray(norArr);
         geom->setNormalBinding(osg::Geometry::AttributeBinding::BIND_PER_VERTEX);

         geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP,0,veArr->size()));

         geode->addDrawable(geom);

         //纹理;
         osg::ref_ptr tex = new osg::Texture2D;
         if(img->valid())
         {
                 tex->setImage(img);
         }

         tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);//列向;
         tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);//行向;

         geom->getOrCreateStateSet()->setTextureAttributeAndModes(0,tex,osg::StateAttribute::ON);
         //geode->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace,osg::StateAttribute::ON);
         return geode;
}

osg::ref_ptr createPlane(int _w, int _h)
{
         osg::ref_ptr geode = new osg::Geode;
         osg::ref_ptr geom = new osg::Geometry;
         geode->addDrawable(geom);

         osg::ref_ptr vArr = new osg::Vec3Array;
         vArr->push_back(osg::Vec3(-_w/2.0,-_h/2.0,-10));
         vArr->push_back(osg::Vec3(-_w/2.0,_h/2.0,-10));
         vArr->push_back(osg::Vec3(_w/2.0,_h/2.0,-10));
         vArr->push_back(osg::Vec3(_w/2.0,-_h/2.0,-10));

         geom->setVertexArray(vArr);

         osg::ref_ptr tArr = new osg::Vec2Array;
         tArr->push_back(osg::Vec2(0.0,0.0));
         tArr->push_back(osg::Vec2(0.0,1.0));
         tArr->push_back(osg::Vec2(1.0,1.0));
         tArr->push_back(osg::Vec2(1.0,0.0));

         geom->setTexCoordArray(0, tArr);

         osg::ref_ptr nArr = new osg::Vec3Array;
         nArr->push_back(osg::Vec3(0.0,0.0,1.0));
         geom->setNormalArray(nArr);
         geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

         geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));

         return geode;
}

 
osg::ref_ptr createCamera(int _x, int _y, int _w, int _h,
         bool _isTargetImpl = false,
         osg::Vec4f _color = osg::Vec4f(0.3,0.6,0.5,1.0),
         osg::Camera::RenderOrder _renderOrder = osg::Camera::POST_RENDER,
         osg::Camera::ReferenceFrame _referenceFrame = osg::Camera::ABSOLUTE_RF)
{
         osg::ref_ptr _camera = new osg::Camera;
         _camera->setViewport(_x, _y, _w, _h);
         _camera->setAllowEventFocus(false);
         _camera->setClearColor(_color);
         _camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         _camera->setRenderOrder(_renderOrder);
         _camera->setReferenceFrame(_referenceFrame);

         if(_isTargetImpl)
         {
                 _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
         }

         //_camera->setProjectionMatrixAsOrtho2D(0,0,_w,_h);
         _camera->setProjectionMatrixAsPerspective(30.0,double(_w)/double(_h),0.01, 999.9);
         _camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

         return _camera;
}

int main(int argc, char *argv[])
{
         osg::ref_ptr _root = new osg::Group;
         _root->addChild(osgDB::readNodeFile("cow.osg"));

    osg::ref_ptr _skybox = createHalfSphere(osgDB::readImageFile("../images/01.jpg"),1000.0);
         osg::ref_ptr _waterPanle  = createPlane(1200,1200);
         osg::ref_ptr _ceep = osgDB::readNodeFile("ceep.ive");

         osg::ref_ptr _mceep = new osg::MatrixTransform;
         _mceep->addChild(_ceep);
         _mceep->setMatrix(osg::Matrix::translate(500.0, 500.0, 0.0));

 
 osg::ref_ptr _rttCam = createCamera(0,0,600,400,false, osg::Vec4f(0.3,0.5,0.8,1.0),osg::Camera::PRE_RENDER,osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
         _rttCam->addChild(_skybox);
         _rttCam->addChild(_mceep);

         _root->addChild(_skybox);
         _root->addChild(_waterPanle);
         _root->addChild(_mceep);
         _root->addChild(_rttCam);

         //背景图片;
         osg::ref_ptr baseTex = new osg::Texture2D;
         baseTex->setTextureSize(600,400);
         baseTex->setInternalFormat(GL_RGBA);
         baseTex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
         baseTex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
         _rttCam->attach(osg::Camera::COLOR_BUFFER, baseTex);

         //法线图;
         osg::ref_ptr normTex = new osg::Texture2D;
         normTex->setImage(osgDB::readImageFile("../images/water.bmp"));
         normTex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
         normTex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);

         _waterPanle->getOrCreateStateSet()->setTextureAttributeAndModes(0, baseTex, 1);
         _waterPanle->getOrCreateStateSet()->setTextureAttributeAndModes(1, normTex, 1);

 
         osg::ref_ptr program = new osg::Program;
         osg::ref_ptr  vertShader = new osg::Shader(osg::Shader::VERTEX);
         osg::ref_ptr  fragShader = new osg::Shader(osg::Shader::FRAGMENT);
         program->addShader(vertShader);
         program->addShader(fragShader);

         if(!vertShader->loadShaderSourceFromFile("water.vert"))
         {
                 printf("load vertex shader error !\n");
         }
         if(!fragShader->loadShaderSourceFromFile("water.frag"))
         {
                 printf("load fragment shader error !\n");
         }

         _waterPanle->getOrCreateStateSet()->setAttribute(program, 1);
         _waterPanle->getOrCreateStateSet()->addUniform(new osg::Uniform("time", float(0.0)));
         _waterPanle->getOrCreateStateSet()->addUniform(new osg::Uniform("baseTex", 0));
         _waterPanle->getOrCreateStateSet()->addUniform(new osg::Uniform("normTex", 1));
 _waterPanle->getOrCreateStateSet()->addUniform(new osg::Uniform("lightPos", osg::Vec3(0.0,0.0,0.0)));//lightPos

 
         osg::ref_ptr viewer = new osgViewer::Viewer;
         viewer->setSceneData(_root);
         viewer->setCameraManipulator(new osgGA::TrackballManipulator);

         while(!viewer->done())
         {

                 float _time = viewer->getFrameStamp()->getSimulationTime();
                 _waterPanle->getOrCreateStateSet()->getUniform("time")->set(_time);

                 osg::Matrix _mmt = viewer->getCamera()->getViewMatrix();
                 _waterPanle->getOrCreateStateSet()->getUniform("lightPos")->set(_mmt.getTrans());

 
                 osg::Vec3 _eye, _center, _up;
                 viewer->getCamera()->getViewMatrixAsLookAt(_eye, _center, _up);

                 osg::Vec3 _ttDir = _center - _eye;

                 osg::Vec3 _refEye = osg::Vec3(_eye.x(),_eye.y(),-_eye.z());
                 osg::Vec3 _refCenter = _refEye + osg::Vec3(_ttDir.x(), _ttDir.y(), -_ttDir.z());
                 osg::Vec3 _nnUp = osg::Vec3(_up.x(), _up.y(), -_up.z());

                
                 _rttCam->setViewMatrixAsLookAt(_refEye,_refCenter,_nnUp);

                 //_rttCam->setViewMatrix(viewer->getCamera()->getViewMatrix());
                 _rttCam->setProjectionMatrix(viewer->getCamera()->getProjectionMatrix());

                 viewer->frame();
         }

         return 0;
}

glsl水包含倒影的实现(rtt) 【转】的更多相关文章

  1. glsl水包含倒影的实现(rtt) [转]

    转自 http://blog.sina.com.cn/s/blog_78ea87380101eixi.html 此文实现一个简单地水面倒影效果,通过rtt相机 获取倒影纹理, 水的基本实现方法(参考前 ...

  2. 关于GLSL中语法和调用规则的一些记录

    glsl是什么就不多说了.这里只介绍一下glsl中一些限定符. glsl中包含两类具有定义性质的符号,一类是和c++中定义变量的一样的符号,用来说明存放数据的类型,如float,int,bool.还有 ...

  3. OpenGL入门1.3:着色器 GLSL

    前言 经过之前一段时间的学习(渲染管线简介)我们已经知道了着色器(Shader)是运行在GPU上的程序,这些小程序为图形渲染管线的某个特定部分而运行,着色器只是一种把输入转化为输出的程序,着色器也是一 ...

  4. CoreAnimation3-专用图层

    CAShapeLayer CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类.你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自 ...

  5. 【转】iOS-Core-Animation-Advanced-Techniques(三)

    原文: http://www.cocoachina.com/ios/20150105/10827.html 专用图层 复杂的组织都是专门化的--Catharine R. Stimpson 到目前为止, ...

  6. [iOS Animation]-CALayer 专用图层

    专用图层 复杂的组织都是专门化的 Catharine R. Stimpson 到目前为止,我们已经探讨过CALayer类了,同时我们也了解到了一些非常有用的绘图和动画功能.但是Core Animati ...

  7. OpenGL着色器入门简介

    说明:本文翻译自LearnOpengl经典教程,OpenGL着色器基础介绍的比较通俗易懂,特总结分享一下! 为什么要使用着色器?我们知道,OpenGL一般使用经典的固定渲染管线来渲染对象,但是随着Op ...

  8. CAEAGLLayer

    CAEAGLLayer 当iOS要处理高性能图形绘制,必要时就是OpenGL.应该说它应该是最后的杀手锏,至少对于非游戏的应用来说是的.因为相比Core Animation和UIkit框架,它不可思议 ...

  9. opengl-glsl

    GLSL 着色器是使用一种叫GLSL的类C语言写成的.GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性. 着色器的开头总是要声明版本,接着是输入和输出变量.uniform和mai ...

随机推荐

  1. IntelliJ IDEA SpringBoot 使用第三方Tomcat以及部署

    花了半天时间终于成功,记录以备查阅. 一.第三方Tomcat部署 部署部分参考的是:把spring-boot项目部署到tomcat容器中 目标:把spring-boot项目按照平常的web项目一样发布 ...

  2. vscode的go插件安装

    vscode安装go的很多插件都是失败,如下: Installing 5 tools at E:\www\go_project\bin go-symbols guru gorename goretur ...

  3. win10网速慢

    升级到win10之后发现网速特别慢,搜了下,网上的解决办法果然好使,按照如下操作即可. 返回桌面,按WIN+R键组合,运行gpedit.msc 打开组策略 依次展开管理模板->网络->Qo ...

  4. vue css动画

    .toggle-cart-enter-active, .toggle-cart-leave-active { transition: all .3s ease-out; } .toggle-cart- ...

  5. setTimeout(fn,0)

    我们都知道setTimeout是一个延迟执行的函数 console.log(); setTimeout(function(){console.log();},); console.log(); 会得到 ...

  6. Django 项目CRM总结

    0. 项目说明: 1. 销售自动分配客户资源: 给销售分配权重及承单数量,创建权重表,通过销售权重进行从大到小进行排序 以承单数循环添加到列表,承单数是多少列表添加就添加多少次 考虑到如果服务重启,或 ...

  7. 五:ZooKeeper的集群命令客户端的链接和命令操作的使用

    一:zookeeper客户端链接[1]进入zookeeper的安装目录的bin目录下         # cd /opt/zookeeper/bin[2]敲击链接客户端的命令(zkCli.sh)    ...

  8. Largest Number——STL的深层理解

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  9. OpenStack 存储服务 Cinder介绍和控制节点部署 (十三)

    Cinder介绍 OpenStack块存储服务(cinder)为虚拟机添加持久的存储,块存储提供一个基础设施为了管理卷,以及和OpenStack计算服务交互,为实例提供卷.此服务也会激活管理卷的快照和 ...

  10. 4.Spark Streaming事务处理

    首先,我们必须知道什么是事务及其一致性? 事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACID特性. 原子性(atomicity).一个事务是一个不可分割的工作单位,事务中 ...