What is the best way to locate all mesh faces that are being lit up by a SpotLight

I am working with a THREE.Mesh that consists of a THREE.BufferGeometry containing "position" and "normal" THREE.BufferAttributes.

This mesh is being lit by a THREE.SpotLight (which is a cone-shaped light source).

Is there a method to identify all the faces of the mesh that are being illuminated by the cone-shaped light? There are no other objects present in the scene, so obstruction is not a concern.

Answer №1

An elementary strategy

Looking at it in a simplistic way, the phrase "illuminated by" could also be interpreted as "within or crossing over, and directly facing the cone."

Initially, establish whether the face is located inside or intersecting the cone. To achieve this, gather all three vertices of the triangle and form a Vector3 indicating the direction from the spotlight.position to each vertex.

// Keep in mind: Extracting the vertices of a face varies based on whether it is indexed.
// Consider "vertex1", "vertex2", and "vertex3" as the face's vertices.

// Converting the vertices into World Coordinates
mesh.localToWorld( vertex1 )
mesh.localToWorld( vertex2 )
mesh.localToWorld( vertex3 )

// Obtaining the spotlight's direction of focus
const spotLook = new Vector3().subVectors( spotlight.target.position, spotlight.position )

// Adjust the vertex vectors relative to the spotlight
vertex1.sub( spotlight.position )
vertex2.sub( spotlight.position )
vertex3.sub( spotlight.position )

// Calculating the angles between the vectors
const angle1 = spotLook.angleTo( vertex1 )
const angle2 = spotLook.angleTo( vertex2 )
const angle3 = spotLook.angleTo( vertex3 )

If ANY of these angles is below the spotlight.angle threshold, then that specific vertex is situated within the spotlight's cone. If all angles exceed the spotlight's angle, then they are all outside the cone.

Next, determine if the face is oriented towards the spotlight by normalizing the vectors between the vertices and finding their cross product.

// These represent the original values of the vertices
vertex1.sub( vertex2 )
vertex1.normalize()
vertex3.sub( vertex2 )
vertex3.normalize()
const crossed = new Vector3().crossVectors( vertex3, vertex1 )

This yields the "face normal," denoting the direction in which the face is pointing. Again, leverage angleTo to ascertain the angle against the spotlight's direction. If the angle exceeds Math.PI/2 (90°), then the face leans towards the spotlight. If greater than that value, the face tilts away from the spotlight.

If a face meets both criteria—facing towards the spotlight AND having at least one vertex inside the cone—then it can be presumed illuminated.

Considerations

Naturally, this method is rudimentary and delivers fundamental outcomes.

Situations may arise where portions of your shape obscure its own faces (self-shadowing).

The actual normals of the face might hinder its light reception. Even if the face points towards the spotlight, if all the normals are angled away, the shader would not illuminate the face despite being technically within acceptable boundaries.

Instances may occur where the penumbra of your spotlight prevents a face from being illuminated, even when parts of it lie within the spotlight cone.

These scenarios necessitate consideration to attain your desired results.

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

What could be causing React to not re-render the page when the button is clicked?

function MyApp() { const [usersData, setUsersData] = useState([]) useAsyncEffect(async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users') const users = await response.json() setU ...

Formatting decimals with dots in Angular using the decimal pipe

When using the Angular(4) decimal pipe, I noticed that dots are shown with numbers that have more than 4 digits. However, when the number has exactly 4 digits, the dot is not displayed. For example: <td>USD {{amount| number: '1.2-2'}} < ...

Comparing the architecture of two JSON objects in JavaScript without taking into account their actual content

One of the tools I rely on for my projects is a Node.js based mock server that helps me specify and mock API responses from the backend. However, it would be beneficial to have a way to ensure both the backend and frontend are in sync with the specified st ...

The curious case of unusual behavior in jQuery's livequery() method

When attempting to use the jQuery plugin "livequery" to highlight certain words within dynamically generated search results, the highlighting does not appear to work! Strangely, adding an alert() function before executing the code causes the highlighting ...

Incorrect implementation of Bootstrap CSS in Jade template

Currently, I am leveraging Express to construct a website. However, there seems to be an issue with my jade template not displaying the bootstrap grid system accurately. Despite double-checking that my app path is correctly set through app.use(express.stat ...

JSON Nesting with Ember.js and Rails

I'm currently developing a simple Ember / Rails application that involves multiple nested relationships. For instance: class Release < ActiveRecord::Base has_many :tracks end Upon accessing my Releases endpoint, I receive JSON data in the follo ...

Revamp the angular design of the mat-tree UI bottom border line issue

Can you help me with changing the direction of the mat tree from right to left? I need to remove the bottom border, please refer to the image https://i.sstatic.net/ecRIO.png here ...

Retrieve the id for the chosen user name within a function that contains an array of objects

const userList = [ {name:"jonh" ,id:EAD1234}, {name:"peter" ,id:EAD1235}, {name:"matt" ,id:EAD1236}, {name:"henry" ,id:EAD1237}, ] In the array above, there are various users with their respective IDs. The goal is t ...

Encountering issues with JavaScript/ajax if statement functionality

Driving me insane! Dealing with 2 modal forms - one for login and another for registration. Javascript handles client-side validation, followed by an ajax call to either a registration or login php file. The PHP files return 'OK' if successful or ...

Encountered an issue during my initial AJAX call

Hello everyone, I am currently attempting to use AJAX to send a request with a button trigger and display the response HTML file in a span area. However, I am encountering some issues and need help troubleshooting. Here is my code snippet: //ajax.php < ...

Strategies for transmitting computed variables from a controller to JavaScript once the computation is complete?

Within my application, I have a button that triggers an action called "method" present in the UserController. This particular action involves executing some specific tasks. def method ***performing necessary calculations and operations*** @my_variable ...

What is the best way to display a button only during office hours from 9am to 5pm using React.js or JavaScript?

If I want a button to only be visible from 9am to 5pm, how can this be achieved where the button is hidden outside of that time frame? ...

I'm encountering issues with this code for a dice game. It's strange that whenever I click the roll dice button, it disappears. Additionally, linking an .css sheet seems to cause the entire page to

I'm currently working with two separate codes: one for HTML and the other for JavaScript. I am facing an issue where the button keeps disappearing when I try to add any CSS styling to it. Even a basic CSS file seems to override everything else and lea ...

What is the best way to utilize purgeCss in conjunction with other module exports?

After reading the documentation, I want to integrate purgeCss into my NextJS project. The recommended configuration in the docs suggests updating the next.config.js file like this: module.exports = withCss(withPurgeCss()) However, I am unsure where exact ...

How to use jQuery to hide list items after a certain threshold

$('li[data-number=4]').after().hide(); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul> <li data-number="0"">1</li> <li data-number="1">2</li> ...

Generate a collection of information by gathering metadata from Xray

I've been struggling to populate an array with metadata retrieved using Xray. The issue arises when the function is called by an API endpoint on my server to fetch links from my application. My main challenge seems to be related to promises, as there ...

Stopping the Bootstrap carousel when an input is focused

I have a Bootstrap carousel with a form inside. The carousel is set to pause when hovered over, but I noticed that if the cursor leaves the carousel while typing in the inputs, it goes back to its default cycle of 5000ms. I want the carousel to remain pau ...

Is it possible to dynamically change the object name using $.ajax function and pass it as a

I'm attempting to parse multiple JSON files into different objects. Here is my approach: function downloadDataSave (targetObject) { // DOWNLOAD CALCULATION BACKUP var filename, response; filename = targetObject.name + '.json' ...

In my experience, Angular will generate an error if a form tag in HTML contains special characters, such as the colon symbol ':' in the 'name' attribute

Currently, I am in the midst of a Salesforce project and I am contemplating utilizing Angular JS for its remarkable capabilities. One issue I have encountered is that Salesforce prefixes form attributes like name and id with dynamic IDs. For example, if th ...

Step-by-step guide on dynamically fetching additional images from a directory using php, jquery, and ajax

I have a scenario where I have multiple folders, each containing up to 20 images. On my HTML page, I want to display the first 5 images and provide a "click to view more" option to show the remaining 15 images when clicked. Currently, the issue I am facin ...