Utilizing JavaScript to merge 3D LUTs for innovative effects

Currently, I am exploring the realm of 3D color LUTs (color lookup tables) in JavaScript and have been pondering if there exists a method to merge multiple 3D LUTs together for export in a unified file. Allow me to elaborate:

Upon obtaining a .cube file (3D color lookup), I parse it, extract the color values, store them in an array, and apply them to an image. Subsequently, I superimpose a new 3D LUT onto the modified image, followed by another application of a different LUT. Consequently, the original image now showcases the cumulative effect of three distinct 3D LUTs applied successively.

While I can readily export each individual 3D LUT into separate files for download, I am faced with the challenge of amalgamating them into one cohesive .cube file. It appears that devising an algorithm for the "combination" of diverse LUTs is imperative.

To illustrate, here is a comparison with how this process is executed in Photoshop:

LUT1:

0.024536 0.000183 0.000244
0.049103 0.000336 0.000458

LUT2:

0.041260 0.021149 0.009125
0.067230 0.023804 0.009125

COMBINED LUT (result):

0.035034 0.020660 0.009308
0.054810 0.022766 0.009430

Your insights or suggestions on achieving this desired merging of LUTs would be greatly appreciated!

Answer №1

After conducting thorough research, I have successfully identified a solution to my issue. In essence, the key was to direct the output of the initial LUT into the input of the subsequent LUT. This necessitates having an interpolation function within the program rather than just relying on a 3D LUT shader.

The process can be outlined as follows:

  1. Generate a new identity LUT of a specified size (which is essentially a default LUT with no modifications)
  2. Go through each point in the 3D LUT and channel the identity color of each point through the ColorFromColor function of the first LUT, followed by the ColorFromColor function of the second LUT. Save the resulting value in the new LUT.

The function's structure resembles this:

function mapColorsQuick(out, image, clut, clutMix){
    let od = out.data,
        id = image.data,
        w = out.width,
        h = out.height,
        cd = clut.data,
        cl = Math.floor(Math.pow(clut.width, 1/3)+0.001),
        cs = cl*cl,
        cs1 = cs-1;

    var x0 = 1 - clutMix, x1 = clutMix;
    for(var y = 0; y < h; y++) {
        for(var x = 0; x < w; x++) {
            let i = (y*w+x)*4,
                r = id[i]/255*cs1,
                g = id[i+1]/255*cs1,
                b = id[i+2]/255*cs1,
                a = id[i+3]/255,
                ci = (dither(b)*cs*cs+dither(g)*cs+dither(r))*4;

            od[i] = id[i]*x0 + x1*cd[ci];
            od[i+1] = id[i+1]*x0 + x1*cd[ci+1];
            od[i+2] = id[i+2]*x0 + x1*cd[ci+2];
            od[i+3] = a*255;
        }
    }
}

This function takes several parameters: out - buffer where the result will be stored image - buffer containing the image in imageData format clut - color look-up table applied to the image clutMix - factor affecting the intensity of the effect (ranging from 0 to 1)

In this scenario, it was necessary to create an identity LUT, save it as an image, pass it as the image argument to the function, apply the new LUT to it, loop the result back through the same function with another LUT application, and repeat this process for any additional LUTs we wish to combine.

I came across this function in the Javascript Film Emulation project on this link.

If you're engaged in canvas 2D image processing, there are numerous interesting resources available, including a functional demonstration found here: this link

I trust that this information will be beneficial to others facing similar challenges in the future!

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 is the best way to prevent duplicates in a Material-UI dropzone area?

Currently, I am utilizing the Material-UI Dropzone component from https://yuvaleros.github.io/material-ui-dropzone/ and my goal is to prevent users from uploading duplicate files that have been previously uploaded. I attempted using an onchange function t ...

Enhance the language with react-intl and MobX State Tree integration

Currently, I am integrating react-intl with Mobx state tree for the first time. Within my project, there are two buttons located in the header section - one for 'it' and the other for 'en'. Upon clicking these buttons, the selected lan ...

AngularJS efficiently preloading json file

I am just starting to learn about angularJS. Apologies if my question is not very clear. Here is the problem I am facing: I have a JSON file that is around 20KB in size. When I attempt to load this file using the 'factory' method, I am receivin ...

"I am currently in the process of converting my https.get() function to return a promise, but it is currently showing as Promise {

I'm attempting to convert a function that utilizes https.get() to retrieve data from an API into a promise-based function so I can utilize async await. In the example below, the data is successfully fetched, but when trying to access the object using ...

When attempting to view the PDF file, it appears completely void

After spending countless hours on this task, I'm still not making any progress. My goal is to download a PDF file from my server while currently running the operation on localhost. However, whenever I open the downloaded PDF, all I see is a blank whit ...

Using AngularJs, you can access the document.body.onfocus event within the controller of

I am attempting to detect when the user closes or cancels the File Upload Window <input type="file"> Since there isn't a built-in listener for the close event of the file upload, I am trying to capture it using the document.body.focus event, s ...

Switching the default browser for npm live-server

When I use the npm live-server package to preview my website as it changes, it keeps opening in Edge even though Chrome is set as my default browser on my system. I attempted to use the command suggested on the npm website: live-server --browser=chrome H ...

What could be causing the issue of req.body being undefined within the destination function of Multer's diskStorage?

I'm currently utilizing Multer for managing file uploads within my Express.js application. However, I've encountered an issue when attempting to access the req.body values in the destination function of Multer's diskStorage option – it con ...

Guide on sending a JavaScript function to a Pug file using Node.js and Express

In my recent project, I developed a node app using express along with a pug file. The express app is configured to listen on port 3000 and render the pug file. One of the key functionalities involves fetching information from an external API. My goal is to ...

A fresh javascript HTML element does not adhere to the css guidelines

While attempting to dynamically add rows to a table using Javascript and jQuery, I encountered an issue. Here is my code: <script> $(document).ready(function(){ for (i=0; i<myvar.length; i++){ $("#items").after('<tr class="item- ...

Combine Angular variable in JavaScript function

I want to combine "proposal.id" in the initial parameter of the window.open function. Here is my current code snippet: <button ion-button color="light" onclick="window.open('https://mywebsite.com/offer?id={{ proposal.id }}', '_self' ...

Display or conceal a div element depending on its CSS class

I need a way to dynamically show or hide a div named "contact-form" on my website based on the CSS class of another div, which indicates whether a product is in stock or out of stock. The goal is to display the div if the class is "in-stock" and hide it i ...

What could be causing me to lose my login information on my React application?

I have a reactjs application that utilizes a django backend for handling authentication. Below is a snippet of my Typescript code from the App.tsx file in my react app: import React, {useState, useEffect} from 'react'; import { BrowserRouter as ...

What is the best method for storing numerical data for a Next.js/React website? Should you use a CSV file, make a backend API call, or download

I'm working on a nextjs website and I want to integrate a chart. Where would be the best place to store the data for this chart? Here are some options I've considered: Save a csv file in the public folder and retrieve it from there Store a csv f ...

Tips for adjusting image hues in Internet Explorer?

I have successfully altered the colors of PNG images in Chrome and Firefox using CSS3. Here is my code: #second_image{ -webkit-filter: hue-rotate(59deg); filter: hue-rotate(59deg); } <img src='http://i.im ...

Trouble with MailChimp AJAX API not initializing the API call

I am currently working on integrating the MailChimp API to enable seamless subscription without redirecting to the MailChimp website. I found a helpful tutorial that I am following. However, whenever I attempt to subscribe, the website displays an error me ...

What are the steps to generate two unique instances from a single class?

Is there a way to output two instances of the class Cat : Skitty, 9 years and Pixel, 6 years, in the console? (() => { class Cat { constructor(name, age) { this.name = name; this.age = age; } } docume ...

Insert the ng-if directive into an element using a directive

I am working on an AngularJS directive that involves looking up col-width, hide-state, and order properties for a flexbox element based on its ID. I want to dynamically add an ng-if=false attribute to the element if its hide-state is true. Is there a way ...

Currently, I am utilizing a Google script to import my emails into a spreadsheet. I am seeking help in identifying and fixing a duplication issue that

For the past few weeks, I have been running a script to gather task data for my company. The script has been running smoothly since 09/03/2023, but recently it started duplicating entries and causing confusion in identifying which tasks are necessary and w ...

Ways to identify the location of the mouse pointer within a specific div

My dilemma involves a rectangle span measuring 100 pixels in width and I am seeking for the user to choose between 0-100%. Upon clicking anywhere within the div horizontally, the corresponding value should be saved and promptly displayed to the user throu ...