1

I'm trying to outline a 3D model in WebGL. I've tried using a stencil buffer techique with glLineWidth and glPolygonMode. However, Mozilla's WebGL reference says that the minimum and maximum widths of lines are 1 (therefore can't be modified). I've tried it using it without glLineWidth and just use wireframe mode.

for (let i = 0; i < node_to_display.leaves.length; i++) {

    if (node_to_display.pickable) {
        this.scene.gl.enable(this.scene.gl.STENCIL_TEST);
        this.scene.gl.clearStencil(0);
        this.scene.gl.clear(this.scene.gl.STENCIL_BUFFER_BIT);
        this.scene.gl.stencilFunc(this.scene.gl.ALWAYS, 1, -1);
        this.scene.gl.stencilOp(this.scene.gl.KEEP, this.scene.gl.KEEP, this.scene.gl.REPLACE);
        node_to_display.leaves[i].primitive.primitiveType = this.scene.gl.TRIANGLES;
    }

    node_to_display.leaves[i].display(); //Display leaves

    if (node_to_display.pickable) {
        this.scene.activeShader.setUniformsValues({ outline_color: [1, 0, 0, 1] });

        this.scene.gl.stencilFunc(this.scene.gl.NOTEQUAL, 1, -1);
        this.scene.gl.stencilOp(this.scene.gl.KEEP, this.scene.gl.KEEP, this.scene.gl.REPLACE);
        node_to_display.leaves[i].primitive.primitiveType = this.scene.gl.LINES;
        node_to_display.leaves[i].display();  //Display leaves in wireframe
  }
}

However this is the result I'm getting:

Model Outline

The problem with this result is that the wireframe still shows where there is a triangle mesh "behind it".

[EDIT] The result I'm looking for is something like this:

Example

  • What kind of output are you looking for? Just a wireframe like this but without the shaded solid behind it? A wireframe with the hidden lines also visible? Or a line around the silhouette of the object, without a wireframe? – Dan Hulme Dec 20 '17 at 14:34
  • @DanHulme I'm sorry, I should've made clear what result I was looking for. This is an example: https://gyazo.com/000673d8afda399013a1ad72e71b7a62 – Daniel Marques Dec 20 '17 at 14:47
  • I assume you rerender your object after your stencil pass. have you reset your primitive type to triangles rather than lines? – Tare Dec 20 '17 at 14:55
  • @Tare By re-render you mean in a different frame or still the same frame? The primitive type is reset to triangles before rendering the object (line 9: node_to_display.leaves[i].primitive.primitiveType = this.scene.gl.TRIANGLES;) – Daniel Marques Dec 20 '17 at 14:58
  • I assume your rendering to be somewhat like this: 1.) render one pass to fill the stencil buffer 2.) render one pass (or in the same pass) to render red wherever the stencil pass has written to 3.) rerender the original image to have it display over the red stencil image so before step three you'd need to reset your primitive type to triangles rather than lines – Tare Dec 20 '17 at 15:04
  • 1
    It's been some time since I worked with stenciling, but I think you might be wrong in your way of going about this. What I think you are doing is rendering the original image, and then rerendering it's wireframe (by setting the primitive type to line), just that you're rendering red wherever the stencil buffer is set. this would of course lead to the red wireframe you get right now. try rendering your second time (the "red pass") with primitive type triangles, I guess that would lead to the whole object being red. – Tare Dec 20 '17 at 15:13
  • look into Post effects, Stemkoski has an example of this – sean wallace Nov 26 '22 at 01:54

0 Answers0