0
$\begingroup$

just as the title says, I'd like to experiment with 3D surfaces which are defined by implicit functions.

For instance, let's say I have an implicit curve of the form x^2 + y^2 + z^2 = 50^2, where "50" is the "radius". You might recognize this as a sphere, but that's not the point. How can I tell javascript to look through and find all points in 3D space in a region that satisfy this equation, and then render them as a solid mesh or with shader?

This is the almost-default code I'm using that js-fiddle loads for me:

import { OrbitControls } from 'https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js'; let camera, scene, renderer; init(); animate(); //3D implicit functions //end of 3D implicit functions function init() { const upButton = document.createElement('button'); upButton.textContent = '↑'; const downButton = document.createElement('button'); downButton.textContent = '↓'; const leftButton = document.createElement('button'); leftButton.textContent = '←'; const rightButton = document.createElement('button'); rightButton.textContent = '→'; // Add buttons to the document body document.body.appendChild(upButton); document.body.appendChild(downButton); document.body.appendChild(leftButton); document.body.appendChild(rightButton);   // Event listeners for button clicks const speed = 0.05; // Adjust movement speed as needed upButton.addEventListener('click', () => { mesh.position.y += speed; }); downButton.addEventListener('click', () => { mesh.position.y -= speed; }); leftButton.addEventListener('click', () => { mesh.position.x -= speed; }); rightButton.addEventListener('click', () => { mesh.position.x += speed; }); camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 ); camera.position.z = 1; scene = new THREE.Scene(); const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 ); const material = new THREE.MeshNormalMaterial(); const mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); const controls = new OrbitControls( camera, renderer.domElement ); controls.minDistance = 0.5; controls.maxDistance = 5; } function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); } 
$\endgroup$
5
  • 1
    $\begingroup$ The common method is called Marching Cubes. $\endgroup$ Commented Aug 7, 2024 at 18:29
  • 1
    $\begingroup$ Hmm, well, marching cubes doesn't look "smooth", are there alternatives to just color and project the pixels, or anything in the three.js library that might make rendering this more efficient, and with anti-aliasing applied? $\endgroup$ Commented Aug 8, 2024 at 16:12
  • 1
    $\begingroup$ Marching cubes is as smooth as you want by refining the grid. You can even improve the smoothness by computing the true surface normals at the vertices. $\endgroup$ Commented Aug 8, 2024 at 16:15
  • $\begingroup$ Marching Cubes works well for implicit functions. You can make it even smoother by finding the vertices via half step approximation — you home in on the vertex location by taking smaller and smaller steps. Also note that when using floats that cracks will form if you do not sort the input vertices. $\endgroup$ Commented Aug 9, 2024 at 23:49
  • $\begingroup$ … and you do not simply say that a pixel/voxel is either on or off, you use the actual value calculated by the implicit function. Then you set the isosurface’s isovalue to suit your taste. Do you know the basics of fractal geometry? $\endgroup$ Commented Aug 9, 2024 at 23:52

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.