For this reason I have created a suitable geometry. For this I use the scheme from my Addon. Produces almost infinite many time-varying geometries with functions .
It is symmetrical and therefore suitable.
With a little elementary geometry, the transformation from cube to sphere can be easily achieved.
The uv values are still missing, will be supplied later.
UPDATE:
The ready solution there Morph box sphere geometry (+shader)
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/morphing-between-two-geometries/31911 -->
<head>
<title> MorphBoxSphere </title>
<meta charset="utf-8" />
<meta charset="utf-8" />
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body> </body>
<script src="../js/three.min.134.js"></script>
<script src="../js/OrbitControls.134.js"></script>
<script>
// @author hofk
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 10);
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xdedede, 1 );
document.body.appendChild( renderer.domElement );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const g = new THREE.BufferGeometry( );
const r = 3; // radius sphere === space cube diagonal
// const sd = r * 1 / Math.sqrt( 2 ); // 1/2 square diagonal
const ss = r * 1 / Math.sqrt( 3 ); // 1/2 square side
const cs = 8; // count of segments per side
const axesHelper = new THREE.AxesHelper( r );
scene.add( axesHelper );
const css = cs + 1;
const hvc = css + cs ; // height vertex count
const vertexCount = css * css + cs * cs;
const faceCount = cs * cs * 4;
let a0, b0, c0, a1, b1, c1, le;
const indices = new Uint32Array( faceCount * 3 * 6 );
const positions = new Float32Array( vertexCount * 3 * 6 );
//const uvs = new Float32Array( vertexCount * 2 * 6 ); // uvs to vertices
g.setIndex( new THREE.BufferAttribute( indices, 1 ) );
g.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ).setUsage( THREE.DynamicDrawUsage) );
//g.setAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
const cube = new Float32Array( vertexCount * 3 * 6 ); // basis positions plane,cube
const diff = new Float32Array( vertexCount * 3 * 6 ); // difference positions cube sphere
//face indices
let idx = 0;
let offs = 0;
for ( let k = 0; k < 6; k ++ ) {
for ( let j = 0; j < cs; j ++ ) {
for ( let i = 0; i < cs; i ++ ) {
// 4 faces / segment
a = offs + hvc * j + css + i;
b1 = offs + hvc * j + i; // bottom
c1 = offs + hvc * ( j + 1 ) + i;
b2 = offs + hvc * j + 1 + i; // left
c2 = offs + hvc * j + i;
b3 = offs + hvc * ( j + 1 ) + i; // right
c3 = offs + hvc * ( j + 1 ) + 1 + i;
b4 = offs + hvc * ( j + 1 ) + 1 + i; // top
c4 = offs + hvc * j + 1 + i;
indices[ idx] = a; // bottom
indices[ idx + 1 ] = b1;
indices[ idx + 2 ] = c1;
indices[ idx + 3 ] = a; // left
indices[ idx + 4 ] = b2,
indices[ idx + 5 ] = c2;
indices[ idx + 6 ] = a; // right
indices[ idx + 7 ] = b3;
indices[ idx + 8 ] = c3;
indices[ idx + 9 ] = a; // top
indices[ idx + 10 ] = b4,
indices[ idx + 11 ] = c4;
idx += 12;
}
}
offs += hvc * cs + css; // + vertex count one side
}
const v = t => 0.5 * ( 1 + Math.sin( t ) );
idx = 0; // reset
// ia, ib, ic, sign
makePositions( 0, 1, 2, 1 );
makePositions( 0, 1, 2, -1 );
makePositions( 1, 2, 0, 1 );
makePositions( 1, 2, 0, -1 );
makePositions( 2, 0, 1, 1 );
makePositions( 2, 0, 1, -1 );
function makePositions( ia, ib, ic, sign ) {
for ( let j = 0; j < css; j ++ ) {
for ( let i = 0; i < css; i ++ ) {
a0 = -ss + 2 * ss * j / cs;
b0 = -ss + 2 * ss * i / cs;
c0 = sign * ss;
cube[ idx + ia ] = a0;
cube[ idx + ib ] = b0;
cube[ idx + ic ] = c0;
le = Math.sqrt( a0 * a0 + b0 * b0 + c0 * c0 );
a1 = r * a0 / le;
b1 = r * b0 / le;
c1 = r * c0 / le;
diff[ idx + ia ] = a1 - a0;
diff[ idx + ib ] = b1 - b0;
diff[ idx + ic ] = c1 - c0;
positions[ idx + ia ] = a0;
positions[ idx + ib ] = b0;
positions[ idx + ic ] = c0;
idx += 3;
}
if( j < cs ) {
for ( let i = 0; i < cs; i ++ ) {
a0 = -ss + 2 * ss * ( j + 0.5 ) / cs;
b0 = -ss + 2 * ss * ( i + 0.5 ) / cs;
c0 = sign * ss;
cube[ idx + ia ] = a0;
cube[ idx + ib ] = b0;
cube[ idx + ic ] = c0;
le = Math.sqrt( a0 * a0 + b0 * b0 + c0 * c0 );
a1 = r * a0 / le;
b1 = r * b0 / le;
c1 = r * c0 / le;
diff[ idx + ia ] = a1 - a0;
diff[ idx + ib ] = b1 - b0;
diff[ idx + ic ] = c1 - c0;
positions[ idx + ia ] = a0;
positions[ idx + ib ] = b0;
positions[ idx + ic ] = c0;
idx += 3;
}
}
}
}
//console.log( 'cube ', cube) /////////////////////////////////////////////////////////////////////////
//console.log( 'diff ', diff) /////////////////////////////////////////////////////////////////////////
//console.log( positions )///////////////////////////////////////////////////////////////////////
const mat = new THREE.MeshBasicMaterial( { color: 0xff00ff, wireframe: true, side: THREE.DoubleSide } );
const mesh = new THREE.Mesh( g, mat );
scene.add( mesh )
const clock = new THREE.Clock( );
let t;
animate( );
function animate( ) {
t = clock.getElapsedTime( );
requestAnimationFrame( animate );
morph( t );
renderer.render( scene, camera );
}
function morph( t ) {
idx = 0; // reset
// ia, ib, ic
setPositions( 0, 1, 2 );
setPositions( 0, 1, 2 );
setPositions( 1, 2, 0 );
setPositions( 1, 2, 0 );
setPositions( 2, 0, 1 );
setPositions( 2, 0, 1 );
g.attributes.position.needsUpdate = true;// to change the positions of the vertices
function setPositions( ia, ib, ic ) {
for ( let j = 0; j < css; j ++ ) {
for ( let i = 0; i < css; i ++ ) {
positions[ idx + ia ] = cube[ idx + ia ] + v( t ) * diff[ idx + ia ];
positions[ idx + ib ] = cube[ idx + ib ] + v( t ) * diff[ idx + ib ];
positions[ idx + ic ] = cube[ idx + ic ] + v( t ) * diff[ idx + ic ];
idx += 3;
}
if( j < cs ) {
for ( let i = 0; i < cs; i ++ ) {
positions[ idx + ia ] = cube[ idx + ia ] + v( t ) * diff[ idx + ia ];
positions[ idx + ib ] = cube[ idx + ib ] + v( t ) * diff[ idx + ib ];
positions[ idx + ic ] = cube[ idx + ic ] + v( t ) * diff[ idx + ic ];
idx += 3;
}
}
}
}
}
</script>
</html>