unity - Blend Shape - 变形器 - 实践

这篇具有很好参考价值的文章主要介绍了unity - Blend Shape - 变形器 - 实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


目的

拾遗,备份


Blend Shape 逐顶点 多个混合思路

blend shape 基于: vertex number, vertex sn 相同,才能正常混合、播放
也就是 vertex buffer 的顶点数量一样,还有 triangles 的 index 要一致

这样 blend shape 才能逐个顶点计算

计算公式:使用一张大佬整理的图,大佬的文章:BlendShapes基础与拓展练习(面捕与物体变形)
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD


Blender

Shift+A 新建一个 sphere
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

选中

unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

Tab 进入 Editor Mode,并且在 Data 页签属性的 Shape Keys 添加对应的 blend shape 状态
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

调整好每一个 Shape Keys (或是叫:blend shape) 的顶点位置
然后再 Object Mode 下,我们可以选中对应的 Shape Keys 然后调整 value 查看变形结果
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

最终我们尝试 K帧动画来查看 多个 shape keys 混合控制的情况
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD


3Ds max

interlude _1 : working on Yui-chan’s face morphing. - 3Ds max 中的演示 二次元 脸部表情 FFD


Unity 中使用

先在 blender 导出 fbx
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

将 fbx 模型拖拽到 hierarchy
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

尝试拖拉 inspector 中的 blend shape 拉杆,即可查看效果
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

所以我们写脚本控制 blend shape 混合拉杆即可达到我们各种表情的混合控制
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

在原来 blendshape_1 基础上在混合 blendshape_2
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

blendshape_1 和 blendshape_2 一起播放
unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

然后可以尝试看一下 blendshape_1 和 blendshape_2 不同速率的控制混合的情况
这里使用 pingpong 算法

unity blendshape,DCC,TA - 加油站,unity,unity,blendshape,shapekeys,变形器,FFD

下面是测试 csharp 脚本

// jave.lin 2023/10/07 测试 blend shape

using System.Collections;
using UnityEngine;

public class TestingBlendShape : MonoBehaviour
{
    public SkinnedMeshRenderer skinnedMeshRenderer;
    private int _BlendShape_1_IDX = -1;
    private int _BlendShape_2_IDX = -1;

    private IEnumerator _couroutine_blendShape1;
    private IEnumerator _couroutine_blendShape2;
    private IEnumerator _couroutine_pingpong;

    private void OnDestroy()
    {
        StopAllCoroutines();
    }

    private void Refresh()
    {
        if (skinnedMeshRenderer != null)
        {
            _BlendShape_1_IDX = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("BlendShape_1");
            _BlendShape_2_IDX = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("BlendShape_2");
        }
    }

    public void ToBlendShape_1()
    {
        Refresh();

        if (_couroutine_blendShape1 != null)
        {
            StopCoroutine(_couroutine_blendShape1);
        }
        StartCoroutine(_couroutine_blendShape1 = Play_ToBlendShape(_BlendShape_1_IDX, 100.0f));
    }

    public void ToBlendShape_2()
    {
        Refresh();

        if (_couroutine_blendShape2 != null)
        {
            StopCoroutine(_couroutine_blendShape2);
        }
        StartCoroutine(_couroutine_blendShape2 = Play_ToBlendShape(_BlendShape_2_IDX, 100.0f));
    }

    public void ToBlendShape_1_2()
    {
        Refresh();

        if (_couroutine_blendShape1 != null)
        {
            StopCoroutine(_couroutine_blendShape1);
        }
        StartCoroutine(_couroutine_blendShape1 = Play_ToBlendShape(_BlendShape_1_IDX, 100.0f));
        if (_couroutine_blendShape2 != null)
        {
            StopCoroutine(_couroutine_blendShape2);
        }
        StartCoroutine(_couroutine_blendShape2 = Play_ToBlendShape(_BlendShape_2_IDX, 100.0f));
    }

    public void ToPingPong_BlendShape_1_2()
    {
        Refresh();

        if (_couroutine_pingpong != null)
        {
            StopCoroutine(_couroutine_pingpong);
        }
        StartCoroutine(_couroutine_pingpong = PingPong_BlendShape());
    }

    public void StopAll()
    {
        StopAllCoroutines();
    }

    public void ResetAll()
    {
        if (skinnedMeshRenderer != null)
        {
            var count = skinnedMeshRenderer.sharedMesh.blendShapeCount;
            for (int i = 0; i < count; i++)
            {
                skinnedMeshRenderer.SetBlendShapeWeight(i, 0.0f);
            }
        }
    }

    private IEnumerator Play_ToBlendShape(int idx, float to_val)
    {
        to_val = Mathf.Clamp(to_val, 0.0f, 100.0f);
        var start_val = skinnedMeshRenderer.GetBlendShapeWeight(idx);
        var cur_val = start_val;

        while (cur_val < to_val)
        {
            cur_val = Mathf.MoveTowards(cur_val, to_val, (to_val - start_val) * Time.deltaTime);
            skinnedMeshRenderer.SetBlendShapeWeight(idx, cur_val);
            yield return null;
        }

        Debug.Log($"play to blend shape [{idx}] : [{to_val}] complete!");
    }

    private IEnumerator PingPong_BlendShape()
    {
        var now_time = Time.time;

        while (true)
        {
            var _time = Time.time - now_time;
            var weight1 = Mathf.PingPong(_time * 200f, 100f);
            var weight2 = Mathf.PingPong(_time * 50f, 100f);
            skinnedMeshRenderer.SetBlendShapeWeight(_BlendShape_1_IDX, weight1);
            skinnedMeshRenderer.SetBlendShapeWeight(_BlendShape_2_IDX, weight2);
            yield return null;
        }
    }
}


Project

个人备份用文章来源地址https://www.toymoban.com/news/detail-850496.html

  • blender 工程: TestingBlenderShapeKeys.blend
  • unity 工程: TestingBlendShape_BRP_2020.3.37f1.rar

  • 百人计划-BlendShapes基础(物体变形与面捕应用)
  • google : how to implementing the blend shape in blender
  • google : how to create shape keys animation in blender
    • Shape Key / Blendshape Hacks to easily create expressions and actions for your avatar
    • Blender 2.8 Shapekeys and Morphing
    • How to Add Shape Keys in Blender
  • 形态键
  • 在Unity中实现BlendShape表情和骨骼动画混合的实践 - 讲得挺不错
  • BlendShapes基础与拓展练习(面捕与物体变形) - 讲得挺不错
  • GDC2011: Fast and Efficient Facial Rigging
  • GDC jeremy_ernst_fastandefficietfacialrigging.pdf
  • 技术美术百人计划-美术 3.5 BlendShape基础 笔记
  • 3.5 BlendShapes基础
  • 百人计划-BlendShapes基础(物体变形与面捕应用)
  • 【技术美术百人计划】美术 3.5 BlendShape基础
  • Unity通过导入器优化动画关键帧数据 - 删除仅仅只有 blend shape 的动画的其他骨骼信息,优化性能
  • interlude _1 : working on Yui-chan’s face morphing. - 3Ds max 中的演示 二次元 脸部表情 FFD

到了这里,关于unity - Blend Shape - 变形器 - 实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity Blend Tree(动画混合树)与AnimationEvent(动画事件)一起使用所带来的多个动画事件触发的问题及解决方法

    最近在添加人物脚步声效,所以打算使用unity的动画事件来制作,但走路动画是用的2d的混合树,就导致了当动画进行混合播放的时候,动画事件也会一起触发 在unity社区进行搜索后发现了这篇2015年的 帖子 ,在unity官方技术人员的评论下找到了答案: 具体做法是通过返回动画

    2024年02月12日
    浏览(32)
  • Unity——网格变形(制作一个压力球)

    主要参考链接:Mesh Deformation, a Unity C# Tutorial(本文为其翻译版) unity项目下载链接:https://download.csdn.net/download/weixin_43042683/87679832 在物体上投射射线并画出调试线。 将力转换为顶点的速度。 用弹簧和阻尼保持形状。 补偿物体变形。 本教程是一个关于网格变形的介绍。我们

    2024年02月11日
    浏览(36)
  • Unity中的网格创建和曲线变形

    在本篇博客中,我们将探讨如何使用Unity实现3D贝塞尔曲线变形效果。 线性公式 二次方公式 三次方公式 曲线的参数形式为: 准备工作 脚本概述 变量定义 变量解析 函数解析 获取所有子节点 GetAllChildren 获取所有子节点 UpdateBezierBend 控制点更新 CalculateBezier Bezier 曲线公式 Ge

    2024年03月24日
    浏览(30)
  • 【游戏开发解答】Unity中对UGUI的Image进行倾斜变形(UGUI | 精灵图 | OnPopulateMesh | 顶点偏移 | 变形)

    本文最终效果 一、前言 嗨,大家好,我是新发。 前同事问了我一个问题,如何将 UGUI 的 Image 进行变形,变成斜斜的, 最直接的就是出图的时候直接就画成斜的,我们不讨论这种情况,这里我们单纯的从技术实现上去思考能不能在 Unity 中通过 UGUI 的 Image 对图片进行倾斜变形

    2024年02月04日
    浏览(39)
  • 【Unity】LineRenderer画线拐点的网格变形问题

    正常情况下,使用Unity中画线工具LineRenderer。可以画出期望的直线。 但当拐点处,两点的距离过小,并且线的宽度不是特别细的情况下。组件动态生成的线会发生变形。 这是因为LineRenderer是根据填入的点位Positions和宽度Width来生成网格。如果两点间距过近,并且有一定的宽度

    2024年02月16日
    浏览(27)
  • 【Unity小技巧】Unity中实现带有Sprite Shape的2D水效果(附项目源码)

    本文是自己的学习笔记,最近发现一个很有意思的2d水效果,所以把它的实现过程写下来分享给大家。 当在 Unity 中实现带有 Sprite Shape 的 2D 水效果时,首先需要理解 Sprite Shape 和水效果的基本概念和工作原理。Sprite Shape 是 Unity 提供的一种 2D 图形工具,用于创建基于轮廓的精

    2024年02月21日
    浏览(31)
  • Unity - 实现模型动态伸长缩短,贴图不变形(材质球参数篇)

     思路为修改模型材质球的Tiling参数,根据与自身localScale的值得到合适的比例,再修改Tiling值

    2024年02月03日
    浏览(36)
  • 神州云服务平台(型号:DCC-CRL1000)基本配置教学视频

            教学视频只提供网络搭建与应用技能大赛第二部分基本配置部分视频,仅供大家学习使用。 2021年全国职业院校网络搭建及应用第二部分基本配置视频 由于在线播放视频有点模糊,所以给大家提供清晰的教学视频下载链接: 神州云服务平台(型号:DCC-CRL1000)基本配

    2024年02月02日
    浏览(30)
  • 134. 加油站 Python

    在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返

    2024年02月04日
    浏览(26)
  • 【Leetcode】134.加油站

    在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周

    2024年02月09日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包