How can I include a custom shader reference in the json material format in three.js?

For those using the JSON Object Scene format 4 for Three.js, there is a specification for materials that can be found here.

However, it seems unclear whether it is possible to reference a custom shader from this specification. Does anyone have any insights on how this could be achieved?

[UPDATE]

Upon reflection, it appears my initial question may not have been clear enough. What I'm really trying to figure out is how to make the JSON loader interpret a material defined by a custom shader within the JSON Object Scene format 4:

"materials": [
    {
        "uuid": "87D95D6C-6BB4-4B8F-8166-A3A6945BA5E3",
        "type": "MeshPhongMaterial",
        "color": 16777215,
        "ambient": 16777215,
        "emissive": 0,
        "specular": 1118481,
        "shininess": 30,
        "opacity": 1,
        "transparent": false,
        "wireframe": false
    }
],
"object": {
    "uuid": "89529CC6-CBAC-412F-AFD1-FEEAE785BA19",
    "type": "Scene",
    "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
    "children": [
        {
            "uuid": "33FA38D9-0AAC-4657-9BBE-5E5780DDFB2F",
            "name": "Box 1",
            "type": "Mesh",
            "geometry": "C3BF1E70-0BE7-4E6D-B184-C9F1E84A3423",
            "material": "87D95D6C-6BB4-4B8F-8166-A3A6945BA5E3",
            "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
        },

In this excerpt, a mesh references a material by its UUID. The issue lies in the fact that the types of materials are predetermined within the WebGLPrograms function, making it challenging to expand this list with a custom shader.

Answer №1

To create a custom shader, you need to develop either a ShaderMaterial or a RawShaderMaterial by specifying the attributes vertexShader and fragmentShader, with both shader codes included in the HTML/JS source.

If you provide the source for both shaders in JSON format, a ShaderMaterial can inherit from the base Material object.

A default vertex and fragment shader code will be visible in the JSON output when using a parameter-less ShaderMaterial.

var shader = new THREE.ShaderMaterial();
console.log(shader.toJSON());
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.js" charset="utf-8"></script>

Update:

After further review, it appears that creating an instance of a custom ShaderMaterial may not be straightforward or clearly defined.

The MaterialLoader is capable of loading a ShaderMaterial with customized vertex and fragment shaders, ensuring compatibility between the Material.toJSON method and the MaterialLoader.

// Ensuring consistency in saving and loading
var loader = new THREE.MaterialLoader();

var shaderMaterial = new THREE.ShaderMaterial();
var shaderMaterialJSON = JSON.stringify(shaderMaterial.toJSON());

console.log('JSON ' + shaderMaterialJSON);

var loadedShaderMaterial = loader.parse(JSON.parse(shaderMaterialJSON));

console.log(loadedShaderMaterial);

// Converting a phong material to a shader material
var phongMatJSON = '{"uuid": "87D95D6C-6BB4-4B8F-8166-A3A6945BA5E3", "type": "MeshPhongMaterial", "color": 16777215, "ambient": 16777215, "emissive": 0, "specular": 1118481, "shininess": 30, "opacity": 1, "transparent": false, "wireframe": false}';

var phongMatObj = JSON.parse(phongMatJSON);
phongMatObj.color = undefined; // Not used in ShaderMaterial
phongMatObj.emissive = undefined; // Not used in ShaderMaterial
phongMatObj.specular = undefined; // Not used in ShaderMaterial
phongMatObj.name = '';
phongMatObj.type = 'ShaderMaterial';
phongMatObj.uniforms = {};
phongMatObj.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
phongMatObj.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 );\n}';

var shaderMatObj = loader.parse(phongMatObj);

console.log(shaderMatObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.js" charset="utf-8"></script>

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

Using Regular Expressions in Express routing

Does anyone have experience serving a file with a dynamic hash in its name on a specific route? The file is named like workbox-someHash.js and the hash changes every time the app is deployed. I attempted to serve it using the following code snippets: &qu ...

Issue with retrieving URL parameters in Nextjs during server side rendering

Currently, I'm attempting to extract the request query, also known as GET parameters, from the URL in server-side rendering for validation and authentication purposes, such as with a Shopify shop. However, I am facing issues with verifying or parsing ...

The URL may change, but the component remains constant when navigating back

My application consists of two primary components: the Project component and MainContainer. The MainContainer component regularly fetches data using a fetchData method. When moving forward, both the URL and component can change dynamically. However, when m ...

``Is there a way to dynamically display an image along with its corresponding title and content

After dynamically inserting a title and content, I found myself struggling to include an image between them. Is there a way to accomplish this? This issue arises in my controller. const postSchema = { title: String, content: String, }; const Post ...

Guide to locating a particular node within an array of nested objects by utilizing the object

Dealing with an array of nested objects, the goal is to compare values with a flat array and update the property matchFound. If the parent's matchFound is true, then all its children should inherit this value. treeData = [{ field: 'make&a ...

Encountering a problem while trying to pin a message on Discord

Whenever a message is pinned in discord, it causes the bot to crash with the following error (although it can recover with forever but that's beside the point). The pinned message can be of any type (regular or embed). if (!value) throw new RangeE ...

Tips on attaching a suffix icon to a material-ui-pickers input box

Here is a snippet of my code: <Box p={6}> <Grid container spacing={2}> <Grid item xs={6}> <TimePicker autoOk label={t('checkIn')} value={time1} onChange={handlecheckIn} clearable /> </Grid> < ...

What distinguishes defining a function through a prototype versus as a class property?

Check out this code snippet: Apple defines its function using a prototype. Banana defines its function using a class property. var Apple = function(){} Apple.prototype.say = function(){ console.debug('HelloWorld'); } var Banana = functio ...

The challenge of handling success and error messages in Ajax with HTML

I encountered an issue with this concrete problem. My goal is to dynamically display a message within a specific div based on the response from my ajax request. I have set up two divs with IDs #uploadResponsesuccess and #uploadResponseerror. However, since ...

Dynamically insert <td> elements into <tr> element using both jQuery and JavaScript

I am facing an issue with adding a new table data (td) element dynamically to the first table row (tr) in my JavaScript code. Here is the original table before adding the new td element: <table> <tbody> <tr> <t ...

Exploring html select and input elements in a loop

Currently, I am in the process of developing an application that calculates the total price of selected items based on user input. Each row consists of two dropdown menus (ID/item) and a quantity input field. Additionally, users have the option to add rows ...

Is it possible to retrieve event.data beyond the onMsg callback function in JS SSE?

My current project involves using three.js to display accelerometer data in real-time and in 3D on a web browser. To transfer data from the remote server to the client side, I am utilizing server-sent-events (SSE). While I have successfully implemented th ...

Sending data back and forth across 2 tabs within one page

I noticed a strange behavior when using multiple tabs on the same page in different modes. When I clicked a button that was supposed to fill in some inputs, the data filled in the last tab opened instead of the one I actually clicked on. The angular input: ...

Can Wireframe be applied to a 3D gltf model within an HTML document?

I am currently working on achieving a specific design concept, which can be viewed at the following link: To guide me through this process, I have been following a tutorial available here: While I have successfully implemented the model and created mater ...

ReCaptcha: connecting to the TextBox's OnKeyDown event using script

I've been figuring out how to integrate ReCaptcha, ASP.NET, and Gaia Ajax. It was a bit of a challenge to use the ReCaptcha AJAX APIs with Gaia to fetch the data from the recaptcha_response_field text box in an AJAX postback through a patch. This was ...

Is there a way to obtain the guild ID during the createGuild event?

Can someone please help me figure out how to get the guild id in the event guildCreate.js? I have tried using guild.id but it returns undefined. Even when I use console.log(guild), it shows a blank space. Using client.guild.id throws an error for id. cons ...

The items in the array cannot be identified

var userInput = prompt('Select a fruit:'); var fruitList = ["apple", 'grapes', "orange"]; for(var i=0; i<fruitList.length; i++); if(userInput == fruitList[i]){ alert("Apologies, we are currently out of ...

A tutorial on preventing backbone.js from automatically adding /# when a dialog is closed

Whenever I navigate back on my backbone page, it automatically adds /# to the URL. This results in loading an empty index page from the Rails home view when pressing back again. Disabling turbolinks fixed this issue for me. However, another problem arises ...

Retrieving the selected value from an added dropdown list using jQuery

Could someone please guide me on how to retrieve the selected value from an appended select list using jQuery? Any assistance would be greatly appreciated. Thank you in advance. var wrapper1 = $(".column1"); array1 = ["sample1", "sample2", "sample3"]; ...

Ajax long-polling - Timeout triggering unexpectedly

I am having an issue with my Ajax code polling my IIS/ASP server. After calling msgPoll("") once, the function seems to be invoked repeatedly instead of every 30 seconds. Can you help me identify what mistake I might be making? var msgTimOut; f ...