【问题标题】:Using OutlinePass (THREE.js r102) with skinned mesh使用带有蒙皮网格的 OutlinePass (THREE.js r102)
【发布时间】:2020-10-02 05:35:23
【问题描述】:

/examples/js/postprocessing/OutlinePass.js 来自 THREE.js r102 似乎不适用于蒙皮网格。具体来说,渲染的轮廓始终停留在网格的静止位置。

有什么方法可以让这个工作(即更新轮廓以反映动画网格的当前姿势)? OutlinePass 似乎没有记录(修改代码本身的 cmets)。

还有其他一些公认的方法来勾勒动画网格吗?我正在从 r7x 迁移一些代码,最终通过手动创建网格副本并应用沿法线缩放的着色器材质来完成此操作。我可以再做一次,但如果有更简单/更好支持的方法来实现相同的效果,我宁愿使用它,而不是复制一个破坏每个新主要版本的方法。

一个简单的 jsfiddle 说明问题:

https://jsfiddle.net/L69pe5q2/3/

这是来自 jsfiddle 的代码。我使用的网格是来自 three.js 发行版的 SimpleSkinning.gltf 示例。在 jsfiddle 中,我从 dataURI 加载它,因此它不会抱怨 XSS 加载,并且我在下面的代码中编辑了 base64 编码的数据(并将其替换为 [FOO]),纯粹是为了便于阅读。

OutlinePass 在 initComposer() 中创建并添加到作曲家。

var camera, light, renderer, composer, mixer, loader, clock;
var scene, mesh, outlinePass;
var height = 480,
  width = 640;
var clearColor = '#666666';

load();

function load() {
  loader = new THREE.GLTFLoader();
  clock = new THREE.Clock();
  scene = new THREE.Scene();
  loader.load('data:text/plain;base64,[FOO]', function(obj) {
    scene.add(obj.scene);
    mixer = new THREE.AnimationMixer(obj.scene);
    var clip = THREE.AnimationClip.findByName(obj.animations,
      'Take 01');
    var a = mixer.clipAction(clip);
    a.reset();
    a.play();

    mesh = obj.scene;
    mesh.position.set(-7, 2.5, -7);

    init();
    animate();
  });
}

function init() {
  initCamera();
  initScene();
  initRenderer();
  initComposer();

  outlinePass.selectedObjects = [mesh];
}

function initCamera() {
  camera = new THREE.PerspectiveCamera(30, width / height, 1, 10000);
  camera.position.set(7, 0, 7);
  camera.lookAt(0, 0, 0);
}

function initScene() {
  light = new THREE.AmbientLight(0xffffff)
  scene.add(light);

}

function initRenderer() {
  renderer = new THREE.WebGLRenderer({
    width: width,
    height: height,
    antialias: false,
  });
  renderer.setSize(width, height);
  renderer.setClearColor(clearColor);
  document.body.appendChild(renderer.domElement);
}

function initComposer() {
  var renderPass, copyPass;

  composer = new THREE.EffectComposer(renderer);

  renderPass = new THREE.RenderPass(scene, camera);
  composer.addPass(renderPass);

  outlinePass = new THREE.OutlinePass(new THREE.Vector2(width, height),
    scene, camera);
  composer.addPass(outlinePass);
  outlinePass.edgeStrength = 10;
  outlinePass.edgeThickness = 4;
  outlinePass.visibleEdgeColor.set('#ff0000');

  copyPass = new THREE.ShaderPass(THREE.CopyShader);
  copyPass.renderToScreen = true;
  composer.addPass(copyPass);
}

function animate() {
  var delta = clock.getDelta();
  requestAnimationFrame(animate);
  update(delta);
  render(delta);
}

function update(delta) {
  if (mixer) mixer.update(delta);
}

function render(delta) {
  composer.render();
}

【问题讨论】:

  • 您的问题是three.js 的已知限制。它不仅在使用OutlinePass 时发生,而且在一般使用Scene.overrideMaterial 时也会发生。蒙皮和变形现在不被尊重。这已经有一个问题,请参阅github.com/mrdoob/three.js/issues/14577
  • @jbg 你找到解决方法了吗?

标签: three.js


【解决方案1】:

根据Mugen87 2019 年 1 月的消息,他说:

有了这个小补丁,现在可以将轮廓通道与动画网格一起使用。用户在应用程序级别唯一需要做的就是将 OutlinePass.depthMaterial 和 OutlinePass.prepareMaskMaterial 的 morphTargets 或蒙皮设置为 true。当然,这仍然是一项手动工作,但至少已经完成了更复杂的着色器增强。

举个例子:

https://jsfiddle.net/2ybks7rd/

github上的参考链接

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 2018-01-12
    • 2015-08-03
    • 1970-01-01
    • 2020-02-16
    • 2016-07-20
    • 2018-01-05
    • 2013-06-26
    • 2018-11-30
    相关资源
    最近更新 更多