Utilizing the power of THREE.ShaderLib.phong while integrating subsurface scattering within ThreeJS

My mesh utilizes a ShaderMaterial with THREE.ShaderLib.phong uniforms. I have successfully linked the map, bump, and specular maps textures. The code snippet below demonstrates this:

defines = {};
defines["USE_MAP"] = "";
defines["USE_BUMPMAP"] = "";
defines["USE_SPECULARMAP"] = "";

var uniforms = THREE.UniformsUtils.clone(THREE.ShaderLib.phong.uniforms);
uniforms.map.value = THREE.ImageUtils.loadTexture('source/images/texture-pink.jpg');
uniforms.bumpMap.value = THREE.ImageUtils.loadTexture('source/images/texture-pink-bump.jpg');
uniforms.bumpScale.value = 0.02;
uniforms.specularMap.value = THREE.ImageUtils.loadTexture('source/images/texture-pink-specular.jpg');

var parameters = {
    fragmentShader: THREE.ShaderChunk["meshphong_frag"],
    vertexShader: THREE.ShaderChunk["meshphong_vert"], 
    defines: defines,
    uniforms: uniforms,
    lights: true,
    fog: false,
    side: THREE.DoubleSide,
    blending: THREE.NormalBlending,
    transparent: (uniforms.opacity.value < 1.0),
    derivatives: true
};

material = new THREE.ShaderMaterial(parameters);

View the outcome https://i.sstatic.net/eSaCO.png.

Additionally, I have implemented separate subsurface scattering code for the mesh. The following code snippet demonstrates this:

<script id="vertexShader" type="x-shader/x-vertex">
    varying vec3 v_fragmentPos;
    varying vec3 v_normal;

    void main() {

        vec4 mvPositions = modelViewMatrix * vec4(position, 1.0);
        v_fragmentPos = (modelMatrix * vec4(position, 1.0)).xyz;
        v_normal = (modelMatrix * vec4(normal, 0.0)).xyz;
        gl_Position = projectionMatrix * mvPositions;
    }
</script>

<script id="fragment_shader" type="x-shader/x-fragment">
    varying vec3 v_fragmentPos;
    varying vec3 v_normal;
    uniform vec3 u_lightPos;

    void main() {

        vec3 _LightColor0 = vec3(1.0, 0.5, 0.5);  
        float _LightIntensity0 = 2.5;
        vec3 translucencyColor = vec3(0.8, 0.2, 0.2);
        vec3 toLightVector = u_lightPos - v_fragmentPos;
        float lightDistanceSQ = dot(toLightVector, toLightVector);
        vec3 lightDir = normalize(toLightVector);
        float ndotl = max(0.0, dot(v_normal, lightDir));
        float inversendotl = step(0.0, dot(v_normal, -lightDir));
        vec3 lightColor = _LightColor0.rgb * ndotl / lightDistanceSQ * _LightIntensity0; 
        vec3 subsurfacecolor = translucencyColor.rgb * inversendotl / lightDistanceSQ * _LightIntensity0;
        vec3 final = subsurfacecolor + lightColor;
        gl_FragColor = vec4(final, 1.0);
    }
</script>

The basic code referenced from Shader - Simple SSS lighting issue, paired with the material code:

sssUniforms = {
    u_lightPos: { type: "v3", value: new THREE.Vector3() }
};

var sssMaterial = new THREE.ShaderMaterial({
    uniforms: sssUniforms,
    vertexShader: document.getElementById('vertexShader').textContent,
    fragmentShader: document.getElementById('fragment_shader').textContent,
});

See the result of subsurface scattering https://i.sstatic.net/zWkHS.png.

Now, I am attempting to combine these two functionalities. While trying to merge the uniforms using THREE.UniformsUtils.merge, I suspect that my approach to combining the vertex and fragment shader codes might be incorrect. As they are strings, I directly copied and pasted them within script tags, unsure if this is the correct method. Is it even feasible to combine them in this manner? If so, could someone provide guidance on this matter? Although I have a decent understanding of JavaScript and have begun delving into Three.js, I lack knowledge in openGL.

Any assistance would be greatly appreciated.

Thank you.

Answer №1

Interacting with your GPU pipeline through vertex and fragment shaders is essential for understanding how to merge them effectively.

Phong Shading involves reading specular, diffused, and ambient lighting in your fragment shader for specific vertices.

https://i.sstatic.net/lZi8n.jpg [Source:wiki]

Subsurface Scattering allows for considering how light interacts within a material, a step beyond just reading light interaction with the material.

https://i.sstatic.net/ViP17.gif

[Source: Link]

For a comprehensive understanding, refer to Chapter-16 Nvidia, which provides solutions to all mathematical problems.

I have developed a Subsurface Scattering solution using Depth Maps, accessible on Git. This code is inspired by pixelnerve.

In conclusion, rather than trying to merge THREE.Phong and Subsurface Scattering, consider extending the same sample code by customizing your fragment shader (you can directly use the provided vertex shader).

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

I possess an array containing objects of different lengths depending on the chosen city. How can I pinpoint the element that contains an object with a specific property?

My dilemma arises from the fact that the length of an array depends on the selected city, making it impossible to select elements using an index. In this scenario, I need to devise a method to choose elements based on the value of one of their properties. ...

Handling Errors: Communicating with the Frontend

I'm facing a challenge with error handling in my authentication API calls. Whenever I trigger the 500 status from Express, my frontend (using Vue) only displays the message Request failed with status code 500 instead of something more informative like ...

Ways to clear the time attribute from an ISO DateTime in date format

How can I remove the time attribute from a date in the format 2016-05-24T05:07:57.756Z and set it to something like 2016-05-25T00:00:00.000Z? Any assistance would be greatly appreciated. ...

Encountering a registration error persistently: [TypeError: Network request failed]

Currently, I am in the process of developing an application using React for the frontend and node.js for the backend. However, I have encountered a persistent network error whenever I try to sign up or log in. What puzzles me is that when I test the API en ...

Tips for repairing a side bar and header with CSS when using a JS & jQuery scroller

I am working on a layout design and my goal is to have the left sidebar, right sidebar, and header remain fixed in place. Here is the CSS code I am using : #container { padding-left: 200px; /* Left Sidebar fullwidth */ padding-ri ...

Consistently shifting the Aframe camera towards the focal point

Is there a way to continuously adjust the view of my Aframe scene based on the current viewing direction? It seems like there are two key components needed for this: (1) obtaining the current viewing direction in the correct format, and (2) creating and u ...

Problem encountered with JavaScript getter on iOS 5

While implementing JavaScript getters in my iPad-optimized website, everything was working perfectly until I updated to iOS 5. Suddenly, the site stopped functioning properly. After thorough investigation, I discovered the root cause of the issue. I have ...

Using the if else and hasClass statements for validations in Cypress testing

I am struggling to validate the titles for a certain component. Here is my specific Cypress code snippet: it('Confirming the correctness of all tile titles', () => { cy.get('.bms-scoreboard__game-tile') .each(($el) => { ...

Wizard for the advanced tab panel

I am facing a challenge with my advanced TabPanel Wizard. It consists of 4 tabs, each serving as its own form to allow for validation within the tab itself. The issue I am encountering is related to the validation behavior of non-rendered tabs. One proble ...

The Chrome Extension Javascript popup appears to be empty

Feeling a bit lost on my first attempt at creating a chrome extension. Check out my manifest.json below: { "manifest_version": 2, "name": "Get Offensive Wallpapers", "version": "1.0", "permissions": [ "tabs", "http://*/*", "https://*/*" ], ...

Discovering the number of intervals running at any given time within the console - JavaScript

I'm having trouble determining if a setInterval() is active or has been cleared. I set up an interval and store it in a variable: interval = setInterval('rotate()',3000); When a specific element is clicked, I stop the interval, wait 10 sec ...

Completing the pledge using ionic/ui-routing

I've encountered an issue with my promise not resolving as expected while using Ionic/ui-routing. This is the structure of my service: return { all: function () { $localForage.getItem('foo').then(function (bar) { re ...

Tips for inserting text to the left rather than the right using Jquery

I recently came across this code snippet shared by some helpful users on stackoverflow and it has been working perfectly for me. However, I do have a couple of queries regarding its functionality. Firstly, how can I ensure that the current selected option ...

Unlocking the Chrome performance tool summary using SeleniumDiscovering the Chrome performance tool

I'm looking to utilize the Chrome performance tool for analyzing my website and then extract a summary of the results using Selenium WebDriver in Java. Despite extensive searching, I haven't been able to find a suitable solution yet. To give you ...

Leveraging the power of the underscore library within the WordPress

I'm currently utilizing the underscore library for handling arrays. I have included the library using the code snippet below in my functions.php file add_action( 'wp_enqueue_scripts', 'jt_enqueue_scripts' ); function jt_e ...

Method for creating a randomized layout grid in MaterialUI where each row contains a total of three columns

In the process of developing a React application that interacts with the reddit api and oAuth. Utilizing MaterialUI, I am currently experimenting with the Component to create a 3 column grid of images with dynamically generated column widths, maxing out a ...

Ways to terminate all AJAX requests within a for loop

Is there a way to cancel all AJAX requests that are being handled by a for loop? var url = ["www.example.com","www.example2.com",....]; for (var i = 0; i < url.length; i++) { var XHR = $.get(url[i], function(data) { //do something }); } I attemp ...

Efficient guide to unlock the secrets of JS height measurements

I've noticed that there are several different 'Height' related properties in JavaScript such as clientHeight, Window.height, scrollHeight, offsetHeight, and more. Although I have a general idea of what they do, I am seeking a formal and det ...

Is it possible to deactivate dynamic binding in Vue.js?

I'm curious if there's a way to disable dynamic binding for a specific instance of an attribute that I'm displaying. Imagine I have the following code, utilizing two-way binding: this.$children[0].$data.hits In this scenario, I have a vac ...

What is the best way to modify JSON data within a file?

To start, I retrieve a JSON array by using the following JavaScript code: $.getJSON("myJSONfile.json") .done(function(data) { myData = data; }); After storing the data in myData, which is a global variable, I proceed to add more informati ...