Trimming a Three.js Sprite to conform with the boundaries of its parent Object

Imagine a scenario where I have a Sprite, which was created and added as a child of an Object with a transparent material, like so:

let mySprite = new THREE.Sprite(new SpriteMaterial({
    map: myTexture
}));

mySprite.scale.set(2, 2, 1.0);
mySprite.position.set(0, 0, 0);
myObject.add(mySprite);

The Object is set with depthWrite: false to allow visibility of the Sprite through it. However, due to the spherical shape of the Object and the square shape of the Sprite, the corners of the Sprite spill over the boundaries of the Object.

Is there a solution to trim or clip the corners of the Sprite so that only the content within the spherical Object is visible?

Answer №1

To add a touch of uniqueness, one option is to have the parents select a distinct ID to be applied to the stencil buffer

const parentMaterial = new THREE.MeshPhongMaterial({
  ...
  stencilWrite: true,                    // activate stencil writing
  stencilRef: stencilId,                 // set this value
  stencilZPass: THREE.ReplaceStencilOp,  // write if depth buffer test passes
});

Subsequently, configure the sprite to only render where that ID is found in the stencil buffer

const spriteMaterial = new THREE.SpriteMaterial({
  stencilWrite: true,                   // activate writing
  stencilRef: stencilId,                // 
  stencilFunc: THREE.EqualStencilFunc,  // render only if stencil = stencilRef;
  depthTest: false,
});

Keep in mind: writing to the stencil buffer has 3 scenarios. What to do if the stencil test fails, what to do if the depth test fails, what to do if both pass. The default action for all 3 is to do nothing. Hence, despite setting stencilWrite to true for the sprite, nothing will be written during sprite rendering due to the default behavior being set to do nothing (THREE.KeepStencilOp).

Ensure that the parents are rendered before the children. If they share the same position, this condition is likely satisfied. However, if they have different positions, adjusting the renderOrder may be necessary. In the provided example, the sprites are transparent and the bodies are opaque; by default, transparent elements are rendered after opaque elements.

Note: this method is limited to 255 sprites as the stencil buffer typically allows for only 256 possible values. For scenarios exceeding this limit, rendering in groups of 255 objects and clearing the stencil buffer between groups is essential.

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  ...
  // Code continuation (trimmed for brevity)

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

Transferring PHP variable to Javascript at a defined junction

My challenge involves passing a PHP variable to Javascript at a specific point in the code. The issue I am facing is that as the PHP code progresses, the variable I need undergoes changes. Although one option would be to extract the PHP variable when the p ...

Retrieving External JSON Data from a Server with Firefox

I've been developing a static local HTML5 charting application that retrieves data from a remote server for output. The code works perfectly in Google Chrome, as shown below, but I'm encountering difficulties getting it to function in Firefox. & ...

Encountering Issues with Accessing Property

Upon trying to run my code, the console is displaying an error that I am unable to resolve. The error specifically states: "TypeError: Cannot read property 'author' of undefined." View the StackBlitz project here The error seems to be coming fr ...

How can you obtain values from a nested JSON object and combine them together?

I have a javascript object that is structured in the following format. My goal is to combine the Name and Status values for each block and then store them in an array. { "datatype": "local", "data": [ { "Name": "John", ...

Is it acceptable to assign a value to exports.new?

In my venture with Node.js and Express, I am aiming for simplicity. Drawing from my experience with Rails, I am following the RESTful structure typical in Rails applications. In setting up my controllers (or routes), I want them to resemble this: // route ...

Make sure the page preloader is visible before any other content is loaded

Currently, I am working on a straightforward preloader page that remains visible until the main content of the page is completely loaded. Despite the functionality of the loading page, my main concern lies in the quick display of the main content before th ...

Creating a seamless integration between a multi-step form in React and React Router

I've been learning how to use React + ReactRouter in order to create a multi-step form. After getting the example working from this link: , I encountered an issue. The problem with the example is that it doesn't utilize ReactRouter, causing the ...

Designing templates for websites and applications using node.js

Simplified Question: As I delve into improving my skills with node.js, I'm exploring the concept of templating. How would using node to serve one HTML file and loading page-specific information through AJAX/sockets impact performance and design princ ...

The compilation of the module has encountered an error with the PostCSS loader. There is a SyntaxError at line 2, character 14 indicating an unknown

I am developing an Angular 8 application. Currently, I am incorporating AlertifyJs into my project. In the styles.css file of Angular, I have imported these libraries: @import '../node_modules/alertifyjs/build/alertify.min.js'; @import '. ...

Place an element in relation to the vertical size of a div that includes written content

Currently, I am working on implementing a button with a popup that appears underneath it when the user hovers over it. The specific requirements for this setup are: The size of the button should not affect the size of the popup The popup should always be ...

Creating a custom progress bar using Javascript and Jquery

I developed a progress bar that is fully functional. Here is the HTML structure: <div class="progress"> <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style ...

Encountering difficulties in transferring bulky files with the request module in Node.js

When working on a Node.js project, I encountered an issue with transferring files from the computer to the server. While I am able to successfully send files that are up to 2mb in size, larger files fail to upload. Here is the code snippet I am using: var ...

Exchange information among unrelated components

I'm working on implementing a vue event bus to facilitate event communication between my components. In my app.js file, I have included the line Vue.prototype.$eventBus = new Vue();. Within one component, I trigger an event using: this.$eventBus.$emit ...

Can you explain the significance of 1x, 3x, etc in the Karma code coverage report for Angular unit testing?

I am a beginner when it comes to Unit Testing in Angular. Recently, I set up karma with code coverage using angular-cli. After running the command ng-test, I checked out the code coverage report and noticed references like 1x, 3x, etc. next to my code line ...

How come these functions continue to be executed asynchronously even when the Async module is being utilized?

My decision to utilize the Async module aimed at populating a mongodb collection according to a specific order proved to be quite challenging. Despite the fact that the code worked without Async, it failed to insert documents in the desired sequence: func ...

Exploring the power of Vuejs3 with Internationalization and the Composition API

Currently, I am working on a frontend interface in VueJS and integrating i18n with Vuejs 3. While the normal implementation of i18n works fine, I encountered issues when trying to use it with the composition API. In my main.js file, I have set up i18n as ...

The issue of an unsuccessful Ajax call arises in a WordPress plugin when utilizing wp_remote_get

Encountering difficulties with the wp_remote_get function in my Wordpress plugin. The objective is to invoke a method within my primary public class using ajax. However, every time I attempt to make the call with the wp_remote_get function, it fails. This ...

A Guide to Retrieving HTML Content Using jQuery's Ajax Method

I am working on a page that contains Option elements with Values linking to external pages. My goal is to utilize Ajax to retrieve the selected Option's Value and use it to load content from those external pages. For example, if a user selects Volleyb ...

How can you prevent the blur event from triggering in jQuery when the next element to receive focus is of a specific type?

I am currently developing a unique form UI where I am working on creating a custom select box replacement. The custom select control consists of a hidden select input within a div, along with anchor elements inside a span that mimic the options of the sele ...

Warning: Promise rejection not handled in error

I've been working with nodejs, express, and argon2 in my project. However, I encountered an error that has left me puzzled as to why it's happening. Strangely, even though I don't have any callbacks in my code, this error keeps popping up. H ...