Creating transparency effect on objects using Physical Material in THREE.js

Is there a way to showcase a translucent PNG texture behind a transparent Physical Material in THREE.js? It seems like currently, THREE.js does not display the translucent texture through the Physical Material.

I discovered that when I set transparent: false on the material, it becomes visible. However, this also makes the texture opaque, which is not my desired outcome.

If you have any insights or solutions on how to make a translucent PNG texture visible through a Physical Material, please share!

https://i.sstatic.net/6mu1y.png

https://i.sstatic.net/52hJK.png

$(document).ready(() => {
  const renderer = new THREE.WebGLRenderer({
    canvas: document.getElementById('canvas'),
  });

  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0x0000ff);
  scene.add(new THREE.AmbientLight(0xffffff, 1));

  const texture = new THREE.TextureLoader().load('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE4AAABOCAYAAACOqiAdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADdSURBVHhe7dAhCgIBFADR1SgYLDatHsv7n2ItXzDILg7Y3ivT57Cu63P57jHdcpvuuU63XKZ7ztO30/TTffo3xyk/Mi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi4yLjIuMi5ZlhcxLwSYJ4qy6wAAAABJRU5ErkJggg==');

  const camera = new THREE.PerspectiveCamera(65, renderer.domElement.clientWidth / renderer.domElement.clientHeight, 0.1, 1000);

  {
    const geometry = new THREE.PlaneGeometry(4, 4);
    const material = new THREE.MeshStandardMaterial({
      color: 0xffff00,
      side: THREE.DoubleSide,
    });
    const plane = new THREE.Mesh(geometry, material);
    plane.position.z = 1;
    scene.add(plane);
  }

  {
    const geometry = new THREE.PlaneGeometry(3, 3);
    const material = new THREE.MeshStandardMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide,
      map: texture,
      transparent: true,
    });
    const plane = new THREE.Mesh(geometry, material);
    scene.add(plane);

    document.getElementById('transparent').onchange = (evt) => {
      material.transparent = evt.target.checked;
      material.needsUpdate = true;
    };
  }

  {
    const geometry = new THREE.PlaneGeometry(3, 3);
    const material = new THREE.MeshPhysicalMaterial({
      side: THREE.DoubleSide,
      roughness: 0.2,
      transmission: 0.8,
      color: 0xffffff,
    });
    const plane = new THREE.Mesh(geometry, material);
    plane.position.z = -2;
    plane.position.x = 1;
    scene.add(plane);
  }

  const startTime = performance.now();

  function render() {
    const now = performance.now();
    const angle = (now - startTime) * 0.002;
    camera.position.set(Math.cos(angle) * 2, Math.sin(angle) * 2, -5);
    camera.lookAt(0, 0, 0);

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
});
<script src="https://code.jquery.com/jquery-3.7.0.slim.min.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="81e4f2aceceee5f4ede4acf2e9e8ecf2c1b0afb7afb2">[email protected]</a>/dist/es-module-shims.js"></script>
<script type="importmap">
  {
    "imports": {
      "three": "https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b5c1ddc7d0d0f5859b8480819b85">[email protected]</a>/build/three.module.js"
    }
  }
</script>
<script type="module">
  import * as THREE from 'three';
  window.THREE = THREE;
</script>
<div style="position: absolute; left: 0; top: 0; z-index: 1; color: white;">
  <input type="checkbox" id="transparent" name="transparent" checked /><label for="transparent"> Transparent</label>
</div>
<canvas id="canvas" width="350" height="150" style="position: absolute; left: 0; top: 0;" />

26/07/2023: Updated code to THREE r154. The issue persists.

Answer №1

The feature known as "transmission" in THREE.MeshPhysicalMaterial represents a more sophisticated form of physically-based transparency that involves additional rendering steps. At the moment, three.js (as well as most other real-time engines I am familiar with) lack the capability to correctly display materials with alpha-blending (.transparent=true) or transmissive properties (.transmission>0) when used within another transmissive material. To achieve multiple layers of transparency, it is recommended to utilize alpha blending with .transparent=true, opacity settings, or a texture containing an alpha channel.

For further insights and discussions on this topic, refer to: https://github.com/mrdoob/three.js/issues/22009

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

The POST Method is failing to transmit all the necessary data

I recently started a new project using angular, node, express, and postgresql/sequelize. It's been an exciting learning experience, but I've encountered some challenges. Specifically, I'm having trouble setting up an update route for a model ...

Modify the property of an element within an array

I have an array of objects with a certain property. I need to perform some mathematical operations on this property and return a new array. However, my current approach does not seem to be working as expected. array.map(el => { el.count * 2; r ...

Tips for sending an icon as a prop in React components

I'm struggling to implement an icon as a prop while using props for "optionText" and "optionIcon". The optionText is working fine, but I'm facing issues with the OptionIcon. File where I'm creating props import Icon from ...

Using AJAX to call a PHP function within a PHP script

I have successfully implemented an AJAX file that can execute content from a PHP file. However, my concern is how to specifically call a particular function within the PHP file if there are multiple functions present. Below is my current AJAX code: $(doc ...

What is the best way to apply a hover effect to a specific element?

Within my CSS stylesheet, I've defined the following: li.sort:hover {color: #F00;} All of my list items with the 'sort' class work as intended when the Document Object Model (DOM) is rendered. However, if I dynamically create a brand new ...

Vue.js: Error 404 - POST request endpoint not found

My goal is to access my Quasar application from other devices connected to the Local Area Network. I have successfully run the app on these devices, but I encountered an error POST http://10.0.0.20:8080/MyComposer/?submitId=3 404 (Not Found) when trying to ...

Combining router.get and https.get in Node.js: A step-by-step guide

Looking for a more efficient method to retrieve information from an http request and send it to the frontend using the path '/get'. Currently, I have combined two functions that seem to work but may not be the most optimal: const router = express ...

Targeting an element on the display with the power of threejs

In my journey as a beginner in 3D graphics and the threejs library, I am experimenting with creating an illusion where a row of boxes seems to 'point' towards a specific point in front of the computer screen. To achieve this effect, I have devel ...

What could be causing the missing texture rendering on vertices in Three.js?

In my Three.js scene, I have utilized BoxGeometries with zero width and textures applied to most surfaces. The rendering works effectively, even with transparent windows on the house. However, when it came time to add the roof, which required angled flat p ...

Unable to achieve the desired focus on a specific element using JavaScript's .focus() method

After executing the command $('#someelement').focus(), I am not receiving any error message but the functionality is not working as expected. Even when I attempt to retrieve document.activeElement, it continues to return the body element. Here i ...

Using onDoubleClick with MUI TextField: A Quick Guide

Whenever the user double clicks the input field, I would like to automatically select the text. I have created a function for this specific action: export const selectText = ( event: React.MouseEvent<HTMLInputElement | HTMLTextAreaElement, MouseEvent& ...

Using ES6, one can filter an array of objects based on another array of values

Seeking assistance with creating a function to filter an array of objects using another array as reference values. For example: The array containing objects: const persons = [ { personId: 1, name: 'Patrick', lastName: 'Smit ...

Ensure that the button becomes clickable only after text has been inputted into the field

How can I make my button active after entering text into the text box? I would appreciate any help or guidance. Here is the code I have been working on: <body> <script> function ActivateButton() { if (input1.value != null) { send ...

Generate a string that will be utilized to interpret a JSON response

I can't seem to extract a specific element from a json using a dedicated function. Can someone please assist me with this issue? Here is the fiddle that I have created for reference: http://jsfiddle.net/jonigiuro/N5TTM/2/ CODE: var data = { "res ...

Switching a set of checkboxes with a main checkbox

I've got this JS code that's doing its job and satisfying all my requirements when one of the checkboxes at the top is checked. However, I'm struggling to uncheck them by following the same process (unchecking the first box is not possible). ...

Guide on parsing an Array of arrays using JSON.parse

I have received a JSON.stringified Array of arrays in a variable named request. alert(request); When I alert the above, I get the following message: "[[\"0\",\"MahaShivRatri\"],[\"0\",\ ...

Tips for efficiently exporting and handling data from a customizable table

I recently discovered an editable table feature on https://codepen.io/ashblue/pen/mCtuA While the editable table works perfectly for me, I have encountered a challenge when cloning the table and exporting its data. Below is the code snippet: // JavaScr ...

Issues persist with AngularFire login authentication and redirect

After spending countless hours scouring various websites, documentation, and numerous pages on Stack Overflow, I am still struggling to wrap my head around these issues. Despite my efforts over the past few days, I have made little progress. My project in ...

Addressing the Cross Domain Issue when Implementing DHIS 2 API with jQuery

Today, I spent hours trying to authenticate my javascript application with the DHIS 2 API using Jquery. According to the API documentation (https://www.dhis2.org/doc/snapshot/en/user/html/ch32s02.html), base 64 authentication is required. However, my attem ...

Angular 8 does not allow for the assignment of type '{}' to a parameter

I have a unique approach for managing errors: private handleErrors<T>(operation = 'operation', result?: T) { return (error: any): Observable<T> => { console.error(error); this.record(`${operation} failed: ${error.m ...