Unity海洋shader笔记②

笔记①提到,要计算泡沫数据需要临近顶点的位移数据,因此为了避免重复计算顶点位移我们需要在正式渲染水面之前就先计算好顶点数据。

生成缓存

将水面修改为随玩家移动而移动后,每一帧需要根据玩家当前位置和水面大小以及LOD等级等数据计算顶点的位移。这里可以直接采用Graphics.Blit()生成一个RenderTexture,也可以采用其他的办法。我刚刚接触到一个很有趣的Compute Shader粒子小项目,虽然没有完全搞懂Compute Shader的原理,不过先可以学会如何运用起来。送入Buffer的是waveSampler结构体数组,结构体包含了预先在初始化中计算好的uv值和保存顶点位移的Vector3变量。接下来就是在Compute Shader中计算顶点位移,并把缓存数据传入GPU。

[numthreads(1024,1,1)]
void Update(uint3 id : SV_DispatchThreadID)
{
    float xPos = _playerLocation.x + ( - displacementSample[id.x].z + 0.5) * 600.0;
    float zPos = _playerLocation.z + (- displacementSample[id.x].x + 0.5) * 600.0;
    float height = tex2Dlod(_heightMap, float4(xPos/1200 +0.25,zPos/1200 + 0.25,0,0));
    float attenuationFac = 1;    
    attenuationFac = saturate(pow((1.0 - height),_ShoreWaveAttenuation));
    float3 worldPos = float3(xPos,0,zPos);
    displacementSample[id.x].displacement = VerticesDisplacement(worldPos, attenuationFac);
}
生成的位移缓存(XYZ→RGB可视化)

对于泡沫的计算我们读取到顶点位移后计算雅可比行列式即可,较小的J值会产生泡沫。

int x1 = floor(i.uv.x * (_resolution - 1)); int x2 = ceil(i.uv.x * (_resolution - 1));
int z1 = floor(i.uv.y * (_resolution - 1)); int z2 = ceil(i.uv.y * (_resolution - 1));
int index1 = x1 * _resolution + z1;
int index2 = x1 * _resolution + z2;
int index3 = x2 * _resolution + z1;
int index4 = x2 * _resolution + z2;
float dxdz = (displacementSample[index1].displacement.x - displacementSample[index2].displacement.x
              + displacementSample[index3].displacement.x - displacementSample[index4].displacement.x) * 0.5 * 0.782;
float dxdx = (displacementSample[index1].displacement.x - displacementSample[index3].displacement.x
              + displacementSample[index2].displacement.x - displacementSample[index4].displacement.x) * 0.5 * 0.782;               
float dzdx = (displacementSample[index1].displacement.z - displacementSample[index3].displacement.z
              + displacementSample[index2].displacement.z - displacementSample[index4].displacement.z) * 0.5 * 0.782;
float dzdz = (displacementSample[index1].displacement.z - displacementSample[index2].displacement.z
              + displacementSample[index3].displacement.z - displacementSample[index4].displacement.z) * 0.5 * 0.782;
float J = dxdx * dzdz - dxdz * dzdx;

我的想法是用当前帧缓存和上一帧的缓存叠加后得到最终的数据,于是在脚本Update()中我重新开了一个RTlastFoamTexture用于保存当前帧的混合得到数据,并在下一次Update()中用于下次混合。

Graphics.Blit(lastFoamTexture, foamTexture, foamMaterial);
Graphics.CopyTexture(foamTexture,lastFoamTexture);
return saturate((-J - 0.02) * 2) + lastFrameFoam * 0.99 - 0.005;

不过这里我注意到了一个问题,如果玩家此时移动速度较快的话混合得到的数据会出现类似“漂移”效果。(生成的图片灰度经过了一定的夸张处理)



原因其实很简单,是因为在新的帧中对上一帧的缓存采样时采用的是当前帧的uv,我们只需要根据玩家位置的变动大小对这个uv差进行补偿即可,改动后该现象消失。

uvOffset.x  = (lastFrameLocation - mainCam.transform.position).x/600;
uvOffset.y  = (lastFrameLocation - mainCam.transform.position).z/600;
foamMaterial.SetVector("_uvOffset",uvOffset);

可以注意到此时泡沫在移动方向背后留下的类似拖影的痕迹,使用混合的缓存可以一定程度模拟泡沫逐渐消散的过程。

泡沫渲染(待完成)


Github: https://github.com/techizgit/UnityPlayground

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容