Create a standard chart with a colored map using Three.js

Recently, I dove into the world of Three.js and found myself on a mission to convert a color map into a normal map. My goal is to create a normal map similar to [image 2], based on the color map shown in [image 1]. Instead of simply uploading files, I wanted to find a way to achieve this without adding unnecessary weight to the project. Here's what I've experimented with so far:

let img = new Image();

img.src = './texture/color.jpg';
img.onload = function () {
    let canvas = document.createElement('canvas');
    canvas.width = img.width;
    canvas.height = img.height;
    document.getElementById('body').appendChild(canvas)
    const c = canvas.getContext('2d')
    c.clearRect(0, 0, canvas.width, canvas.height);
    c.fillStyle = '#EEEEEE';
    c.fillRect(0,0,canvas.width, canvas.height);

    //draw background image
    c.drawImage(img, 0, 0);
    //draw a box over the top
    c.fillStyle = "rgba(200, 0, 0, 0)";
    c.fillRect(0, 0, canvas.width, canvas.height);

    draw(c, canvas);
};


function draw(c, canvas)
{


    let img2 = c.getImageData(0, 0, canvas.width,canvas.height);
    console.log(img2.data)
    let d = img2.data;
    for (let i=0; i<d.length; i+=4) {
        let r = d[i];
        let g = d[i+1];
        let b = d[i+2];

        v1 = r < 75 ? r / (50 - r) : r * (255 - r);
        v2 = g > 75 ? g / (50 - g) : g * (255 - g);
        v3 = b > 75 ? b / (50 - b) : b * (255 - b);

        d[i] = v1;
        d[i+1] = v2;
        d[i+2] = v3;
    }
    console.log(img2.data)
    c.putImageData(img2, 0, 0);
}

Answer №1

I have limited knowledge about Three.js, but from what I do know, it simplifies the process of integrating 3D assets with canvases effortlessly.

On another note, I have developed a pure JavaScript function that effectively generates normal maps from color maps. This function was originally created in C# for winforms about 4 years ago and has been ported to JavaScript. It employs a recursive algorithm to extract the necessary data for conversion, resulting in slow processing speed due to the intricacy involved in obtaining high-quality normal maps.

Despite the slow processing speed, the function produces clean and precise normal maps from given color maps, offering a straightforward understanding of its functionality.

I have provided a live demo for you to observe the function in action.

While there are faster solutions available for pixel data manipulation, the method I implemented utilizes nested recursion to showcase the Sobel algorithm and pixel manipulation effect, enabling a clear demonstration of normalization.

Asynchronous updates have not been included in this implementation, so you will be alerted to the processing by a change in the cursor icon while the map generation is in progress.

Additionally, I have included four variations of the original image within the code, with three out of four variants commented out. The application begins at a 256x256 scale for a reasonable processing time. The sizes range from 128 to the original 1024, although I recommend avoiding the full-scale version as it may cause operation delays in your browser.

Similar to the C# version, users can control the intensity of the resulting normal calculations by adjusting the brightness parameters. This functionality could serve as a foundation for generating real-time normal maps applied to geometries within Three.js, offering a visualization of the mapping process.

Below is a screenshot of the results obtained after processing the 256x256 image:

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

To complement the live demo, here is the code provided:

normalize.htm

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Normalizer</title>
<link rel="stylesheet" href="css/normalize.css">
</head>
<body onload="startup()">
    <canvas id="input" class="canvas"></canvas>
    <canvas id="output" class="canvas"></canvas>
    <div class="progress">
        <input type="button" class="button" onclick="totallyNormal()" value="Normalize!" />
        <span id="progress">Ready to rock and / or roll on your command!</span>
    </div>
    <script src="js/normalize.js"></script>
</body>
</html>

normalize.css

  html {
    margin: 0px;
    padding: 0px;
    width: 100vw;
    height: 100vh;
  }

  // Additional CSS code continues...

normalize.js

// JavaScript code for the Normal Map Generator
// Implementation by Brian "BJS3D" Spencer
// Incorporating W3C-proposed algorithm for pixel brightness calculation with the Sobel Operator.

// Further code continues...

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 methods can be used to authenticate the user's input?

I am facing an issue with my program where it breaks if there is a space behind the last number entered. I want to prevent the function from breaking when a space is entered. I tried using $.trim but couldn't get it to work. I also attempted using an ...

Updating the value of a rails parameter with JavaScript

I am trying to enhance my search form by pre-populating the fields with the "last searched values" when a user submits a search. The search form and results are displayed on the same page, and if there is no previous search, the fields should show placehol ...

JavaScript array images are not showing when using the img tag

For this module, I am working on creating a flipbook (magazine) using images stored in a JavaScript array. However, I am facing an issue where the images are not loading up properly. Instead of displaying the image, it shows as [object" htmlimageelement]=" ...

Having trouble accessing properties that are undefined while using react JS, specifically when trying to read a 'map' property

Currently, I am in the process of building a blog with ReactJS and NextJS within VS Code. Despite not encountering any errors during coding, when I attempt to run it, the browser displays: "TypeError: Cannot read properties of undefined (reading 'map& ...

How can I change the transparency of a CSS background color using JavaScript?

I have a question about CSS: .class1 { background: #fff } Now, I need to achieve the following: .class2 { background: rgba(255,0,0,0.5) }; Is there a way to use JavaScript only to change the background property of .class1 and give it an opacity of 0.5? ...

Tips for Incorporating the YouTube Iframe API into Your ReactJS Project

While working in React, I am attempting to build a custom YouTube player component that includes a new set of player controls. The YouTube iframe API provides the following code snippet for creating a player instance: var tag = document.createElement(&ap ...

File upload tool for CKEditor 5 with Angular integration

Looking to develop a versatile file upload plugin for various document types (pdf, docx, etc.) that can upload to a server and generate links within the document. I've been researching potential solutions over the past couple of weeks, but many of th ...

Issue with AngularJS: error:areq Invalid Argument

<!DOCTYPE html> <html ng-app> <body data-ng-controller="SimpleController"> <div class="container"> Title: <br/> <input type="text" ng-model="title" />{{title}} <br/> ...

I must determine whether the contents of an array exceed zero

THE SUMMARY: I have three value numbers for an array. If the total addition of the array's elements is greater than 0, I need to display "el funcionamiento no es infinito", otherwise "es infinito". It seems that it's not working because I belie ...

Transfer all image files from Node.js to the frontend

What is the best way to send all image files from my backend nodejs server folder to my Reactjs client? I have set up a website where users can sign in and upload their files. However, I am facing an issue where only one file is visible on the client side, ...

Accessing Route Parameters from Any Component

If my URL follows this structure: /blog/[post_id]/something What's the best practice for passing $post_id to any component within the tree? I'm familiar with retrieving route parameters using getInitialProps, but I struggle with passing values ...

Managing multiple carousels simultaneously using the middle mouse button in Swiper.js

I am currently utilizing 5 carousels on my screen, all of which are operated by the same navigation buttons. In addition to this, I require the ability to control them using the middle mouse scroll. However, when I activate the mouse wheel control, only ...

When the Jqueryui dialog is closed, it effectively terminates the current JavaScript thread

Hello there, I'm currently facing an issue with closing my jQuery dialog box. The situation involves a comet connection that sends messages to my browser. My goal is to perform certain actions upon receiving a message, close the dialog, and then conti ...

The Jquery Datatable fails to display the accurate number of rows based on the selections made in the dropdown

I am working on an ajax call that returns a table. In the success method, I am using $("#tableID").dataTable();. Although it shows paging and the number of rows in the dropdown, it is displaying all rows instead of only the number of rows selected in the d ...

How to italicize a portion of output using JavaScript

There are numerous inquiries on the internet and on this site regarding how to make italic fonts, however, none specifically address how to italicize only a section of a string. In my scenario, I have a form where I input the book title, author's nam ...

The GLTFLoader does not support the replacement of its default materials

I am currently working on a scene that includes: AmbientLight color: light blue PointLight color: pink a gltf object loaded with textures Using the GLTFLoader, I successfully loaded a gltf object with texture map. The model is displayed correctly with ...

Integrate Vue Login Functionality using Axios HTTP Requests

Hello everyone! I am new to Vue and currently struggling with making an HTTP Request to my backend. When I check the browser console, I can see the access token retrieved from /login endpoint but when I try to fetch data from api/users, it returns "Token ...

Is it possible to refresh resources in Node.js without the need to restart the server?

Is there a middleware or library that allows access to files added after the server starts without requiring a restart? I currently use koa-static-folder, but it seems unable to handle this functionality. ...

Exploring the variable scope in Node.js with a focus on separating routes

My routing configurations are stored in an external folder. Find them in the ./routes directory This is how I set up my routes within the server.js file: app.get('/', routes.index); app.post('/validation', register.valid); The reg ...

Require assistance in understanding JSON data in the form of a variable

Apologies for any language barriers, but I have encountered a problem that I need help with. I am trying to create a highchart from an AJAX call. The following code works perfectly: chartOptions = { chart: { renderTo: 'grafica1', type: 'ar ...