How can I make transparent png sprites in three.js cast and receive shadows?

Is there a way to enable sprites in three.js to cast and receive shadows without rendering the alpha channel as a shadow?

I have all my assets saved as transparent PNGs, and while mapping textures onto sprites is working well, I'm struggling with the issue of shadows. Ideally, I'd like the shadow cast by the sprite to ignore the PNG's alpha channel so that light can pass through it, but I haven't found much information on how to achieve this in the three.js documentation.

Thinking along the lines of PaRappa the Rapper or Adventure Xpress style, any suggestions would be greatly appreciated!

Answer №1

Unfortunately, sprites in three.js do not have the ability to cast shadows.

However, there is a workaround available by using PlaneBufferGeometry and ensuring it always faces the camera:

scene.add( plane );

Then, within the render loop:

plane.lookAt( camera.position );

If you wish for the plane not to cast a shadow where its texture is transparent, you will need to create a custom depth material. You can find an example of this in this specific three.js example.

Without implementing a custom depth material, the plane will appear as solid when viewed from the perspective of the light source.

Version: three.js r.76

Answer №2

Here are the shaders that I ultimately decided to use.

Fragment shader. Adjust the alpha value of the pixel by modifying pixel.a in this fragment shader. If the alpha value drops below 0.5, the fragment shader discards the pixel, making it appear transparent.

#include <packing>

uniform sampler2D texture;
varying vec2 vUV;

void main() {

    vec4 pixel = texture2D( texture, vUV );
    if ( pixel.a < 0.5 ) discard;
    gl_FragData[ 0 ] = packDepthToRGBA( gl_FragCoord.z );

}

Vertex shader. This vertex shader is pretty standard. I thought I'd include it here just in case your current vertex shader is causing any issues. Rest assured, this one works seamlessly with the above fragment shader.

varying vec2 vUV;

void main() {

    vUV = uv;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1 );
    gl_Position = projectionMatrix * mvPosition;

}

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

Utilizing React Router with Material-Table for Efficient Column Value Filtering

Is there a way to dynamically pass Route params into the filtering fields of a React table component? I am currently utilizing the material-table component and have a list of links structured like this: <ul> <li> <Link to="/Products/ ...

Maximizing JavaScript DOM efficiency

In my code, I have numerous elements that need to be hidden and displayed dynamically. To facilitate this, I plan on utilizing the document.getElementById('x').style.display method. However, instead of directly using this method each time, I have ...

Passing data from input to Angular's $scope (filter)

I'm currently working on my first custom filter, and while the basic principle is functioning (it displays all the CDs of an artist from 7 and up), I'm encountering an issue where the filter doesn't update when I change the value. It consist ...

How can I cut an array by value in Vue?

I am working on a component that has a list of objects and I need to implement functionality where, when toggled, the objects' title prop is either added to or removed from an array. Adding the value was easy to do, but removing it has proven challeng ...

Convert an array to a string using a JavaScript function

I am encountering an issue with the code below: Every time I pass the Array to "track," I encounter an error. It seems like there might be a mismatch between passing an object and a string as input, but I am uncertain and unable to verify. for (var i = 0; ...

What is the best way to transfer data in a JavaScript onclick event and then retrieve it in the click handler function?

I've been struggling with this issue for some time now. When researching the onclick JavaScript call, I noticed that sometimes it is written as onClick with a capital C, while other times it's simply onclick. The code I'm working on is part ...

Exploring the power of TypeScript for authenticating sessions with NextJS

Utilizing next-auth's getSession function in API routes looks something like this for me: const mySession = await getSession({ req }); I have confirmed that the type of the mySession is outlined as follows: type SessionType = { user: { email: s ...

positioning a text input in the center instead of at the top of the page

Hello everyone, I am just starting out with HTML and I have a question. How can I make the Username: <input type="text" name="Username" style="- margin-top: 200px;"> appear in the center of the page instead of at the top? I've tried changing the ...

Tips for identifying a particular kind of user within a group of users

Incorporating nodeJs along with mongoDB, I have created a user collection that stores two types of users: student and teacher. Currently, I am seeking a way to retrieve all users belonging to the student type. ...

What is causing Puppeteer to incorrectly capture this page when attempting to take a screenshot?

Utilizing the Node.JS library puppeteer, this code captures a screenshot of a webpage and saves it as a png image: #!/usr/bin/env node const puppeteer = require("puppeteer"); (async () => { const browser = await puppeteer.launch({args: ['--no- ...

Is the presence of a potential leak suggested by this arrangement in the heap snapshot retainer hierarchy

While analyzing a Heap snapshot, I came across a retainer hierarchy that looks like this: https://i.sstatic.net/Zg3bJ.png Is it possible that the MuiThemeProviderOld element (highlighted in yellow and from the @material-ui/core library) is causing a memo ...

Utilizing JSON data for efficient React component rendering

As a newcomer to React, I am currently in the process of constructing a dashboard that showcases data from three different sensors. The information regarding these sensors is stored in a single JSON file where each sensor has its own ID and name. This JSON ...

Display the list items when the page first loads

I currently have this code snippet: <nav> <ul class="sel"> <li> <a href="#LINK1" data-title="A">A</a> </li> <li> <a href ...

JavaScript object that is simultaneously multidimensional and associative

I have a requirement to create a multidimensional associative object, and I've managed to get it partially working. Here is a simplified version: var sources = { tales: ['some content', 'some more content'], thehut: [&ap ...

enhancing the style of my Express project with CSS and EJS

Currently, I am facing challenges with linking CSS to my EJS files in a project I am developing using Node/Express/EJS. Despite creating a public folder with a CSS subfolder and the main.css file inside, I am unable to get the CSS to display in the browser ...

JavaScript: Efficient method for converting currency values within an array

Hello everyone, I have come up with the code below to convert currencies, but the issue is that I am manually listing out each currency in a switch block. If I have a hundred currencies to convert, I would need to create a hundred switch cases. Is there a ...

What is the proper way to select this checkbox using Capybara in Ruby?

Is there a way to successfully check this checkbox?view image description I attempted the following: within('div[id="modalPersistEtapa"]') do element = @driver.find_element(:xpath, '//*[@id="2018_4"]/ ...

arrange list in Angular.js

Currently, I am attempting to sort an array using Angular JS with the orderBy function. However, I am experiencing difficulties sorting it based on a specific key. Below is the code snippet: var app = angular.module('sortModule', []) app.contr ...

during implementation of ng-repeat directive with JSON dataset

When I receive JSON data and attempt to display it using the ng-repeat directive, I encounter an error ng-dupes error <table> <tr ng-repeat="emp in empArr"> <td>{{emp.empcode}}</td> <td>{{emp.empName}}< ...

Issue with Three.js GLTF loader peculiar behavior while attempting to incorporate three-dimensional text

I had an idea to import a prebuilt gltf scene created in Blender, then add some 3D text using the ttf loader and manipulate it. Each loader worked perfectly when used separately, but strange things started happening when I combined them into a single scrip ...