<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【3D游戲基礎(chǔ)】蒙皮骨骼動(dòng)畫(huà)與骨架

          共 4666字,需瀏覽 10分鐘

           ·

          2022-12-30 09:01

          效果

          目標(biāo)!畫(huà)出蒙皮動(dòng)畫(huà)的骨架。
          7e48d3856bd2cc5291afcbf939992f0d.webp

          視頻

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

          PPT

          https://zfxdvouj61.feishu.cn/file/boxcnwgESO6zdQetO7oNhKboNsd
          以下為PPT文字稿,建議還是看視頻

          講講自己對(duì)蒙皮骨骼動(dòng)畫(huà)的理解,并在 Cocos Creator 3.6 中繪制出骨架~希望對(duì)大家有幫助~

          6a6f90e62150d0463ecb6784bbb51fae.webp

          這是我們今天實(shí)現(xiàn)效果,在 Cocos Creator 中把骨架畫(huà)出來(lái),圖中綠色的線(xiàn)就是繪制的骨架

          7e48d3856bd2cc5291afcbf939992f0d.webp

          在開(kāi)始之前,我們介紹一下如何導(dǎo)入模型?長(zhǎng)按3d資源拖入到資源管理器中.

          bc15f04490782503b3bfe5721c8601fb.webp

          讓我們看看gltf資源包括什么(介紹最下方),mesh 網(wǎng)格,texture 貼圖,material 材質(zhì),animation 動(dòng)畫(huà) ,skeleton 骨架數(shù)據(jù)。根節(jié)點(diǎn)有個(gè)動(dòng)畫(huà)組件,cips是動(dòng)畫(huà)列表,default clip 是默認(rèn)動(dòng)畫(huà), play on load 是加載后自動(dòng)播放。Sockets 是掛點(diǎn)系統(tǒng)。啟用 useBakedAnimation 時(shí)會(huì)使用預(yù)烘焙骨骼動(dòng)畫(huà)系統(tǒng)(所有動(dòng)畫(huà)數(shù)據(jù)都會(huì)按照指定幀率提前預(yù)采樣、烘焙到全局復(fù)用的骨骼動(dòng)畫(huà)貼圖合集上),禁用 useBakedAnimation 后會(huì)使用實(shí)時(shí)計(jì)算骨骼動(dòng)畫(huà)系統(tǒng)(動(dòng)畫(huà)數(shù)據(jù)會(huì)輸出到場(chǎng)景的骨骼節(jié)點(diǎn)樹(shù)中)。

          1b19f287d1dcb736443079788bfcf44d.webp

          mesh 就是網(wǎng)格,由三角形拼成的網(wǎng)格,可以看到這個(gè)網(wǎng)格有7325個(gè)頂點(diǎn),和11186個(gè)三角形,minpos 就是包圍盒最小值, maxpos 就是包圍盒最大的值

          cdda2b0f85d7021cd43efe7f11419a40.webp

          關(guān)于網(wǎng)格,這張圖會(huì)看的清楚一點(diǎn),由多個(gè)三角形構(gòu)成。

          a56ddf96ad6907105f21e6198bf72dba.webp

          材質(zhì)就像是給剛才的網(wǎng)格穿上的衣服,貼圖就像是衣服上好看的圖案

          b4b75eeebd84b36c0aa5c0f37f38fe49.webp

          可以在這個(gè)模型上看到貼圖的部件,是通過(guò)紋理映射的方式顯示這張圖片。例如手套映射到貼圖的右下角。

          da41d4baba2154f5a4defad95fbc9c8b.webp

          還有一種常見(jiàn)的貼圖叫法線(xiàn)貼圖,簡(jiǎn)單來(lái)說(shuō)這張貼圖可以讓模型更有凹凸感

          397b52840ccabc41389ede30ff2713aa.webp

          骨架,就像是人體的骨骼一樣。蒙皮,蒙的就是網(wǎng)格相對(duì)于骨架的位置

          cd676a1a399e0e6597017078a8ac6f03.webp

          事實(shí)上,在實(shí)現(xiàn)中并沒(méi)有骨架,并不是一條一條的線(xiàn),而是一個(gè)一個(gè)的點(diǎn)。叫做關(guān)節(jié)或者說(shuō)骨骼點(diǎn)。蒙皮就是根據(jù)根據(jù)這個(gè)點(diǎn),計(jì)算網(wǎng)格點(diǎn)的位置。

          6e268b315d0093dac01409d81150c66a.webp

          選中場(chǎng)景中的3d模型,點(diǎn)擊動(dòng)畫(huà)編輯器,進(jìn)入動(dòng)畫(huà)編輯模式。可以預(yù)覽動(dòng)畫(huà)效果。

          168b8d336d2be566b00891cd132408a0.webp

          點(diǎn)擊播放按鈕就可以播放了。可以看到右上角的屬性面板并沒(méi)有變化,那么這個(gè)動(dòng)畫(huà)是移動(dòng)的是什么呢?

          9d019a3824f3bb6a1c296090ed153f37.webp

          前面幾個(gè)點(diǎn)的 postion rotation 并沒(méi)有發(fā)生變化

          f0ca2ea8bb0ccb2fc2def6c48acecca1.webp


          可以看到后面幾個(gè)點(diǎn)位移旋轉(zhuǎn)發(fā)生了變化,這些點(diǎn)就是骨骼(關(guān)節(jié))。蒙皮動(dòng)畫(huà)的本質(zhì)是改變骨骼的節(jié)點(diǎn)信息,網(wǎng)格再根據(jù)骨骼點(diǎn)實(shí)時(shí)計(jì)算網(wǎng)格的形狀。

          2a7b9738a93089c6863470a5e08f80ad.webp

          材質(zhì),網(wǎng)格,骨架是由蒙皮網(wǎng)格渲染器(skinmeshrenderer) 組織在一起。

          6e8087b1d4e546959d92e4a0026a65fd.webp

          總結(jié)一下,一個(gè)3d資源拖入到場(chǎng)景中的結(jié)構(gòu)是怎么樣的。根節(jié)點(diǎn)有一個(gè)骨骼動(dòng)畫(huà)組件。他的兒子中包含了骨骼蒙皮渲染組件(將材質(zhì),網(wǎng)格,骨骼組織在一起)。還有種兒子是骨骼(關(guān)節(jié)),蒙皮動(dòng)畫(huà)實(shí)際上是對(duì)這些骨骼點(diǎn)進(jìn)去移動(dòng)旋轉(zhuǎn),然后網(wǎng)格再根據(jù)這個(gè)點(diǎn)的信息,再計(jì)算網(wǎng)格的形狀(蒙皮)。

          904beb6f2e7c43048a6ecc54020d17d3.webp

          了解了上面的知識(shí),我們現(xiàn)在開(kāi)始實(shí)戰(zhàn)吧。我們的目標(biāo)是畫(huà)出這個(gè)骨骼!

          cc15e6e3a91de30f9d353dd656d704c1.webp

          我們?cè)撊绾卫L制骨架呢?只要在這些骨骼點(diǎn)和其父節(jié)點(diǎn)畫(huà)一條線(xiàn)就行了。

          e4f47f8a2b403d62afc42399cc2e4775.webp

          我們要畫(huà)的是這些骨骼,這些骨骼的數(shù)據(jù)應(yīng)該在哪里獲取呢?是的,就在骨架數(shù)據(jù)中獲取,骨架數(shù)據(jù)就是在蒙皮網(wǎng)格渲染器中。

          486cc07ec347e415da32e08cbbbb00d3.webp

          model 就是對(duì)應(yīng)這初始節(jié)點(diǎn)。先拿到蒙皮網(wǎng)格渲染器的組件,找到骨架數(shù)據(jù),再找到骨骼點(diǎn),并做上標(biāo)記。最后再遞歸按深度優(yōu)先的順序把所有骨骼點(diǎn)保存起來(lái)。這個(gè)bones就是所有的關(guān)節(jié)點(diǎn)了。

          6ad134f40d011fe30c38b46d7e3c11b7.webp

          那么我們應(yīng)該用什么組件畫(huà)骨架呢?這里用了 Cocos Creator 的線(xiàn)段組件。對(duì)有爸爸的骨骼們創(chuàng)建線(xiàn)段組件。把每個(gè)骨骼和他爸爸的世界坐標(biāo)告訴線(xiàn)段組件,就能畫(huà)出骨架了。

          59fd15c48fc031717eac24174187f2f6.webp

          還需要注意的是,要想把這東西畫(huà)到最前!需做到 透 深 優(yōu)!透是指透明渲染隊(duì)列。在 Cocos Creator 默認(rèn)的前向渲染管線(xiàn)中,是先渲染不透明隊(duì)列再渲染透明隊(duì)列。選擇透明隊(duì)列就可以再更后的階段繪制。深 指的是 深度讀寫(xiě)都關(guān)閉,深度寫(xiě)是影響之后東西的繪畫(huà),深度讀是只被之前繪畫(huà)的深度影響,當(dāng)然我們都不想影響就都關(guān)了。優(yōu) 是只 優(yōu)先級(jí),要在最后畫(huà)!

          1467eabdd022dae8233ed195b07def26.webp

          最后,介紹一下這個(gè)腳本怎么使用。將這個(gè)腳本拖入到場(chǎng)景中,再掛上場(chǎng)景中的3D模型就可以了。

          8abda8fa5a6920dfccda736f01215b5e.webp

          小結(jié)~ 1.動(dòng)畫(huà)驅(qū)動(dòng)骨骼 2.骨骼決定網(wǎng)格 3.畫(huà)最前,透深優(yōu)

          代碼
              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('歡迎關(guān)注微信公眾號(hào)【白玉無(wú)冰】 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[]
          }
          }
          }
          }
          視頻

          “點(diǎn)贊“ ”在看”?鼓勵(lì)一下11375fa0e5e0a7f8a69c83a22d4853db.webp

          瀏覽 48
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天爱天天干天天 | AV一区波多野结衣 | 欧美黄色日韩 | 青娱乐国产在线视频 | 国产精品91福利 |