How can a color gradient blend be applied to geometry on multiple axes using THREE.JS shader?

After referencing Apply color gradient to material on mesh - three.js

I successfully implemented a flower shader that applies a vertical color gradient across the Zinnia. The colors transition from red to yellow vertically, creating a gradient based on height. (refer to image 1)

Here is the selected vertex shader:

      float f = clamp((vPos.z - bbMin.z) / (bbMax.z - bbMin.z), 0., 1.);
      vec3 col = mix(color1, color2, f);
      vec4 diffuseColor = vec4( col, opacity );

And the selected fragment shader:

      gl_FragColor = vec4(mix(color1, color2, vUv.y), 1.0);

The code above indicates that the color gradient properly responds to the z-axis.

I also managed to create a flower shader where the color transitions from black at the center of the rose to red at the edges, responding to the Y axis horizontally. (refer to image 2)

Here is the selected vertex shader for this setup:

      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);

And the selected fragment shader:

      gl_FragColor = vec4(mix(color1, color2, vUv.y), 1.0);

This code demonstrates that the color blending occurs along the y-axis in this instance.

(FINALLY!) My question: How can I combine these two shaders to achieve a composition where the center of the flower darkens towards black as it approaches the center, while maintaining the existing vertical gradient? The blend from black to red would occur on the y-axis (or even from black to transparent?), and the blend from red to yellow on the z-axis? -- This adjustment aims to add depth to the zinnia when viewed from the side.

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

https://codepen.io/ricky1280/pen/zYWyzQv (shader begins on line 271 in html of this pen)

To ensure petals are visible from a perfect profile view:

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

https://codepen.io/ricky1280/pen/RwMEgmj (shader starts on line 227 of html in this pen)

For example, here is the red-yellow shader applied to the rose, with the gradient visible from a perfect profile view https://i.sstatic.net/sVtuX.png

https://codepen.io/ricky1280/pen/dymwRBW (shader starts on line 265 of html in this pen)

(for instance, the red-yellow shader applied to the rose creates a visible gradient from a profile view)

Thank you for taking the time to read through all this—I struggle with GLSL, so any assistance would be greatly appreciated.

Answer №1

I have adjusted the fragment shader to achieve a specific effect:

float f = clamp((vPos.z - bbMin.z) / (bbMax.z - bbMin.z), 0., 1.);

// Calculate distance to center of XY plane
float distCenter = length(vPos.xy);

// Re-map values to range [0.0, 0.2] => [0, 1]
distCenter = smoothstep(0.0, 0.2, distCenter);

// Multiplying by 0 results in black color
// Multiplying by 1 maintains original color value
vec3 col = mix(color1, color2, f) * distCenter;

vec4 diffuseColor = vec4( col, opacity );`

Result:

The flower transitions to black as it reaches the center of the fragment: https://i.sstatic.net/rTqgc.jpg

You can adjust the 0.2 value within the smoothstep() to control the width of the gradient. If you are unfamiliar with the length() function, you can learn more about it in the Book of Shaders glossary.

Answer №2

If you're looking to merge these two shaders together, the solution is simple - just combine them!

https://example.com/image.png

Here's how the material will appear:

    let mergedMaterial = new THREE.MeshBasicMaterial({
      roughness: 1,
      metalness: 0,
      side: THREE.DoubleSide,
      onBeforeCompile: shader => {
        shader.uniforms.param1 = uniforms.param1;
        shader.uniforms.param2 = uniforms.param2;
        shader.vertexShader = `
        varying vec2 vUv;
        varying vec3 vPos;
      ${shader.vertexShader}
    `.replace(
          `#include <begin_vertex>`,
          `#include <begin_vertex>
    vPos = transformed;
    vUv = uv;
    `
        );
        shader.fragmentShader = `
        uniform vec3 param1;
        uniform vec3 param2;
        varying vec2 vUv;
        varying vec3 vPos;
      ${shader.fragmentShader}
    `.replace(
          `vec4 diffuseColor = vec4( diffuse, opacity );`,
          `
      float value = clamp((vPos.z - param1.z) / (param2.z - param1.z), 0., 1.);
      vec3 colorMix = mix(param1, param2, value);
      vec4 diffuseColor = vec4( colorMix, opacity );`
        );
      }
    });

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

Does jqgrid navgrid have an event called "on Refresh"?

Is there a way to trigger an event before the grid automatically refreshes? I am looking for something similar to "onSearch" but for the reset button. Below is the code snippet for the navgrid: $("#jqGrid").jqGrid('navGrid','#jqGridPag ...

Setting a fixed data value within a div for subsequent retrieval through a function

I found a helpful example that demonstrates how to convert numbers into words. You can check it out here. The function for converting numbers into words is implemented in the following HTML code: <input type="text" name="number" placeholder="Number OR ...

The PKIJS digital signature does not align with the verification process

Explore the code snippet below const data = await Deno.readFile("./README.md"); const certificate = (await loadPEM("./playground/domain.pem"))[0] as Certificate; const privateKey = (await loadPEM("./playground/domain-pk ...

Leverage Next.js 13 to utilize both search parameters and route parameters in a static site

I'm currently in the process of setting up a blog using the Next.js application directory. I have a route that is structured as follows: /blogs/category/[name] This route displays all blogs within a specific category and utilizes an SSG page, implem ...

Three.js strategy for selecting elements in 3D scene with marquee feature

I'm in the process of developing a 3D model editing application with the help of THREE.js. This application allows users to load CAD models and visualize them on the screen. Users can manipulate the camera to pan, zoom, and rotate around the scene to ...

Is there a way to retrieve command line arguments from a running Electron Application?

I am currently facing a challenge with retrieving command line arguments from an Electron application. When the application is launched with command line arguments, I need to utilize these arguments in the renderer process (specifically within a webview). ...

When utilizing Ionic Firebase, the user profile saved in the sidemenu is stored using the Events class. However, the saved profile disappears as soon as

Hello there. I am currently working on displaying my user's information in the sidemenu, and after some research, I found that using the Events class might solve this issue. However, I have noticed that the data saved in subscribe gets destroyed whene ...

What strategies can be employed to streamline the code provided?

Can someone help simplify this JavaScript code for me? I would really appreciate it. Thank you! $(function() { $("#show1").click(function() { $("#showmore1").toggle(); }) $("#show2").click(function() { $("#showmore2").toggle(); ...

What is the best way to utilize the GET Method with a hashtag incorporated into the URL?

For instance: www.sample.com#?id=10 Currently, I am not able to retrieve any value from $_GET['id']. Despite my attempt to eliminate the hashtag from the URL using JavaScript, no change occurs: $(document).ready(function(){ $(window.location ...

Apollo Server Studio is failing to detect the schema configured in Apollo setup

Here is the stack I'm working with: Apollo Server, graphql, prisma, nextjs I've set up a resolver.ts and schema.ts for my graphql configuration under /graphql resolver.ts export const resolvers = { Query: { books: () => books, } ...

What is the best way to activate a CSS animation?

I've hit a roadblock while attempting to trigger a CSS animation. Here's my CSS: h3[id="balance-desktop"]{ color: black; -webkit-animation-name: gogreen; -webkit-animation-duration: 2s; animation-name: gogreen; animation-du ...

Explore the associative array within a JSON using jQuery to extract and manipulate the values within the array

I'm working with a JSON file containing surnames and first names in an array, along with other objects. How can I specifically extract the names "Jhon" and "Jason"? Below is a snippet from my JSON file: [{ "surname": "Vlad", "first_name": [ ...

Ways to insert HTML text into an external webpage's div element without using an iframe

Is it possible to generate HTML and SVG code based on the position of a Subscriber on a web page or within a specific div? I would like to provide some JavaScript code that can be inserted inside a particular div on the page. Using an iframe is not ideal ...

Utilizing jQuery for serializing unorganized lists

I have created multiple lists within a list and I need to pass the IDs using jQuery to another PHP file (updateDB.php). I attempted to serialize the list data but was unsuccessful. I'm not certain if I have implemented it correctly, I searched extens ...

Angular's watch feature fails to trigger when the value is modified

My setup includes two sliders, one for brightness and the other for contrast. They are linked to a "brightness" model and a "contrast" model. These sliders are located within a tab interface, and I noticed that every time the tab was changed, the values we ...

I'm curious if it's possible to modify a webpage loaded by HtmlUnit prior to the execution of any javascript code

To begin, I want to elaborate on the reasoning behind my question. My current task involves testing a complex web page using Selenium + HtmlUnit, which triggers various JavaScript scripts. This issue is likely a common one. One specific problem I encount ...

Creating a function in React to be passed as a prop

Recently, I was given the task of enhancing a user interface as a small challenge to help me dive into the world of programming. My goal is to incorporate a date picker into my search bar to allow users to filter their search results by selecting specific ...

Comparing a number to the sum of numbers in JavaScript using VUE

Newbie in the world of JavaScript and VUE. In my data, I have a variable called numberOfItems with a value of 10. I am trying to check if this value is equal to the total sum of 5 different variables. var numberOfItems = 10 var destinations = (this.campa ...

"Integrate a URL segment into the primary URL with the help of AngularJS or JavaScript

One interesting case involves a URL path that is structured in the following way. http://localhost:12534/urlpart1/urlpart2?querystring=140 The challenge here is to replace "urlpart2" with "urlpart3" using either javascript or AngularJS. One approach is t ...

Tips for altering the background of a video on Vonage

Hello everyone, Currently, I am incorporating the Vonage API for video calling into my project. I would like to tweak the video background - does anyone have any ideas on how to accomplish this? I eagerly await your responses! Thank you in advance! ...