What is the best way to put together the perfect attire for Threejs shaders?

I have been experimenting with using Three.js' built-in ShaderChunks for implementing lighting and fog effects, and I decided to start by mimicking a setup from one of the ShaderLib shaders. Initially, I utilized the following code snippet:

customMaterial = new ShaderMaterial({
    lights: true,
    uniforms: UniformsUtils.merge( [
      UniformsLib.common,
      UniformsLib.specularmap,
      UniformsLib.envmap,
      UniformsLib.aomap,
      UniformsLib.lightmap,
      UniformsLib.emissivemap,
      UniformsLib.fog,
      UniformsLib.lights,
      {
        emissive: { value: new Color( 0x000000 ) },
        diffuse: { value: new Color( 1,1,1 ) }
      }
    ]),
    vertexShader: document.getElementById("vertexShader").textContent,
    fragmentShader: document.getElementById("fragmentShader").textContent
  })

The shader code was directly copied from meshlambert_vert.glsl and meshlambert_frag.glsl, inspired by this entry in the ShaderLib.

However, when rendering my test scene with two different cameras/renderers simultaneously, I encountered an issue where changing one camera's perspective affected the lighting angle of objects using the customMaterial.

It seems that this could be related to the shared references of these UniformLib objects elsewhere.

Uncertain of the appropriate solution or why it works differently than the standard material, I suspect there is a missing step in the process that I am unaware of.

I have created a codepen to isolate the problem as much as possible, closely resembling the original ShaderLib source. My assumption now is that there might be a pass-by-reference where a copy should be made in the inner workings of the WebGLRenderer. https://codepen.io/cl4ws0n/pen/dVewdZ

Additionally, I attempted adding a second scene and moving objects between them but to no avail. Separate scenes with shared materials also did not resolve the issue. https://i.sstatic.net/UrqTV.gif

Answer №1

The WebGLRenderer component contains specific predefined criteria for different materials to follow. One example is the requirement for a flag labeled as isMeshLambertMaterial, which can be viewed at: https://github.com/mrdoob/three.js/blob/r87/src/renderers/WebGLRenderer.js#L1780

To address this, ensure that your material includes the attributes isMeshLambertMaterial: true and isMeshBasicMaterial: false.

Answer №2

Matjaz Drolc has pointed out a bug in version three r87, where the needsUpdate flags aren't working correctly for ShaderMaterials. To solve this issue, you can manually trigger an update before each render pass using the codepen link I provided, resulting in a correct rendering. Check out the fork here

I've raised an issue on the repository, so if you want to follow its progress, you can do so by visiting this link.

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

How can I customize a default button in HTML to hide the selected option from the dropdown menu?

Hey there! I'm currently working on a website that needs to be bilingual, with Spanish as the default language. I want to include a dropdown button that allows users to translate the content into English. Here's what I've tried so far: ...

Efficiently showcase connected pages in real-time

I've come across an issue with my express app. Whenever a navigation link (such as Home, Home1, or Home2) is clicked, an error occurs. However, if I manually type in http://localhost:8001/home1, it displays home1.html without any issues. What I' ...

What is the best way to handle an AJAX JSON response in AngularJS?

Need help with extracting properties from a JSON object returned by a REST service in AngularJS? Want to parse the firstName, lastName, and other attributes from the JSON response? Check out the code snippets below for guidance. Here is an example of an A ...

Form calculation

An issue has arisen with my calculating form for a client where an incorrect amount is displayed when 0.93 is entered into the percentage box. Original calculation: 10 x 10 x 15 x 0.93 = 13.95 Corrected calculation: 10 x 10 x 15 x 0.93 = 1.395 I am seek ...

What is the best way to send an XML body using Angular 5 with POST method?

I am currently developing an Ionic application that needs to make REST API calls with XML as the body. However, I am facing issues in getting the call to post with XML. This is my LoginProvider where I utilize DOMParser to parse data to XML before sending ...

False return - Inoperative link - Scroll option

I have a JavaScript drop-down menu that is functioning correctly, but when I click on one of the links in the dropdown, the link does not work. I suspect it has something to do with my "return false/true" setup. Here's my JavaScript code: function d ...

Using a Firebase token repeatedly: simple steps to follow

I have integrated Firebase Web Notification using Firebase SDK. The implementation process involves two files: a) generate-token.js and b) firebase-messaging.sw.js To get access token, permission is requested by calling requestPermission function. Upon ...

Switching the displayed image depending on the JSON data received

As a beginner in javascript and jQuery, I am working on displaying JSON results in the browser. My goal is to generate dynamic HTML by incorporating the JSON data. Below is an example of the JSON structure: [{"JobName":"JobDoSomething","JobStatus":2,"JobS ...

Are there any instances where CSS is overlooking certain HTML elements?

In the following HTML code snippet, the presence of the element with class ChildBar is optional: <div class="Parent"> <div class="ChildFoo"></div> <div class="ChildBar"></div> <!-- May ...

Create dynamic transitions for hidden elements using a special technique

Is it possible to smoothly transition a div element from display:none to display:block? I attempted to first set the display to block and then apply a transition, but it doesn't seem to be working as expected. HTML <input type="text" class="inp"& ...

Just delving into React for the first time and encountering undefined values in PropTypes

I am completely new to React and attempting to create a basic weather application in order to understand how components interact with each other. I have a forecast.json file that contains information such as temperature, date, humidity, wind speed, wind di ...

Using jQuery to dynamically add a class to elements that have tab focus

I want to apply a css class to elements that are focused by the tab key, without adding the class when focused by a mouse click. I have managed to achieve this using jQuery with the focusin and focusout events. Here is the code that I currently have: $( ...

The Vue.js @click event does not function properly when used in a selection on mobile

I designed a dropdown menu with different options, and when one is selected it updates the "Value" in vue to a specific amount. Then, I display the selected amount in an input field. For example: <select class="form-control" style="max-width: 150px;" ...

The hover functionality fails to activate when a z-index is applied

My issue revolves around 2 divs: one containing a link and the other a box-shaped container. The link is set with position:fixed; causing it to fly over the container div. To resolve this, I attempted to assign a negative z-index value to the link, but unf ...

Replace the hyperlink with plain text using JQuery

Is there a way to replace a hyperlink within an li element with different text but without removing the entire list item? <li class="pull-left"> <a href="#" class="js-close-post" data-post-id="1"> Close </a> </li> ...

Activate on click using JavaScript

When a link with the class .active is clicked, I want to use a JavaScript function to deactivate any other active links. The structure of the code should be as follows: <ul class="product"> <li><a href="#myanmar" class="active">Mya ...

Is it possible to establish a standard view for the date/time input field, disregarding the user's

When working with a Django Form, I am incorporating a datepicker. While the solution may involve JS and HTML, my query remains specific. date_field= forms.DateField( input_formats=['%Y-%m-%d'], widget=forms.DateInput( format=& ...

Interacting with PHP variables in JSON format

I've recently started using JSON to exchange data between pages, but I am facing a challenge that I can't seem to solve. Essentially, my issue lies in one page where I am utilizing jquery's getJSON method to retrieve JSON data from another ...

Having trouble sending AJAX select options with Choices.js

I'm currently utilizing Choices.js (https://github.com/jshjohnson/Choices) along with Ajax to dynamically populate data into my select field from a database. However, I've encountered an issue when using the following code: const choices = new C ...

Can these similar functions be combined into a single, unified function?

Currently, I have 3 functions - and more to come soon - that all perform the same task. However, they control different enumerated divs/variables based on which div triggers the mousewheel event. I am wondering if there is a way to condense these very si ...