网页
资讯
视频
图片
知道
文库
贴吧
地图
采购
进入贴吧
全吧搜索
吧内搜索
搜贴
搜人
进吧
搜标签
日
一
二
三
四
五
六
签到排名:今日本吧第
个签到,
本吧因你更精彩,明天继续来努力!
本吧签到人数:0
一键签到
成为超级会员,使用一键签到
一键签到
本月漏签
0
次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行
补签
。
连续签到:
天 累计签到:
天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
03月25日
漏签
0
天
unity3d吧
关注:
116,129
贴子:
559,621
看贴
图片
吧主推荐
视频
游戏
1
2
3
下一页
尾页
43
回复贴,共
3
页
,跳到
页
确定
<<返回unity3d吧
>0< 加载中...
【技术分享】Unity3D实现大规模数量的渲染
只看楼主
收藏
回复
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
一楼防吞
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
简单阐述下思路
大致分为四步:
1. 内存中用一个数组(System.Array)存放每个粒子的位置、速度、加速度。
2. 增删粒子时,将数组 Set 到 ComputeBuffer ,转移给显存。
3. 将 ComputeBuffer 设置给 ComputeShader 实现每帧更新。
4. 一次性渲染出所有的粒子。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
第一步:
我们需要声明一个结构体来代表每个粒子,同时在脚本里面声明一个超。。。大。。的数组。
(如果不想数组一来就这么大,也可以自行管理一个自动增加长度的数组。当然这不是今天的主题)
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
第二步:
1. 申请一个 ComputeBuffer,并维护其生命周期。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
2. 增加粒子的逻辑
需要注意的是,从GPU读回数据非常的消耗(大约5ms),所以千万不要每帧都GetData,但SetData却很快。
这里只是一个示例,实际上怎么使用这个还请自行判断。
(实际上楼主的代码是GetKey按住F,每帧随机发5000个粒子) 233333333
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
让我们先做第四步,先看到所有的粒子,再想办法更新。
这里楼主图快,用一个比较简单的办法,
直接在摄像机的 OnPostRender 里面使用 Graphics.DrawProcedural
mat.SetBuffer,将 pBuffer 设置给材质。
mat.SetPass(0),准备渲染材质的第0个pass。
每个粒子渲染24个顶点,用6个Quad组成一个Cube。
至于为什么要Cube,没有为什么。。 我就是喜欢Cube。
让我们一起来见证奇迹
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
增加了2006个粒子
纳尼? 粒子呢?
哈哈哈,太天真了,居然这样就想渲染出粒子。。
我们需要创建一个特殊的shader和它的材质,用于将ComputeBuffer中的数据渲染出来。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
我们创建一个Unlit Shader,名为ParticleBatch,
下面列出重点部分:
在shader中,声明同样的结构体,以及一个StructuredBuffer用于承接 mat.SetBuffer 设置过来的数据。
appdata里面需要加上SV_VertexID,
instID先别管它,因为楼主现在并没有使用GPU Instancing
vert函数很重要,它必须处理将每24个顶点组成一个Cube,并且从_Buffer中获取出wpos,来重置每个顶点的位置。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
这就对了嘛
由于粒子是随机生成的,所以是一坨,接下来我们让它们动起来。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
如果用CPU来计算粒子的动态的话,我就不多说了,直接在 Update 里面根据你想要的算法改变 particles 数组中每个粒子的位置,然后每帧调用 ComputeBuffer.SetData 提交,就可以看到改变了。
做得好的话,还是可以支持个10来万粒子的。
如果你想看百万个粒子,那继续看下面。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
楼主决定使用 ComputeShader,这种和 ComputeBuffer 浑然一体的东西。
创建一个ComputeShader,名为ParticleUpdate,声明两个 kernel 函数,
一个用于根据速度更新位置,一个用于根据加速度更新速度
ParticleUpdate.compute
至于脚本里面嘛,简单得很,在 Update 函数里面调用这两个 kernel 函数:
NBodySimulate.cs Update()
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
匀速直线运动的粒子群
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
接下来,增加加速度,使粒子具有更有趣的行为
这个加速度怎么加呢?每个人都可以玩出不同的花样。
我们在中间加一个恒星,给每个粒子提供一个简单的万有引力。
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
上图增加了后期特效
其实只是增加了一段万有引力的代码
调用:
每帧按照以下四步计算所有粒子:
1. 根据上一帧的万有引力更新速度
2. 根据本帧新速度更新位置
3. 清空加速度
4. 根据万有引力计算新的加速度
_17th_
Script
11
该楼层疑似违规已被系统折叠
隐藏此楼
查看此楼
13W个粒子
登录百度账号
扫二维码下载贴吧客户端
下载贴吧APP
看高清直播、视频!
贴吧页面意见反馈
违规贴吧举报反馈通道
贴吧违规信息处理公示