草庐IT

【游戏开发实战】下载原神模型,PMX转FBX,导入到Unity中,卡通渲染,绑定人形动画(附Demo工程)

林新发 2023-04-13 原文

文章目录

一、前言

嗨,大家好,我是新发。
我这两天在做一个RPG打群架的个人作品,涉及到一些渲染和人物动画控制的问题,顺手写篇教程,这里角色模型我用原神的模型来演示。

效果如下

原神模型使用守则:
◆允许完善物理,修正模型权重、表情等bug
允许改色,适度更改衣装,添加spa、toon等
◆请勿二次配布,以及拆取部件以用于改造其他模型
请勿用于18禁作品,极端宗教宣传,血腥恐怖猎奇作品,人身攻击等
请勿用于商业用途
◆他人使用本模型所造成的一切不良后果,不由模型改造者与miHoYo承担,请向使用者追究全部责任

二、原神模型下载

原神的模型可以在官网直接下载到。

1、第一期模型

官网:https://ys.biligame.com/gczj/

2、第二期模型

官网:http://ys.biligame.com/pjdkx/

3、第三期模型

官网:https://ys.biligame.com/beyel

4、第四期模型

官网:https://ys.biligame.com/ysl

5、第五期模型

官网:https://www.bilibili.com/blackboard/activity-raop07Ymhm.html

6、第六期模型

官网:https://www.bilibili.com/blackboard/activity-kiOl0D1nF8.html

7、第七期模型

官网:https://www.bilibili.com/blackboard/activity-btLCSzTTsK.html

8、模型合集打包下载

如果你不想一个个下载,可以从我的网盘下载,我已经全部打包好了,
网盘地址:https://pan.baidu.com/s/1gUCyDuu9D2Aoug6weK2WxA
提取码:bbr5

三、pmx转fbx

我们下载下来后,模型的格式是pmx

我们需要把它转为fbx格式才能导入Unity中使用。pmxfbx可以通过Blender来转,刚好我之前自学了Blender,也写过几篇Blender配合Unity的文章,大家感兴趣的可以看看:
《【游戏开发创新】上班通勤时间太长,做一个任意门,告别地铁与塞车(Unity | 建模 | ShaderGraph | 摇杆 | 角色控制)》

《【游戏开发创新】自学Blender建模,自制孔明灯,在Unity中点亮整个星空,愿新年,胜旧年(Unity | 建模 | 粒子系统 | 预设)》

《【游戏开发创新】当我学了Blender 建模,自制3D电脑桌面,回收站爆发了,把我做的模型都吐了出来(Blender | Unity | FBX)》

回归正题,下面就来教大家如何使用Blenderpmx转为fbx格式。

1、Blender下载与安装

Blender官网:https://www.blender.org/
中文手册:https://docs.blender.org/manual/zh-hans/2.79/about/introduction.html

由于Blender官网的下载速度太慢,建议去Blender中国社区下载,地址:https://www.blendercn.org/

根据你的电脑系统下载对应的版本,我是windows系统,点击下载windows平台的安装包,

下载完后直接傻瓜式安装即可~

2、Cats插件下载与安装

Blender是开源免费的,轻量又强大,易于上手,很适合个人独立开发者学习和使用,它具有丰富的插件生态,就像VSCode一样,我们这里要将pmx转为fbx格式,就需要用到一个Cats插件。
Cats插件自身也是开源的,我们直接从GitHub上下载。
地址:https://github.com/GiveMeAllYourCats/cats-blender-plugin
如下,点击Cats Blender Plugin,下载下来的是一个zip文件,

现在我们打开Blender,然后点击菜单Edit / Preferences,打开偏好设置窗口,

点击Add ons,然后点击install按钮,

然后选择我们刚刚下载的Cats插件文件,点击Install Add-on

安装完毕后,记得勾选上它,(如果你没勾选,插件就是禁用状态的)

现在,我们就可以在编辑区的侧边栏那里看到CATS插件了,(注:侧边栏显示和隐藏的快捷键是N

3、导入pmx模型

我们在CATS插件中点击Import Model按钮,

然后选择pmx文件,点击Import Any Model按钮,

此时导进来的模型的材质有问题,是这样子的,

4、修复材质问题

我们打开侧边栏的Misc,然后点击Shadeless(即使用卡通材质),

此时我们就可以看到正常显示了,

看下细节

5、修复模型:Fix Model

我们可以看到,模型的节点命名并不是按照Unity骨骼映射的英文命名,

我们点击CATS插件的Fix Model按钮,即可自动进行修复,除此之外,它还会帮我们删除多余无用的骨骼,将使用同一张贴图的节点合并为一个Mesh并重命名为Body等,

修复后可以看到变成英文命名了,

6、导出fbx

点击CATS插件的Export Model按钮,即可导出fbx文件,

建议导出fbx文件放在pmx文件同级目录中,

如下,

四、Unity部分

1、导入fbx和贴图

我们上面的fbx文件和tex文件夹(里面是贴图)一起拷贝到Unity工程中,(如果你没有拷贝tex文件夹,在Unity中显示的就是白模)

此时我们把模型拖入场景中,看到的效果是这样的,

2、从fbx中导出材质球

上面我们看到,模型的材质效果不是 卡通渲染风格,当你去定位模型的材质的时候,会发现材质是嵌在fbx文件里的,

我们并不能对fbx内的材质进行编辑,

没关系,我们把材质导出来。
选中fbx文件,在Inspector窗口中点击Materials,设置LocationUse External Materials (Legacy),然后点击Apply按钮,

此时材质球就会从fbx文件中导出来了,

接下来我们就可以修改材质球的shader了,默认是Standard

3、卡通渲染

卡通渲染不像 PBR那样有标准流程和衡量准则,可以说卡通渲染是人们主观审美 + 现实环境抽象的结合,不同人对卡通渲染的理解理念不同,不过随着卡通渲染的不断发展,也形成了一套固定思路。

3.1、简单粗暴,使用Unlit/Texture

最粗暴的方式就是直接使用Unlit材质,在贴图上表现出卡通效果。
我们把材质球的shader全部改成Unlit/Texture(也就是无光照模型,直接显示贴图纹理),

效果如下:

当然,这过于简单了,缺点很明显,没有光照效果。

3.2、基于光照的卡通渲染

我们对比看下原神游戏中的画面效果,是一种次时代卡通效果。我们可以看到,它是有光照效果的,太阳在右侧,人物面朝太阳方向时,光照面会有高光,背面会有阴影;当背朝太阳时则相反。

我们需要考虑光照,也就是基于光照模型的卡通渲染。

3.3、UnityToonShader项目

基于光照模型的卡通渲染,我在GitHub上找到了一个项目,地址:https://github.com/Sorumi/UnityToonShader
如果你访问不了GitHub,可以访问我的CODE CHINA,我已将它Fork过来了,

3.4、ToonMultiStepShader.shader

进入上面这个项目的Assets/Shaders目录,可以看到一些shader脚本,我使用的是这个ToonMultiStepShader.shader

shader代码如下:

Shader "Toon/Basic/MultiSteps"
{
    Properties
    {
        // 颜色
        _Color ("Color", Color) = (1, 1, 1, 1)
        _HColor ("Highlight Color", Color) = (0.8, 0.8, 0.8, 1.0)
        _SColor ("Shadow Color", Color) = (0.2, 0.2, 0.2, 1.0)
        
        // 贴图
        _MainTex ("Main Texture", 2D) = "white" { }
        
        // 渐变
        _ToonSteps ("Steps of Toon", range(1, 9)) = 2
        _RampThreshold ("Ramp Threshold", Range(0.1, 1)) = 0.5
        _RampSmooth ("Ramp Smooth", Range(0, 1)) = 0.1
        
        // 镜面
        _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
        _SpecSmooth ("Specular Smooth", Range(0, 1)) = 0.1
        _Shininess ("Shininess", Range(0.001, 10)) = 0.2
        
        // 边缘
        _RimColor ("Rim Color", Color) = (0.8, 0.8, 0.8, 0.6)
        _RimThreshold ("Rim Threshold", Range(0, 1)) = 0.5
        _RimSmooth ("Rim Smooth", Range(0, 1)) = 0.1
    }
    
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        
        CGPROGRAM
        
        #pragma surface surf Toon addshadow fullforwardshadows exclude_path:deferred exclude_path:prepass
        #pragma target 3.0
        // 基础色
        fixed4 _Color;
        // 高光颜色
        fixed4 _HColor;
        // 阴影色
        fixed4 _SColor;
        // 主贴图
        sampler2D _MainTex;
        // 渐变阈值
        float _RampThreshold;
        // 渐变平滑度
        float _RampSmooth;
        // 渐变阶数
        float _ToonSteps;
        // 镜面平滑度
        float _SpecSmooth;
        // 光滑度
        fixed _Shininess;
        // 边缘颜色
        fixed4 _RimColor;
        // 边缘阈值
        fixed _RimThreshold;
        // 边缘光滑度
        float _RimSmooth;
        
        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };
        
        // 线性阶跃
        float linearstep(float min, float max, float t)
        {
            return saturate((t - min) / (max - min));
        }
        
        inline fixed4 LightingToon(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
        {
            half3 normalDir = normalize(s.Normal);
            half3 halfDir = normalize(lightDir + viewDir);
            
            float ndl = max(0, dot(normalDir, lightDir));
            float ndh = max(0, dot(normalDir, halfDir));
            float ndv = max(0, dot(normalDir, viewDir));
            
            // 平滑阶跃
            float diff = smoothstep(_RampThreshold - ndl, _RampThreshold + ndl, ndl);
            float interval = 1 / _ToonSteps;
            // float ramp = floor(diff * _ToonSteps) / _ToonSteps;
            float level = round(diff * _ToonSteps) / _ToonSteps;
            float ramp ;
            if (_RampSmooth == 1)
            {
                ramp = interval * linearstep(level - _RampSmooth * interval * 0.5, level + _RampSmooth * interval * 0.5, diff) + level - interval;
            }
            else
            {
                ramp = interval * smoothstep(level - _RampSmooth * interval * 0.5, level + _RampSmooth * interval * 0.5, diff) + level - interval;
            }
            ramp = max(0, ramp);
            ramp *= atten;
            
            _SColor = lerp(_HColor, _SColor, _SColor.a);
            float3 rampColor = lerp(_SColor.rgb, _HColor.rgb, ramp);
            
            // 镜面
            float spec = pow(ndh, s.Specular * 128.0) * s.Gloss;
            spec *= atten;
            spec = smoothstep(0.5 - _SpecSmooth * 0.5, 0.5 + _SpecSmooth * 0.5, spec);
            
            // 边缘
            float rim = (1.0 - ndv) * ndl;
            rim *= atten;
            rim = smoothstep(_RimThreshold - _RimSmooth * 0.5, _RimThreshold + _RimSmooth * 0.5, rim);
            
            fixed3 lightColor = _LightColor0.rgb;
            
            fixed4 color;
            fixed3 diffuse = s.Albedo * lightColor * rampColor;
            fixed3 specular = _SpecColor.rgb * lightColor * spec;
            fixed3 rimColor = _RimColor.rgb * lightColor * _RimColor.a * rim;
            
            color.rgb = diffuse + specular + rimColor;
            color.a = s.Alpha;
            return color;
        }
        
        // 表面着色器
        void surf(Input IN, inout SurfaceOutput o)
        {
            fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = mainTex.rgb * _Color.rgb;
            
            o.Alpha = mainTex.a * _Color.a;
            
            o.Specular = _Shininess;
            o.Gloss = mainTex.a;
        }
        
        ENDCG
        
    }
    FallBack "Diffuse"
}

将其导入Unity工程中,

3.5、材质球设置

把材质球的shader改为Toon/Basic/MultiSteps,如下

调整一下高光、阴影、渐变阈值、镜面、边缘等参数,

3.6、效果演示

效果如下,我们在修改太阳光方向,观察不同角度的效果,

4、添加动画

我们要给角色添加动画,加入你现在已有一些人形骨骼动画,想套用在原神的模型上,怎么弄呢?我来教你~

4.1、人形动画资源获取

假设你手头上没有人形动画,这个时候,我就要推荐你一个高级网站了:Mixamo,地址:https://www.mixamo.com/

MixamoAdobe旗下的一个产品,可以上传静态人形模型文件,在网站上绑定人形模板动画,并可以下载绑定动画后的模型文件。

我之前有写过一篇文章专门介绍这个网站:《在线免费角色动画网站:mixamo》

我们选择一个喜欢的动作,比如我选这个

点击Download按钮,

格式选择FBX,不要包含网格(选Without Skin),然后点击DOWNLOAD

这样我们就得到了一个含动画的fbx文件,

4.2、设置人形动画

我们把动画fbx文件导入Unity中,如下

选中动画fbx文件,在Inspector窗口中点击Rig,把Animation Type设置为Humanoid,然后点击Apply

此时我们点击Configure,可以看到人形动画Avatar的绑定信息,

如下

同样的,把我们原神的fbx模型的Animation Type也改为Humanoid

同样点击Configure按钮,检查一下Avatar

4.3、添加Animator动画

最后一步,把动画文件拖给模型父节点,此时会自动挂一个Animator组件,我们设置一下Avatar对象,如下

注意,如果要让动画循环播放,需要把动画的Loop Time勾选上,如下

4.4、运行效果

加个背景图,运行效果如下,

emmmm,还是少一点效果,我们加上泛光屏幕后处理,如下

注:关于屏幕后处理,我在之前一些文章中与讲到,可以看我之前的文章:
《【游戏仿真实验】使用Unity仿真电视机光学三原色显示画面,我是要成为海贼王的男人》
《Unity后处理(图像优化特效技术),实现影视级别的镜头效果,辅助标签:PostProcessing》

好了,剩下的就是大家自由发挥了,添加一些其他动画,进行组合、控制。
关于Animator动画控制,我之前写过相关教程,推荐大家看下,《Unity动画状态机Animator使用》

四、Demo工程下载

本文Demo工程我已上传到CODE CHINA,感兴趣的同学可自行下载学习,
地址:https://codechina.csdn.net/linxinfa/MiHoYoModelTest

五、完毕

好啦,就到这里吧~
我是林新发:https://blog.csdn.net/linxinfa
原创不易,若转载请注明出处,感谢大家~
喜欢我的可以点赞、关注、收藏,如果有什么技术上的疑问,欢迎留言或私信~

有关【游戏开发实战】下载原神模型,PMX转FBX,导入到Unity中,卡通渲染,绑定人形动画(附Demo工程)的更多相关文章

  1. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  4. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  5. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  6. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  7. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

随机推荐