Unity中RampTex介绍和应用: 溶解特效优化

您所在的位置:网站首页 unity模型变黑 Unity中RampTex介绍和应用: 溶解特效优化

Unity中RampTex介绍和应用: 溶解特效优化

2023-04-20 15:15| 来源: 网络整理| 查看: 265

Unity中RampTex介绍和应用: 溶解特效优化

上一篇文章介绍了溶解特效和其基本的原理, 接下来的两篇文章在此基础上增加了优化的内容.

今天主要的内容如下:

介绍RampTex 使用RampTex来优化溶解特效的边缘

我们先来看看最终的效果:

在这里插入图片描述 再来之前的效果做对比:

在这里插入图片描述

可以看到, 优化过后的效果, 在溶解边缘有一层像是火烧的感觉, 比起原来的效果显得更炫丽一点, 没有那么干巴巴.

而要做到这个效果, 我们需要借助RampTex来实现.

RampTex和噪声纹理一样, 也是Shader里面使用比较多的一种技术, 特别是在卡通渲染领域, 用来制作层次的大块颜色纹理, 效果很好.

那么我们就开始介绍RampTex吧.

什么是RampTex

Ramp有阶梯, 斜坡, 渐变的意思, 所以RampTex可以翻译为: 渐变纹理.

我们先看看渐变纹理长啥样:

在这里插入图片描述

可以看到, 这张纹理的特点是, u方向的颜色(使用(u, 0)取值)是一种渐变的效果(白->黄->红->灰->黑), 而v方向的颜色是一样的, 严格上说这个纹理只是一个一维的纹理, v方向的信息用不着. 下面的RampTex说明了这个问题:

在这里插入图片描述

也就是说我们完全可以只存储少量的信息, 这个也是后面一个优化点, 下章再介绍.

那么怎么来理解RampTex呢?

因为原来的模型是使用PBR渲染来制作的, 用来说明这个原理不是很直观, 所以这里我们换一个模型:

在这里插入图片描述

左边是从RampTex采样, 右边是正常采样, 中间是两张纹理的重叠效果展示.

可以看到, 蓝色方框框起来的部分, 在纹理上是从左到右为黄色到红色的渐变, 可以对应上.

上面的图示应该是比较直观了, 我们使用RampTex来采样, 就可以获得一种渐变的效果.

当然, 这里的RampTex是用来做溶解的, 不是给模型本身添加渐变效果, 所以看起来会有点怪, ^_^.

到这里为止, 我们只需要明白: RampTex是一种渐变纹理, 用于提供一种渐变信息. 注意这里的渐变信息不一定是颜色, 也可以是某种判断条件, 只是使用颜色来展示和存储, 好直观了解而已, 前面介绍的噪声纹理也是类似的, 理解这点很重要, 如果只是将其局限的看做颜色信息, 那么很多概念和原理都没法很好的理解.

使用RampTex来优化溶解特效的边缘

理解了RampTex是用来提供渐变信息这一点后, 我们来分析我们想要的效果.

想象一下, 火焰燃烧纸片时的场景, 纸片最接近火焰的部分是不是从白色到白黄色再到黄红色, 最后到红色的变化过程, 描述起来有点抽象, 大家可以自行网上搜索一下进行观察.

而这种渐变过程和所用到的渐变信息就是通过RampTex来提供的.

看上面的图, 是不是从白到黄, 再从黄到红, 最后到黑? 这就是用来模拟火焰烧纸片的物理现象.

结合一下之前介绍的噪声纹理, 我们需要将其由黑变白的过程, 映射到RampTex的由白变黄, 再到红, 最后到黑的过程.

是不是有点没太明白?

下面我尝试说人话.

首先使用噪声纹理给模型贴图:

在这里插入图片描述

通过上一篇文章的内容, 我们知道, 越黑的部分, 代表越先进行溶解, 越白的部分代表越后进行溶解.

在这里插入图片描述

如果需要将RampTex的变化映射到这个过程, 我们就需要使用噪声纹理的值去RampTex采样:

在这里插入图片描述

也就是说, 在噪声纹理上黑的部分, 在RampTex上应该是白的部分, 在噪声纹理上灰的部分, 对应RampTex上黄红的部分.

这里我特意加深了效果映射效果, 本身的情况没有这么明显.

相信大家应该有点感觉了吧, 总之这里能理解: 使用噪声纹理的值(由像素的uv坐标采样得到), 去采样RampTex即可得到这种效果就好.

在这里插入图片描述

然后叠加上模型本身的纹理效果:

在这里插入图片描述

显然, 这不是我们想要的效果.

我们需要的是: 只在溶解边缘有渐变的效果, 其它的部分正常显示.

接下来我们分几个情况来分析, 如果这个像素:

发生溶解, 直接丢弃像素 未发生溶解 使用本身纹理采样的颜色 使用本身纹理采样的颜色+渐变采样的颜色

其中"使用本身纹理采样的颜色"可以用"使用本身纹理采样的颜色+渐变采样的颜色(但是颜色值为0, 也就是相当于没加)"来替代.

所以我们得出结论, 如果想要达到目的, “只需要”, 对于未发生溶解的像素:

如果这个像素是发生溶解像素周围的像素, 那么就附加渐变采样出来的颜色 否则附加的颜色为0, 也就是黑色

怎么样? 看起来很简单吧?

简单才怪…

这个算法必须要解决的问题就是: 我特么怎么知道那些像素是溶解像素周围的像素???

最直观的想法当然是做判断啦:

fixed4 frag (v2f i) : SV_Target { fixed4 dissolveCol = tex2D(_DissolveTex, i.uv.zw); clip(dissolveCol.r - _DissolveThreshold); // ---- 获取溶解边缘像素 fixed4 rampColor = 0; // 三层圈之外的颜色使用原色 fixed offset = dissolveCol.r - _DissolveThreshold; if (offset >= 0) { if (offset < 0.04) { rampColor = tex2D(_RampTex, 0); } else if (offset < 0.08) { rampColor = tex2D(_RampTex, dissolveCol); } else if (offset < 0.12) { rampColor = fixed4(0, 0.2, 0, 0); } } // ---- 结束 fixed4 col = tex2D(_MainTex, i.uv.xy); col += rampColor; return col; }

因为dissolveCol.r - _DissolveThreshold < 0的像素会发生溶解, 被抛弃, 所以offset = dissolveCol.r - _DissolveThreshold; 这个offset就可以用来判断溶解边缘像素.

我们通过offset将溶解边缘像素划分为三层:

第一层0 ~ 0.04我们给一个0作为采样坐标, 在RampTex上采样获得白色 第二层0.04 ~ 0.08选择噪声采样值作为采样坐标, 在RampTex上采样随着噪声采样值的变化而变化 第二层0.08 ~ 0.12我们固定给一个绿色

也就是说, 溶解边缘会有三层颜色, 依次是: 白色, (从白色到黄色再到红色最后到原色的变化色), 绿色. 下图可以清晰的看出我们预期的结果:

在这里插入图片描述

去掉原色的影响后, 效果更清晰:

void frag(...) { //.... col += rampColor; if (rampColor.r > 0) { col = rampColor; } return col; }

在这里插入图片描述 然后我们看看真实的效果:

在这里插入图片描述

是不是有点那啥意思了? 哈哈.

但是这样直接指定颜色, 而且用了多个if, 感觉有点傻, 所以我们在下一篇文章里换一个思路来实现.

总结

今天借溶解特效优化的例子来认识了RampTex, 主要展示结合实际使用来介绍RampTex, 是为了加深大家对于RampTex的认识和理解, 溶解特效本身并不是重点.

下一篇文章会使用另一个思路来实现最后的一部分轮廓颜色, 还是基于RampTex, 只不过更合理和自然. 主要的目的是介绍SmoothStep函数和其使用, 可能对于像我一样数学不太好的同学来说, 会有一定的理解难度, 但是这种实现却非常漂亮, 同时可以让大家再一次领略数学和Shader的魅力.

好了, 今天就是这样, 希望对大家有所帮助.



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3