/images/avatar.png

Papalqi

arkit动画模型规范

arkit动画模型规范 Neutral-静态的pose 一.创建Blendshape 曲线 苹果通过ARKit面部捕捉技术,提供开发者使用iphoneX以上的机器的前置摄像头,实现面部捕捉。blendshape名称是写死的,总共51个blendshape我们需要去实现,不过我们可以实现一些而不是全部。强烈建议的是,命名和功能需要保持一致。所有的值是在0-1之间. eyeBlinkLeft eyeLookDownLeft eyeLookInLeft eyeLookOutLeft eyeLookUpLeft eyeSquintLeft eyeWideLeft eyeBlinkRight eyeLookDownRight eyeLookInRight eyeLookOutRight eyeLookUpRight eyeSquintRight eyeWideRight jawForward jawRight jawOpen mouthClose mouthFunnel mouthPucker mouthLeft mouthRight mouthSmileLeft mouthSmileRight mouthFrownLeft mouthFrownRight mouthDimpleLeft mouthDimpleRight mouthStretchLeft mouthStretchRight mouthRollLower mouthRollUpper mouthShrugLower mouthShrugUpper mouthPressLeft mouthPressRight mouthLowerDownLeft mouthLowerDownRight mouthUpperUpLeft mouthUpperUpRight browDownLeft browDownRight browInnerUp browOuterUpLeft cheekSquintRight noseSneerLeft noseSneerRight eyeBlinkLeft ;eyeLookDownLeft ;eyeLookInLeft eyeLookOutLeft eyeLookUpLeft eyeSquintLeft eyeWideLeft eyeBlinkRight eyeLookDownRight eyeLookInRight eyeLookOutRight eyeLookUpRight eyeSquintRight eyeWideRight jawForward jawLeft jawRight jawOpen mouthClose mouthFunnel mouthPucker mouthLeft mouthRight mouthSmileLeft mouthSmileRight mouthFrownLeft mouthFrownRight mouthDimpleLeft mouthDimpleRight mouthStretchLeft mouthStretchRight mouthRollLower mouthRollUpper mouthShrugLower mouthShrugUpper mouthPressLeft mouthPressRight mouthLowerDownLeft mouthLowerDownRight mouthUpperUpLeft mouthUpperUpRight browDownLeft browDownRight browInnerUp browOuterUpLeft browOuterUpRight cheekPuff cheekSquintLeft cheekSquintRight noseSneerLeft noseSneerRight 二.

UE4动画系统源码剖析

动画基础概念 3D模型动画的基本原理是让模型中各顶点的位置随时间变化。主要种类有Morph(变形)动画,关节动画和骨骼蒙皮动画(SkinnedMesh)。 (自己搭的blog被黑了,只有本地备份,太伤了,所以文章会有一些格式问题) 从动画数据的角度来说,三者一般都采用关键帧技术,即只给出关键帧的数据,其他帧的数据使用插值得到。但由于这三种技术的不同,关键帧的数据是不一样的。 Morph(渐变,变形)动画是直接指定动画每一帧的顶点位置,其动画关键中存储的是Mesh所有顶点在关键帧对应时刻的位置。 关节动画的模型不是一个整体的Mesh,而是分成很多部分(Mesh),通过一个父子层次结构将这些分散的Mesh组织在一起,父Mesh带动其下子Mesh的运动,各Mesh中的顶点坐标定义在自己的坐标系中,这样各个Mesh是作为一个整体参与运动的。动画帧中设置各子Mesh相对于其父Mesh的变换(主要是旋转,当然也可包括移动和缩放),通过子到父,一级级的变换累加(当然从技术上,如果是矩阵操作是累乘)得到该Mesh在整个动画模型所在的坐标空间中的变换(从本文的视角来说就是世界坐标系了,下同),从而确定每个Mesh在世界坐标系中的位置和方向,然后以Mesh为单位渲染即可。关节动画的问题是,各部分Mesh中的顶点是固定在其Mesh坐标系中的,这样在两个Mesh结合处就可能产生裂缝。 第三类就是骨骼蒙皮动画即SkinnedMesh了,骨骼蒙皮动画的出现解决了关节动画的裂缝问题,而且效果非常酷,发明这个算法的人一定是个天才,因为SkinnedMesh的原理简单的难以置信,而效果却那么好。骨骼动画的基本原理可概括为:在骨骼控制下,通过顶点混合动态计算蒙皮网格的顶点,而骨骼的运动相对于其父骨骼,并由动画关键帧数据驱动。一个骨骼动画通常包括骨骼层次结构数据,网格(Mesh)数据,网格蒙皮数据(skin info)和骨骼的动画(关键帧)数据。下面将具体分析。 SkinnedMesh中文一般称作骨骼蒙皮动画,正如其名,这种动画中包含骨骼(Bone)和蒙皮(Skinned Mesh)两个部分,Bone的层次结构和关节动画类似,Mesh则和关节动画不同:关节动画中是使用多个分散的Mesh,而Skinned Mesh中Mesh是一个整体,也就是说只有一个Mesh,实际上如果没有骨骼让Mesh运动变形,Mesh就和静态模型一样了。 Skinned Mesh技术的精华在于蒙皮,所谓的皮并不是模型的贴图(也许会有人这么想过吧),而是Mesh本身,蒙皮是指将Mesh中的顶点附着(绑定)在骨骼之上,而且每个顶点可以被多个骨骼所控制,这样在关节处的顶点由于同时受到父子骨骼的拉扯而改变位置就消除了裂缝。 Skinned Mesh这个词从字面上理解似乎是有皮的模型,哦,如果贴图是皮,那么普通静态模型不也都有吗?所以我觉得应该理解为具有蒙皮信息的Mesh或可当做皮肤用的Mesh,这个皮肤就是Mesh。 而为了有皮肤功能,Mesh还需要蒙皮信息,即Skin数据,没有Skin数据就是一个普通的静态Mesh了。 Skin数据决定顶点如何绑定到骨骼上。顶点的Skin数据包括顶点受哪些骨骼影响以及这些骨骼影响该顶点时的权重(weight),另外对于每块骨骼还需要骨骼偏移矩阵(BoneOffsetMatrix)用来将顶点从Mesh空间变换到骨骼空间。在本文中,提到骨骼动画中的Mesh特指这个皮肤Mesh,提到模型是指骨骼动画模型整体。骨骼控制蒙皮运动,而骨骼本身的运动呢?当然是动画数据了。 每个关键帧中包含时间和骨骼运动信息,运动信息可以用一个矩阵直接表示骨骼新的变换,也可用四元数表示骨骼的旋转,也可以随便自己定义什么只要能让骨骼动就行。除了使用编辑设定好的动画帧数据,也可以使用物理计算对骨骼进行实时控制。 线性混合蒙皮算法 在骨骼动画的蒙皮算法中,出现最早、最经典,也是应用最为广泛的算法是线性混合蒙皮算法。 根据骨骼动画的基本原理,动画模型之所以能够运动,是由于其骨骼带动了蒙在骨骼之上的皮肤一同动作,实现了动画效果。因此,因首先设置好模型骨架以及各骨骼之间的关联性,当运动数据到来时,计算皮肤顶点的新位置,就可以完成模型的运动。 黑色与白色的皮肤顶点分别与其相同颜色的骨骼相绑定。 方框里的皮肤顶点离两个骨骼关节最近,它们同时受到两个骨骼关节的影响。当骨架运动的时候,对于这些受多个骨骼共同影响的皮肤顶点,我们要计算它们变换后的位置信息,即找到皮肤网格自动变形后的方法,传统一般采用线性混合蒙皮算法。线性混合蒙皮算法是由 Lander 最早提出并实现的一种柔性绑定算法。Lander 利用线性混合蒙皮算法实现了人体上臂的动画,解决了之前的刚性绑定算法在关节处的失真问题。该算法的基本原理可以用下列公式表示 V表示顶点变换前的世界坐标系中的位置,V’表示顶点变换后的位置,i 表示同时影响该顶点的骨骼数量,一般取 2-4 之间的值。W_i表示第 i 个骨骼对该顶点的施加的影响权重,取 0-1 之间的值,M_i表示在模型初始参考姿势下,与顶点相关的第 i 个骨骼由本地坐标转换为世界坐标的转换矩阵(即骨骼变换的绝对矩阵),通过矩阵M_i能将骨骼 i 从初始位置转换到动画数据来到时的新位置上. 综上所述,线性混合蒙皮算法即是求得一个顶点在每个骨骼影响下的一系列新的位置,然后对这些位置数据进行加权平均计算得到最后的结果。 在线性混合蒙皮算法中,顶点的新位置 V′是通过其初始位置V 乘以一个矩阵 C 得到,这个矩阵被称为变换矩阵。  我们可以使用 OFFSET(偏移)的 3 个量来表示子关节相对父关节的偏移量;用 CHANNELS 来表示关节旋转通道数量和旋转顺序,其中根关节有6个通道,其他关节有3个通道,与根关节相比少了XYZ的位置(position)信息,这是因为其他关节都可以根据相对其于父关节的偏移量计算坐标位置。 运动数据对应的是骨架信息中各关节点的层次数据,即CHANNELS 中 Zrotation Xrotation Yrotation 顺序的数据。对于子关节来说,平移信息存储在骨架信息的 OFFSET 中,旋转信息则来自于运动数据部分;对于根关节来说,平移量是 OFFSET 和运动数据部分中定义的平移量之和。要得到蒙皮所需的绝对变换矩阵,首先需要根据 BVH 文件中的旋转数据分别创建三个方向轴(Y 轴,X 轴,Z 轴)对应的旋转矩阵,然后将它们按顺序相乘得到矩阵R (也称相对矩阵): 绝对变换矩阵是由关节的相对矩阵乘上它的父关节的绝对矩阵得到的,其中,根关节的绝对变换矩阵就是它的相对矩阵。因此,根据骨架各关节之间的关系,可以计算出每一个关节的绝对变换矩阵,用来将关节的本地坐标变换为世界坐标。

UE4 lightmass数据流程

构建 在编辑器中,我们可以找到build的按钮,当然,我们这里讨论的并不是构建所有的东西,而仅仅讨论在构建灯光的时候。关于构建参数,请参考光照设置 编辑器构建系统 当我们点击build的时候,我们将触发下面的函数, 1 2 3 4 5 6 7 FEditorBuildUtils::EditorBuild(); //其会调用StopRenderingThread(); if (GUseThreadedRendering) { StartRenderingThread(); } 其中,关于build的内容定义为 目前我们仅关心的是BUILDTYPE_Lighting,看buildLighting的分支 这里会对BSP进行特殊处理,如果场景中没有BSP的话,我们就不需要进行 geometryrebuild。之后,我们会进行BuildLighting。 我们看一下传入的数据LightingBuildOptions的填充,其是取的config里面的数据 在这里,收前强制关闭所有的texture property windows,因为这些在构建灯光时是无效的。 之后有一个回调这个目前来看并没有东西,我们暂且先不去管他。 建立构建系统 首先FStaticLightingManager,其为单例模式,用来进行管理静态光照的所有系统和子系统。其只是一个管理功能,而不是一个真正的执行build的类。 其最开始的入口就是CreateStaticLightingSystem。如果目前已经有了StaticLightingSystems那么会发生警告说 如果目前没有残存的余孽的话,我们会有进行接下来的流程。这里会有一个逻辑,如果我们的配置中没有选择bOnlyBuildVisibility,也就是是由只是构建可见的,其会在结束后build ReflectionCaptures。 之后,对整个world的所有level进行判断,看是否有lighting scenario,这个概念是说同一个level可以有不同的光照图。这里是说,这个level是否是一个lightingscenario。 我们会把需要构建的level进行添加,如果我们对应的level,我们添加空的。 我们会将每一个level添加入FStaticLightingManager内部中的真正处理的类为StaticLightingSystem其进行处理的单元是一个level,这从它的构造函数可以很明显的看出来。 在FStaticLightingManager中有一个针对class FStaticLightingSystem*的指针。 之后获取列表中StaticLightingSystems的指针,然后进行真正的构建,BeginLightmassProcess,如果成功,SendProgressNotification进行显示,如果失败DestroyStaticLightingSystems通知显示。 每一个level的构建 因此,我们进入FStaticLightingSystem,来进行每一个level的构建 初始化。对所有的UPrimitiveComponent,里面的VisibilityId进行赋值INDEX_NONE初始化。对所有的level,如果不是当前的PersistentLevel,那就FindStreamingLevel。并且在设置中,会有设置,如是否只build CurrentLevel,bOnlyBuildSelectedLevels等会有不同的变化。那些被Skipped的Levels会被收集。这里还会有TextureStreaming的配置的搜集。在进行load一些其他的LoadGlobalIniFile里面的东西。 收集灯光,剔除所有的AGeneratedMeshAreaLight(在逻辑上是自发光物体)。搜集场景中所有的ULightComponentBase存储在TArray Lights; 收集mesh,Gather static lighting info from BSP.Gather HLOD primitives Gather static lighting info from actors.Recurse through HLOD trees, group actors and calculate child ranges。

UE4光照单位与基于物理的灯光

丑话说在前面,基于物理的灯光参数有没有用呢?看如何对待,如果我只要效果,你如何进行灯光的调节只要最后好看,就没有问题;但是如果我们想要一个能够复用的灯光资源库,这就是一个非常好的一种方法。现在来说等白嫖(别人把理论研究清楚,因为现在还没有基于这种做法而商业成功的项目)而不是自己去研究是一个非常务实的想法。 在unreal中如果我们把灯光值调到和现实中一致的单位,默认情况下一定是曝光过度。这是因为我们的EV值。因为引擎中的成像原理和现实中的相机的一致。EV值代表的是快门,光圈,ISO的组合结果。 我们为什么要基于物理照明? 基于物理的光照使我们能够根据实际值为场景设置基础的光照,并且即使稍后能调整它也能表现很好。如果你的场景拥有截然不同的光源。一个简单的例子是一个场景,有太阳,也有一些人造光,如灯或火把。一个天真的方法,也就是经常采用的方法就是让太阳比灯强四倍,如果经过调整,可能看起来合理。但是,请考虑您决定在场景中再添加五盏灯。这可能会摒弃你的太阳和灯之间的微弱人工平衡,需要重新调整。每当变量快速变化时,这种不断调整会耗费大量时间并导致大量冗余工作。当然,问题是太阳的强度只比灯泡高四倍,这实际上是扯淡的。它比典型灯要大50-70倍。 Unreal 在4.19版本增加了基于物理的灯光参数。很多情况下我们都是结果导向的,所以用不用我们在值得商榷的,毕竟这个流程能够提升的东西并不是非常的多。唉,再说吧。 光学的定义 1.光强度(luminous intensity)是光源在单位立体角内辐射的光通量,以I表示,单位为坎德拉(candela,简称cd).1坎德拉表示在单位立体角内辐射出1流明的光通量. 2.光通量(luminous flus)是由光源向各个方向射出的光功率,也即每一单位时间射出的光能量,以φ表示,单位为流明(lumen,简称lm). 3.光照度(illuminance)是从光源照射到单位面积上的光通量,以E表示,照度的单位为勒克斯(Lux,简称lx). 坎德拉是基本单位,就是先定它,其他都是推导的。最初是用蜡烛来定义的。1948年第九届国际计量大会上决定采用处于铂凝固点温度的黑体作为发光强度的基准,同时定名为坎德拉,曾一度称为新烛光,1967年第十三届国际计量大会又对坎德拉作了更加严密的定义。由于用该定义复现的坎德拉误差较大,1979年第十六届国际计量大会决定采用现行的新定义。 所以,液晶屏单位是坎德拉,投影仪是使用的是流明.流明是1坎德拉的光源在单位立体角里放射的光通量。 换算体系: Candela= 0.09290304 Lux 日间场景 夜间场景 在夜间场景中,月亮是场景中的主要光源。使用完全逼真的月亮的亮度值会导致相当无聊的外观。考虑到月亮在晴朗的夜空中提供了大约0.25勒克斯的空间,与阳光提供的20,000 - 120,000勒克斯相比,这是一个绝对巨大的差距。 由于场景完全依赖于自然光线,这将意味着一个非常黑暗的场景。所以我们实际上在这种情况下增强了间接照明。话虽如此,我们在各种光源(月亮,天光等)上均匀地增强了照明,使它们的相对关系保持完整。这是使用现实价值观的真正要点 , 不是教条地坚持它们,而是提供一个坚实的基础,从而以足够灵活的方式调整和实现你的艺术目标,以便将来修改。

Lighting系列1

UE4 Lighting系列1 光照基础 UE4中的所有光源都是通过lightmass和直接照明两种方式作用于物体。同时灯光分直接光和间接光。 各种灯光的Movable和Stationary类型都会对物体产生直接光照明。所有Static类型灯光,自发光材质物体以及Stationary经过lightmass后会对物体产生间接光照明。反射也是一种间接光照明(动态天光产生的天光反射属于直接光)。 如果场景中拥有这两种光照类型,那么我们就说这是全局光照。在默认情况下,光源都是设置为全局光照。 虚幻引擎的间接光照是通过lightmass生成lightmap来完成的 1.1 Direct Light 直接从光源所在处打出射线进行计算,对于有光源半径的光而言会多做一些计算。 直接光都是动态光,可以实时变化颜色,亮度等等 1.2 Indiret Light 间接光照的计算核心是光子映射算法. 所有的间接光都是静态光,但我们仍然可以通过后期以及材质来模拟的实时调整间接光的颜色和亮度。 1.2.1Lightmass Lightmap为HDR,存有灯光方向信息。UE4使用Lightmass对光照进行预计算,以节省动态光照计算的成本。Stationary light build完灯光后还有Shadowmap,如果有Stationary天光会有sky occlusion map(Bent normal信息)。 材质,物体,灯光,后期都可以控制Lightmass。 1.2.1.1Lightmass的设置 最主要的两个参数: Static Lighting Level Scale Indirect Lighting Quality 对时间的影响 Lightmass portal提高lightmap的品质 Light Scenarios提供静态光变化的可能性 1.2.1.2光照贴图需要注意以下问题: 不要有重叠的部分 不要超过0~1的UV空间 Flag-Mapping并不是最好的方式且经常导致光照贴图错误 尽量占满UV空间 如果模型很大而且复杂,最后分成数个物体,这样也能有助于裁剪等机制 尽量减小光照贴图分辨率以减少贴图尺寸 相互不接触的线之间要保持至少2像素的距离,以防止光照污染 展UV的时候注意Min Lightmap resolution, 定义了UV块之间的距离。这个值要小于等于lightmap resolution,否则会出现lightmap像素无法匹配而溢出的问题。 1.2.2ILC (indirect light cache间接光缓存) ILC是对动态物体进行间接光的

UE4制作材质和打光前的准备——lookdev

为什么我们需要LookDev 我们在工作中多数情况都是分工合作,把比较大的资源拆分开来给不同的人员进行制作,最后每个人对资源进行提交审核并组合到一起。因为资源要求统一,所以正常来说每个人提交的资源表现效果应该基本一致,但是因为制作环境的不同,可能会导致单独渲染出来的图差异不大,但是将两个资源放在同一个光照环境下却效果差异很大的情况。 那我们该怎么杜绝这种情况的发生呢?这就是lookdev环节存在的重要意义之一了。我们先聊聊LookDev在CG流程的哪个环节,以及主要内容吧。“Lookdev,或者Look Development这项工作一般会在模型贴图和灯光之间。一般规模大一些的工作室部门分工比较详细,会有专门的lookdev部门。有些公司是灯光部门的人负责lookdev,也有些公司是贴图部门负责lookdev。但是不管有没有这个部门, lookdev这个步骤是不能少的。 简单来说 lookDev的一个主要内容就是让不同人员制作的不同资产在统一光照环境下有统一的表现效果。 好的HDR贴图 1、要有一个相对明确的光源,这样能更准确的体现出模型的高光情况。 2、明暗交界比较清晰,使模型结构清晰不显得平。 3、光照也没有过于死黑的地方。 上图中,虽然光照比较均匀,但是光源不明确,无法产生准确的高光,会让人感觉整个材质是无高光的,但实际上模型是有较强反射存在的。但是实际使用中,还是要根据项目情况以及项目风格来确定一个项目统一的HDR贴图。 unreal能借鉴的技术 中灰球、镜面球和色卡主要作用就是做绝对的参考。就像做实验一样,制作cg内容也需要控制变量才能确保资产质量的统一,和材质的准确度。通常实景拍摄和素材拍摄的时候也会拍摄当场的球和色卡。进入后期制作时会用色卡统一较对一切内容,确保从贴图到lookdev到灯光渲染 所有人的参考图和素材等等颜色一致。 一个灰球,一个全反射的金属球(铬球),以及一个标准色卡。这三个元素实际上不仅仅是再lookdev环节开始使用,而是基本上从贴图开始就会用到。从矫正贴图素材颜色,到lookdev做材质时的参考,再到灯光部门摆灯等等,都需要这些元素的参考。 灰球使用的参数是线性空间下的0.18,也就是SRGB下的0.5的中灰球,可以让我们比较方便的观察到光源方向以及强度。铬球是一个全反射金属材质,用来观察高光及反射的信息。 最后一个标准色卡,是用来协助我们对图像颜色进行校准,对图像进行标准校色使用的。我 如何打光在准备场景时 ![image5.png][5] 关闭自动曝光 (auto exposure) Guanbi SSAO和SSR 保持默认的tone mapper(色调映射) 关闭Vignetting 关闭bloom 建立两个材质球 第一个Chrome sphere ,第二个Gray 一般是使用一个灰球和一个铬球收集拍摄场景的全局光照信息。 灰球又叫diffuse ball,来判断全局的光照效果,主光方向,阴影的范围和暗度。我们特别熟悉的是50度灰,现在我们要再多记住一个值叫18度灰,为什么是18度。18%就是传说中人眼视觉中间调,定一个测光的标准。 反射光测光,通俗地讲就是在曝光补偿为±0的时候拍一张照片,然后将照片饱和度降到0,定义测光区域的输出总是和百分之十八的灰是一样的。 一米宽,10米厂的板子,最左边是100%反光的白,最右边是0%反光的黑,从左到右平均分11份,亮度依次90%,80%……递减。这样组成的板子和10米长的白板比,反射了其18%亮度的光线。 当拍摄场景很暗的时候,建议把灰球换成白球,因为光照不够的时候就,灰度球的漫反射信息是不够的。