Tips for concealing the overlap between two 3D objects in three.js?

What is the best way to conceal or hide the intersection of two object3Ds in three.js? For instance:

Imagine there are two spheres named 'S-Red' and 'S-Blue'

Since S-Red is transparent, it appears like this:

https://i.sstatic.net/p9Uto.jpg

However, I would like it to be displayed like this instead:

https://i.sstatic.net/7BwV1.jpg

Answer №1

Adjusting the transparency of sphere pixels using a fragment shader:

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

body, canvas { 
  margin: 0;  
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/controls/TransformControls.js"></script>
<script>
  var scene = new THREE.Scene();
  var camera = new THREE.PerspectiveCamera(75, innerWidth/innerHeight, 0.01, 1000);
  camera.position.set(5,5,0);
  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(innerWidth,innerHeight);
  document.body.appendChild(renderer.domElement);
  let orbit = new THREE.OrbitControls(camera, renderer.domElement);
  scene.add(new THREE.GridHelper(500, 100, 0x666666, 0x444444));
  let s1 = sphere(3,  2, 0)
  let s2 = sphere(3, -2, 1)
  let u1 = s1.material.uniforms, u2 = s2.material.uniforms;
  requestAnimationFrame( render );
  
  function sphere(radius, position, color){
      color = color.toFixed(1)
      var geometry = new THREE.SphereGeometry(radius, 50, 50);
      var material = new THREE.ShaderMaterial({
          transparent: true,
          depthWrite: false,
          side: THREE.DoubleSide,
          uniforms: {c: {type: "3f"}, o: {type: "3f"}},
          vertexShader:   `
            varying vec3 p;
            void main() {
              // transfer vertex position to fragment shader, 
              // this value is interpolated by gpu hardware between pixels of triangle, 
              // containing this vertex
              p = position; 
              gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            }`,
          fragmentShader: `
            varying vec3 p;  // position of current pixel relative to sphere center
            uniform vec3 c;  // center of current sphere
            uniform vec3 o;  // center of opposite sphere
            void main() {
               vec3 a = abs(p)*50.0;  
               float opacity = a.x<1. || a.y<1. || a.z<1. ? 0.8 : 0.3;               
               // here is test of shpere overlapping   
               opacity = distance(o, p + c) < 3.0 ? 0.0 : opacity; 
               gl_FragColor = vec4(vec3(${color}, 0.0, 1.0 - ${color}), opacity);
            }`
      });
      let mesh = new THREE.Mesh(geometry, material);
      mesh.translateX(position)
      scene.add(mesh);
      let control = new THREE.TransformControls(camera, renderer.domElement);
      control.addEventListener('dragging-changed', e => orbit.enabled = !e.value);
      scene.add(control);
      control.attach(mesh)
      return mesh;
  }

  function render() {
      requestAnimationFrame( render );
      let p1 = s1.position, p2 = s2.position;
      u2.o.value = u1.c.value = [p1.x, p1.y, p1.z];
      u1.o.value = u2.c.value = [p2.x, p2.y, p2.z];
      u1.c.needUpdate = u1.o.needUpdate = 
      u2.c.needUpdate = u2.o.needUpdate = true;   
      renderer.render( scene, camera );
  }
</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

Tips for closing an event when switching between tabs or windows

I'm in the process of developing an online test portal within my Angular application, and I need to figure out how to automatically close/end the session when a user navigates (opens a new tab or window) to a different page. Is there a way to achieve ...

React - The `component` prop you have supplied to ButtonBase is not valid. Please ensure that the children prop is properly displayed within this customized component

I am attempting to use custom SVG icons in place of the default icons from Material UI's Pagination component (V4). However, I keep encountering this console error: Material-UI: The component prop provided to ButtonBase is invalid. Please ensure tha ...

Getting the checked values from an AngularJS Material checkbox

<md-checkbox ng-repeat="program in ctrl.programs" ng-model="ctrl.programsSelected[program.id]"> {{program.name}} </md-checkbox> Checked Items: {{ctrl.programsSelected | json}} Current Output: Checked Items: [null,true,true,true,null,true, ...

Improving audio performance using the Web Audio API

I've encountered an issue with my live stream setup. I have a desktop application streaming PCM data over a websocket connection to my web page, but when I try to play the track, I hear glitches. To address this, I created a bufferArray to store part ...

Retrieve information stored within an object's properties

Possible Duplicate: Accessing a JavaScript Object Literal's Value within the Same Object Let's take a closer look at this JavaScript object var settings = { user:"someuser", password:"password", country:"Country", birthplace:countr ...

@SpringBootApplication is unable to retrieve static files

Located within the directory path: src/main/resources/static/ js css img etc.. Despite numerous attempts to configure addResourceHandlers, the static files remain undetected. The issue persists no matter what I try. ...

Transferring a JavaScript element's ID to PHP

Recently, I came across a JavaScript function that automatically updates the date and time for me. I found the script on this URL: http://jsfiddle.net/pLsgJ/1/ setInterval(function() { var currentTime = new Date ( ); var currentHours = curren ...

Acquire JSON data from a URL and display it on the webpage

I'm facing an issue where the JSON data I'm trying to fetch from a URL is not displaying due to an uncaught reference error in my code. How can I modify the code to ensure that the data gets shown? var url = "https://fantasy.premierleague.com/ ...

Having trouble getting the Bootstrap navbar mega menu to function properly on an Asp.Net Core platform

I attempted to incorporate a Bootstrap navbar mega menu dropdown into my layout using the code from this source: However, after downloading and inserting the code into my layout, the mega menu does not expand or take any action when clicked. In the Chrome ...

Variations in AmbientLight Screen Presentations

While working on illuminating the model using AmbientLight in three.js, I noticed a difference in color rendering between the test environment and production environment, despite using the same light source. Despite my efforts to troubleshoot the issue, I ...

Retrieve information from a MySQL database by utilizing a drop-down menu and subsequently employ a search feature to refine data based on the chosen option from the drop-down

I am looking to create a seamless interface that combines the functionality of a dropdown list with filters/options and a search function featuring a search bar and an "Ok" button. Once a filter/option like "Team" is selected from the dropdown list, the s ...

Creating a secure ZIP file with password protection using node.js

Currently, I am faced with the challenge of creating a ZIP file in node.js with password protection. Despite using the "node-zip" module for this task, it lacks the functionality to provide password protection: var zip = new require('node-zip') ...

Enhancing bar chart presentation with text in d3

Looking to enhance my bar chart by adding text tooltips that appear when hovering over each bar. While I am a beginner with d3, I've been struggling to implement this feature effectively. Despite trying various methods gleaned from online resources, t ...

The detailed record of this run can be accessed at:

npm ERR! code ENOTEMPTY npm ERR! syscall rename npm ERR! path /usr/local/lib/node_modules/expo-cli npm ERR! dest /usr/local/lib/node_modules/.expo-cli-dKBr48UN npm ERR! errno -39 npm ERR! ENOTEMPTY: The directory cannot be renamed because ...

What is the best way to delete a specific section from a CubeGeometry?

I have been working with ThreeCSG/CSG to subtract a small cube from a larger cube, which changes the appearance but not the actual geometry. When using PhysiJS (a physics engine) on another cube, it doesn't fall into the hole as expected. You can chec ...

Tips for adding spacing when the sidebar collapses and expands in a React application

I am attempting to achieve a layout where the body adjusts its space when the sidebar collapses and expands. Here is how it appears when the sidebar expands: see expanded sidebar here And this is how it looks when the sidebar collapses: see collapsed s ...

How do I initiate PUT and DELETE requests from my HTML code?

I am currently in the process of developing a web application that will manage items within a list. Previously, I used buttons with event listeners and JavaScript functions to handle editing and deleting items. However, I am now transitioning towards build ...

A guide on utilizing the .getLastRow() function in Google Apps Script

I am relatively new to Google Script and I am currently working on a piece of code that is giving me some trouble. My goal is to have the program loop through a range of cells in a spreadsheet, printing them out until it reaches the last row. Despite try ...

Difficulty encountered while using React.js map function to access specific JSON data

I'm encountering an issue where I am unable to read data from a JSON file. After checking that the data is stored in the component state and logging it to the console once the component is mounted, I attempted to render the URL string from the JSON da ...

Steps for Verifying the Legitimacy of an AJAX Request

In the process of creating a website where users are required to solve puzzles quickly, I am utilizing JavaScript to track the time taken for each puzzle. However, I am concerned about the possibility of users manipulating this data before it is sent to th ...