glsl水包含倒影的实现(rtt) 【转】
http://blog.sina.com.cn/s/blog_78ea87380101eixi.html
此文实现一个简单地水面倒影效果,通过rtt相机 获取倒影纹理, 水的基本实现方法(参考前一博文:osg通过glsl实现一个平面的水效果(法线贴图)),具体代码如下:
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) 【转】的更多相关文章
- glsl水包含倒影的实现(rtt) [转]
转自 http://blog.sina.com.cn/s/blog_78ea87380101eixi.html 此文实现一个简单地水面倒影效果,通过rtt相机 获取倒影纹理, 水的基本实现方法(参考前 ...
- 关于GLSL中语法和调用规则的一些记录
glsl是什么就不多说了.这里只介绍一下glsl中一些限定符. glsl中包含两类具有定义性质的符号,一类是和c++中定义变量的一样的符号,用来说明存放数据的类型,如float,int,bool.还有 ...
- OpenGL入门1.3:着色器 GLSL
前言 经过之前一段时间的学习(渲染管线简介)我们已经知道了着色器(Shader)是运行在GPU上的程序,这些小程序为图形渲染管线的某个特定部分而运行,着色器只是一种把输入转化为输出的程序,着色器也是一 ...
- CoreAnimation3-专用图层
CAShapeLayer CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类.你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自 ...
- 【转】iOS-Core-Animation-Advanced-Techniques(三)
原文: http://www.cocoachina.com/ios/20150105/10827.html 专用图层 复杂的组织都是专门化的--Catharine R. Stimpson 到目前为止, ...
- [iOS Animation]-CALayer 专用图层
专用图层 复杂的组织都是专门化的 Catharine R. Stimpson 到目前为止,我们已经探讨过CALayer类了,同时我们也了解到了一些非常有用的绘图和动画功能.但是Core Animati ...
- OpenGL着色器入门简介
说明:本文翻译自LearnOpengl经典教程,OpenGL着色器基础介绍的比较通俗易懂,特总结分享一下! 为什么要使用着色器?我们知道,OpenGL一般使用经典的固定渲染管线来渲染对象,但是随着Op ...
- CAEAGLLayer
CAEAGLLayer 当iOS要处理高性能图形绘制,必要时就是OpenGL.应该说它应该是最后的杀手锏,至少对于非游戏的应用来说是的.因为相比Core Animation和UIkit框架,它不可思议 ...
- opengl-glsl
GLSL 着色器是使用一种叫GLSL的类C语言写成的.GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性. 着色器的开头总是要声明版本,接着是输入和输出变量.uniform和mai ...
随机推荐
- Python图像处理库(2)
1.4 SciPy SciPy(http://scipy.org/) 是建立在 NumPy 基础上,用于数值运算的开源工具包.SciPy 提供很多高效的操作,可以实现数值积分.优化.统计.信号处理,以 ...
- vue分页tbale小荔枝
首先,动态加载数据 <table class="table table-bordered table-condensed no_margin_bottom jyjg_tab" ...
- jquery.validate验证表单配合回调提交和h5.storage本地保存笔记
表单验证插件我使用:jquery.validate.js 支持中文提示,可扩展性强!教程地址 本地保存状态信息使用:h5提供的storage,浏览器支持5m的存储量,存储类型必须是string类型,并 ...
- ESLint 使用入门
在团队协作中,为避免低级 Bug.产出风格统一的代码,会预先制定编码规范.使用 Lint 工具和代码风格检测工具,则可以辅助编码规范执行,有效控制代码质量. 在以前的项目中,我们选择 JSHint 和 ...
- 如何将hdf5文件转换成tflite文件
我们用keras训练模型后,通常保存的模型格式类型为hdf5格式,也就是.h5文件. 但如果我们想要移植到移动端,特别是基于tensorflow支持的移动端,那就需要转换成tflite格式. 如何转换 ...
- ansible学习-playbook的YAML语法
[一篇非常好的ansible参考博文] 初识Ansible http://liumissyou.blog.51cto.com/4828343/1616462 --------------------- ...
- code M资格赛 补题
A: 音乐研究 时间限制:1秒 空间限制:32768K 美团外卖的品牌代言人袋鼠先生最近正在进行音乐研究.他有两段音频,每段音频是一个表示音高的序列.现在袋鼠先生想要在第二段音频中找出与第一段音频最相 ...
- 【欧拉回路】Play On Words(6-16)
[UVA10129]Play On Words 算法入门经典第6章6-16(P169) 题目大意:有一些单词,问能不能将它们串成字符串(只有前缀和后缀相同才能连) 试题分析:很巧妙的一道题,将每个单词 ...
- 【递归】【线段树】【堆】AtCoder Regular Contest 080 E - Young Maids
给你一个1~n的排列p,n是偶数,每次从中任选一对相邻的数出来,插到排列q的开头,如此循环,问你所能得到的字典序最小的排列q. 我们先确定q开头的两个数q1,q2,q1一定是p的奇数位的最小的数,而q ...
- python3-开发进阶Django中序列化以及rest_framework的序列化
一.django框架的序列化 直接上代码 1.这是app下的models.py from django.db import models # Create your models here. clas ...