Sign in to follow this  
quddusaliquddus

How to Project a Terrain onto a Sphere?

Recommended Posts

Hi all :D, I am trying to create a Sphere with Fractal Terrain. I have the code for creating a terrain using the Diamond Square Algorithm. I also have the code for creating a 3D Sphere. All this is in WPF using Visual Basic .NET I would like to know how I could project the Terrain onto a Sphere. I am at a complete loss as how to do this. Any help is appreciated. Thanks Q :) PS Diamond Square Algorithm Result: [IMG]http://i40.tinypic.com/1547jtf.jpg[/IMG] Sphere Result: [IMG]http://i42.tinypic.com/qovd49.jpg[/IMG]

Share this post


Link to post
Share on other sites
Well, its actually pretty simple :)

You have <insert an algorithm of your choice here> that creates your terrain height data. From that you can construct vertices as if the terrain raises height values on a flat plane. So each height value is just a difference of the original (flat) vertex height and the height from your terrain algorithm output.

For a sphere its the same. Just take the unmodified vertex position on the sphere's surface and translate this vertex along the direction vector from the sphere's center to this particular vertex position by the amout of the height output from your terrain algorithm for this location.

Of course there are more advanced techniques such as building six flat terrain patches as faces of a single cube. Then you can apply a transformation for each vertex that transforms it from flat cube face space to sphere space.

Share this post


Link to post
Share on other sites
I'm assuming you want the result to be something like a planet; a sphere with terrain.

The easiest way I've found is to use 3d noise, and wherever the vertex lies relative to the origin of the sphere, displace it outwards whatever the noise is at that point. There is no projection needed. Unless you were subdividing the planet into 6 quadtrees, then you would need to project them from a cube to a sphere (not difficult). Even then, the noise would still simply be a function of any given point on the sphere.

Here is a great method of projecting a cube (6 quadtrees) to a sphere.

Share this post


Link to post
Share on other sites
Hi. Thanks for the help guys (and the link). Would you guys go over my implementation and see where Im going wrong? If so- I will post it on the forum.

I have managed to create peaks on the sphere modifying points belonging to six triangles. Then I simply tried to extend the height of the sphere using the data from the Diamond Square Algorithm (without success).

So - is anyone up for looking @ the code?

Share this post


Link to post
Share on other sites
Thanks.

[The Diamond Square Algorithm]



'Assign Square Corner Indexes
SqrSize = Points.Count - 1
SqrCorners(0) = 0
SqrCorners(1) = Sqrt(SqrSize) - 1


'### Diamond Step

'Assign Centre Index
Centre = SqrSize / 2

'Create Centre Point3D
Dim CentrePoint As New Point3D

'Assign to Centre Point3D
CentrePoint.X = Points(Centre).X
CentrePoint.Y = (Points(SqrCorners(0)).Y + Points(SqrCorners(1)).Y + Points(SqrCorners(2)).Y + Points(SqrCorners(3)).Y + (Rnd.Next(0, RandomRange) / 1000)) / 4
CentrePoint.Z = Points(Centre).Z

'Assign Centre Point3D to Points Collection
Points(Centre) = CentrePoint
Points(DiamCorners(1)) = CentrePoint
Points(DiamCorners(2)) = CentrePoint
Points(DiamCorners(3)) = CentrePoint

'### Call DiamondSquareAlgorithm for each quarter with reduced random range

'Split into Four Squares

'Bottom Left
Dim Square1 As New Point3DCollection((SqrSize / 2) - 5)

'Bottom Right
Dim Square2 As New Point3DCollection((SqrSize / 2) - 5)

'Top Left
Dim Square3 As New Point3DCollection((SqrSize / 2) - 5)

'Top Right
Dim Square4 As New Point3DCollection((Sq
Next

'Populate Square 2
'Bottom Right Square

For i = 0 To (SqrSide / 2) - 1

For j = 0 To (SqrSide / 2) - 1

Square2.Add(Points((i * SqrSide) + j + (SqrSide / 2)))

Next

Next

'Populate Square 3
'Top Left Square

For i = 0 To (SqrSide / 2) - 1

For j = 0 To (SqrSide / 2) - 1

Square3.Add(Points(((i + SqrSide / 2) * SqrSide) + j))

Next

Next

'Populate Square 4
'Top Right Square

For i = 0 To (SqrSide / 2) - 1

For j = 0 To (SqrSide / 2) - 1

Square4.Add(Points(((i + SqrSide / 2) * SqrSide) + j + (SqrSide / 2)))
are with new quarters using loop

'Populate Square 1
'Bottom Left Square

Dim Index As Integer = 0

For i = 0 To (SqrSide / 2) - 1

For j = 0 To (SqrSide / 2) - 1

Points((i * SqrSide) + j) = Square1(Index)

Index = Index + 1

Next

Next

'Populate Square 2
'Bottom Right Square
'Top Left Square

Index = 0

For i = 0 To (SqrSide / 2) - 1

For j = 0 To (SqrSide / 2) - 1

Points(((i + SqrSide / 2) * SqrSide) + j) = Square3(Index)

Index = Index + 1

Next

Next

'Populate Square 4
'Top Right Square Next

'### Return current whole square

End If

End Function





[Edited by - quddusaliquddus on June 24, 2009 9:09:57 AM]

Share this post


Link to post
Share on other sites
Maybe try placing the code in source tags to make it easier to read? Although I'm not sure if it can highlight VB.

Also, is there a specific problem with the code you posted?

Share this post


Link to post
Share on other sites
[The Sphere-Creation Code]



Dim Ext As Double = InputBox("Ext: ", "Extension", "1")

'For Adding Peaks to Sphere

'Dim P3DHeightList As Point3DCollection = DiamondSquareAlgorithm(Point3DList, 100)

'Dim s1, s2, s3, s4, s5, s6 As Integer

'For j = 1 To ((n / 2))

' For i = 0 To n + 1 Step 2

' 'Dim s1 As Integer

' 'Assign Values
' HorizSegment = i
' VertiSegment = j
' 'Calculate Point
' Square = ((VertiSegment - 1) * n * 6) + 6 * HorizSegment + 1
' s1 = Square

' Point3DList(s1) = getPeak(Point3DList(s1), r, Ext)

' '===

' 'Dim s2 As Integer

' 'Assign Values
' HorizSegment = i + 1
' VertiSegment = j
' 'Calculate Point
' Square = ((VertiSegment - 1) * n * 6) + 6 * HorizSegment - 3
' s2 = Square

' Point3DList(s2) = getPeak(Point3DList(s2), r, Ext)

' '===

' 'Dim s3 As Integer

' 'Assign Values
' HorizSegment = i + 2
' VertiSegment = j
' 'Calculate Point
' Square = ((VertiSegment - 1) * n * 6) + 6 * HorizSegment - 1
' s3 = Square

' Point3DList(s3) = getPeak(Point3DList(s3), r, Ext)

5

SphereMesh.Positions.Add(Point3DList(P + Q))

triangleMesh.TriangleIndices.Add(P + Q)

Next

P = P + 6

Next

Next

'Add to Viewport
Dim triangleModel As New GeometryModel3D(SphereMesh, material)

Dim model As New ModelVisual3D()
model.Content = triangleModel
model.SetValue(NameProperty, "Earth")

Me.V.Children.Add(model)

Dim stopTime As DateTime = DateTime.Now
Console.WriteLine(stopTime)

Dim duration As TimeSpan = stopTime - startTime
'MessageBox.Show(duration.ToString)





[Edited by - quddusaliquddus on June 24, 2009 9:19:15 AM]

Share this post


Link to post
Share on other sites
Thanks again.

One specific problem seems to be that in the Sphere-creation code - when I call the getpeak function - if I pass the Y value of P3DHeightList as the 'Ext' parameter - it doesnt give the desired effect i.e. it should extend that particular peak outwards by that given amount. This doenst happen.

So theres something going wrong.

Share this post


Link to post
Share on other sites
I've been doing something similar recently- generating Perlin noise in a GLSL Vertex Shader, taking the XYZ value of the vertices of a base sphere, then using using the single value returned from the noise function to displace each vertex along the sphere's normal. Works well!

With lookup-table based shading
http://vimeo.com/5074567

And with phong directional lighting
http://vimeo.com/5281011

I know it's not what you're trying to do, but thought you might be interested.

a|x
http://machinesdontcare.wordpress.com

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this