Planet textures using libnoise
Moderators: winston, another_commander
- LittleBear
- ---- E L I T E ----
- Posts: 2882
- Joined: Tue Apr 04, 2006 7:02 pm
- Location: On a survey mission for GalCop. Ship: Cobra Corvette: Hidden Dragon Rated: Deadly.
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 :
Same Planet in real space:
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 :
Same Planet in real space:
OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits, The Galactic Almanac, Renegade Pirates can be downloaded from the Elite Wiki here.
-
- Quite Grand Sub-Admiral
- Posts: 364
- Joined: Tue Aug 17, 2004 7:05 am
- Location: Orange, NSW, Australia
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.
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.
David Taylor.
-
- Quite Grand Sub-Admiral
- Posts: 364
- Joined: Tue Aug 17, 2004 7:05 am
- Location: Orange, NSW, Australia
That might have been funny... I could get the mangled names using objdump. Luckily I don't have to go there now :)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++).
Regards,
David Taylor.
David Taylor.
-
- Quite Grand Sub-Admiral
- Posts: 364
- Joined: Tue Aug 17, 2004 7:05 am
- Location: Orange, NSW, Australia
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.
David Taylor.
- aegidian
- Master and Commander
- Posts: 1161
- Joined: Thu May 20, 2004 10:46 pm
- Location: London UK
- Contact:
Questions, questions, questions...
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?
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
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;
}
}
}
http://oolite.aegidian.org/extra/oolite-059.png
http://oolite.aegidian.org/extra/oolite-062.png
http://oolite.aegidian.org/extra/oolite-067.png
-
- Quite Grand Sub-Admiral
- Posts: 364
- Joined: Tue Aug 17, 2004 7:05 am
- Location: Orange, NSW, Australia
Re: Questions, questions, questions...
I'm impressed at how quickly you pulled that together... weren't you busy with other things? ;)aegidian wrote:Not developing on the PC I couldn't compile your experiments, so I picked up my graphics textbooks and rolled my own.
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.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?
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.
David Taylor.
Re: Questions, questions, questions...
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.
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.
Author of Marcan Rayger adventures - unofficial fan-fic novellas set in the Frontier universe.
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!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.
Great work!
Also, I wouldn't mind the sun being further away in this version...
Author of Tales from the Frontier - official Elite 4 anthology.
Author of Marcan Rayger adventures - unofficial fan-fic novellas set in the Frontier universe.
Author of Marcan Rayger adventures - unofficial fan-fic novellas set in the Frontier universe.
- JensAyton
- Grand Admiral Emeritus
- Posts: 6657
- Joined: Sat Apr 02, 2005 2:43 pm
- Location: Sweden
- Contact:
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.
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.
E-mail: [email protected]
- aegidian
- Master and Commander
- Posts: 1161
- Joined: Thu May 20, 2004 10:46 pm
- Location: London UK
- Contact:
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 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.
- LittleBear
- ---- E L I T E ----
- Posts: 2882
- Joined: Tue Apr 04, 2006 7:02 pm
- Location: On a survey mission for GalCop. Ship: Cobra Corvette: Hidden Dragon Rated: Deadly.
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!
All are earth-type but different land masses. I can even make out deserts and mountain ranges! Wow!
OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits, The Galactic Almanac, Renegade Pirates can be downloaded from the Elite Wiki here.
-
- Quite Grand Sub-Admiral
- Posts: 364
- Joined: Tue Aug 17, 2004 7:05 am
- Location: Orange, NSW, Australia
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.
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.
David Taylor.