Updating textures dynamically for individual faces in a three.js environment

I have been facing a difficult challenge for some time now, struggling to achieve my goal while unsure if I am on the right path.

The Objective

My current project involves developing a three.js web application that loads JavaScript models and assigns custom materials using three.js. Specifically, I am focusing on creating natural lighting effects (including Global Illumination and Ambient Occlusion) on a house model by dynamically toggling the visibility of objects in different combinations. However, the issue arises when objects are moved independently, causing sticky shadows due to pre-baked lighting and ambient occlusion textures rendered in three.js without any real-time light sources.

The Dilemma

To address this problem, I have alternate texture maps available for various combinations of lighting. My approach involves updating specific faces' textures during runtime to display shadow-free textures when necessary, rather than relying on predefined textures with baked shadows.

Current Strategy

After extensive research, I have identified two key findings:

  • To update textures dynamically, I must utilize THREE.MeshFaceMaterial with multiple alternative materials and reference their indices later.

  • Changing individual faces' materials at runtime is not feasible; instead, modifying an entire material affects all connected faces sharing that material index.

I am attempting to implement a solution outlined in this example: (WebGL / Three.js Different materials on one complex object (grid)).

1) Implementation Issues

While I have successfully altered face colors dynamically, changing textures proves problematic. When applying THREE.MeshFaceMaterial to a geometry, the mesh displays random colors instead of the intended texture. Debugging tools can help identify the source of this issue, as checking the DOM structure reveals proper material assignment without errors.

2) Alternative Approaches

If I manage to resolve the texture updating challenges, ensuring seamless transitions between varying textures remains a concern. Will incorporating vertex colors or custom shaders be required to blend textures smoothly? Additionally, exploring solutions like light mapping and texture blending may offer insights, yet they seem unrelated to my immediate needs of dynamic lighting adjustments.

As a novice in game development practices, I seek advice on refining my approach to overcome these obstacles efficiently. How would an experienced game developer tackle this particular challenge?

Answer №1

Instead of relying on baked maps, I recommend exploring screen-space ambient occlusion (SSAO) techniques for a more adaptable approach when dealing with changing geometry. One of the simplest SSAO methods involves applying an unsharp mask to the depth of the scene. The original paper detailing this process can be found at: . This method is both elegant and straightforward - so much so that I was able to code my own version during a flight from San Francisco to New York with enough time left over for a nap.

Answer №2

To apply materials to all sides of a cube:

let materialIndex;
for (let i = 0; i < 12; i ++) {
    if(i%2==0) materialIndex = new_material_index;
    cube.geometry.faces[ i ].materialIndex = materialIndex;
}

The variable new_material_index should be replaced with the appropriate value.

To apply materials to one side, you need to pair up faces like {0,1}, ... {10,11}

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

Ways to alter the typography style if the text exceeds a certain length

I need some assistance with using Material UI in my ReactJs project with TypeScript. I am trying to decrease the font size of typography when the text exceeds 3 lines. Here is a snippet of my code: const checkFontSize =() => { if(text.leng ...

react-query: QueryOptions not functioning as expected when utilizing userQueries()

When passing certain "query options" while using useQueries() to fetch multiple queries simultaneously, these specified "query options" do not get applied during query executions (e.g. refetchOnWindowFocus has a value of true but I want it to be false). F ...

Rendering a component and updating state with inline onClick event handlers

When discussing the concept of pure render methods in React and highlighting the serious anti-pattern of setting state inside the render function, how strictly should this be adhered to? It is understood that triggering a setState within the render functio ...

The discrepancy between the heights of a div using Jquery and JavaScript

There is a container div encompassing all the site's content, which dynamically stretches. Additionally, there are multiple other divs that also stretch using the same method as in 20 other sites. Despite trying various methods with jQuery and JavaSc ...

The functionality of activating a button is not functioning as expected in AngularJS framework

Next to the question I have linked here, I am exploring a different approach. As a beginner in AngularJS/Cordova/Ionic, my goal is to achieve different outcomes when the "Eingepasst" button is clicked, each with unique logic compared to "Gewonnen" or "Ver ...

Guide on setting up and customizing run.json within the latest JetBrains Fleet for Next.js

I've been attempting to set up input/output for the latest IDE from JetBrains, Fleet. However, I've hit a roadblock and can't seem to figure it out on my own. That's why I'm turning to the Stack Overflow community for help - how do ...

`How can we efficiently transfer style props to child components?`

Is there a way to pass Props in the Style so that each component has a unique background image? Take a look at this component: countries.astro --- import type { Props } from 'astro'; const { country, description } = Astro.props as Props; --- & ...

Navigating to my own posts within Nuxt: A guide

Having trouble with internal links in my template, as they are not directing to the correct URLs. <nuxt-link :to="blog.url" >{{ blog.title }} by {{ blog.author }}</nuxt-link > In my data, I have the foll ...

I am currently dealing with an issue where 3 controllers are responsible for fetching data from a database and displaying it in a dropdown list. However, the problem arises when a value is selected from the list as it

This particular one serves as the main controller and module for this page. var bookinsert = angular.module('bookinsert', ['ngCookies']); bookinsert.controller('book_insert_ctrl', function ($scope, $http, $rootScope, $cookies ...

Is there a way to set up an automatic pop-up for this?

Experience this code function AutoPopup() { setTimeout(function () { document.getElementById('ac-wrapper').style.display = "block"; }, 5000); } #ac-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100%; back ...

Create a unique onblur event listener for every element in a loop in Javascript

https://i.sstatic.net/tRYul.png I have added several items to a column in the database, but I am unsure of how to implement an onblur function for validation for each item within a loop. For example, if the NAME field is empty, I want to display an alert ...

An unexpected 'u' token was encountered in the JSON data at the beginning while parsing with NextJS from the router.query

I have successfully passed data through the URL path from my main page to my quotes page component in NextJS 13. However, I encountered an error when trying to refresh the page. Quotes Page Component import React from 'react' import { useRouter ...

Avoid activating the panel by pressing the button on the expansion header

I'm facing a problem with the delete button on my expansion panel. Instead of just triggering a dialogue, clicking on the delete button also expands the panel. How can I prevent this from happening? https://i.stack.imgur.com/cc4G0.gif <v-expansion ...

Call getElementById upon the successful completion of an AJAX request

In the process of constructing a mini quiz, I am utilizing a variable quizScore to store the score. Each question in the quiz is displayed using AJAX. An individual AJAX call captures the ID of the button pressed (for example, on question 2, the button ID ...

JQuery: Techniques for accessing the assigned font of an element

Can the assigned font of an element be retrieved using jQuery? For example, if there is this CSS: #element { font-family: blahblah,Arial; } In the above case, the Arial font will be assigned to #element. Is it possible to extract that information using ...

Differences between using a getter in Vue.js/Vuex compared to directly accessing state values on the create lifecycle hook

As I utilize the created lifecycle hook within vue.js to fetch data from my store and pass it to a vue component's data, an interesting observation arises. When I employ this.selectedType = store.state.selectedType, the data is successfully retrieved ...

Deployment replacement in Kubernetes encounters error

I've developed a NodeJS script to deploy review apps to Kubernetes for my GitLab repository, using the Kubernetes NodeJS client. Including abbreviated definitions of Kubernetes resources for thoroughness: const k8s = require('@kubernetes/client ...

A guide on organizing JSX elements based on JSON data

What I Aim to Achieve: I am looking to display a list of elements using the .map method, and then arrange them in descending order based on their date. Despite attempting to use .sort and .filter before rendering the elements, I have not been successful. ...

Linking the location of the pop-up to the currently selected text box

I am currently experimenting with setting the top and left values relative to the selected_element (which is active at the time of triggering the popup) in a manner similar to a tooltip. I attempted to use $().position() in combination with jQuery, but it ...

Unlock the power of polymer iron-ajax by seamlessly linking input element data to the iron-ajax's body attribute

Having some trouble binding data from an input element to the "body" attribute of iron-ajax. In the past, using core-ajax in Polymer 0.5, I could easily bind values like so: <core-ajax id="ajax" method="POST" contentTy ...