1

我试图让变形对象通过 JS 更改它的属性,但我什至无法通过任何 Spark 模块获取它。

Spark AR 有面部扭曲变形的示例项目。 https://developers.facebook.com/docs/ar-studio/tutorials-and-samples/samples/face-distortion/ 您甚至可以在教程中看到,附加了一些变形对象,称为 faceDistortionPack。该对象位于资产中,我尝试通过脚本中的不同方式获取它,但无法实现。我想写一些js逻辑来操作变形。

const Scene = require('Scene');
const Diagnostics = require('Diagnostics');

const faceMesh = Scene.root.find('facemesh_distortion');

Diagnostics.log(faceMesh); // FaceMesh: https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/scenemodule.facemesh
Diagnostics.log(faceMesh.deformation); // null
Diagnostics.log(faceMesh.find('faceDistortionPack')); // Exception...
// ....

我想获取“faceDistortionPack”对象来访问它的属性,例如“nose_z”,所以我可以通过 JS 更改它们。

4

2 回答 2

1

虽然这是一个很老的问题,但我想如果有人对此感到困惑并遇到这个问题,我还是会回答的。

首先:有一个惊人的有用提示、教程、片段等集合,称为Spark AR 社区。在那里,您可以找到一个GitBook,其中包含官方脚本对象参考的替代、更好的索引和更好的工作版本。如果您在官方参考中迷失了方向,或者经常发生它不起作用,我建议您使用它。在那里你可以看到,上一个答案中提到的 BlendShapesMesh从 Spark AR v85+ 开始被弃用,所以这对任何人都没有帮助。()

所以,如果我理解正确的话,你想要实现的是访问 faceMesh 的 Blendshapes 并通过脚本更改它们的值。你需要做的是:

  1. 按照本教程中的说明进行操作:https ://sparkar.facebook.com/ar-studio/learn/tutorials/face-distortion-retouching/
  2. 应用 Blendshapes 后,稍微调整一下 Blendshapes,这样你就明白发生了什么。
  3. 将脚本添加到您的资产。您将希望通过脚本访问 faceMesh-Object 的 Blendshapes 的权重属性。这可以通过使用Mesh-Class的 getBlendshapes()-Method 来完成。这是一个代码示例:
//Require Modules
const Scene = require('Scene');
const Diagnostics = require('Diagnostics');
const Reactive = require('Reactive');

//Enable async/await [part 1]
(async function () {

  //Load Assets as Promise

const loadAssets = await Promise.all(
  [
      Scene.root.findFirst("faceMesh0"),  //Put name of your facemesh here, default is faceMesh0
  ]
).then(function(assets){
    const faceMesh = assets[0]; //Assign the facemesh from the assets-Array of the promise to a variable you can work with better
    const faceMeshShapes = faceMesh.getBlendShapes(); //Access all Blendshapes of the faceMesh-Object and store them in an Array

您现在拥有的是一个名为 faceMeshShapes 的变量,它是一个包含 Blenshapes 数组的对象。您可以使用控制台记录它,Diagnostics.log(faceMeshShapes)并看到其中有一个名为“_value”的数组,其中填充了所有作为对象的 Blendshape,具有weight-Property,它使用 scalarValue 指定Blendshape的权重。您可以通过使用 scalarValue-Class 的 pinLastValue() 方法将其转换来控制台记录此值,并且可以通过将其绑定到自定义值来分配不同的值,您可以使用 val() 方法将其转换为标量值反应模块。这是一个例子:

Diagnostics.log(faceMeshShapes._value[0].weight.pinLastValue()); //console log the Value of the weight property's scalarValue of the Blendshape that's stored at the index 0 of the _value-Array
faceMeshShapes._value[0].weight = Reactive.val(0.5) //set the weight to 0.5
Diagnostics.log(faceMeshShapes._value[0].weight.pinLastValue()); //console log the changed value of the weight property

所以基本上,这就是您可以访问每个 Blendshape 权重的方式。索引应根据它们在 spar AR studio 中列出的顺序,从第一个 BlendShape 的 0 开始。现在你可以用这个值做很多事情,比如将它绑定到一个动画,让它从 0 到 1 进行动画处理,或者使用面部跟踪模块绑定到嘴巴张开等等。

最后但同样重要的是,不要忘记任何分号并关闭所有括号。

  });

})(); // Enable async/await [part 2]

PS:通过控制台记录对象所有属性的列表,有时确实有助于了解正在发生的事情以及如何访问内容。特别是因为 spark AR 文档在这方面非常薄弱(而且总体上非常薄弱)。您可以使用MDN中的以下功能来执行此操作。这没什么花哨的,但它完成了工作并且已经救了我几次:)

function listAllProperties(o) {
  var objectToInspect;
  var result = [];

  for(objectToInspect = o; objectToInspect !== null;
          objectToInspect = Object.getPrototypeOf(objectToInspect)) {
        result = result.concat(
          Object.getOwnPropertyNames(objectToInspect)
        );
    }
  return result;
}
于 2021-02-28T18:37:59.857 回答
0

您发布的链接不再有效。

我猜下面的链接现在对于其他研究这个的人来说更相关。我制作了一系列 blendShapes 动画,这些链接很有用。基本上循环通过每个 blendShape 的权重。

https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/scenemodule.blendshapesmesh

https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/scenemodule.blendshape

于 2020-05-11T22:19:43.980 回答