Mixing colors in THREE.js vertex shader based on height levels

How can I change the color of the mesh to blue only when the height is zero?

Currently, I am using a mixture of colors:

https://i.sstatic.net/x3s4d.png

The issue with this blending method is that it lacks precision. I want the color blue to appear only when the height is zero (inside the red path I created in paint).

I have customized a material for the mesh like this:

material = new THREE.ShaderMaterial({
                
                      uniforms: THREE.UniformsUtils.merge([
                      THREE.UniformsLib['lights'],
                      {
                    lightIntensity: {type: 'f', value: 1.0},
                    diffuse: {type: 'c', value: new THREE.Color(0x0000ff)},
                        color0: {
                          value: new THREE.Color("blue")
                        },
                        color1: {
                          value: new THREE.Color("green")
                        },
                        color2: {
                          value: new THREE.Color("brown")
                        },
                        color3: {
                          value: new THREE.Color("black")
                        },
                        bboxMin: {
                          value: geom.boundingBox.min
                        },
                        bboxMax: {
                          value: geom.boundingBox.max
                        }
                
                          }
                        ]),
                      vertexShader: `
                        uniform vec3 bboxMin;
                        uniform vec3 bboxMax;
                        varying vec2 vUv;
                            varying vec3 vPos;
                varying vec3 vNormal;
                        void main() {
                          vPos = (modelMatrix * vec4(position, 1.0 )).xyz;
                          vNormal = normalMatrix * normal;
                          vUv.y = (position.y - bboxMin.y) / (bboxMax.y - bboxMin.y);
                          gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
                        }
                      `,
                      fragmentShader: `
                        uniform vec3 color1;
                        uniform vec3 color2;
                        uniform vec3 color3;
                        uniform vec3 color0;
                        varying vec2 vUv;
                    
                        uniform vec3 diffuse;
                        varying vec3 vPos;
                        varying vec3 vNormal;

                        struct PointLight {
                          vec3 position;
                          vec3 color;
                        };
                        uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
                        
                        void main() {
                    vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
                      for(int l = 0; l < NUM_POINT_LIGHTS; l++) {
                        vec3 adjustedLight = pointLights[l].position + cameraPosition;
                        vec3 lightDirection = normalize(vPos - adjustedLight);
                        addedLights.rgb += clamp(dot(-lightDirection, vNormal), 0.0, 1.0) * pointLights[l].color;
                      }
                
                                  
                                            gl_FragColor = mix(vec4(mix(mix(mix(color0, color1, vUv.y), color1, vUv.y), mix(color1, color2, vUv.y), vUv.y), 1.0),addedLights, addedLights);
                                            }
                                          `,
                                        lights: true
                                        });

Answer №1

Consider utilizing the step() function. For a detailed explanation, refer to this definition. The functionality is as follows:

float step(float edge, float x)

  • This function takes a constant value for edge and a variable value for x.
  • If x is less than the edge value, it results in 0, otherwise, if x is greater than the edge value, it returns 1.

An example usage would be defining colors based on height values, such as transitioning from blue to green at a certain threshold.

vec3 green = vec3(0.0, 1.0, 0.0);
vec3 blue  = vec3(0.0, 0.0, 1.0);

float edge = 0.2;

float colorMix = step(edge, height);
vec3 finalColor = mix(blue, green, colorMix);

The choice of 0.2 for the edge value was made to provide a visible distinction between the blue and green regions.

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

Display or conceal a div based on the size of the screen using HTML and CSS

Hey there, I recently finished my first React Project and I’m wondering if there’s a way to hide the 'side-menu' section on mobile screens using CSS. Any suggestions? <div className='side-menu'> <SiderComponent /> < ...

Code for remotely connecting to a server and starting a Node.js application called app.js via SSH

I am attempting to establish an SSH connection to two servers sequentially in order to execute the following command: sudo node app.js This is the code I am using: #!/bin/bash while read line; do ssh -i "sshtest.pem" ec2-user@$line "sudo node app. ...

Sending AngularJS data using the POST method to be retrieved in PHP's $_POST

After successfully implementing a post request from my AngularJS app to a PHP script, I am now trying to ensure that the data received in my php script is stored in the $_POST['jwt'] variable. Below is an example of my AngularJS code: var dataR ...

jQuery: Issue with controller function execution when using ajax

Currently, I am working on developing a web application using C# MVC that dynamically fetches information from a server to enhance performance. However, I have encountered some errors and I am having trouble pinpointing the exact cause. Allow me to provid ...

Is there a way to utilize an X3D clipPlane on a singular object within a scene without causing interference with the rest?

I'm currently developing an application using X3D and I want to implement a clipping plane (clipPlane) for one specific object in my scene without impacting the other objects. However, it appears that when I define a clipPlane, it affects the entire s ...

Server crashing as nodemon encounters mongoose issue

Currently, I am in the process of learning Node JS, Mongodb, and Express JS. My goal was to create a database using Mongodb Compass and store some data within it. However, every time I attempt to run my code, my nodemon server crashes after a few minutes o ...

Troubleshooting problems with connecting Express JS and MongoDB

I've written a simple code to connect express js to mongodb, and I've installed both packages. However, I'm encountering an error. Can someone help me troubleshoot this? const express = require("express"); const app = express(); app.listen( ...

How can I target only one mapped item when using onClick in React/NextJS?

Apologies if this question is repetitive, but I couldn't find a better way to phrase my issue. The code in question is as follows: const [isFlipped, setFlipped] = useState(false); const flip = () => { if (!isFlipped) { setFlipped(tr ...

Implementing an import statement in an Electron renderer script

After following the Electron typescript quick-start code structure by cloning the repo, everything worked fine. However, when attempting to split my code into multiple .ts files and import them into the renderer script, I encountered an issue. Upon adding ...

Critical section in Node.js - transferring data from frontend to JSON file

I have a question about synchronizing requests for writing data to a file from multiple users simultaneously. In Java, there is the synchronized keyword but I am unsure how it can be achieved in Node.js. app.post("/register", function(req, res){ f ...

Tips for adjusting the position of an object when resizing the window

The problem at hand is as follows: Upon refreshing the page, my object is initially positioned correctly. However, resizing the window causes the object to resize and reposition correctly. But, if I refresh the page after resizing the window, the object i ...

Most effective method for adding JQuery events to dynamically generated buttons

I am dynamically generating Twitter Bootstrap modals based on user actions (Long Story). Sometimes, the user may see up to 100 modals on their screen. Each modal contains 5 dynamic buttons, each serving a different purpose with unique ids. I am using jQue ...

The jQuery click event to change the color function is functioning properly, but there seems to be an issue with

I'm having trouble changing the font-family using the code below, even though the color is changing properly. What am I missing here and how can I correct it? $(document).ready(function(){ $("body").on("click",".selectableColor", function(){ ...

Why is the React onClick method returning undefined upon the first selection, and why are the values being passed not consistent with

While attempting to create a list of users that, when clicked, should open up a corresponding user's message, I encountered an issue where clicking for the first time resulted in an 'undefined' value being passed. I've tried troublesho ...

What is the process for adding a stereo effect to a video-mapped sphere?

If I ensure all of my assets are properly linked and use either the oculusRiftEffect.js or StereoEffect.js plugins, how can I modify my html file to be compatible with Google Cardboard? You can find my Gist link below. https://gist.github.com/4d9e4c81a6b1 ...

Switch the displayed image(s) based on the radio button selection made by the user

I need help implementing a feature on my website where users can change an image by selecting radio buttons. For example, there are three options: 1) Fox 2) Cat 3) Dog When the user chooses "Fox," I want an image of a fox to be displayed. If they then sw ...

"An ActionResult is received as null when the model is passed as an

Has anyone encountered a situation where the model is null when passed to the controller? I inserted an alert in the ajax call to verify the value and it seemed correct, but upon debugging on the first line of the controller's ActionResult, it shows a ...

What makes node.js operate in an asynchronous manner?

After reviewing various 'suggestions' and conducting research, one question remains unanswered: Why does node.js operate asynchronously? Based on my findings: Languages like PHP and Python are considered scripting languages (although there may ...

Utilizing JavaScript text variables as hidden inputs

My JavaScript code is responsible for populating a modal from various sections of a website. Essentially, when the modal expansion button is clicked, it collects all data associated with that particular button press. While this functionality works flawles ...

Adding animation to a div that is being appended can be done by using JavaScript functions and

I am looking to incorporate animation into my title div. Below is the HTML code I have so far: <div class="particles" id="tittle"> <!-- Displaying title from Firestore using JavaScript --> </div> Here is the CSS cod ...