V7投稿|奇怪的板子(shader)保姆级分享|山下人

首先筛一波大佬…放视频!!!
cut_0002


ok希望到这里还在看的,就是和我一样的小可爱了。
因为各种各样的原因,做了上面的效果。
这里贴上它最原始的模样…如图:
image
可以看到纹理中间有大量的白色区域,以及周围一圈黑色的边缘部分。
那么如何利用这个图片做到视频中的效果呢。
基于当前项目还在运营所以不方便贴出全部代码,然而既然号称保姆级分享,总要让坐下的朋友有所收货才行。

首先功能的拆分
1>指定区域颜色修改
2>指定位置扣指定大小的洞洞
3>纹理左下和洞洞内部生成阴影
4>内部水波纹效果

下面开始具体的内容分享:文章会讲解的稍微啰嗦一点,大佬们就请珍惜自己时间酌情翻阅哈…

(1)我们需要让黑色的边框区域变成白色,同时内部的白色区域要成为我们指定的颜色(为什么要这样呢?因为策划小宝贝要- -…)

那么如何操作呢,我们新建一个最传统的内置sprite effect文件。
既然是2d不涉及形变的效果,那么vs就不是我们的重要部分了。我们将注意力集中到fs部分。
开始我们的第一轮转变。
首先增加策划小宝贝想要自己指定的颜色

image
然后在fs中将原本要输出的颜色改成我们指定的颜色

image

下一步就是区分出原图的中黑色和白色区域并且进行不同颜色处理代码如下:

image
关键在于理解o = mix(A,B,C); -----> A *(1 - C)+ B * C
简单的说就是当颜色越接近白色,C值越小,那么B的作用越小,A的作用越大就越偏向于我们指定的颜色。那么反过来越接近黑色(原图的边框)C值越大,B的作用越大,那么就越偏向于B的颜色。(B值是我们指定的toCol = vec4(1.0))。
为什么要用这么拗的写法呢。用if else去写逻辑 易读性不会更强么?
这是因为step,mix,smoothstep等方法是有硬件加速这个buff的,况且fs(逐像素)是个十分敏感的朋友,在这个家伙身上的操作哪怕是一丁点的性能提升也是值得的喔。
OK经过这个步骤我们的图片变成了如下:
image ->image
这里解释一下为什么为什么o.a也要进行mix步骤,是因为策划小宝贝的需求是白色边框的透明度保持不变,而内部颜色是可以指定透明度的,当然这个透明度还不能影响到子节点。所以我们也不能用mainColor的alpha。

(2)在指定的位置扣洞…为什么不叫画圆?因为我觉得扣洞洞很可爱
扣洞该如何做呢,项目里的需求是洞洞的区域要透明可视化到底下的内容。
这里就使用最基础的SDF(有向距离场)知识去扣了。代码如下:

image
image

这里SDF内容不做深入说明了,感兴趣的童鞋可以自行查阅或者看看下面的详细说明:
https://blog.csdn.net/weixin_44053279/article/details/129576750

这里还附带了几个SDF的造型方法以及利用SDF+RayMarching实现的软硬阴影效果。虽然项目中大概率用不上,不过用于学习是完全没问题的。
挖洞的内容相对简单,无非是在某个长度限制范围内的像素我们使它透明即可。效果如下:
image
使用smoothstep是为了洞洞的边缘相对平滑减少锯齿,这只是消除锯齿最微不足道,但是也不可缺少的做法了。就像谈恋爱,牵手不是终点,可是这一步都没有的话,就容易变成耍流氓了。
OK停止谈恋爱的幻想,我们进行下一步。

(3)纹理和洞洞内部生成阴影。
听上去花里胡哨,其实只是进行简单的uv偏移并且指定颜色。当然这里因为板子会不停地旋转(开了那个该死的物理引擎)所以我们需要同步计算当前的旋转信息,来保持uv偏移的方向始终在我们期待的方向。
效果如下:

image

为了方便观察,所以uv阴影的颜色稍微橘里橘气了一点。
具体的思路是,获取指定方向偏移后的catchUv,如果当前的uv采样结果是透明区域,并且catchUv采样结果是非透明区域,则叠加上指定的阴影颜色。
catchUv的计算逻辑大致如下:

image

shadowBaseUv.xy对应了期望偏移的方向,而tmpAnglesp.y是当前节点的旋转信息。这里顺便附上rotate_cw和ccw。

image

OK最后一步了
(4)水波纹
这个看上去奇奇怪怪的东西,其实…是有点奇怪。
咳咳。开玩笑的…这个伪造的水波纹,机智的童鞋可能一眼就发现了,这玩意儿就是个sin()或者cos()。
你以为真的这么简单么?呵呵…是啊- -就是这么简单。
sin()的图形如下。顺便安利一个函数网站,玉兔大佬推荐的(其实是我逐帧看视频发现的,这事儿不能让肌肉哥知道了)。

https://www.desmos.com/calculator?lang=zh-CN

image
这里能非常方便的看出来a对应高度,b对应左右移动,c对应波动的幅度。实在懒得做动图了,大家臆想一下,或者打开网站输出y=sin(x+b)*c+a 生成滑条以后手动感受一下。
有这个逻辑我们在做接下来的事情就简单了。
核心代码如下:

image image

本质上做的事情是,当前UV的y小于sin的返回值则使用水波纹的指定颜色即可。请无视WAVE_OUTLINE那是为了兼容一些特殊需求写的。当然这里还需要有个额外处理的计算是,板子是在旋转的,同样利用我们前面使用的旋转信息。
image
对UV进行相应的旋转,就能保持水波纹一直在板子相对的视线底部了。
至于为什么会有水波纹忽快忽慢的效果,是在游戏中不停计算当时的旋转角速度,然后按照指定比例换算成期望的sin偏移线速度即可。为了在板子角速度衰减到0的时候水波纹保持一定的"荡漾"感,在原本的角速度基础上增加一个旋转幅度即可。
效果图下:安安静静的时候还是挺可爱的

image


OK…打完收工。

一气呵成可能有些内容还没有说的很清楚,有朋友开喷后我尽量补全哈。
2d shader的天花板不高,但是起点更加亲民,未来有机会我也会分享一些3d效果。
(最近痴迷做黄泉大招<星穹铁道>)

顺便安利几个修炼方法:

1>基础:

首先是弥补基础知识的短缺,这个就好像牵手一样,它虽然不是目标,可是真的不能没有。你非要从那啥开始…也不是不行。这里推荐一个那啥的网站
https://www.shadertoy.com/view/4ttSWf
如果你得能打开,然后…(喵了个咪你电脑这么好么)然后感受一下被iq大神碾压的滋味。是啊,我代码全开源,每个字和方法都明白,但是就是看不懂…
如果你难受了,请调整好心态,饭是一口口吃的,梳理N遍基础知识,才能支持我们走的更远,而且这些内容对于未来进军3d渲染有有非常大的帮助,虽然我是从麒麟子开始的,那时候我还喜欢女孩子…咳咳 聊偏了。即便如此我还是用了不少时间反复咀嚼玉兔小姐姐的视频,一个能从光照,材质,公式,实战全方面教学的素材,实属难能可贵。链接附上:
https://www.bilibili.com/cheese/play/ss13504?query_from=0&search_id=2872507712820709154&search_query=不捣药的玉兔&is_PCend=1
也可以考虑先试几个免费内容,觉得适合自己再考虑更进一步。(这里的知识同样含金量很高)
【【玉兔|图形学与游戏开发】学会写Shader后,可以做哪些岗位?】https://www.bilibili.com/video/BV1dq421F7Lh?vd_source=9f6e095b5e8965c5f713f8971e95db9f

2>实战:

进阶下一步的话,就需大量的练习,2d/3d的效果看到的想到的,逐步拆分,实现,在实现的过程中倒逼自己去补足之前缺失的知识和错误的理解。这个期间就会遇到各种麒麟子的文章了,要学会分辨,毕竟很多时候,他不是为了让你听明白,只是为了让你喜欢上他…
当你没有头绪或者找不到想要实现的效果,不妨打开 https://www.shadertoy.com/

3>深入:

寻找一个感兴趣的图形API练手,练手说起来轻松,当你经历webgl两三百行就为了画个三角形的时候心态就不一样了。再向后可以考虑进军引擎渲染管线了,cocos之所以强大,也源于它的开源。固然我们一直在喷,拿它和unity比,和UE比。可它也一直在成长,在优化,只有当你深入去看源码才能理解很多设计和毛病,才能让你未来喷的更有力度,甚至提供出自己的解决方案,而不是仅仅做一个口无遮拦的人。这世上并不缺乏提出问题的人,更需要的是解决问题的人。

4>迎娶白富美:

醒醒朋友…

12赞

:+1:

1赞

顶顶顶顶顶~

1赞

感谢分享~~

1赞

PS:参与征稿活动需要活动页面贴链接哦!

“在活动页面评论区以 “ 文章标题+文章链接 ” 的形式提交作品,即为成功参与活动。示例:我的文章标题是《XXXXXXXX》,文章链接:XXXXXXX。”

这不是我东哥么

顶顶顶!!!!先膜拜,再Mark

1赞

这不是我朱哥么

你答应把肌肉男友介绍给我的,可别忘了

生动有趣 活灵活现 确实牛逼

大佬客气了,只是恰好项目需要,后面会尽量分享点酷炫但是没啥用的东西 :blush: