This project mostly consists of the spectral.js port, with a small demo to demonstrate color mixing. spectral.js repository: https://github.com/rvanwijnen/spectral.js
This is a port of javascript color mixing library spectral.js, which uses Kubelka-Munk theory to model absorption, scattering and reflectance of light on a pigment. Each method is commented, and most directly translated methods are labeled with the original javascript code segments. As Scratch does not support storing objects in variables, this project implements a custom memory system to loosely mimic javascript functionality. Due to this, additional memory management is necessary to keep performance costs low. More information can be found inside of the project on this issue. Info from the original repo: Spectral.js generates a spectral reflectance curve from a given RGB triplet by calculating the weights for combining the seven primary spectral reflectance curves: White, Cyan, Magenta, Yellow, Red, Green, and Blue. The resulting spectral reflectance curve is then used to calculate the Kubelka-Munk ( K/S ) values which are used in the mix function. What sets Spectral.js apart is its spectral mixing model, which simulates how real pigments combine based on light absorption and scattering — rather than relying on RGB math. When colors are mixed, it calculates an effective concentration for each pigment using the formula: C^2=f^2*T^2*L Where: ( L ): luminance ( T ): tinting strength — applied exponentially to emphasize its effect on stronger or weaker pigments ( f ): user-defined mixing factor This formula integrates luminance ((L)), tinting strength ((T)), and the user-defined mixing factor ((f))—capturing how strongly a pigment influences the mix based on both its optical weight and intent. These concentrations are used to compute the weighted sum of each color’s Kubelka-Munk ( K/S ) value, resulting in a combined ( K/S_{mix} ) for the mixture. Then the inverse Kubelka-Munk function is used which takes ( K/S_{mix} ) divided by the total concentration and returns the reflectance ( R ): R = 1 + (K / S_mix) - sqrt((K/S_mix)^2+2*(K/S_mix)) Using the CIE 1931 Color Matching Functions weighted with the D65 Standard Illuminant the reflectance ( R ) is then converted to CIE XYZ. All spectral and colorimetric calculations are performed using 64-bit floating point precision ensuring stable results.