Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OutlinePass can not be applied with different kinds of meshes in the scene #21227

Closed
Feirell opened this issue Feb 8, 2021 · 1 comment
Closed

Comments

@Feirell
Copy link

Feirell commented Feb 8, 2021

Describe the bug

This bug seems to be related to the bug #17701 but can be reproduced by a completely different approach.

Three will throw an error when trying to apply a outline pass on a scene with instanced and normal meshes.

Error:

three.module.js:12456 Uncaught TypeError: Cannot read property 'isInterleavedBufferAttribute' of undefined
    at Object.get (three.module.js:12456)
    at setupVertexAttributes (three.module.js:14119)
    at Object.setup (three.module.js:13789)
    at WebGLRenderer.renderBufferDirect (three.module.js:23669)
    at renderObject (three.module.js:24192)
    at renderObjects (three.module.js:24165)
    at WebGLRenderer.render (three.module.js:23959)
    at OutlinePass.render (OutlinePass.js:319)
    at EffectComposer.render (EffectComposer.js:150)
    at init (index.js:108)

To Reproduce

Steps to reproduce the behavior:

  1. Add instanced mesh to the scene
  2. Add normal mesh to scene
  3. Add normal mesh to the scene
  4. Try to apply an outline on the first normal mesh

Code

import {
    DoubleSide,
    InstancedMesh,
    Matrix4,
    Mesh,
    MeshLambertMaterial,
    MeshPhongMaterial,
    PerspectiveCamera,
    PlaneBufferGeometry,
    Quaternion,
    Scene,
    SphereBufferGeometry,
    TorusBufferGeometry,
    Vector2,
    Vector3,
    WebGLRenderer
} from "three";
import {EffectComposer} from "three/examples/jsm/postprocessing/EffectComposer";
import {RenderPass} from "three/examples/jsm/postprocessing/RenderPass";
import {OutlinePass} from "three/examples/jsm/postprocessing/OutlinePass";

// issue related to https://github.com/mrdoob/three.js/issues/17701
// code based on https://github.com/mrdoob/three.js/blob/master/examples/webgl_postprocessing_outline.html

function addSpheresInstanced() {
    const geometry = new SphereBufferGeometry(3, 48, 24);
    const material = new MeshLambertMaterial({color: 0xff00aa});

    const instanced = new InstancedMesh(geometry, material, 10);

    const mat = new Matrix4();

    const position = new Vector3();
    const rotation = new Quaternion();
    const scale = new Vector3();

    for (let i = 0; i < 10; i++) {
        position.set(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2);

        const scaleAmount = Math.random() * 0.3 + 0.1;
        scale.set(scaleAmount, scaleAmount, scaleAmount);

        mat.compose(position, rotation, scale);
        instanced.setMatrixAt(i, mat);
    }

    instanced.instanceMatrix.needsUpdate = true;

    return instanced;
}

function addFloor() {
    const floorGeometry = new PlaneBufferGeometry(12, 12);
    const floorMaterial = new MeshLambertMaterial({side: DoubleSide});

    const floorMesh = new Mesh(floorGeometry, floorMaterial);
    floorMesh.rotation.x -= Math.PI * 0.5;
    floorMesh.position.y -= 1.5;
    floorMesh.receiveShadow = true;

    return floorMesh;
}

function addTorus() {
    const torusGeometry = new TorusBufferGeometry(1, 0.3, 16, 100);
    const torusMaterial = new MeshPhongMaterial({color: 0xffaaff});

    const torusMesh = new Mesh(torusGeometry, torusMaterial);
    torusMesh.position.z = -4;
    torusMesh.receiveShadow = true;
    torusMesh.castShadow = true;

    return torusMesh;
}

function init() {
    const width = window.innerWidth;
    const height = window.innerHeight;

    const renderer = new WebGLRenderer();
    renderer.setSize(width, height);
    document.body.appendChild(renderer.domElement);

    const scene = new Scene();

    const camera = new PerspectiveCamera(45, width / height, 0.1, 100);
    camera.position.set(0, 0, 8);

    const spheresInstanced = addSpheresInstanced();
    scene.add(spheresInstanced);

    const torus = addTorus();
    scene.add(torus);

    const floor = addFloor();
    scene.add(floor);

    const composer = new EffectComposer(renderer);

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

    const outlinePass = new OutlinePass(new Vector2(width, height), scene, camera);
    composer.addPass(outlinePass);

    outlinePass.selectedObjects = [torus];

    composer.render();
}

init();

Live example

https://jsfiddle.net/q8e0h7du/

Expected behavior

There should be no error and the outline should be rendered around the torus.

Platform:

  • Device: Desktop
  • OS: Windows
  • Browser: Chrome
  • Three.js version: r125
@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 8, 2021

This is actually a duplicate of #18533.

Thanks for the detailed report though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants