Hexo 博客 添加 3D 看板娘 替换原来的 Live2D

0.前言

前两天用 VRoid Studio 捏了一个 3D 的 loli ,后来想想能不能把这个 3D 形象替换到那个博客站点的原来的 Live2D 看板娘那边去。花了一上午时间在 GitHub 上找相关的 Demo,又花一下午带一晚上反复调试,终于把这个 3D 看板娘调通了。

手机端暂时还没有实现出来效果,主要是尺寸对不上,不过也就是在那个 JS 里面调一下尺寸的事情。晚点再来研究研究。

我们找的这个 GitHub 代码是 Momijinn/SampleWebMMD ,他实现了在网页上加载 PMX 格式的 MMD 模型、 VMD 格式的动作,以及相应的音频档案,调用的是 Three.js 这个库,以及 MMDLoader 这个插件,这个库鄙人也没有研究过,只是之前没跳槽之前看产品经理在业务群里面发过这个库的演示页面,鄙人稍微瞅了一眼,毕竟鄙人不是前端。。。

1.修改 SampleWebMMD

把他的代码拉下来,然后做一些必要的修改。

index.html里面原来的几个手动切换动作的按钮去掉,不要。

把捏好并转换好的 .pmx的模型连同相应的相对路径的贴图文件丢进pmx目录,最好pmx里面再建一个子目录再丢。

把做好的.vmd的动作文件丢进vmd目录。

然后修改 JS。

原来的模型太亮了,去掉全局光,改成点光。 原来的

Init = () => {
  scene = new THREE.Scene();

  const ambient = new THREE.AmbientLight(0xeeeeee);
  scene.add(ambient);

  renderer = new THREE.WebGLRenderer({ alpha: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setClearColor(0xcccccc, 0);

  // documentにMMDをセットする
  document.body.appendChild(renderer.domElement);

  //cameraの作成
  camera = new THREE.PerspectiveCamera(40, windowWidth / windowHeight, 1, 1000);
  camera.position.set(0, 18, 10);
}

改成

Init = () => {
  scene = new THREE.Scene();

  const ambient = new THREE.AmbientLight(0xcccccc);
  // scene.add(ambient);

  spotLight = new THREE.SpotLight();
  spotLight.color = new THREE.Color(0xffffff);

  spotLight.castShadow = true;

  spotLight.position.set(0, -10, 60);

  // 光的强度 默认值为1
  spotLight.intensity = 1;
  // 从发光点发出的距离,光的亮度,会随着距离的远近线性衰减
  spotLight.distance = 350;
  // 光色散角度,默认是 Math.PI * 2
  spotLight.angle = 0.4;
  // 光影的减弱程度,默认值为0, 取值范围 0 -- 1之间
  spotLight.penumbra = 0.1;
  // 光在距离上的量值, 和光的强度类似(衰减指数)
  spotLight.decay = 1;

  // 设置阴影分辨率
  spotLight.shadow.mapSize.width = 1024;
  spotLight.shadow.mapSize.height = 1024;

  // 投影近点 --> 从距离光源的哪一才产生阴影
  spotLight.shadow.camera.near = 0.1;
  // 投影原点 --> 到光源的哪一点位置不产生阴影
  spotLight.shadow.camera.far = 300;
  // 投影视场
  spotLight.shadow.camera.fov = 40;

  scene.add(spotLight);


  renderer = new THREE.WebGLRenderer({ alpha: true });
  effect = new THREE.OutlineEffect( renderer, {
    defaultThickness: 0.01,
    defaultColor: [ 0, 0, 0 ],
    defaultAlpha: 0.8,
    defaultKeepAlive: true // keeps outline material in cache even if material is removed from scene
  } );
  renderer.setPixelRatio(window.devicePixelRatio);
  // renderer.setSize(window.innerWidth, window.innerHeight);
  if (window.innerWidth < window.innerHeight) document.body.remove(); // 手机端暂不展示
  renderer.setSize(480 * window.innerWidth / window.innerHeight, 480);
  renderer.setClearColor(0xcccccc, 0);
  renderer.domElement.style.pointerEvents = 'none';
  // documentにMMDをセットする
  document.body.appendChild(renderer.domElement);

  //cameraの作成
  camera = new THREE.PerspectiveCamera(40, windowWidth / windowHeight, 1, 1000);
  camera.position.set(0, 18, 52);
  effect.render( scene, camera );
}

每次动作执行完还要停两秒才循环下一次,去掉这个停顿。 原来的

helper = new THREE.MMDAnimationHelper({ afterglow: 2.0, resetPhysicsOnLoop: true });

改成

helper = new THREE.MMDAnimationHelper({ afterglow: 0.0, resetPhysicsOnLoop: true });

把他加载的模型改成我们自己的模型 ,原来的

const Pmx = "./pmx/pronama/プロ生ちゃん.pmx";

改成

const Pmx = "./pmx/mlj/mlj.pmx"; // 这里改成你准备好的 pmx 文件的路径

把他加载的动作改成我们自己的动作。 原来的

const MotionObjects = [
  { id: "loop", VmdClip: null, AudioClip: false },
  { id: "kei_voice_009_1", VmdClip: null, AudioClip: true },
  { id: "kei_voice_010_2", VmdClip: null, AudioClip: true },
];

改成

const MotionObjects = [
  { id: "float_with_rotate", VmdClip: null, AudioClip: false }, // 改成你的 vmd 文件名,不要后缀
  { id: "kei_voice_009_1", VmdClip: null, AudioClip: false },
  { id: "kei_voice_010_2", VmdClip: null, AudioClip: false },
  { id: "loop", VmdClip: null, AudioClip: false },
];

原来的

  //Set VMD on Mesh
  VmdControl("loop", true);

改成

  //Set VMD on Mesh
  VmdControl("float_with_rotate", true); // 改成你的 vmd 文件名,不要后缀

2.部署到对象存储

然后把改好的整个仓库的文件上传到一个网络空间。因为贴图有十几兆大小,国外的空间速度肯定慢,还是找一个阿里云或者别的什么云的对象存储或者CDN丢上去,得要那种文件名不变且可以带有子路径的那种。鄙人用的是百度智能云。但是这样的话流量就是个问题,如果网站流量比较大的话就要考虑其他方式了,因为对象存储是按流量计费的。

3.修改 Live2D Wrapper

之前我们用的是 galnetwen 做的 Live2D Wrapper,我们就直接在他的基础上修改相关的 NJK 文件。我们之前已经把引用的 JS 放进了单独的 NJK 文件,然后用布局 NJK 连接的。将 themes/next/layout/_third-party/live2d/live2d.njk中的

<script type="text/javascript">
    var message_Path = '/live2d/'
    var home_Path = 'https://haremu.com/'  //此处修改为你的域名,必须带斜杠
</script>
<script type="text/javascript" src="/live2d/js/live2d.js"></script>
<script type="text/javascript" src="/live2d/js/message.js"></script>
<script type="text/javascript">
    loadlive2d("live2d", "/live2d/model/tia/model.json");
</script>

直接去掉,或者注释掉。

然后再把前面的

<div id="landlord">
    <div class="message" style="opacity:0"></div>
    <canvas id="live2d" width="280" height="250" class="live2d"></canvas>
    <div class="hide-button">隐藏</div>
</div>

改为

<div id="landlord">
    <div class="message" style="opacity:0"></div>
    <!-- <canvas id="live2d" width="280" height="550" class="live2d"></canvas> -->
    <iframe src="放置显示 3D 模型的 HTML 页面 URL" frameborder="no" style="pointer-events: none; width: 100%; height: 100%"></iframe>
    <div class="hide-button">隐藏</div>
</div>

其中的 iframe需要改为第二大块你放在 CDN 或者对象存储的HTML文件地址。

然后通过 CSS 控制模型展示的大小,还有不能影响鼠标点击网页元素了。鄙人写的是

  <style>
    #landlord {
      bottom: -50px;
      width: 1000px;
      height: 550px;
      left: -300px;
      pointer-events: none;
    }
    
    #live2d {
      display: block;
      height: 100%;
      width: 100%;
    }
  </style>

如果之前没有用过这个 Live2D 的话,还要在 head里面加一个 CSS 文件。在themes\next\layout\_partials\head\head.njk中添加

<link rel="stylesheet" href="/live2d/css/live2d.css" />

其中的 href改成你准备好的这个 wrapper 的 CSS 的URL。

此外,鄙人是单独把原来 Live2D 的 Wrapper 放到单独的 NJK 里面了。布局的 NJK themes\next\layout\_third-party\index.njk是这样的。

{% include 'baidu-push.njk' %}

{% include 'rating.njk' %}

{%- if theme.algolia_search.enable %}
  {% include 'search/algolia-search.njk' %}
{% elif theme.swiftype_key %}
  {% include 'search/swiftype.njk' %}
{% elif theme.local_search.enable %}
  {% include 'search/localsearch.njk' %}
{%- endif %}

{% include 'live2d/live2d.njk' %}

{% include 'chat/chatra.njk' %}
{% include 'chat/tidio.njk' %}

{% include 'tags/pdf.njk' %}
{% include 'tags/mermaid.njk' %}

4.效果

这样就基本完成了修改。效果是这样的。
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要为 Hexo 博客添加搜索功能,你可以使用第三方搜索引擎,如 Algolia 或 Google Custom Search。这里我们介绍如何使用 Algolia。 Algolia 是一个强大的搜索引擎,提供了易于使用的 API,可以轻松地将搜索功能添加到你的 Hexo 博客中。以下是如何为 Hexo 博客添加 Algolia 搜索的步骤: 1. 注册 Algolia 账户并创建一个应用程序。 2. 安装 Hexo Algolia 插件。 ``` npm install hexo-algolia --save ``` 3. 在博客根目录下创建一个名为 `algolia.json` 的配置文件,并填写以下内容: ``` { "applicationID": "YOUR_APP_ID", "apiKey": "YOUR_API_KEY", "indexName": "YOUR_INDEX_NAME" } ``` 将 `YOUR_APP_ID`、`YOUR_API_KEY` 和 `YOUR_INDEX_NAME` 替换为你在 Algolia 上创建的应用程序的信息。 4. 在你的 Hexo 主题中添加搜索框和搜索结果页面。 在主题的相应文件中添加以下代码: 搜索框: ```html <form class="search-form" method="get" action="/search/"> <input class="search-input" type="text" placeholder="Search" name="query"> <button class="search-submit" type="submit">Search</button> </form> ``` 搜索结果页面: ```html --- title: "Search Results" layout: "search" --- <section class="search-results"> {% for page in page.posts %} <article class="search-result"> <h2 class="search-result-title"><a href="{{ page.url }}">{{ page.title }}</a></h2> <p class="search-result-excerpt">{{ page.excerpt }}</p> </article> {% endfor %} </section> ``` 5. 重新生成站点并上传到你的服务器。 ``` hexo generate ``` 6. 同步你的博客数据到 Algolia 上。 ``` hexo algolia ``` 完成以上步骤后,你的 Hexo 博客就可以使用 Algolia 进行搜索了。当用户在搜索框中输入关键字并提交时,将会跳转到搜索结果页面,显示与关键字匹配的文章列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值