Creator3D:shader13_水面涟漪

前言

首先咱们回顾一下之前的两篇关于水面的文章

在上边的这两篇文章中,水面的动态效果都是基于顶点着色器,也就是模型的顶点来实现的。
其中在第二篇文章中,菜鸟预期是实现一个波浪扩散的效果,但是最终没有实现。于是菜鸟下去专门研究了一下,终于研究出来了。

效果展示

正文

1.UV是什么?

在顶点着色器中我们能看见一行代码:

v_uv = a_texCoord;

那么UV,也就是a_texCoord到底表示的是什么?

大家都清楚,对于三维的模型,有一个重要的三维坐标系统:顶点坐标(x,y,z)。但是除了这个,还有另一个重要的坐标系统:UV坐标。

什么是UV,简单来说就是切图映射到模型表面的依据。U代表图片在水平方向的坐标,V代表图片在垂直方向的坐标。

U,V的取值都是0~1,也就是(水平方向的第U个像素/图片宽度,垂直方向的第V个像素/图片高度)。它定义了图片上每个点的位置的信息. 这些点与3D模型是相互联系的, 以决定表面纹理贴图的位置. UV就是将图像上每一个点精确对应到模型物体的表面. 在点与点之间的间隙位置由软件进行图像光滑插值处理. 这就是所谓的UV贴图.

2.涟漪


仔细看图,大家可能就会发现,涟漪的效果实际上也就是咱们最常用的正弦曲线,

实现原理
了解了uv,也了解了涟漪的原理,那么怎样将这两点结合起来,实现咱们需要的效果呢。

  • 确定扩散起始点startPos,也就是中心点。因为startPos是与uv坐标进行计算,所以他是一个vec2类型。同时uv坐标坐标的x,y范围是(0~1).
  • 扩散方向:uv的扩散方向实际是中心点到其本身的法线方向的偏移,
  • 扩散,也就是波速,利用cc_timer.x时间控制

3.代码

//计算uv到起点的向量
vec2 dv = startPos - v_uv;   
//计算向量的长度
float dis = sqrt(dv.x * dv.x + dv.y * dv.y);
//更具扩散范围计算power 
float p=(power/range)*((range-dis)>0.0 ? range-dis : 0.0);

float sinFactor = sin(dis*frequency-cc_time.x*speed)*0.01*p;
//归一化
vec2 dv1=normalize(dv);
//计算每个像素uv的偏移量
vec2 offset= dv1 * sinFactor;
// //偏移
vec2 uv=offset+v_uv;

4.地址

  • 微信公众号:搬砖小菜鸟

    扫码关注公众号,发送"水面涟漪"可获取源码
3赞

勤劳的小菜鸟

nice ,就是喜欢多产的男人

感觉shader挺好玩的,

哈哈,喜欢可以关注一波奥

其实,你的第二个实现方式挺好的,只需要再细化一下网格数量就可以了。

嗯嗯,当时我也想过创建一个网格数量比较密的plane,但是不会创:joy:

zan…

怎么引入pow/e/pi这些参数呢?我参考别人的一个例子,写道后面这几个参数编译找不到警报。

你可以看一下我的代码

var plane= primitives.plane({
width:1,
length:1,
widthSegments: 100,
lengthSegments: 100
});

var mesh = utils.createMesh(plane);
this.getComponent(ModelComponent).mesh = mesh;

试试看

自定义网格密度吗

找到一个#difine pi, pow没找着

originals
是什么参数呢?

primitives替换originals,效果很棒,不过只能运行之后才能看到效果。

编辑器也是可以看,只要开启刷新

棒!大佬!

强,我完了试一下

坐等白嫖,哈哈

看了帖子有好几遍,根据思路我自己写出来完全不是这个效果。
这个波纹的核心不是uv的偏移吗?
我写出来就是整体拉伸紧缩效果。
感觉还是思路不对。