I'm currently developing a user-friendly browser application for editing shaders in three.js using react-three-fiber. I want to enhance the functionality by allowing users to add additional uniforms to the ShaderMaterial. However, I do not want to expose the underlying JavaScript code. Therefore, I am looking for a way to implement a dropdown menu that enables users to select a new uniform and provide values for it (e.g., an input field for adding an image as a Sampler2D).
My main concern is whether there is a more efficient approach to achieve this without creating an extensive list of type aliases on the frontend.
At present, my strategy involves generating an array of potential types that users can interact with in the React interface. Subsequently, the selected type's string value is processed through a large switch statement to determine the appropriate material to add. However, this method seems cumbersome and I am exploring if there is a better solution leveraging some inference or functionality within Three.js.
I provide the array of JavaScript objects generated from user inputs, which is then processed to produce an object of materials. (Note: I am unsure whether using forEach or map is more optimal in this scenario, as I am not modifying the returned array)
import * as THREE from 'three';
// determines the appropriate THREE.JS type for allocation
export function buildUniforms(uniforms: Uniform[]) {
console.log("Building the Uniforms");
const transformedUniforms = {};
uniforms.map((un) => {
console.log(un);
let value;
switch (un.type) {
case "Vector3":
value = new THREE.Vector3(un.value[0], un.value[1], un.value[2]);
break;
case "Vector2":
value = new THREE.Vector2(un.value[0], un.value[1]);
break;
// and so on
}
transformedUniforms[`${un.title}`] = {
value: value
};
});
return transformedUniforms;
}
export interface Uniform {
title: string;
type: string;
value: any;
}