Unity中实现ShaderToy卡通火(原理实现篇)

文章目录

  • 前言
  • 一、我们在片元着色器中,实现卡通火的大体框架
    • 1、使用 noise 和 _CUTOFF 判断作为显示火焰的区域
    • 2、_CUTOFF : 用于裁剪噪波范围的三角形
    • 3、noise = getNoise(uv, t); : 噪波函数
  • 二、顺着大体框架依次解析具体实现的功能
    • 1、 uv.x *= 4.0; : 使用 uv 在 x 轴上的值,从(0,1)扩大到(0,4)
    • 2、noise = getNoise(uv, t); : 噪波函数
    • 3、_CUTOFF : 用于裁剪噪波范围的三角形
    • 4、卡通火形状部分
    • 5、卡通火颜色部分


前言

在上一篇文章中,我们实现卡通火ShaderToy到ShaderLab的移植。在这篇文章中,我们来解析一下其原理。

我们在分析时,需要从整体到局部。
依次从输出结果倒着逐步分解,这样对于复杂的效果就不会迷失目标。

  • Unity中实现ShaderToy卡通火(移植篇)

一、我们在片元着色器中,实现卡通火的大体框架

  • 在片元着色器中,我们可以看出主要实现的几个功能
			fixed4 frag(v2f_img i) : SV_Target{float2 uv = i.uv;uv.x *= 4.0;float t = _Time.y * 3.0;float3 col = 0;float noise = getNoise(uv, t);//shape _CUTOFF to get higher further up the screen_CUTOFF = uv.y;//and at horiz edges_CUTOFF += pow(abs(uv.x * 0.5 - 1.), 1.0);//debugview _CUTOFF field//fragColor = float4(float3(_CUTOFF),1.0);   if (noise < _CUTOFF){//blackcol = 0;}else{//firefloat d = pow(getDepth(noise), 0.7);float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);col = hsv2rgb(hsv);}return float4(col, 1.0);}

1、使用 noise 和 _CUTOFF 判断作为显示火焰的区域

if (noise < _CUTOFF)
{//blackcol = 0;
}
else
{//firefloat d = pow(getDepth(noise), 0.7);float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);col = hsv2rgb(hsv);
}
  • black部分(当在遮罩范围外时,返回黑色)

  • fire部分(显示 火的形状 和 火的着色)

  1. hsv2rgb : 由 hsv 转化为 RGB 色
    请添加图片描述

  2. hsv : 色相、饱和度、亮度
    请添加图片描述

  3. d :使用pow调节色阶范围

  4. getDepth(noise) : 将黑白灰渐变色分离成几个色阶,以表现卡通效果
    请添加图片描述

2、_CUTOFF : 用于裁剪噪波范围的三角形

  • 可以看出这就是我们卡通火的大概轮廓
    在这里插入图片描述
    三角形两侧都是 1(白色),在比较时,小于1的部分都显示黑色。

3、noise = getNoise(uv, t); : 噪波函数

请添加图片描述


二、顺着大体框架依次解析具体实现的功能

fixed4 frag(v2f_img i) : SV_Target
{float2 uv = i.uv;uv.x *= 4.0;float t = _Time.y * 3.0;float3 col = 0;float noise = getNoise(uv, t);//shape : 模拟出火焰大体形态(三角形)_CUTOFF = uv.y;//and at horiz edges_CUTOFF += pow(abs(uv.x * 0.5 - 1.), 1.0);if (noise < _CUTOFF){//blackcol = 0;}else{//fire//计算得到 火的轮廓float d = pow(getDepth(noise), 0.7);//计算得到 色相、明度、饱和度loat3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);//将 HSV 转化为 RGBcol = hsv2rgb(hsv);}return float4(col, 1.0);
}

1、 uv.x *= 4.0; : 使用 uv 在 x 轴上的值,从(0,1)扩大到(0,4)

在这里插入图片描述

在这里插入图片描述

2、noise = getNoise(uv, t); : 噪波函数

//获取整屏的噪波效果
float getNoise(float2 uv, float t)
{//given a uv coord and time - return a noise val in range 0 - 1//using ashima noise//add time to y position to make noise field move upwardsfloat TRAVEL_SPEED = 1.5;//octave 1float SCALE = 2.0;float noise = snoise(float3(uv.x * SCALE, uv.y * SCALE - t * TRAVEL_SPEED, 0));//octave 2 - more detailSCALE = 6.0;noise += snoise(float3(uv.x * SCALE + t, uv.y * SCALE, 0)) * 0.2;//move noise into 0 - 1 range    noise = (noise / 2. + 0.5);return noise;
}
  • 使用 TRAVEL_SPEED 、 SCALE 和 t 作为噪波因子,作为影响生成噪波的主要参数
    TRAVEL_SPEED : 流速
    SCALE :缩放
    t :时间

  • snoise(float3(x,y,z)); : 噪波生成算法(这里使用了 ashima noise 算法)

  • Perlin噪声与Simplex噪声笔记
    这里引用一篇别人的笔记,作为该噪音函数的讲解

  1. 第一次噪波效果
    请添加图片描述
  2. 第二次噪波效果
    请添加图片描述
  3. 两次噪波叠加效果
    请添加图片描述
  4. noise = (noise / 2. + 0.5);将噪波归一化(0,1):
    请添加图片描述

3、_CUTOFF : 用于裁剪噪波范围的三角形

  • _CUTOFF = uv.y;
    在这里插入图片描述

  • uv.x * 0.5 - 1 :值域范围改变(0,4)-> (0,2) -> (-1,-1)
    在这里插入图片描述

  • abs(uv.x * 0.5 - 1.); : 使值域变成对称的样子 (-1,-1) -> (1,0)、(0,1)
    在这里插入图片描述

  • pow(abs(uv.x * 0.5 - 1.), 2.0);可以用指数函数来控制三角形状的边扭曲程度
    在这里插入图片描述

  • uv.y + pow(abs(uv.x * 0.5 - 1.), 1.0) :实现三角形状
    在这里插入图片描述

4、卡通火形状部分

  • 将黑白灰渐变色分离成几个色阶,以表现卡通效果

//计算得到 火的轮廓
float d = pow(getDepth(noise), 0.7);

// 将黑白灰渐变色分离成几个色阶,以表现卡通效果
float getDepth(float n)
{//given a 0-1 value return a depth,//remap remaining non-_CUTOFF region to 0 - 1//实现边缘虚化的作用,把原本尖锐的边缘 ,变得虚化柔和float d = (n - _CUTOFF) / (1. - _CUTOFF);return d;//色调分离d = floor(d * _Steps) / _Steps;return d;
}
  • n - _CUTOFF 的效果
    在这里插入图片描述

  • float d = (n - _CUTOFF) / (1. - _CUTOFF); :边缘虚化,归一化后
    在这里插入图片描述

  • 色调分离 : d = floor(d * _Steps) / _Steps;
    把上面计算的结果,进行乘以一个较大的数,使用向下取整后,再除以这个较大的数归一化。以达到卡通效果中,一块一块的色调效果
    在这里插入图片描述

  • pow 用来调节亮度

5、卡通火颜色部分

  • hsv 是一种符合 人眼 对颜色感性认识 的特征值

计算得到 色相、饱和度、亮度。这里的特征值是 计算出符合 火的颜色区间范围。
其他效果的颜色,需要自己调整寻找颜色算法

float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);

请添加图片描述

  • rgb 是一种符合 计算机硬件设计 的 颜色设计。使用算法把 hsv 转化到 rgb

float3 hsv2rgb(float3 c)
{
float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

这里给出taecg老师总结的 HSV 2 RGB 算法链接

  • ShaderToy系列:HSV

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223843.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yolov8实战第二天——yolov8训练结果分析(保姆式解读)

yolov8实战第一天——yolov8部署并训练自己的数据集&#xff08;保姆式教程&#xff09;-CSDN博客 我们在上一篇文章训练了一个老鼠的yolov8检测模型&#xff0c;训练结果如下图&#xff0c;接下来我们就详细解析下面几张图。 一、混淆矩阵 正确挑选&#xff08;正确&#…

C#串口通讯

在C#写串口通讯小程序时&#xff0c;可以使用System.IO.Ports命名空间提供的SerialPort类。下面是一个简单的例子&#xff0c;包含了一个基本的UI&#xff0c;用于设置串口参数和进行通讯。这里使用了Windows Forms&#xff08;WinForms&#xff09;来创建UI。 步骤&#xff1…

数据结构——队列

目录 一、队列的定义 二、队列的实现 1. 队列的顺序存储结构 1.1. 顺序队 1. 创建顺序队 2. 删除顺序队 3. 判断队列是否为空 4. 判断队列是否已满 5. 入队 6. 出队 7. 获取队列长度 8. 获取队首元素 1.2. 环形队 1. 创建环形队 2. 删除环形队 3. 判断环形队列…

C++导出C标准的dll动态库

1 新建项目 1.1 使用VS新建一个空项目 1.2 在属性页中将配置类型改为&#xff1a;动态库(dll) 2 添加头文件 添加文件Api.h&#xff0c;示例代码如下 #pragma once#define DLLEXPORT __declspec(dllexport)extern "C" {DLLEXPORT int getAdd(int a, int b); //求…

C++中的多态你真的了解吗?多态原理全面具体讲解

目录 1. 多态的概念 2. 多态的定义及实现 2.1 多态的构成条件 2.2 虚函数 2.3 虚函数的重写 2.4 C11 override 和 final 2.5 重载、覆盖(重写)、隐藏(重定义)的对比 3. 抽象类 3.1 概念 4. 多态的原理 4.1 虚函数表 4.2多态的原理 4.3 动态绑定与静态绑定 5. 单继…

使用helpdesk帮助台有什么好处?

Helpdesk帮助台是一套帮助IT团队管理IT工单生命周期、自动化日常工作、优化工作流程的集合&#xff0c;它可以帮助IT团队提高生产力、降低成本、改善服务水平和客户体验。 而helpdesk帮助台管理软件所带来的好处不仅限于IT运营&#xff0c;所有利益相关者都会受益&#xff0c;…

【C语言必学知识点五】指针

指针 导言一、指针与指针变量二、指针变量的创建和指针类型三、指针类型的意义3.1 指针 /- 整数3.2 指针解引用 四、野指针4.1 定义4.2 野指针的成因4.3 指针未初始化4.4 指针越界访问4.5 指针指向的空间被释放4.6 如何规避野指针 五、指针运算5.1指针-整数5.2 指针-指针5.2.1 …

企业微信群发策略:高效触达客户的全新路径

在当前的数字化时代&#xff0c;企业微信已经成为了企业和客户之间沟通交流的主要渠道。通过企业微信进行定向消息群发&#xff0c;我们可以迅速传递信息至目标客户&#xff0c;进而提高品牌知名度、增强用户参与度。为了更好地利用企业微信进行精准、高效的营销推广&#xff0…

贰[2],函数OpenWindow/CloseWindow

函数OpenWindow C形式 LIntExport void OpenWindow( const HTuple& Row, const HTuple& Column, const HTuple& Width, const HTuple& Height, …

短剧分销平台开发,打造短剧内容变现新模式

短剧目前已经成为了影视行业中的一匹黑马&#xff0c;短剧主要是根据爽文小说翻拍&#xff0c;将小说中精彩高潮的剧情翻拍成短剧爽文&#xff0c;使得观众沉浸在短剧中&#xff0c;欲罢不能&#xff01; 短剧分销平台是短剧推广的新模式&#xff0c;它打破了传统的分销模式。…

代码随想录算法训练营 | day51 动态规划 309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费

刷题 309.最佳买卖股票时机含冷冻期 题目链接 | 文章讲解 | 视频讲解 题目&#xff1a;给定一个整数数组&#xff0c;其中第 i 个元素代表了第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多…

启动cad显示丢失mfc140u.dll怎么办?mfc140u.dll丢失有效解决方法分享

在CAD软件或其他软件中&#xff0c;有时候会出现由于找不到mfc140u.dll文件而无法执行代码的错误提示。这个问题可能是由于多种原因引起的&#xff0c;例如文件损坏、缺失或被病毒感染等。下面将介绍五个常见的解决方法&#xff0c;并解释mfc140u.dll丢失的原因以及该文件对CAD…

女生学习Java合适吗?需要学哪些?

其实女生心思细腻也更容易理解用户心理&#xff0c;更容易注意到其他人注意不到的细节&#xff0c;对这方面感知能力比男性要强&#xff0c;所以说女生做Java也是个不错的选择。 从难易程度上来说&#xff0c;需要一定的逻辑思维能力&#xff0c;Java抽象度较高&#xff0c;在…

C#里面的泛型(T),泛型类,泛型方法,泛型接口等简单解释

https://blog.csdn.net/dap769815768/article/details/81946506 只是比较简单的解释&#xff0c;在实际使用中&#xff0c;如果遇到需要深入研究的场景&#xff0c;再翻阅相关资料深入研究下。 一、泛型T 这个T在实际使用中很常见&#xff0c;比如List<T>。其实我们还…

7-1 六度空间 (PTA-数据结构)

“六度空间”理论又称作“六度分隔&#xff08;Six Degrees of Separation&#xff09;”理论。这个理论可以通俗地阐述为&#xff1a;“你和任何一个陌生人之间所间隔的人不会超过六个&#xff0c;也就是说&#xff0c;最多通过五个人你就能够认识任何一个陌生人。”如图1所示…

Openwrt源码下载出现“The remote end hung up unexpected”

最近项目原因需要下载openwrt21.02版本源码&#xff0c;花费了很多时间&#xff0c;找到正确方法后&#xff0c;发现可以节省很多时间&#xff0c;记录下过程&#xff0c;方便自己&#xff0c;可能方便他人。 一.问题阐述 openwrt21.02下载链接如下&#xff1a; git clone -…

MySql表分区类型

在MySQL中&#xff0c;表分区是一种将大型表拆分成更小、更易管理的部分的技术。表分区可以帮助提高查询性能、简化数据管理和维护等方面。在MySQL中&#xff0c;有几种不同类型的分区可以用于对表进行分区。以下是MySQL中常用的分区类型&#xff1a; 1. RANGE分区&#xff1a…

2024年企业在数据安全战略方面有哪些变化

根据IBM的数据&#xff0c;2023年数据泄露的平均成本达到了创纪录的445万美元&#xff0c;比2020年上涨了15%&#xff0c;仅是财务影响就足以终结一家企业&#xff0c;但数据泄露也可能对品牌声誉和客户对企业的看法产生毁灭性影响。 安全领导人忙得不可开交&#xff0c;随着员…

Python Click 简单使用说明

Python Click库的来源&#xff1a; Click是一个Python的命令行接口库&#xff0c;它由Alexandru Dutra和Ignacio Vergara于2010年创建。Click的目标是提供一种简单而灵活的方式来创建命令行应用程序。 常用参数说明&#xff1a; click.command()&#xff1a;这个装饰器用于定…

EasyCode代码生成模板

前言&#xff1a; EasyCode是 IDEA 开发的一个代码生成插件&#xff0c;主要通过自定义模板&#xff08;基于velocity&#xff09;来生成各种你想要的代码。相信大家都了解EasyCode是干嘛用的&#xff0c;下面是比较简约的一个生成模板&#xff0c;个人比较喜欢。 Controller …