IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity学习shader笔记[一百零八]简单萤火效果 -> 正文阅读

[游戏开发]Unity学习shader笔记[一百零八]简单萤火效果

之前用粒子系统基于原有萤火虫的粒子改了一波慢萤火效果就被惊艳到了,开始大家讨论,就都觉得这样大数量的粒子消耗挺大的,后面测试过才发现单纯的粒子系统在总粒子数量3000,每秒300的生成数量,屏幕呈现有1000多个粒子的时候, 在华为P30也能稳定维持FPS在60帧左右。可能unity后面做了优化。

思路

首先要确定的是在范围内绘制出流动和显隐, 这个功能是很多其他功能的基础,例如雪花,落叶,落花,战火等,扩展效果 一般是添加一些随机翻转,缩放,替换贴图等。 应用范围比较广。

尝试思路

c#能传入一个世界坐标,或者在shader里面找到模型内某个点的坐标,shader中深度图转换坐标后对应上这个位置的将其绘制出来。后来觉得这个思路不太正确。

  1. 因为深度转只能在给定的深度转出世界坐标,当某些部分的深度本身代表的区域不在cube内部的时候,转出的世界坐标也不在cube内部,传入的世界坐标都是在cube内部,那么这个区域就成了一个deadzone, 任何点都不会在这里出现。 点在运动图中因为从非deadzone走入deadzone而导致相应位置转不出相应坐标而出现的闪烁问题。这样只能在cube范围比较大的时候使用,deadzone与非deadzone夹杂,非deadzone足够多 ,表现才可能不太违和。

  2. 基于点去在shader中绘制一定范围的以该点为圆心的圆形区域,再以此采样贴图去表现,也是实现起来坑比较多的。主要是采样贴图这个部分,圆形区域内的所有uv不能确保全部计算正确,采样贴图注定做不很好,表现效果就不太正常。

  3. 就算上面的问题解决了,屏幕大范围的深度图采样和重建世界坐标消耗是比较大的,移动端会比较影响性能,严重一些就是移动端会因此砍掉这个。

所以这个方向做了一部分就停止了

最后思路

还是采用中规中矩的C#生成mesh,shader进行运动和细致表现的方法,能够轻松表现萤火与普通物体的互相遮挡的关系和空间感。 在c#中给出同一位置的四个顶点,分配完整的uv,在shader中连成由两个三角形组成的矩形,最后将所有的三角形组合成一个mesh。耗时的工作在GPU中做。

正方形面片的生成
在shader中根据顶点对应的UV,将顶点局部坐标位置以自身运动坐标为基础, 摄像机up轴和right轴为方向的扩展。

随机运动
使用柏林噪声函数,初始的模型坐标乘以时间变量和速度变化量,然后随机选取两个分量生成噪声,噪声用于位置偏移xyz,偏移可以乘以一个放大值表示路径的扩大程度。最后顶点原始位置加上这个偏移量,因为柏林噪声只要输入值是连续的,结果值就是连续的。输入是time的变种,总体来说是连续的,结果值就不会出现突变导致位置突变。

边界显隐
判断世界坐标xyz是否到了边界,取xyz分量离世界坐标边界的最小值,到了阈值范围就进行透明度变化

边界控制
运动后的粒子如果某个维度超过了边界值,就该维度对边界值取余,取余结果加上反向边界重新赋值给该维度。表现上就是在左边界飘出去的萤火,会在右边界飘进来。

问题

距离和速度的计算分离

每个面片的运动是独立的,那么思路在shader是每个面片根据自身初始的局部坐标位置来与时间做运算,得到不同的实时随机噪声,用这个噪声来扩大一定的倍数代表xyz方向上的运动路径。c#中不能得到每个面片的路径。统一传入到shader中的也是类似于time的一个变量。 干脆就用time变量了。

太久没写shader了,距离和速度的计算分离开始时候没有想清楚
perlin_noise 这个函数类似于用输入变量作为uv去采样柏林噪声图。
因此输入变量的变化快慢决定了结果值的变化快慢。
所以当显隐速度过快的时候,可以在输入哪里乘以小数减小变化量。

透明度

Blend One One 本身是当前颜色和缓冲区颜色直接叠加的方式进行变亮的。在不进行透明度调节的时候,可以表现出萤火的高光。但是在透明度调节的时候,其本身的含义就决定了透明度不会影响到表现效果。即不会有隐现效果。

位置的计算

M矩阵转换的时候,注意四维向量右乘四维矩阵,M的第四列前三行代表的是物体在世界坐标系的位移。如果用三维向量去乘,那么unity会自动补齐第四位为0,得到的结果将会是忽略了位移的模型空间到世界空间的变换,所以和M矩阵计算的时候,模型坐标系位置向量的第四位应该是1。

缩放的影响

边界值是世界单位的,顶点在模型坐标系中进行了位移计算后,转到裁剪空间的过程中,M矩阵包含了物体的缩放。
位移后的顶点会以相同的缩放进行放大,原来的边界就不足以囊括所有的顶点了。所以边界值要做对应维度的缩放。举个例子x方向最大维度是f,则x方向最大的边距是x+f,在x方向是1倍的时候,能包住所有粒子。 但是x方向扩大了三倍,为了保证x方向的边距能够包含所有的粒子,x方向最大的边距是x+3f。

工程链接

Unity 非后处理简单萤火效果

过程中有一些中间版本有点有趣,备份了一下。

请添加图片描述

请添加图片描述

请添加图片描述

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:31:34  更:2022-10-31 12:33:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/17 6:11:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码