Galaxies simulation: Change color of a point and display text on mouseover

I have created a simulation of positions of 4672 of the nearest galaxies: Web Simulation of 3D distribution of galaxies < 200 Mpc from Milky Way

The code is here: galaxies/index.htm at master · RiteshSingh/galaxies · GitHub

The galaxies are points.

I want to color a point on mouseover and load the name of the galaxy.

I have spent many days trying to achieve it, but I have only achieved coloring all the points at once (as is happening in the current version).

  1. How should I go about doing it?
  2. Is a simple onMouseover function available in Three.js?

Thank you so much for your time and patience with a beginner :pray: :pray: :pray:

1 Like

See this example, it uses a Points object with a custom ShaderMaterial that allows for custom colors on each vertex, instead of across the entire material.

Maybe instead of changing the size when you mouse over, you’d like to change its customColor rgb values.

2 Likes

Thank you @marquizzo for your most kind reply :pray: :pray:

I am able to change color, as well as do basic raycasting, however, I am unable to separately raycast/color individual point. All the points are raycasted and colored as a group as seen here: Web Simulation of 3D distribution of galaxies < 200 Mpc from Milky Way

If/when free, could you please check where I am going wrong and what should I do to correct it?

Complete code: galaxies/index.htm at master · RiteshSingh/galaxies · GitHub

Relevant Code:

window.addEventListener( "mousemove", onDocumentMouseMove, false );

var selectedObject = null;

function onDocumentMouseMove( event ) {

	event.preventDefault();
	if ( selectedObject ) {

		selectedObject.material.color.set( '#fff' );
		selectedObject = null;

	}

	var intersects = getIntersects( event.layerX, event.layerY );
	if ( intersects.length > 0 ) {

		var res = intersects.filter( function ( res ) {

			return res && res.object;

		} )[ 0 ];

		if ( res && res.object ) {

			selectedObject = res.object;
			selectedObject.material.color.set( '#69f' );

		}

	}

}

var raycaster = new THREE.Raycaster();
var mouseVector = new THREE.Vector3();

function getIntersects( x, y ) {

	x = ( x / window.innerWidth ) * 2 - 1;
	y = - ( y / window.innerHeight ) * 2 + 1;

	mouseVector.set( x, y, 0.5 );
	raycaster.setFromCamera( mouseVector, camera );

	return raycaster.intersectObject( dots, true );

}

Maybe this topic will be helpful: How to put extra distance between target and camera while retaining control target vector? (camera animation)

1 Like

Did you read through the code of the example I gave you? It looks like you didn’t change anything, because you’re still updating the color of the material, which affects the entire set of points.

You need to update the color attribute of a single vertex in attributes.color.array[index];

Like this:

attributes.color.array[index * 3 + 0] = red;
attributes.color.array[index * 3 + 1] = green;
attributes.color.array[index * 3 + 2] = blue;

If this seems too complicated, you could just create a THREE.Sphere() with the color that you want, and then move it to the position of the intersection to cover the point. When you mouseout, you could hide it with sphere.visibility = false. Might be a simpler solution.

2 Likes

@marquizzo I’ve tried to do something like this: https://jsfiddle.net/prisoner849/y5xqzu1c/
It’s not so precise. Or I do something wrong :slight_smile:

1 Like

@prisoner849 yeah, man! You’ve got to set your raycaster’s precision threshold to something lower.

See line 74 below, all I changed was raycaster.params.Points.threshold = 0.1; The default value is 1.

https://jsfiddle.net/marquizzo/29ogvp6z/1/

2 Likes

Totally forgot about that setting :smile:

1 Like

Did you read through the code of the example I gave you? It looks like you didn’t change anything, because you’re still updating the color of the material, which affects the entire set of points.

@marquizzo Deeply grateful for your patience with me. Sorry if I seem to not put in enough effort. I request you to trust me, that the issue is mainly of code literacy. To me, the example itself reads somewhat like a paragraph in another language with about half of the words known to me. Therefore, I couldn’t immediately make a connection from my code to your example.

I will go through whatever you and @prisoner849 have most kindly written. I promise to spend as much time and effort as is needed to understand it and adopt it for my code. I assure you that I had spent not less than ten hours trying to fix the issue before reaching out to you for the 2nd time. I posted a seemingly un-modified code because that was the closest I could come to make it work: there was no use posting my non-working mess.

Thanks again for everything!!! :pray: :pray: :pray:

1 Like