# Equirectangular Projection of Sphere onto Texture

Okay so I have a script that generates planets and that all works fine but I want to essentially create a “heightmap” of the surface of the sphere based on the vertex distance from the center minus the planet’s radius (sea level). So I managed to get the latitude and longitude of every vertex but for whatever reason when I process these values in the xCord = … and yCord = … lines they always end up both equaling zero - no matter what, which I don’t understand. Essentially with those two lines all I am doing is converting the latitude and longitude coordinates into x and y pixel coordinates. Part of my code is available below.

EDIT: By the way 72 and 36 are the dimensions of the texture.

EDIT 2: So I tried changing all of the constants in the xCord = … and yCord = … lines and now they aren’t returning zero, so that was one of the problems and now I’m getting… something. The screenshot below shows the output. What I don’t get is why 0,0 is the position of the bottom, left pixel and 72,36 is not the top, right pixel as I thought this was the case.

EDIT 3: I think I resolved a bunch of problems with calculating latitude and longitude and everything seems to be working but I’m still getting undesirable results, without any color changing yet I should get a completely black map, a full map… help? Screens below.

``````	void MakeMap () {

texture = new Texture2D(72, 36);

vertices = planetVars.vertices;

float xCord = 0;
float yCord = 0;

for(int i = 0; i < vertices.Length; i++){

Vector3 globalVertPos = planet.transform.TransformPoint(vertices*);*
``````
• ``````  	Vector3 vectorA;*
``````
• ``````  	vectorA = (globalVertPos - planet.transform.position);*
``````
• ``````  	vectorA.y = 0;*
``````
• ``````  	float lng = 0;*
``````
• ``````  	Vector3 refRight= Vector3.Cross(Vector3.up, planet.transform.forward);*
``````
• ``````  	float ang = Vector3.Angle (vectorA, planet.transform.forward);*
``````
• ``````  	float sign = (Vector3.Dot(vectorA, refRight) > 0.0f) ? -1.0f: 1.0f;*
``````

_ lng = sign * ang;_

• ``````  	//print(lng);*
``````
• ``````  	float lat = 0;*
``````
• ``````  	lat = Vector3.Angle (vectorA, (globalVertPos - planet.transform.position));*
``````
• ``````  	if(globalVertPos.y < planet.transform.position.y){*
``````

_ lat *= -1;_

• ``````  	}*
``````
• ``````  	//print(lat);*
``````

_ xCord = (lng + 180f) * (texture.width/360f);_
_ yCord = ((lat - 90f) * (texture.height/180f));_

• ``````  	float dist = Vector3.Distance(globalVertPos, planet.transform.position);*
``````
• ``````  	color = Color.Lerp (white, black, dist);*
``````
• ``````  	texture.SetPixel ((int)xCord, (int)yCord, color);*
``````
• ``````  }*
``````
• ``````  texture.Apply();*
``````
• }*
EDIT 2:
[20724-equirectangular+project+screenshot.png|20724]*
EDIT 3:
[20755-equirectangular+projection+screenshot+2.png|20755]*

Okay, so I finally figured out how to do this, instead of trying to use vertex data I just created a sphere of positions surrounding my planet as a list of Vector3’s, then I cast a rays down onto the planet and save the raycast hit positions. Instead of processing vertices in my function above I process the raycast hit points and it works almost flawlessly.

Can you show the script you’re using to save points via raycasting?