Unity3D GPU Selector/Picker
一、概述
1.动机
Unity3D中通常情况下使用物理系统进行物体点击选择的基础,对于含大量对象的场景,添加Collider组件会增加内容占用,因此使用基于GPU的点击选择方案
2.实现思路
对于场景的每个物体,构建一个<meshrenderer,color>,在点击后,替换物体材质的颜色为该字典中相应键值的颜色, 进行渲染,获取RenderTexture,并转存在Texture中,然后采集鼠标点击位置的颜色,查询该颜色对应的meshrenderer,之后对从相机到鼠标点击位置的射线与mesh中的三角面求交,从而得出点击位置
3.实现过程
3.1 模型的Read/Write
由于需要进行射线与模型三角面求交计算,所以需要勾选模型的该选项,但勾选该选项后,会驻留除模型三角面信息之外的如法线、切线等其他大量的数据在内存中,从而快速的引起内存不足的问题,因此需要将模型的三角面存储在ScriptableObject对象中
3.2 多个交点
射线可能与模型会有多个交点,因此需要选取离相机最近的点作为结果
3.3 使用的RenderTexture的大小
初始实现时,使用了与分辨率同等大小的RenderTexture,若为1920*1080,其内存占用则为31.6MB,会引起Gfx.ReadbackImage的占用,因仅需关注鼠标点击位置的颜色,因此可调整RenderTexture的尺寸,而调整采样Camera的方向即可,并调整其
3.4 Directionary<meshrenderer,color>的设计
将Color的RGB通道作为层号、行号和列号,因此整个字典就像一个叠在一起的鸡蛋托盘一样;
为了提高利用颜色值检索时的精度,增加颜色键值的STEP,可能并未起作用,即RGB值每次递增STEP,而不是1,如R值依次为0,2,4,6,…
对于RGB值使用无符号整型即可,即ubyte;
使用位移操作代替乘法与除法操作;
3.5 问题
如果点击后场景颜色发生了变化,可能是GPU Selector中使用的Shader修改了材质中的Color属性。因此,需要注意使用Directionary<meshrenderer,color>中的颜色渲染时,Shader中Color属性名的唯一性
3.6 笔记
MeshCollider可能带来与triangles数据等量的内存占用;
Model.Read/Write会带来数倍的内存消耗
1M=1024KB=1048576Bytes
3.7 关键API与算法
(a)API:
Camera.SetReplacementShader/Camera.ResetReplacementShader
Camera.RenderWithShader
(b)射线与三角面求交
Möller-Trumbore算法
(c)IEquatable接口的实现文章来源:https://www.toymoban.com/news/detail-633089.html
二、遗留问题
1.目前只能在Gramma色彩空间中进行使用,对采样RenderTexture的RenderTextureReadWrite和Texture2D的bool linear的设置好像没有起作用,待继续调试文章来源地址https://www.toymoban.com/news/detail-633089.html
到了这里,关于Unity3D GPU Selector/Picker的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!