编写shader模拟水波扩散效果
2016-05-01 21:46
387 查看
这次分析了shadertoy上的一个例子
先上效果图。
先上效果图。
中心是一个大的波纹,我们可以用鼠标控制小的波纹,产生干涉。 用opengl模拟水纹是一个复杂的过程,这里我们采用的方法是。。。欺骗法。 将水纹看成黑白相间的圆环,因为只有黑白两色,水纹上的圆环移动时会产生干涉的假象。 我们还是直接来一步一步的看代码,先在屏幕上画一个圆环。
#define PI 3.1415 float ripple(float dis){ return sin(dis*2.*PI);//返回一个-1到1的值 } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy;//每一点的像素 vec2 center=vec2(0.5,0.5);//圆环中心位置 float dis=distance(uv,center);//距离 float value=ripple(dis); fragColor = vec4(value,value,value,1.0); }
圆环的原理就是定一个中心,如果像素的值到圆环都相等,则这一圈像素颜色一样,sin函数会返回-1到1,如果返回的值小于0,在赋颜色的时候会将其置为0,也就是黑色。 然后我们可以根据正弦函数的性质,给圆环加上大小,疏密等属性。
float ripple(float dis,float scale,float width,float num,float speed){ return width*(sin(dis*2.*PI*num-iGlobalTime*speed)/(1./scale*dis*2.*PI*num)); }//dis:距离 scale:圆环扩散的距离 width:圆环宽度 num:圆环疏密 speed:圆环扩散速度
这个公式可以试着调调看,比如`-iGlobalTime*speed` 改变他的正负值,`(1./scale*dis*2.*PI*num)`不要这个值试试。 然后我们再画一个小圆,距离为鼠标到每一个像素的值。
value+=ripple(distance(uv,iMouse.xy/iResolution.xy),2.,1.,10.,5.);
将小圆的像素值叠加到中心波纹上,最后返回的仍然是value的值。 如果你想要更多的圆,照画鼠标圆的方法叠上去就ok了。 最后上一下全部的代码。
#define PI 3.1415 //画圆环 float ripple(float dis,float scale,float width,float num,float speed){ return width*(sin(dis*2.*PI*num-iGlobalTime*speed)/(1./scale*dis*2.*PI*num)); } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy;//遍历像素 vec2 center=vec2(0.5,0.5);//大圆中心 float dis=distance(uv,center);//大圆距离 float value=ripple(dis,5.,2.,10.,3.);//大圆的像素值 value+=ripple(distance(uv,center-0.2),2.,1.,5.,5.);//叠加一个小圆 value+=ripple(distance(uv,iMouse.xy/iResolution.xy),2.,1.,10.,5.);//叠加一个鼠标控制的小圆 fragColor = vec4(value,value,value,1.0); }
但是这种方法有一个缺陷,只有各个圆的颜色相同时才能有波纹干涉的假象,甚至alpha值也必须相同,这就导致了我们不能做更加真实的水面倒影效果(假设鼠标为人物的行走,将大圆的alpha值降低,跟随鼠标的小圆高亮,波纹的假象就会被破坏。) 比如这样:
我现在想不到解决的方法,如果你有好的想法非常欢迎和我探讨。
相关文章推荐
- 反编译ARB program to GLSL shader日记
- 虚幻3引擎
- 基于顶点纹理的无限大海水仿真
- 图形加速卡技术 [专业的基础技术文章]
- 关于VR(主要是虚拟城市场景)的一些想法及实现(可能会连载)
- 编译ics
- 项目中的简单shader
- Simulating Ocean Water
- 在c++中模以”委托“
- 关于NGUI中UITexture贴图自定义的shader文件在UISrollView中不报错的解决方案
- OpenGL&D3D State Machine
- 得到一个 a4e9 bitmap的倒影
- 为什么DirectX 11 在把矩阵(例如View矩阵)传给shader之前要进行转置
- DirectX 8 开发者常见问题集
- error X3025:global variebles are implicitly constant,enable compatibility mode to allow modificatiom
- dx编译shader报错:global variables are implicitly constant, enable compatibility mode to...
- 2016年的游戏引擎设计
- Unity5.0内置Shader解析
- 纹理过滤模式中的Bilinear、Trilinear以及Anistropic Filtering
- Bump Mapping综述