Generating a Gsphere

Started by
19 comments, last by Scottehy 13 years, 11 months ago
Hey guys. I've just started one of my assignments for in my final year of university and I'm in need of some help with creating a gsphere. Part of my project I'm working on is creating some procedural planet generation. I've been looking at the way this great tutorial shows a simple way to make Spherical Landscapes - http://freespace.virgin.net/hugo.elias/models/m_landsp.htm In a paragraph he mentions that gspheres are a much better better choice for this problem. I've created what I think is called an lsphere with the help of some tutorials, but I've no clue on how to even create a gsphere. I've tried looking for any example of some with no luck. Another problem that lies is I'll need to create UV and normal coordinates for the gsphere as well. Heres how I've created the current sphere I'm using which works quite well but the textures pack up at the poles and it looks a little messy.

void Sphere::BuildSimpleSphere()
{
	float phiStep = PI / m_NumStacks;

	// Don't count the poles as rings.
	int numRings = m_NumStacks - 1;

	// Compute Vertices for each stack ring.
	for( int i = 1; i <= numRings; ++i )
	{
		float phi = i * phiStep;
		
		// Vertices of ring
		float thetaStep = 2.0f * PI / m_NumSlices;
		for( int j = 0; j <= m_NumSlices; ++j )
		{
			float theta = j * thetaStep;

			// Need to possibly fix up the normal and texture co-ords because of  - (m_Radius/2) due to centering the sphere
			NiPoint3 pos;
			pos.x = (m_Radius * sinf(phi) * cosf(theta)) - (m_Radius/2);
			pos.y = (m_Radius * cosf(phi)) - (m_Radius/2);
			pos.z = (m_Radius * sinf(phi) * sinf(theta));

			NiPoint3 normal = pos;
			normal.UnitizeVector(normal);

			NiPoint2 uv;
			uv.x = theta / (2.0f * PI);
			uv.y = phi / PI;

			m_Vertices.push_back(pos);
			m_Normals.push_back(normal);
			m_UVs.push_back(uv);
		}
	}

	// Poles: note that there will be texture coordinate distortion
	m_Vertices.push_back( NiPoint3((0.0f) - (m_Radius/2), (-m_Radius) - (m_Radius/2), 0.0f) );
	m_Vertices.push_back( NiPoint3((0.0f) - (m_Radius/2), (m_Radius) - (m_Radius/2), 0.0f) );

	m_Normals.push_back( NiPoint3(0.0f, -1.0f, 0.0f) );
	m_Normals.push_back( NiPoint3(0.0f, 1.0f, 0.0f) );

	m_UVs.push_back( NiPoint2(0.0f, 1.0f) );
	m_UVs.push_back( NiPoint2(0.0f, 0.0f) );

	int northPoleIndex = (int)m_Vertices.size() - 1;
	int southPoleIndex = (int)m_Vertices.size() - 2;

	int numRingVertices = m_NumSlices + 1;

	// Compute indices for inner stacks (not connected to poles).
	for(int i = 0; i < m_NumStacks - 2; ++i)
	{
		for(int j = 0; j < m_NumSlices; ++j)
		{
			m_Indices.push_back(i * numRingVertices + j);
			m_Indices.push_back(i * numRingVertices + j + 1);
			m_Indices.push_back((i + 1) * numRingVertices + j);

			m_Indices.push_back((i + 1)  *numRingVertices + j);
			m_Indices.push_back(i * numRingVertices + j + 1);
			m_Indices.push_back((i + 1)  *numRingVertices + j + 1);
		}
	}

	// Compute indices for top stack.  The top stack was written 
	// first to the vertex buffer.
	for(int i = 0; i < m_NumSlices; ++i)
	{
		m_Indices.push_back(northPoleIndex);
		m_Indices.push_back(i  +1);
		m_Indices.push_back(i);
	}

	// Compute indices for bottom stack.  The bottom stack was written
	// last to the vertex buffer, so we need to offset to the index
	// of first vertex in the last ring.
	int baseIndex = (numRings - 1) * numRingVertices;
	for(UINT i = 0; i < m_NumSlices; ++i)
	{
		m_Indices.push_back(southPoleIndex);
		m_Indices.push_back(baseIndex + i);
		m_Indices.push_back(baseIndex + i + 1);
	}
}
If anyone can show me how to create one for my situation it would be greatly appreciated as it's driving me a little stir crazy. Thanks a heap, Scott.
Advertisement
Tbh, I never heard of the terms gsphere and lsphere (just g-strings), but you can get away without slices and without the singularities at the poles relatively trivial by creating 6 rectangles (or simply: a cube), and normalizing each vertex.

This gave me awesome results once I experimented with procedural planets.


pre-edit: Just found this article which might be of interest for you (I was talking about what he calls "quadcube").
gsphere is an abbreviation for geosphere, which is short for a geodesic sphere.
I have no idea what an G-Sphere is, but it could be a geodesic sphere? If so, here is a good tutorial on how to construct them: Make a geodesic sphere.
Thanks for the reply guys. It looks like the geodesic sphere is what I'm looking for. Only problem is I'm not perfect with some 3D stuff yet. So if anyone has some tutorials on how to generate one of these it would be greatly appreciated. I always get stuck on setting up things like the indices.

The VB one seems a little funky? Thanks for that great blog on the person who is building this crazy planet generator. I'm reading that at the moment.
Quote:Original post by Scottehy
Thanks for the reply guys. It looks like the geodesic sphere is what I'm looking for. Only problem is I'm not perfect with some 3D stuff yet. So if anyone has some tutorials on how to generate one of these it would be greatly appreciated. I always get stuck on setting up things like the indices.

The VB one seems a little funky? Thanks for that great blog on the person who is building this crazy planet generator. I'm reading that at the moment.
Indexing is always the hardest part. I say dig yourself into it, so that if you face an other indexing nightmare again, it will be much easier to solve. But a piece of paper and a pen can do wonders.
The usual method for a geosphere is starting off with an icosahedron, and doing recursive subdivisions on each triangles by joining the midpoint of the edges. That's the closest you can get to a perfectly trianglulated sphere (which is actually mathematically impossible).

Everything is better with Metal.

Thanks oliii, trouble is I'm having an issue wrapping it around my head how to generate one. The tutorials I've been looking at for them are just confusing and seem a little over complex. Would you possibly have any tutorial sites on them that aren't to bad?
I'll see if I can dig up an old, old demo, and clean it up!

Everything is better with Metal.

Awesome, thank you :)

This topic is closed to new replies.

Advertisement