GPU Instancing GPU Skin详解

1、GPU Skin与GPU Instance

骨骼动画是指通过定义骨架结构,然后在上面蒙皮,然后对骨架做动作驱动模型运行的动画,游戏中大部分的角色表现是通过骨骼动画进行的。骨骼动画本质上最终是通过Skin和Skeleton的Animation变换模型的顶点数据。骨骼动画既可以在CPU端实现,也可以在Gpu端实现。
在现有的很多游戏引擎中,骨骼动画的实现大多在CPU端进行实现,例如Unity,原因有很多:比如引擎希望在骨骼动画中加入一些复杂的如动作融合, 骨骼部位分离动画,IK,重定向,骨骼蒙版,跟骨骼动画等等复杂的动作机制,来表现更高质量的动作表现。
 

为什么需要GPU Skin?
但是我们知道Skin是一个对每个mesh上的点进行变换的并行问题,在CPU端实现会带来极大的性能限制,尤其在手游中,很多要求同屏人数多的游戏到了后期会受制于同屏的角色数。我在过往项目的统计在Unity中,一般中端机器可以支撑8-10W面左右的普通mesh,但是如果是Skinnedmesh,大约1.5W面就会遇到瓶颈。
总的来说CPU断的Skin可以做复杂的动画机制,但是效率很低。这时我们想到了GPU Skin。GPU Skin在GPU上并行的对mesh的点进行Skin变换,可以极大的提升效率,另外它节省了相对来说更宝贵的CPU资源。不过支持复杂的动画机制相对难度较大。
所以在一些游戏的实现中,可以思考对于怪物以及不重要的玩家对象采取GPU Skin,因为这些单元大多也不需要很复杂的融合,blend tree这种机制,但是却可以快速的渲染,而对重要的主角这种才保留GPU Skin的形式。
 

Skin的原理
假设我们有一个骨架Skeleton,骨架是由一些有父子关系的节点(即骨头)组成,每个骨头代表一个坐标系。一段骨骼动画通常记录了每个骨头在其父空间相对于初始姿态的几何变换(根骨骼的父空间可以认为就是模型的局部空间)。
在初始的时候,Skeleton被摆到一个初始的姿态,即T-POSE,同时和这个骨骼对其建立角色的模型。
这样对于任意一帧动画,模型上任何一个顶点P最终在模型局部坐标系下的位置Pl就等于
Pl = Mroot-local ..*M2-3 * M1-2 * MBind1 * PLT + Mroot-local ..*M2-3 * M1-2 * MBind2 * PLT + ...
这里面Plt是TPOSE下这个顶点的坐标。
MBind1是影响这个顶点的第一根骨骼的从模型局部坐标系到这根骨骼的TPOSE下的坐标系的转换矩阵(也被简单称为这根骨骼的绑定矩阵,它意味着把顶点从局部坐标变换到这根骨骼坐标系下面的坐标)。
Mm-n表示在m的父骨骼n的坐标系下,m骨骼在此运动帧相对于TPOSE时的运动,因此M1-2 * MBind1 * PLT就相当于将局部坐标系TPOSE下的一个模型点变换到了它的父骨骼坐标系下此帧时的坐标。
这样级联的网上乘,最终得到了这个运动帧下这个顶点在局部坐标系下的位置。
我们可以把Mroot-local ..*M2-3 * M1-2 * MBind1 用一个矩阵Mf来表示,即Pl = Mf1*PLT + Mf2*PLT+... 。
这个Mf就是在第f帧,将模型的TPOSE的局部坐标转变为此时姿态的局部坐标的转换,更简洁的说,这个Mf就是第f帧的运动变换矩阵,知道了这个Mf,我们就可以方便的将任意顶点进行动画驱动。
由于通常一个顶点会被很多根骨骼影响,例如两个手指间的某个顶点会同时受到两根甚至三根骨骼影响,所以这里要后面再加几根骨骼的影响,不过通常对于效率考虑,引擎会限制收影响的骨骼根数,如1,2或4等。
 

纯CPU Skin:
通常CPU Skin的做法就是,在CPU内实时的计算上面的运动矩阵,然后循环的对每一个顶点进行矩阵相乘,然后在进行必要的融合等高级动作处理技术得到最终这个顶点的局部坐标,传给gpu。
显然从性能上,CPU要每帧去计算每根骨头的变换矩阵,优化后是O(N)次矩阵乘法(N是骨骼数量),然后再进行顶点蒙皮在进行O(v)次矩阵乘法(v是顶点数量),这里面最容易称为瓶颈的是后者,因为场景的角色顶点量经常是数以万计的。
 

Unity的内置GPU Skin:
Unity内置的GPU Skin做法为了不影响用户的vs的书写以及兼容复杂的animator机制,因此做了一套半GPU Skin的方法。它利用了现代硬件API所具有的一些transform feed back这种机制,骨骼变换矩阵这里还是每一帧在CPU上做,但是蒙皮那里放到GPU上,然后蒙皮之后利用transform feed back得到蒙皮后的顶点位置,再次传入用户的vs,或者在CPU内进行一些融合等操作。
这种做法还是需要每帧去计算骨骼变换矩阵(这个开销不大),节省了Skin,但是它要多走一次客户的vs处理,并且如果用到cpu内的复杂动作处理的话,还涉及到将vertex buffer从GPU到CPU之间的传递。
 

纯GPU Skin:
由于上文的Pl = Mf1*PLT,我们预先保存每个骨骼在每一帧的Mf1。我们将这些变换矩阵伪装成一个贴图传递给显卡,然后只要将TPOSE的VBO和这张贴图给显卡,上面的蒙皮过程就完全在显卡计算了,先根据当前的帧和骨骼sample贴图获取这个矩阵m,然后做矩阵变换进行蒙皮,然后走其他的vs处理。
我们知道这个pose变换矩阵由4*4=16个float组成(其实去掉最后一列的其次化表示是3*4),而对于RGBfloat这样的贴图格式,一个像素可以存储3个float,这样我们就可以用4个像素去表示一个数组。我们可以按照我们自己定义的顺序,预先将一个角色的每一个动作的每一帧的每一个骨骼的转换矩阵用这4个像素排布在这张图上,就等于我们用一张图而不是一些animationclip来存储了这个角色的所有动作。
 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPU Instancer is an out of the box solution to display extreme numbers of objects on screen with high performance. With a few mouse clicks, you can instance your prefabs, Unity terrain details and trees. GPU Instancer provides user friendly tools to allow everyone to use Indirect GPU Instancing without having to go through the deep learning curve of Compute Shaders and GPU infrastructure. Also, an API with extensive documentation is provided to manage runtime changes. --------------------------------- Features --------------------------------- - Out of the box solution for complex GPU Instancing. - VR compatible. Works with both single pass and multipass rendering modes. - Mobile compatible. Works with both iOS and Android. - Easy to use interface. - Tens of thousands of objects rendered lightning fast in a single draw call. - GPU frustum culling. - GPU occlusion culling (non-VR platforms only). - Automatically configured custom shader support - Complex hierarchies of prefabs instanced with a single click. - Multiple sub-meshes support. - LOD Groups and cross-fading support (with animation or fade transition width). - Automatic 2D Billboard generation system (auto-added as last LOD). - Shadows casting and receiving support for instances (frustum culled instances still can cast shadows). - Unity 5.6 support. - Well documented API for procedural scenes and runtime modifications (examples included). - Example scenes that showcase GPU Instancer capabilities. Prefab Instancing Features: - Ability to automatically instance prefabs at your scene that you distribute with your favorite prefab painting tool. - Automatically Add-Remove prefab instances without any aditional code. - Automatic detection and updating of transform position, rotation and scale changes. - Full or area localized rigidbody and physics support. - Add-Remove-Update prefab instances with or without instantiating GameObjects (examples included). - Instance based material variations through API (similar to Material Property Blocks). - Enabling and disabling instancing at runtime per instance basis. - API to manage instanced prefabs at runtime. - Includes mobile demo scene with custom controllers. Detail Instancing Features: - Dense grass fields and vegetation with very high frame rates. - Included vegetation shader with wind, shadows, AO, billboarding and various other properties. - Support for custom shaders and materials. - Cross quadding support: automatically turns grass textures to crossed quads. - Ability to paint prefabs with custom materials on Unity terrain (with Unity terrain tools). - Ability to use prefabs with LOD Groups on Unity terrain. - Further performance improvements with automatic spatial partitioning. - API to manage instanced terrain detail prototypes at runtime (examples included). - Editor GPU Instancing simulation. Tree Instancing Features [BETA]: - Dense forests with very high frame rates. - Speed Tree support with wind animations. - Included billboard baker and renderers. - Custom vertex color wind animation support for Soft Occlusion Tree shaders. Third Party Integrations: - Gaia integration. - Map Magic integration. Planned Features: - Tree Creator support with wind animations (a limited version is currently available). - Support for animation baking and skinned mesh renderers. Requirements: - DirectX 11 or DirectX 12 and Shader Model 5.0 GPU (Windows, Windows Store) - Metal (macOS, iOS) - OpenGL Core 4.3 (Windows, Linux) - Vulkan (Android, Windows, Linux) - OpenGL ES 3.1 (Android 8.0 Oreo or later) - Modern Consoles (PS4, Xbox One) To provide the fastest possible performance, GPU Instancer utilizes Indirect GPU Instancing using Unity's DrawMeshInstancedIndirect method and Compute Shaders. GPU Instancing results in magnitudes of performance improvement over static batching and mesh combining. Also, other available solutions for GPU Instancing (including Unity's material option and the DrawMeshInstanced method) fail short on limited buffer sizes and therefore result in more draw calls and less performance. By using the indirect method GPU Instancer aims to provide the ultimate solution for this, and increases performance considerably while rendering the same mesh multiple times. For more Information: Getting Started API Documentation

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值