【3D游戏基础】蒙皮骨骼动画与骨架

news2025/2/25 11:57:52

效果

目标!画出蒙皮动画的骨架。
e9a6eceb1b848d67ed52b272a25518db.gif

视频

https://www.bilibili.com/video/BV1pM411m7Yw

PPT

https://zfxdvouj61.feishu.cn/file/boxcnwgESO6zdQetO7oNhKboNsd
以下为PPT文字稿,建议还是看视频

讲讲自己对蒙皮骨骼动画的理解,并在 Cocos Creator 3.6 中绘制出骨架~希望对大家有帮助~

917774a7dd4dc5621689d9c7c931f3b4.png

这是我们今天实现效果,在 Cocos Creator 中把骨架画出来,图中绿色的线就是绘制的骨架

e56cb73a7b2a86eea0bf849fdd0dceda.gif

在开始之前,我们介绍一下如何导入模型?长按3d资源拖入到资源管理器中.

3239e265fd9e9402f295dfbde7292a8b.png

让我们看看gltf资源包括什么(介绍最下方),mesh 网格,texture 贴图,material 材质,animation 动画 ,skeleton 骨架数据。根节点有个动画组件,cips是动画列表,default clip 是默认动画, play on load 是加载后自动播放。Sockets 是挂点系统。启用 useBakedAnimation 时会使用预烘焙骨骼动画系统(所有动画数据都会按照指定帧率提前预采样、烘焙到全局复用的骨骼动画贴图合集上),禁用 useBakedAnimation 后会使用实时计算骨骼动画系统(动画数据会输出到场景的骨骼节点树中)。

ca707008c5cd549a36973264d8b29e0b.png

mesh 就是网格,由三角形拼成的网格,可以看到这个网格有7325个顶点,和11186个三角形,minpos 就是包围盒最小值, maxpos 就是包围盒最大的值

5842f5d70503c8439e3d15405e3e3fdb.png

关于网格,这张图会看的清楚一点,由多个三角形构成。

6b0c57e8196eaadc7431f6e4a2b951dc.jpeg

材质就像是给刚才的网格穿上的衣服,贴图就像是衣服上好看的图案

284f11be6199e72ae57dd1544e99f154.png

可以在这个模型上看到贴图的部件,是通过纹理映射的方式显示这张图片。例如手套映射到贴图的右下角。

c134807ed053c57cbe6e381861689b75.png

还有一种常见的贴图叫法线贴图,简单来说这张贴图可以让模型更有凹凸感

b6a97462dfc8d34638893ee763579cfe.jpeg

骨架,就像是人体的骨骼一样。蒙皮,蒙的就是网格相对于骨架的位置

e5e97fbdbae56e3472480041d8fd8dd4.jpeg

事实上,在实现中并没有骨架,并不是一条一条的线,而是一个一个的点。叫做关节或者说骨骼点。蒙皮就是根据根据这个点,计算网格点的位置。

39ab4f246fe7a15a064281ad876cf365.jpeg

选中场景中的3d模型,点击动画编辑器,进入动画编辑模式。可以预览动画效果。

7180682665d56bdc694fa4aa74614510.png

点击播放按钮就可以播放了。可以看到右上角的属性面板并没有变化,那么这个动画是移动的是什么呢?

879ef2c77d288227ce1bc6925c64967f.gif

前面几个点的 postion rotation 并没有发生变化

0bafefe5144d13b6db1055eb77c48b4d.gif

可以看到后面几个点位移旋转发生了变化,这些点就是骨骼(关节)。蒙皮动画的本质是改变骨骼的节点信息,网格再根据骨骼点实时计算网格的形状。

fe8ff0417190695e2d4322a42633ff71.gif

材质,网格,骨架是由蒙皮网格渲染器(skinmeshrenderer) 组织在一起。

d73a57ac7ddc82a2944e4dada8c0e6f2.png

总结一下,一个3d资源拖入到场景中的结构是怎么样的。根节点有一个骨骼动画组件。他的儿子中包含了骨骼蒙皮渲染组件(将材质,网格,骨骼组织在一起)。还有种儿子是骨骼(关节),蒙皮动画实际上是对这些骨骼点进去移动旋转,然后网格再根据这个点的信息,再计算网格的形状(蒙皮)。

6b7e9e3db019a68c00c7a6fb4a7c5ab3.png

了解了上面的知识,我们现在开始实战吧。我们的目标是画出这个骨骼!

1e2b37159690a9552fef36a23ceea602.gif

我们该如何绘制骨架呢?只要在这些骨骼点和其父节点画一条线就行了。

4131ad1a5520e4169719b7a171bc35ee.gif

我们要画的是这些骨骼,这些骨骼的数据应该在哪里获取呢?是的,就在骨架数据中获取,骨架数据就是在蒙皮网格渲染器中。

7c4823de585afd63ab43de3f94043576.png

model 就是对应这初始节点。先拿到蒙皮网格渲染器的组件,找到骨架数据,再找到骨骼点,并做上标记。最后再递归按深度优先的顺序把所有骨骼点保存起来。这个bones就是所有的关节点了。

e5251098297954ac53753701cc7b7269.png

那么我们应该用什么组件画骨架呢?这里用了 Cocos Creator 的线段组件。对有爸爸的骨骼们创建线段组件。把每个骨骼和他爸爸的世界坐标告诉线段组件,就能画出骨架了。

4b7d2c3b3bf92d53e0187141d7abc445.png

还需要注意的是,要想把这东西画到最前!需做到 透 深 优!透是指透明渲染队列。在 Cocos Creator 默认的前向渲染管线中,是先渲染不透明队列再渲染透明队列。选择透明队列就可以再更后的阶段绘制。深 指的是 深度读写都关闭,深度写是影响之后东西的绘画,深度读是只被之前绘画的深度影响,当然我们都不想影响就都关了。优 是只 优先级,要在最后画!

82a858227f9b8fcb51d8ef04461ccca0.png

最后,介绍一下这个脚本怎么使用。将这个脚本拖入到场景中,再挂上场景中的3D模型就可以了。

3728f7cf6f77c73cf9194ffeff8339e5.png

小结~ 1.动画驱动骨骼 2.骨骼决定网格 3.画最前,透深优

b7683129c281f48730a950efeb269f3d.png

代码

import { _decorator, Component, Node, SkinnedMeshRenderer, Line, SkeletalAnimation, Color, gfx, GradientRange, log } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('SkeletonHelper')
export class SkeletonHelper extends Component {

    @property(Node)
    model: Node = null!

    private bones: Node[] = []
    private lines: Line[] = []

    start() {
        log('欢迎关注微信公众号【白玉无冰】 https://mp.weixin.qq.com/s/-I6I6nG2Hnk6d1zqR-Gu2g')
        const skeletalAnimation = this.model.getComponent(SkeletalAnimation)
        skeletalAnimation.useBakedAnimation = false; // maybe todo
        const skinMeshRds = this.model.getComponentsInChildren(SkinnedMeshRenderer)
        skinMeshRds.forEach(element => {
            const skinningRoot = element.skinningRoot
            element.skeleton.joints.forEach((v) => {
                const node = skinningRoot.getChildByPath(v)
                node['isBone'] = true;
            })
        });

        const bones = this.getBoneList(this.model);
        this.bones = bones;

        for (let i = 0; i < bones.length; i++) {
            const bone = bones[i];
            if (bone.parent && bone.parent['isBone']) {
                const line = this.addComponent(Line);
                const state = { priority: 255, depthStencilState: new gfx.DepthStencilState(false, false) }
                // @ts-ignore
                line._materialInstance.overridePipelineStates(state)
                line.worldSpace = true;
                line.width.constant = 0.01;
                line.color.mode = GradientRange.Mode.TwoColors //there are some bugs in cocos creator // engine\cocos\particle\models\line-model.ts   // engine\cocos\particle\animator\gradient.ts
                line.color.colorMin = Color.BLUE
                line.color.colorMax = Color.GREEN
                line.positions = [bone.worldPosition, bone.parent.worldPosition] as never[]
                this.lines.push(line)
            }
        }
    }

    showSkeleton(show: boolean) {
        this.lines.forEach(l => l.enabled = show)
    }

    private getBoneList(object: Node) {
        const boneList: Node[] = [];

        if (object['isBone']) {
            boneList.push(object);
        }

        for (let i = 0; i < object.children.length; i++) {
            boneList.push.apply(boneList, this.getBoneList(object.children[i]));
        }
        return boneList;
    }

    lateUpdate(deltaTime: number) {
        let lineIndex = 0;
        for (let i = 0; i < this.bones.length; i++) {
            const bone = this.bones[i];
            if (bone.parent && bone.parent['isBone']) {
                const line = this.lines[lineIndex++];
                line.positions = [bone.worldPosition, bone.parent.worldPosition] as never[]
            }
        }
    }
}

视频

2fd730477563a8c40cfc047c064b0d8c.jpeg

“点赞“ ”在看” 鼓励一下392048b3bf09888566afd6c2f328e199.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/118656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全志Tina Linux MPP (多媒体框架)开发指南支持百问网T113 D1-H哪吒DongshanPI-D1s V853-Pro等开发板

1 简述 整理 MPP sample 使用说明文档的目的是&#xff1a;使 MPP sample 更好用。 2 简介 MPP sample 一般存放在 MPP Middleware 的 sample 目录下。此外&#xff0c;MPP Framework 的 demo 目录下也有一些 sample。 本文档主要介绍 MPP Middleware 各 sample 的基本使用方…

【再学Tensorflow2】TensorFlow2的建模流程:疫情发展趋势分析

TensorFlow2的建模流程&#xff1a;疫情发展趋势分析时间序列简介基本概念平稳性白噪声随机游走&#xff08;Random Walk&#xff09;识别一个时间序列Augmented Dickey-Fuller Test(ADF)Kwiatkowski-Phillips-Schmidt-Shin Test(KPSS)时间序列模型预测准确度的衡量衡量预测准确…

舆情监测系统适用哪些行业,如何选择舆情监测系统?

当前&#xff0c;去网上搜索第三方舆情监测工具可以看到很多家不同公司的产品&#xff0c;比如TOOM舆情监测系统&#xff0c;那我们该如何选择舆情监测系统?舆情监测系统到底适用什么行业&#xff0c;带着这些疑问&#xff0c;接下来我们简单了解一下。 ​一、舆情监测系统适…

6.前端笔记-JS-流程控制

1、流程控制 通过控制代码的执行顺序实现我们要完成的功能。控制代码按照什么结构顺序执行 有三种结构&#xff1a;顺序结构、分支结构、循环结构 1.1 顺序流程控制 最简单、最基本的流程控制。程序按照代码的先后顺序&#xff0c;依次执行 1.2 分支流程控制 从上到下执行…

ArcGIS基础实验操作100例--实验8绘制中点连线

本实验专栏来自于汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a; 请访问实验1&#xff08;传送门&#xff09; 基础编辑篇--实验8 绘制中点连线 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

【操作系统】CPU平均负载和使用率

1.CPU的平均负载 &#xff08;1&#xff09;什么是CPU的平均负载 单位时间内系统处于【可运行状态】和【不可中断状态】的平均进程数&#xff0c;就是平均活跃进程数&#xff0c;和CPU使用率并没有直接关系 可运行状态 正在使用CPU或者正在等待CPU的进程用 ps aux命令看到的…

【OpenCV-Python】教程:9-1 级联分类器训练

OpenCV Python 级联分类器训练 【介绍】 使用增强的弱分类器级联包括两个主要阶段: 训练和检测阶段。使用基于HAAR或LBP模型的检测,在object detection tutorial中进行了描述。本文档概述了训练您自己的增强弱分类器级联所需的功能。当前的手册将走过所有不同的阶段: 收集训练…

机器学习-决策树算法原理及实现-附python代码

1.决策树-分类树 sklearn.tree.DecisionTreeClassifier官方地址&#xff1a; https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier 在机器学习中&#xff0c;决策树是最常用也是最强大的监督学…

用双因子认证2FA替换Google authenticator谷歌令牌,助力准上市公司实现等保安全审计

21世纪初&#xff0c;某人力资源科技公司试水HR SaaS赛道&#xff0c;以大客户为目标客群&#xff0c;持续深耕&#xff0c;稳扎稳打&#xff0c;如今已是一家专门为中大型企业提供一体化HR SaaS及人才管理产品/解决方案的头部企业。其产品覆盖了从员工招募、入职、管理到离职的…

Linux系统安装Mysql5.7(详解)

Linux系统上安装软件的3种方式&#xff1a; 本次使用二进制发布包安装方式安装Mysql5.7 &#xff08;一&#xff09;下载Mysql5.7的二进制包 这里可以选择去Mysql官网下载&#xff0c;但是由于服务在外国&#xff0c;下载速度实在是太慢了。这里我们可以选择去阿里云的镜像网…

数据通信基础 - 解调技术(PCM)

文章目录1 概述2 脉冲编码调制技术2.1 采样2.2 量化2.3 编码3 扩展3.1 网工软考真题1 概述 #mermaid-svg-K45XtgYRoAw04KU0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-K45XtgYRoAw04KU0 .error-icon{fill:#5522…

医疗影像工具LEADTOOLS 入门教程: 使用文档编写器创建文档 - 控制台 C#

LEADTOOLS是一个综合工具包的集合&#xff0c;用于将识别、文档、医疗、成像和多媒体技术整合到桌面、服务器、平板电脑、网络和移动解决方案中&#xff0c;是一项企业级文档自动化解决方案&#xff0c;有捕捉&#xff0c;OCR&#xff0c;OMR&#xff0c;表单识别和处理&#x…

【数据结构】Leedcode消失的数字(面试题)

目录 一、题目说明 二、题目解析 一、题目说明 题目链接: leetcode消失的数字 数组nums包含从0到n的所有整数&#xff0c;但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗&#xff1f; 示例1&#xff1a; 输入&#xff1a;[3,0,1] 输出&#x…

菜鸟也能懂的 - 音视频基础知识。

前言 说到视频&#xff0c;大家自己脑子里基本都会想起电影、电视剧、在线视频等等&#xff0c;也会想起一些视频格式 AVI、MP4、RMVB、MKV等等。 但是我们如果认真思考这些应该就有很多疑问&#xff0c;比如以下问题&#xff1a; mp4 和 mkv有什么区别 &#xff1f; 视频封装…

Lua基本数据类型

Lua官网文档入口 http://www.lua.org/ document --> manual 一、基本数据类型 lua 中有八种基本数据型&#xff0c;分别是&#xff1a; nil&#xff0c;boolean&#xff0c;number&#xff0c;string&#xff0c;function&#xff0c;userdata&#xff0c;thread 和 tab…

vue - - - - - vue-property-decorator的使用

哪有小孩天天哭&#xff0c;哪有赌徒天天输 。遇到不会的技术、知识点&#xff0c;看得多了&#xff0c;掉的坑多了&#xff0c;也就会了。 vue-property-decorator的使用1. 单文件组件写法 - Component的使用2. 组件内使用变量3. 使用计算属性 - get的使用4. 生命周期5. metho…

Nydus 镜像扫描加速

文&#xff5c;余硕上海交通大学22届毕业生阿里云开发工程师从事云原生底层系统的开发和探索工作。本文 6369 字 阅读 16 分钟GitLink 编程夏令营是在 CCF 中国计算机学会指导下&#xff0c;由 CCF 开源发展委员会&#xff08;CCF ODC&#xff09;举办的面向全国高校学生的暑期…

Java字符集编码解码详细介绍

文章目录字符集字符集的基本认识字符集编码和解码字符集 字符集的基本认识 字符集基础知识 计算机底层不可以直接存储字符的。计算机中底层只能存储二进制(0、1) 二进制是可以转换成十进制的 计算机底层可以表示十进制编号。计算机可以给人类字符进行编号存储&#xff0c;这套…

【进阶C语言】数据的存储形式

文章目录一.数据类型分类二.整形的存储形式1.源码&#xff0c;反码&#xff0c;补码的关系内存中数据的存储——二进制源码&#xff0c;反码&#xff0c;补码的关系正数负数三.大小端1.概念2.例题&#xff1a;判断当前编译器的存储形式四.浮点数的存储形式1.二进制的补充&#…

【k8s系列】kube-state-metrics中kube_endpoint_address指标

文章目录背景环境操作方法1&#xff1a;kube_endpoint_address_not_ready选择大于0的验证方式1验证方式2方法2&#xff1a;kube_endpoint_address_available选小于0的方法3&#xff1a;kube_endpoint_address{ready"false"}选大于0的解释参考author: ningan123date: …