instancing system
描述:
结构:
- List InstanceObject 指定为场景的container.
- Monitor 显示器,显示生成的object,使用graphic.drawmeshinstance;
- 工具-笔刷,在editorview中创建instances;
设计原则:
显示器运行在prefab中,prefab装载着instance Data.
显示器继承monoBehaviuor
控制显示器object的位置可以影响所有instance Data的显示位置.
编辑器显示器:运行在编辑器工具中
Runtime显示器:Mono物体中
数据应该都要存到Constant Buffer中.这样在shader中可以做tint的功能.
GameObject能够控制所有instance的transform.
需要用到一个command buffer Draw所有Instances
command buffer装载所有的数据.
InstanceShader中接收并处理cbuffer的数据.
注册到RenderingSystem中(最后再接入)
Instance中需要一个个对应的列表材质进行setbuffer.而不是设置全局buffer.
shader中需要编写instanced structure接收buffer的数据.
bufferInfo中的结构尽量简化.
重新定义序列化的文件结构.
transform矩阵定义重构.
view Type 重构.
显示层级Isolated 单一化显示
最后读取静态序列化数据
完成吸色器的状态
测试到的问题:
最大数组不能超过1024,超过时可以开一个新的data来避免1024溢出
待完善,笔刷距离patinting。(高优先级)
刷出来物体matrix的法线不匹配地形方向。
editor状态下没有显示物体.(高优先级)
笔刷状态卡顿比较严重(但是在游戏运行是卡顿可以解决)
笔刷刷的颜色需要对其进行伽马矫正(已经在shader中完成gamma矫正)
拾色器的颜色拾取出来颜色变暗.
Display中显示的buffer颜色数据不一致.
buffer 数据不一致.
配置项
- 渲染物体
- 渲染材质
- 统一覆盖渲染材质
- 可控transform
- 分组(备用)
基本代码结构
1 | class InstancingData : scriptableObject |
实例对象的结构
- 源模型
- 对应渲染材质
- 位置
- 旋转
- 大小
- 法线
- 颜色
1 | struct InstanceObject{ |
1 | public struct InstanceBuffer{ |
1 | CBUFFER_START(_CBufferInstance) |
笔刷 EditorTool
结构
笔刷形状
笔刷状态
有配置文件可以配置笔刷的详细设置。
显示_handles
设置当前的instanceData层级
编辑器中可视化数据
切换自动显示当前显示的数据
配置项
- 工具快捷键
- 快捷键B呼出笔刷
- G lookAt笔刷位置
- S 吸取指定位置的屏幕颜色
- 调节笔刷散布噪声级别
工具状态
- 工具未初始化状态
- 显示未初始化的提示
- 橡皮擦模式
- shift 切换到橡皮擦模式
- 松开shift 切换回笔刷模式
- shift + 左键清理笔刷范围内的数据
- 笔刷模式热键B
- 左键放置数据
- 调整大小模式
- f进入调整模式
- 鼠标左右移动调整笔刷大小
- 鼠标上下移动调整笔刷射线高度
- 按住shift 调整精度变小
- 鼠标左键确定调整大小
- 鼠标右键取消并推出该模式
- 调整密度模式
- shift + f 进入调整模式
- 鼠标左键确定调整大小
- 鼠标右键取消并退出该模式
- 最大密度为64位
- 调整噪声权重模式
- D 进入调整模式
- 鼠标左键确定调整大小
- 右键取消并退出该模式
- 权重最大为1
- 调整噪声强度模式
- shift + D进入该模式
- 鼠标左键确定调整大小
- 右键取消并退出该模式
- 噪声强度最大为5
- 调整笔刷物体大小模式
- shift + S进入模式
- 鼠标左键确定调整大小
- 右键取消并退出该模式
- 大小最大为5
- 调整笔刷颜色
- s直接吸取场景渲染中的颜色
- 或者出现一个圆盘,让用户自己调整颜色
- 按住s键进入拾色器
- 松开s键执行吸色功能
- 吸色模式旁边会有当前吸取的颜色提示
其他配置
- 生成物体可配置
- 散布范围可配置
- 散布密度上限可配置
- 快捷键配置
- 笔刷形状
- 噪声形状
- instance数据篡改
功能
投射射线获取交点,在交点中根据交点平面的法线重建一个圆盘,在此圆盘上按照配置的物体密度重新投射射线检测交点。
如果在检测圆盘中已存在数据,检测圆盘中密度的数量,不超过最大密度进行放置。
编辑器中,打开笔刷后,检查场景中含有对应mono的物体,如果没有,则询问是否需要创建。
当存在mono物体,显示所有读取到的实例物体,编辑时,会按照顺序创建一个列表,并且可以使用快捷键切换到下一个instance data中进行编辑,每次切换的数据都会有提示。
每次成功刷上,记录当前位置。当下一次刷的时候对比上一次位置的距离,如果没超过阈值,则不执行笔刷刷数据的功能。反之则执行。
笔刷预览显示物体位置大小形状网格,并且有预览材质和预览shader.
第一次启动和使用都有提示界面出现进行配置.
如果没有加载上实例数据,则弹窗询问是否需要创建数据,确认后数据会保存在resources/instance目录里面.
笔刷绘制修改器,需要旋转、颜色、大小等属性随机,可以实现一个修改器并且添加内容即可.
随机颜色的修改器逻辑,需要参考到色卡和随机种等算法.
需求
基于Editor 窗口的笔刷,在视窗中投射球体到场景中,放置物体。
用graphic.drawmesh显示已经放置的物体
判断球体中放置的物体的密度,物体密度会有上限。
Editor中绘制笔刷预览笔刷位置(handles)
可以吸附物体碰撞体进行放置物体
笔刷功能时屏蔽Unity的鼠标事件(指定事件)
拦截默认鼠标事件Event
预览位置按照距离着色
按下F键视角会移动到鼠标附近的位置LOOKAT
可通过笔刷删除已经布置的物体
按下翻页键可以切换当前的层级,instance”层级”.也就是instance scriptableobject
当层级里的instanceObject超过了1024个对象,那么则下次刷的时候自动寻找下一个没有满1024的层级。
当第一层已经达到1024个实例数据,需要策略切换到下一层再绘制.
Bonus
- 十六进制色彩转换
- 快捷键配置
- 配置面板GUI自定义
- S 吸取指定位置的屏幕颜色
- 可以undo上一次刷的记录
- 可以把整个系统做成package
- 使整个工具与unity更加统一
笔记
根据法线变换整体的顶点坐标,矩阵变换,求法线的变换矩阵然后转换。
每个场景中创建一个储存数据的文件,该文件路径统一放在Resources,而且文件名与场景文件名字相同。如果该场景没有实例文件,调用笔刷后会提示是否要创建实例文件,如果是,则创建一个新的实例文件。
在游戏加载时,实际会创建一个实例,该实例用于显示所有储存在数据中的“物体”,用作数据的可视化。如果该场景没有实例文件,则进入待机模式,当场景发生变化后,又重新检测一遍是否有实例对象。
overlays Menu Custom 将层级的放在空格键可打开的overlay menu中,提高使用效率.
编辑器中实例数据可视化。
当缩小笔刷大小的时候,密度也随之上升。算是一个显而易见的bug.
将在编辑器中读取文件的静态方法抽象出来.做成一个通用的方法.
handles显示与模型匹配度较低,笔刷使用时感知力度较小.
刷出来的物体大小没有变化,旋转没有变换。
层级应该移动到overlays页面中,可以在overlays中对对应层级隐藏
笔刷稳定性运行检测再0617日完成.
- 重点,修改颜色变化的功能.让其笔刷数据的颜色会随着一定规律变化,不太单调.
- cbuffer显示后的数据和显示结果不一致.待修复
- 单一显示和整体显示的功能.
- 完善mono状态下的displayer
- 引导功能的完善.
- 说明手册和功能列表.使用文档.
施工compute buffer
- 一个float 占4个字节
- 确定的结构
1 | struct InstanceInfo |
(3+4+3+4)*4
1 | 重要参数 |
indirect Arguments:
AppendsturctBuffer;
drawMeshInstance会分割批次
DrawMeshInstanceIndirect不会分割批次,保证了每个instanceId的顺序.
DMII: DrawMeshInstanceIndirect
每次一层layer设置新的offset;
如果使用sturcturedbuffer.一个material 只会有一个buffer数据被设置.并不会叠加数据.
DMII 中一个材质就相当于一个draw batch被传输.
重写文档.
使用每个id的值去设置顶部颜色产生有不一样的variation