Planet textures using libnoise

An area for discussing new ideas and additions to Oolite.

Moderators: another_commander, winston

User avatar
LittleBear
---- E L I T E ----
---- E L I T E ----
Posts: 2718
Joined: Tue Apr 04, 2006 7:02 pm
Location: I escaped The Labyrinth with the assistance of my fledgling. After many battles, I'm in the Nexus.

Post by LittleBear »

Yep. Sun is much further out. Took about 6 minutes at J speed to get there.

I think the problem on the F7 screen is that the new planet image is being super-imposed over the old planet image.

Still looks stunning in real space though!

F7 Screen :

Image

Same Planet in real space:

Image
My OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits and Renegade Pirates can be downloaded from the Elite Wiki here.

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Post by dajt »

Sorry about the sun - I'll post another exe with the original distance. I'd got used to it and didn't notice!

What you're seeing on the planetary info page is the original atmosphere and clouds being rendered, which I'd disabled in the space view while debugging the textures. I'll put the originals back for now until the libnoise ones are going.

Thanks for pointing out the things I'd missed, it was getting late when I posted the exe.
Regards,
David Taylor.

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Post by dajt »

Ahruman wrote:The only alternative I can think of to wrapping like this is to use the mangled symbols directly, which is possible but horrible (and I really don’t feel like going into it). Building the wrapper into a DLL sounds feasible. The fact that the GNUstep compiler flavour doesn’t support C++ sounds perverse and dogmatic, but maybe that’s just me; building gcc with both ObjC and C++ support shouldn’t be much harder than building it with just one of the two (and is different from supporting ObjC++).
That might have been funny... I could get the mangled names using objdump. Luckily I don't have to go there now :)
Regards,
David Taylor.

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Post by dajt »

OK, posted another exe here.
  • Cloud layer restored to planets in space view.
  • Caching planetary textures to make things a bit faster - but what about memory consumption?
  • Changed it so planet textures set by OXPs won't be overwritten.
  • Put the sun back where it used to be.
Regards,
David Taylor.

User avatar
aegidian
Master and Commander
Master and Commander
Posts: 1152
Joined: Thu May 20, 2004 10:46 pm
Location: London UK
Contact:

Questions, questions, questions...

Post by aegidian »

Not developing on the PC I couldn't compile your experiments, so I picked up my graphics textbooks and rolled my own.

Now, do I understand this correctly:-

libnoise has built in routines for generating neato planet textures (their webpage seems to imply this)? Are these what you're using?

To turn perlin noise (with each value clamped between 0.0and 1.0) into colour I presume you're either sampling a 1d texture at the given value, or using some other gradient method? Or is this another function of libnoise?



To experiment myself, and lacking libnoise, I rolled my own simple Perlin noise generator and copied it into TextureStore. At the moment it picks colours from a five value LERP. But I would change this to better take the standard and polar sea and sky values from the planet data if I were to go ahead and include this into Oolite. (This could also help to reduce the 'pinching' effect of textures at the planetary poles).

What do you think, keep libnoise or use a roll-our-own version?

Code: Select all

float lerp5( float v0, float v1, float v2, float v3, float v4, float q)
{
	if (q < 0.25)
		return v0 * (1.0 - q * 4.0) + v1 * q * 4.0;
	q -= 0.25;
	if (q < 0.25)
		return v1 * (1.0 - q * 4.0) + v2 * q * 4.0;
	q -= 0.25;
	if (q < 0.25)
		return v2 * (1.0 - q * 4.0) + v3 * q * 4.0;
	q -= 0.25;
	if (q < 0.25)
		return v3 * (1.0 - q * 4.0) + v4 * q * 4.0;
	return v4;	// values of q over 1.0
}

float my_lerp( float v0, float v1, float q)
{
	float q1 = 0.5 * (1.0 + cosf((q + 1.0) * PI));
	return v0 * (1.0 - q1) + v1 * q1;
}

void addNoise(float * buffer, int p, int n, float scale)
{
	int x, y;
	float R[n*n];
	
	for (y = 0; y < n; y++) for (x = 0; x < n; x++) R[y * n + x] = randf();	// random array

	float r = (float)p / (float)n;
	for (y = 0; y < p; y++) for (x = 0; x < p; x++)
	{
		int ix = floor( (float)x / r);
		int jx = (ix + 1) % n;
		int iy = floor( (float)y / r);
		int jy = (iy + 1) % n;
		float qx = x / r - ix;
		float qy = y / r - iy;
		float rix = my_lerp( R[iy * n + ix], R[iy * n + jx], qx);
		float rjx = my_lerp( R[jy * n + ix], R[jy * n + jx], qx);
		float rfinal = scale * my_lerp( rix, rjx, qy);

		buffer[ y * p + x ] += rfinal;
	}
}

void fillSquareImageDataWithSmoothNoise(unsigned char * imageBuffer, int width, int nplanes)
{
	float accbuffer[width * width];
	int x, y;
	for (y = 0; y < width; y++) for (x = 0; x < width; x++) accbuffer[ y * width + x] = 0.0f;

	// generate 6 octaves of noise
	int octave = 4;
	float scale = 0.5;
	int  n;
	for (n = 0; n < 6; n++)
	{
		addNoise( accbuffer, width, octave, scale);
		octave *= 2;
		scale *= 0.5;
	}
	
	for (y = 0; y < width; y++) for (x = 0; x < width; x++)
	{
		int p;
		float q = accbuffer[ y * width + x];
		q = 2.0f * ( q - 0.5f);
		if (q < 0.0f)
			q = 0.0f;
		for (p = 0; p < nplanes - 1; p++)
			imageBuffer[ p + nplanes * (y * width + x) ] = 255 * q;
		imageBuffer[ p + nplanes * (y * width + x) ] = 255;
	}
}

void fillSquareImageWithGenTex(unsigned char * imageBuffer, int width, int nplanes, float impress, float bias,
	OOColor* c0, OOColor* c1, OOColor* c2, OOColor* c3, OOColor* c4)
{
	float accbuffer[width * width];
	int x, y;
	for (y = 0; y < width; y++) for (x = 0; x < width; x++) accbuffer[ y * width + x] = 0.0f;

	// generate 4 octaves of noise
	int octave = 4;
	float scale = 0.5;
	int  n;
	for (n = 0; n < 6; n++)
	{
		addNoise( accbuffer, width, octave, scale);
		octave *= 2;
		scale *= 0.5;
	}
	
	for (y = 0; y < width; y++) for (x = 0; x < width; x++)
	{
		float q = accbuffer[ y * width + x];
		
		q = impress * q + bias;
		
		if (q < 0.0)	q = 0.0;
		if (q > 1.0)	q = 1.0;
		
		float red = lerp5( [c0 redComponent], [c1 redComponent], [c2 redComponent], [c3 redComponent], [c4 redComponent], q);
		float blue = lerp5( [c0 blueComponent], [c1 blueComponent], [c2 blueComponent], [c3 blueComponent], [c4 blueComponent], q);
		float green = lerp5( [c0 greenComponent], [c1 greenComponent], [c2 greenComponent], [c3 greenComponent], [c4 greenComponent], q);
		
		if (nplanes == 1)
			imageBuffer[ y * width + x ] = 255 * q;
		if (nplanes == 3)
		{
			imageBuffer[ 0 + 3 * (y * width + x) ] = 255 * red;
			imageBuffer[ 1 + 3 * (y * width + x) ] = 255 * green;
			imageBuffer[ 2 + 3 * (y * width + x) ] = 255 * blue;
		}
		if (nplanes == 4)
		{
			imageBuffer[ 0 + 4 * (y * width + x) ] = 255 * red;
			imageBuffer[ 1 + 4 * (y * width + x) ] = 255 * green;
			imageBuffer[ 2 + 4 * (y * width + x) ] = 255 * blue;
			imageBuffer[ 3 + 4 * (y * width + x) ] = 255;
		}
	}
}
Test shots (with simple 256x256 6 octave noise and lerp5 across white, yellow, brown, green blue)...

http://oolite.aegidian.org/extra/oolite-059.png
http://oolite.aegidian.org/extra/oolite-062.png
http://oolite.aegidian.org/extra/oolite-067.png
"The planet Rear is scourged by well-intentioned OXZs."

Oolite models and gear? click here!

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Re: Questions, questions, questions...

Post by dajt »

aegidian wrote:Not developing on the PC I couldn't compile your experiments, so I picked up my graphics textbooks and rolled my own.
I'm impressed at how quickly you pulled that together... weren't you busy with other things? ;)
aegidian wrote: libnoise has built in routines for generating neato planet textures (their webpage seems to imply this)? Are these what you're using?

To turn perlin noise (with each value clamped between 0.0and 1.0) into colour I presume you're either sampling a 1d texture at the given value, or using some other gradient method? Or is this another function of libnoise?
libnoise has a lot of good stuff in it. There are multiple noise generators, probably all based on perlin noise, but with usefully different results.

Then there are modifiers and combiners which take the output of one or more of the noise generators and distort or combine them. This is good for clouds and water, for example.

The generators and modifiers have various properties that can be used to increase detail or otherwise change the results.

It has a class to do the mapping of the output of these things to spherical shapes, taking account of distortion at the poles. Then you just get a rectanguler array of Color objects which have the RGBA values, which is trivial to convert to the 4-byte RGBA values required for an OpenGL texture with alpha.

It has flexible color mapping - you assign RGBA values to height ranges between -1 and 1.

Have a quick flick through the libnoise tutorials - 15 minutes reading will give you a feel for the flexibility.

I think using libnoise is a good idea because there is a lot of good code there that we don't have to write, with demonstrably excellent results if we use it properly. To get comparable results to what libnoise is capable of (not what I've done), would take much effort on our part.

Windows was always going to be the hard platform to get going and it is already working.

You should have no trouble getting libnoise happening on the Mac, and Winston already has the required compiler on Linux. The debian question is the only nagging point and I wouldn't compromise the implementation for that.

Even if you don't want to use it, I'd like to find a way to keep it in the Windows version after all this effort. The required changes to Oolite code are quite minor so far, and the Mac has a few Mac-only pieces of code already (speech, iTunes).

Having said all that, I still have to see how fast libnoise is when generating the really good textures. It may end up being too slow.
Regards,
David Taylor.

User avatar
Wolfwood
---- E L I T E ----
---- E L I T E ----
Posts: 734
Joined: Wed Mar 29, 2006 9:53 am
Location: Finland
Contact:

Re: Questions, questions, questions...

Post by Wolfwood »

I haven't had time to try out the new PC version yet, but from what I've seen here, it is definitely worth it to keep these graphics around!

And if calculating the textures takes a bit of time, how about taking advantage of the time it takes for the player to enter a new system? What I mean is that it takes 15 seconds for the nav. comp to get the countdown done and then there is a second of two of those circles running on your screen that could be used for some heavier calculation in the background...

The F7 screen would still be problematic, of course, but you might want to use low quality textures there - or place some placeholder graph/text, like "retrieving" on the graphics spot while the calculations are running.
Author of Tales from the Frontier - official Elite 4 anthology.
Author of Marcan Rayger adventures - unofficial fan-fic novellas set in the Frontier universe.

User avatar
Wolfwood
---- E L I T E ----
---- E L I T E ----
Posts: 734
Joined: Wed Mar 29, 2006 9:53 am
Location: Finland
Contact:

Post by Wolfwood »

dajt wrote:What you're seeing on the planetary info page is the original atmosphere and clouds being rendered, which I'd disabled in the space view while debugging the textures. I'll put the originals back for now until the libnoise ones are going.
Ah, I tried the planets out and they are fabulous! Now I cannot wait to see how the better quality textures and libnoise atmosphere&clouds will look like!

Great work! :D

Also, I wouldn't mind the sun being further away in this version... :wink:
Author of Tales from the Frontier - official Elite 4 anthology.
Author of Marcan Rayger adventures - unofficial fan-fic novellas set in the Frontier universe.

User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

I built libnoise on the Mac last night – the makefile doesn’t work but doing it in Xcode is trivial – and I’m going to try to get the noisy-planets build working.

Wolfwood’s comment on using hyperspace time is right on the button – start rendering in a thread as soon as the countdown begins.

Cacheing is good. I’d say an in-memory cache of the last few systems, and possibly a disk cache with the last few several dozen systems visited. I find I often move around in the same general area; caching would be particularly useful when running trade routes.

User avatar
aegidian
Master and Commander
Master and Commander
Posts: 1152
Joined: Thu May 20, 2004 10:46 pm
Location: London UK
Contact:

Post by aegidian »

Okay, keep it in the branch and please move the discussion to the oolite-devs mailing list.
"The planet Rear is scourged by well-intentioned OXZs."

Oolite models and gear? click here!

User avatar
aegidian
Master and Commander
Master and Commander
Posts: 1152
Joined: Thu May 20, 2004 10:46 pm
Location: London UK
Contact:

Post by aegidian »

Sorry for the interruption. I locked this thread while we discussed (away from the board) the status of the libnoise branch.

The end result is that this will remain an unsupported branch for the time being. Bug reports and feedback on libnoise textured planets executables should be directed towards dajt, rather than mixed in with the feed back for the main version (without procedurally textured planets).

Thanks.
"The planet Rear is scourged by well-intentioned OXZs."

Oolite models and gear? click here!

User avatar
LittleBear
---- E L I T E ----
---- E L I T E ----
Posts: 2718
Joined: Tue Apr 04, 2006 7:02 pm
Location: I escaped The Labyrinth with the assistance of my fledgling. After many battles, I'm in the Nexus.

Post by LittleBear »

Got to post say how great this is and so varied. I've been jumping around alot playtesting an OXP I'm working on and all the planets seem unique.

All are earth-type but different land masses. I can even make out deserts and mountain ranges! Wow! :D
My OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits and Renegade Pirates can be downloaded from the Elite Wiki here.

User avatar
drew
---- E L I T E ----
---- E L I T E ----
Posts: 2186
Joined: Fri May 19, 2006 9:29 am
Location: In front of a laptop writing a book.
Contact:

Post by drew »

<shakes head in amazement> Awesome!

Cheers,

Drew.
Author of the Oolite Saga, the officially licensed Elite: Reclamation and Elite Dangerous: Premonition
WebsiteFacebookTwitter

magamo
Competent
Competent
Posts: 45
Joined: Sat Feb 25, 2006 7:07 pm

Post by magamo »

I tried grabbing the 'textured-planets' branch out of SVN today. I'm guessing that right now, this is still being worked on more privately by dajt, as there seems to be no code calling on libnoise when I compile the source, and the planets look about how they always have.

dajt
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 365
Joined: Tue Aug 17, 2004 7:05 am
Location: Orange, NSW, Australia
Contact:

Post by dajt »

The build process for the textured planets isn't obvious. There is a readme file in the deps windows static libs libnoise directory that gives an overview of how I build what I call "libnoise" which is the standard libnoise plus some bridging code so ObjC can call the C++.

This code is in the files ptg.cpp and ptg.h. I didn't include the actual libnoise source files but I think you'll find them in the Mac deps directory somewhere. It's a bit of a mess at present as I wasn't expecting anyone else to try and build it yet.

So after this special version of libnoise is built you can link Oolite with it.

If you're on Linux you won't see anything different because the GNUmakefile is set up to only use this stuff for Windows. If you managed to make libnoise, then you can add -DLIBNOISE_PLANETS to the Linux ObjC flags and you should get the textured planets.
Regards,
David Taylor.

Post Reply