Layering Geometry in Three.js

Is it feasible to have a Three.js mesh consistently displayed on top of the scene, regardless of its position being obscured by other objects? I am working on incorporating a lasso selection feature with a mesh and require the selecting box to render above the rest of the scene.

Answer №1

Absolutely.

Start by following these steps:

renderer.autoClear = false;

Next, establish a separate scene consisting solely of the desired objects to be displayed above the rest. Then, within your rendering loop:

renderer.clear();                     // clear buffers
renderer.render( mainScene, camera );  // render primary scene
renderer.clearDepth();                // clear depth buffer
renderer.render( overlayScene, camera);// render overlay scene

three.js r.152

Answer №2

To display only a single mesh in the front, you can achieve this by adjusting the depthTest property of the object's material to false:

var frontMaterial = new THREE.MeshStandardMaterial({
  color: 'blue',
  depthTest: false
});

mesh.material = frontMaterial;

View an example in this code snippet


Note: Ensure that you have renderer.sortObjects set to the default value of true.

Answer №3

A functional illustration is provided below showcasing the VisualLayers class designed for managing multiple layers. It incorporates the technique of setting renderer.autoClear = false and managing clearing depth as highlighted by West Langley in his explanation.

This methodology is advantageous because it does not alter the renderOrder of objects (which is an alternate method), thus avoiding potential issues, and can be utilized independently from layering for various scenarios.

Feel free to experiment with different options in the user interface to observe their effects:

// @ts-check

////////////////////////
// LAYER SYSTEM
////////////////////////

/** @typedef {{name: string, backingScene: THREE.Scene, order: number}} Layer */

class VisualLayers {
    /**
     * @type {Array<Layer>}
     * @private
     */
    __layers = [];

    constructor(
        /** @private @type {THREE.WebGLRenderer} */ __renderer,
        /** @private @type {typeof THREE.Scene} */ __Scene = THREE.Scene
    ) {
        this.__renderer = __renderer;
        this.__Scene = __Scene;
    }

    defineLayer(/** @type {string} */ name, /** @type {number=} */ order = 0) {
        const layer = this.__getLayer(name);

        // The default layer always has order 0.
        const previousOrder = layer.order;
        layer.order = name === "default" ? 0 : order;

        // Sort only if order changed.
        if (previousOrder !== layer.order)
            this.__layers.sort((a, b) => a.order - b.order);

        return layer;
    }

    /**
     * Get a layer by name (if it doesn't exist, creates it with default order 0).
     * @private
     */
    __getLayer(/** @type {string} */ name) {
        let layer = this.__layers.find((l) => l.name === name);

        if (!layer) {
            layer = { name, backingScene: new this.__Scene(), order: 0 };
            layer.backingScene.autoUpdate = false;
            this.__layers.push(layer);
        }

        return layer;
    }

    removeLayer(/** @type {string} */ name) {
        const index = this.__layers.findIndex((l) => {
            if (l.name === name) {
                l.backingScene.children.length = 0;
                return true;
            }

            return false;
        });

        if (index >= 0) this.__layers.splice(index, 1);
    }

    hasLayer(/** @type {string} */ name) {
        return this.__layers.some((l) => l.name === name);
    }

    /** @readonly */
    get layerCount() {
        return this.__layers.length;
    }

    ...
}
html,body,#container {
    margin: 0px;
    padding: 0px;
    width: 100%;
    height: 100%;
}

canvas {
    background: transparent;
    display: block;
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
}
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="76020113171d06171813364758435843">[email protected]</a>/dist/tweakpane.min.js"></script>
...
<script src="//unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="53233c202723213c303620203a3d3413657d62647d67">[email protected]</a>/build/postprocessing.js"></script>

Answer №4

In addition to adjusting the object.renderOrder property, it is crucial to set material.depthTest to false on the relevant objects.

var spriteMaterial = new THREE.SpriteMaterial( { map: texture1, depthTest: false} );

    this.context1 = context1;
    this.texture1 = texture1;

    var sprite1 = new THREE.Sprite( spriteMaterial );
    sprite1.scale.set(30,15,1);
    sprite1.center.x=0;
    sprite1.center.y=0;
    sprite1.position.set( 0, 0, 0 );
    this.scene.add( sprite1 );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing the old state in React js: A step-by-step guide

I have a collection of Faq elements. Clicking on a question should display the answer for that specific question while hiding all other answers. The issue I'm facing is that even though it displays the answer for the clicked question, it fails to hi ...

Using jQuery to serialize parameters for AJAX requests

I could use some help figuring out how to set up parameters for a $.ajax submission. Currently, I have multiple pairs of HTML inputs (i pairs): > <input type="hidden" value="31" name="product_id"> <input > type="hidden" value="3" name="qua ...

Is it considered acceptable to invoke Vuex actions asynchronously directly from router.js?

My goal has been reached. However, are there any negative consequences to this achievement? ...

Change when the div is shown or hidden

I'm attempting to add a transition effect when the DIV with the class .socialmenu is either shown or hidden. Below is the CSS code I've used, but it doesn't seem to be working: .socialmenu { bottom: 0; left: 0; right: 0; hei ...

Style the code presented within a div tag

I am in the process of creating a JavaScript-powered user interface that can generate code based on user interactions. While I have successfully implemented the code generation functionality and saved the generated code as a string, I am facing difficultie ...

Dynamic Setting of Protractor Driver Path

I have a test that needs to be executed on IE, CEFmp, and Chrome. The requirements are as follows: There should be a single conf.js file for IE, Cefmp, and Chrome. The test should dynamically read the browser type from a file and run the test accordingly ...

Receiving accolades within a nested function while implementing a Higher Order Component

I'm currently working on creating a Higher Order Component (HOC) to manage some functionalities in React. Here is my implementation: import React, { useState } from "react"; export default function withFormControl(WrappedComponent) { return props ...

I have always wondered about the meaning of " + i + " in Javascript. Can you explain it to

<script> var x,xmlhttp,xmlDoc xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "cd_catalog.xml", false); xmlhttp.send(); xmlDoc = xmlhttp.responseXML; x = xmlDoc.getElementsByTagName("CD"); table="<tr><th>Artist</th><th>Ti ...

List enhancement through various filters

I currently have data that is filtered by category. this.data = response.data.items.filter(item => item.category_id === categ_id) Now, I am looking to apply an additional filter to only show items with a certain quantity count. For example: this.data ...

Simplifying complex JSON structures by un-nesting arrays

Within my Formik form, I have 3 fields: MemberMemberID, EventEventID, and event_date. This form represents an event (such as a Tuesday club) taking place on a specific date and attended by various members. Formik stores the data in key-value pairs within ...

Javascript - eliminate elements that are either children or parents from an array

There is a code to remove child or parent elements from a random array that may contain both child and parent elements. For instance: <html> <body> <div id='1'> <div id='2'> ...

Unable to back out of side navigation

My side navigation menu is giving me some trouble. It opens up just fine when I click the button, but it won't close back up when I click it again. The button is supposed to toggle between opening and closing the side navigation. I've looked at ...

Invalidating Vue3 setErrors causes issues with defining fields

I have successfully implemented form validation using Vue 3, vee-validate, and yup schema. However, I am facing an issue when trying to validate errors returned from the server, such as a duplicated email. While setting custom error messages like this work ...

Meteor: Simplifying the process of deleting two documents from separate collections in MongoDB with just one click

There is a possibility that some "news documents" (from one collection) may contain an image (from another collection I'm using cfs:standard-packages and cfs:filesystem for file handling). Here is an example of a news document in the Mongo Database: ...

Conceal the nearest parent element above using JavaScript (or jQuery)

I need to implement a functionality where clicking a button hides a specific HTML class. The structure of the HTML is as follows: <thead> <tr class="employee-list"> <th> <button class="show-emp">S ...

Error: Unexpected TypeError occurred stating that 'map' cannot be read from undefined, although the map method is not being used in the code

I have recently developed an Ethereum application for conducting transactions using React and the ethers module. Below, you can see a snippet of my code, specifically focusing on the function sendTransactions: import {ethers} from 'ethers'; impor ...

Optimizing normals for unindexed BufferGeometry in Three.js

Currently, I am attempting to refine the normals of a mesh starting from an non indexed BufferGeometry. A similar query has been addressed in the past, however, the Three.js API has undergone significant changes since then and I am unable to make it work o ...

Cracked Code at Position 880 (LeetCode)

Given an encoded string S, the decoded string is determined by reading each character and following the steps below: If the character is a letter, it is written directly onto the tape. If the character is a digit (denoted as d), the current tape i ...

Sveltejs template not displaying on M1 MacBook Air after running - stuck on blank screen

Currently, I am in the process of learning Sveltejs and have been utilizing for the tutorial, which has been quite effective. However, I decided to work on developing and testing Sveltejs applications locally on my MacBook Air M1. I downloaded the provid ...

Change a date and time structure into just the time using JavaScript

I'm faced with a date and time form as shown below: 2021-06-04 11:23:37.000 I am attempting to convert this form to just the time: Post conversion: 11:23:37 Please note that the original form 2021-06-04 11:23:37.000 remains constant. ...