# Vertex Shader Sphere Projection and CPU Distance Calculation

I have multiple planes whose vertices are transformed to a position on a sphere in the vertex shader. The GLSL function called pointToSphere transforms a point p to a position on a sphere with a radius of 100 units centered around localcenter.

I need to find a way to calculate the distance between the newly transformed planes and some position C on the CPU side. My algorithm has N number of planes for each side, and I need to find the distance between each plane and point C, not the entire sphere.

This doesn’t work plane.distanceTo(C)

CODE EXAMPLE:

let camera, scene,rtCamera,renderTarget,rtScene, renderer;
let uniforms, mesh, w;
let bbox  = new THREE.Box3();

renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor('white');
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

return 
uniform vec3 wTl;
uniform vec3 ps;
vec3 pointToSphere(vec3 p, vec3 localCenter){
return 100.0*normalize(p-localCenter) + localCenter;
}

varying vec3 v3n;
void main() {
vec3 newPosition   =  pointToSphere(position,wTl) ;
gl_Position = projectionMatrix  * modelViewMatrix * vec4( newPosition, 1.0 ) ;
}

}

return 
uniform vec3 ucolor;
void main() {
gl_FragColor  = vec4(ucolor,1.0);
}

}

init();

function init() {
w = 100
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.001, 100000);
camera.position.z = 250;

let controls = new THREE.OrbitControls(camera, renderer.domElement);

var front = buildMesh();
var fg = new THREE.Group(front)

var back = buildMesh();
var bg = new THREE.Group(back)
bg.position.z = -w;
bg.rotation.y=(Math.PI)

var right = buildMesh();
var rg = new THREE.Group(right)
rg.position.z = -((w)/2);
rg.position.x =  ((w)/2);
rg.rotation.y = (Math.PI/2)

var left = buildMesh();
var lg = new THREE.Group(left)
lg.position.z = -((w)/2);
lg.position.x = -((w)/2);
lg.rotation.y=(-Math.PI/2)

var top = buildMesh();
var tg = new THREE.Group(top)
tg.position.z = -((w)/2);
tg.position.y = ((w)/2);
tg.rotation.x=(-Math.PI/2)

var bot = buildMesh();
var bog = new THREE.Group(bot)
bog.position.z = -((w)/2);
bog.position.y = -((w)/2);
bog.rotation.x=(Math.PI/2)

var g = new THREE.Group()

var sides = [
...fg.children,
...bg.children,
...rg.children,
...lg.children,
...tg.children,
...bog.children,
]

var cnt = centerPosition(g)
var localCenter = new THREE.Vector3();
for (let index = 0; index < sides.length; index++) {
const element = sides[index];
let color = new THREE.Color( 0xffffff );
color.setHex( Math.random() * 0xffffff );
element.worldToLocal(localCenter.copy(cnt))
element.material.uniforms['wTl'].value = localCenter
element.material.uniforms['ps'].value = element.position
element.material.uniforms['ucolor'].value = color

}

}

function buildMesh(t){
let geometry = new THREE.PlaneGeometry(w, w,50,50);
uniforms = {
ucolor:{value:new THREE.Vector3()},
wTl:   {value:new THREE.Vector3()},
ps:    {value:new THREE.Vector3()}
};
uniforms: uniforms,
wireframe:false
});

var mesh = new THREE.Mesh(geometry, material);
return mesh
}

function centerPosition(g) {
bbox.expandByObject(g);
var center = new THREE.Vector3();
bbox.getCenter(center);
return center
}

update()

function update(t) {
renderer.render(scene, camera);
requestAnimationFrame (update);
}
 <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script> 

I ended up finding an answer. To obtain the center of a projected plane that is projected on the GPU, you need to take the position of the unprojected plane and project it.

function project( v, r, center ){
v.sub( center ).setLength( r ).add( center );
}

let positionCenter = new THREE.Vector3()

This will give you the center of the mesh then use plane.localToWorld(positionCenter) positionCenter.distanceTo(C) to get the correct distance.