Page 1 of 1

Stuff about Mapconv

Posted: 27 Oct 2009, 11:24
by Beherith
Thanks to Braindamages repo, ive been poking around with the mapconv source.
The trick to get it to compile under visual studio is to disable precompiled headers.

I noticed quite a few interesting things;

Metal map shouldnt be the same size as heightmap, it should be (heightmap-1)/2 -the same size as the typemap- because otherwise it gets rescaled.
Mapconv calculates the size of the map from the texturemap only, and nothing else. It will resize the height, metal and typemaps according to the texture map. Feature map must be of the correct size (heightmap-1) because that uses pixel values.

Mapconv has support for variable tree size and tree placement rotation built in, but spring doesnt read these variables yet.

Every map compiled with mapconv has variable default tree size, but spring doesnt read this info in the featurehandler.

Also, random rotation is supported, but not by the engine :(

Code: Select all

MapFeatureStruct ffs;
ffs.featureType=t_type;
ffs.relativeSize=0.8f+float(rand())/RAND_MAX*0.4f;
ffs.rotation=0;
ffs.xpos=(float)startx+x*8+4;
ffs.ypos=0;
ffs.zpos=(float)starty+y*8+4;
I have figured out what causes scanlines. When mapconv splits the texture into files for tiling, it doesnt take square 1k chunks from the heightmap, but uses lines of 32 pixels in each image, which then get passed on to the texture compressor of your choice.
Image

You can clearly see dark and light colored strips of terrain very close to each other. So when this is compressed into dds files, the mipmaps are interpolated from non neighbouring areas, thus resulting in scanlines. The only way to combat this is to use a box filter in the compression tool, since this equates to mipmaps made with nearest neighbour filtering.

This is highly sub optimal, since it results in ugly mip levels, as there are much better filters around for making mipmaps.

Also, im having trouble getting my own compiled mapconv to work on 32*32 maps, since it runs out of memory on texture, and cant allocate itself 1gb :(

Re: Stuff about Mapconv

Posted: 27 Oct 2009, 17:17
by Frostregen
Rotation should work.
I use ffs.rotation=X; inside SME too.

Maybe mapconv does not set the right values?

Re: Stuff about Mapconv

Posted: 27 Oct 2009, 22:33
by hunterw
Beherith wrote: Metal map shouldnt be the same size as heightmap, it should be (heightmap-1)/2 -the same size as the typemap- because otherwise it gets rescaled.
Aha! No wonder metal spots are so damn blobby in-game.
Image

You can clearly see dark and light colored strips of terrain very close to each other. So when this is compressed into dds files, the mipmaps are interpolated from non neighbouring areas
How do some versions of mapconv avoid the scanlines then?

Re: Stuff about Mapconv

Posted: 27 Oct 2009, 23:18
by Beherith
Frostregen: It doesnt work for the runtime generated trees, which include the 2d trees and the 3d default trees. I know from using SME that it works for all other features.

Hunterw:
Currently, my mapconv avoids this by forcing nvdxt to use the box filter, which is basically a nearest neighbour filter. This filter doesnt sample below outside of the map tile when it generates mipmaps. This, while resulting in no scanlines, is highly unoptimal, since using the nearest neighbour filter for mipmaps, while fast, is very ugly. Look at apophis or astroturf for good examples of why this workaround sucks, as the mipmaps basically look like high frequency noise.

Re: Stuff about Mapconv

Posted: 29 Oct 2009, 03:04
by Frostregen
Oh, did not know this. But this should be trivial to fix, as the coords are definitely handed over correctly, just the rotation has to be missing then.

*looking at code*

Code: Select all

glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
glCallList(displist);
Yup, just missing rotation.
Tomorrow I will create a fix. Needs slight shader modification too (unless rotation is handled there already).

Re: Stuff about Mapconv

Posted: 29 Oct 2009, 11:49
by Beherith
Not just rotation, but RelativeSize as well. Would you be kind enough to patch in a scale matrix as well? Or just the dot product of the two?

Re: Stuff about Mapconv

Posted: 29 Oct 2009, 12:10
by Frostregen
I think scaling is a different story:
Rotation is already stored on a per Feature basis.

Code: Select all

struct MapFeatureInfo
{
	float3 pos;
	int featureType;	//index to one of the strings above
	float rotation;
};
Scale is not contained in MapFeatureInfo.
Also scaling would change footprint and height too,
so every piece of code which uses this info needs to be adapted too.

Currently I'm only "dry"-coding (without compiling), so I'll stick to adding rotation first. ;)

Re: Stuff about Mapconv

Posted: 29 Oct 2009, 16:41
by Beherith
Ah, mapconv code says its not used, but it doesnt keep it at one...

Code: Select all

struct MapFeatureStruct
{
	int featureType;	//index to one of the strings above
	float xpos;
	float ypos;
	float zpos;

	float rotation;
	float relativeSize;		//not used at the moment keep 1
};

Re: Stuff about Mapconv

Posted: 29 Oct 2009, 21:06
by Argh
Can you hack up a version of Mother's that doesn't use the "compression" at all, and tells Spring that there's a 1:1 relationship with the tilesets? IOW, SMF doesn't care if they're stored in any particular order, IIRC, so just tell it that each 1024 atlas is 1,2,3...end, instead of 4,283182,1020...end.

That will get rid of the "compression", greatly reduce artifacts, and will be, at most, a few megabytes larger (for the whole map).

If a version of SMF was written that took full advantage of it being in strict order, or a flag could be put into current SMF that specified that the map's always using strict order (i.e., you made a very teeny change to current SMF) then I'll betcha that the CPU requirements for finding and fetching the atlas coordinates suddenly get a lot better, too.

Just ideas, mind you, feel free to ignore them, but it looks like that minor optimization could increase beauty and increase rendering speeds whilst lowering CPU use while costing very little in additional filesize per map, considering most of us don't use "compression".

That's one of those ideas that never quite worked, yet Spring's still wasting cycles on it, and I would like to see a version where it just skipped having to read which column, row to read and just went in order. Should get to skip at least two loops that way.

Oh, and it would also reduce the number of textures sent over to the fragment shader, which should result in both increased shader and CPU efficiency.

Re: Stuff about Mapconv

Posted: 30 Oct 2009, 03:27
by Beherith
Btw, you can set absolute 0 compression by using a negative value for compression on mapconv.

Re: Stuff about Mapconv

Posted: 30 Oct 2009, 07:18
by Forboding Angel
SO wait, c 0.0 is still compressed a little bit? lol wow Somehow I'm not surprised ;p

Re: Stuff about Mapconv

Posted: 30 Oct 2009, 08:13
by Argh
Yeah, but 0 compression won't speed it up much. It still jumps through some hoops on the way, IIRC, that could be eliminated in a no-compression, optimized read of the atlases and the quads.

Re: Stuff about Mapconv

Posted: 30 Oct 2009, 10:48
by Beherith
At 0.0 compression, the compression is lossless. Above it its lossy, below it its uncompressed.