结合使用OutlinePass(THREE.js r102)和蒙皮网格

时间:2019-03-28 22:47:29

标签: three.js

THREE.js r102中的

/examples/js/postprocessing/OutlinePass.js不适用于蒙皮网格。具体来说,渲染的轮廓始终保持在网格的静止位置。

是否有某种方法可以使它工作(即更新轮廓以反映动画网格物体的当前姿势)?似乎没有记录OutlinePass(在代码本身中修改注释)。

是否还有其他概述动画网格的方法?我正在从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();
}

1 个答案:

答案 0 :(得分:1)

根据Mugen87,他在2019年1月说:

有了这个小补丁,现在就可以在动画网格物体上使用轮廓传递了。用户在应用程序级别只需要做的就是将OutlinePass.depthMaterial和OutlinePass.prepareMaskMaterial的morphTargets或外观设置为true。当然,这仍然是手动操作,但至少已经完成了更复杂的着色器增强。

举个例子:

https://jsfiddle.net/2ybks7rd/

github上的参考链接