18-06-13, 21:32 | #121 |
Moderator
Joined: Jul 2003
Posts: 33,359
|
I've seen those lines between textures before and was told it was caused by the graphicscard when anti-aliasing is set in the card's settings.
So not in the gamesettings but in the card settings. And people have also reported the problem being fixed after they had disabled the anti-aliasing setting in the graphicscard. Not sure if it means anything to you or if it is usefull but I thought I'd just throw it out there. Good news on the optimizing! Something my levels can certainly use! And many others as well ofcourse. |
18-06-13, 21:42 | #122 |
Member
Joined: Aug 2010
Posts: 1,810
|
meta2tr, the problem is mipmapping WILL cause edge bleeding in any case, because it downsamples original textures and therefore interpolates adjacent pixels (no matter if it is bilinear, bicubic or mitchell algorithm, no matter if it's power of 2 or not). You indeed can align UV coordinates to cut off edges, but it's not a proper solution, because bleeding edges will become more and more obvious with every mip level, so you will have to increase cutting off more and more, which will in turn produce incorrect texture transitions between faces.
Cochrane, yes, every texinfo can intersect any other texinfo, but we don't need strict child-parent relationship, we only need to define max. size of parent tile, and then clamp it. All other texinfos that are inside this parent tile will be automatically downsampled correctly. |
18-06-13, 21:54 | #123 | |||||
Golden
Joined: Apr 2006
Posts: 16,751
|
Quote:
As you know, mipmapping means that if the camera is further away from the polygon, a lower-resolution version of the texture is used instead (or actually most often two, with a linear interpolation between the results, hence "tri"-linear filtering). With the lower resolution, more and more texture coordinate locations will lie close enough to the edge to be problematic - before, there may have been, say, three pixels between the location and the edge, but at the low resolution used for mipmapping, it's only one or even none. Hence, the next texture starts to affect the resulting color values for texture coordinate locations much further from the edge. This becomes the bleeding effect. To solve that bleeding, I could tell OpenGL to switch to the low-resolution version later (but this doesn't solve it, it just hides it a bit), or I add areas of the edge color between the different textures (the thing discussed now) so that the color that bleeds in is actually correct. I could also dynamically move the texture coordinates based on the resolution selected, which would require pixel shaders, but that would mean that textures get distorted when they are further away, which will look horrible. I cannot tell the texture unit to limit the pixels it picks to satisfy a particular color request. So it's one of these kludges I mentioned above. That, or disabling mipmapping. Quote:
Edit to add: Quote:
Quote:
Quote:
In general, I'm not sure if this really provides many advantages over just padding each texinfo individually. There are certainly edge cases where it can help, but the required finding of intersections is not quite trivial. Plus, the resulting resizing regions need not be rectangular. I guess I could start with the "each texinfo individually" version and then later try your version as an optimization to cut down on VRAM usage. (In an earlier version of my post I said that your method couldn't work. That was actually me misunderstanding what you wanted to do, so please ignore it.) Last edited by Cochrane; 18-06-13 at 22:06. |
|||||
19-06-13, 07:35 | #124 | |||||
Member
Joined: Aug 2010
Posts: 1,810
|
Quote:
Quote:
Quote:
BUT!!! Suddenly I remembered something about animated textures in TR engines. At least in TR3 they had 4 animated ranges on a single 64x64 texture tile, and this whole tile was placed somewhere in every level where it couldn't be seen. For ex., in HOUSE.TR2 it is placed on manor's roof: I don't remember the exact purpose of it, but I guess they did it to overcome some kind of animated ranges bug. So, this effectively makes my solution unusable at least in TR3. Quote:
Quote:
Last edited by Lwmte; 19-06-13 at 07:44. |
|||||
19-06-13, 08:48 | #125 | |
Member
Joined: Apr 2008
Posts: 368
|
Thanks for the explanations on mipmapping. It certainly does seem quite difficult to get it right.
Quote:
I've created a couple of levels with lots of texture pages (1024 and 2000). Each texture page is unique, and the number of dots in the image is the page number. The level is a modified tut1 where the starting room has a wall of textures in grid, in which each face is mapped to a texture page like this: On my pc, TRNG can display pages 1 to 1037, then from mid-way into 1038 they appear as black. However, in classic tomb4, all 2000 are displayed!! |
|
19-06-13, 09:36 | #126 |
Member
Joined: Feb 2012
Posts: 56
|
Awesome work Lwmte, much respect because the TR format is a real headache, it's a massive amount of work to get it as far as you - well done!!
Tragically I lost all the retrofit src in a HD crash a while - buuuut it's so freaky I started rewriting it again last night as I finally have some free time, and then I got your message!! The answer you are looking for to fix the mip map line problem is here: typedef struct { // 4 bytes u8 Xcoordinate; // 1 if Xpixel is the low value, 255 if Xpixel is the high value in the object texture u8 Xpixel; u8 Ycoordinate; // 1 if Ypixel is the low value, 255 if Ypixel is the high value in the object texture u8 Ypixel; } tr2_object_texture_vert; is incorrect in the documents it's actually as follows: typedef struct { // 4 bytes i8 Xcoordinate; // 1 if Xpixel is the low value, 255 if Xpixel is the high value in the object texture u8 Xpixel; i8 Ycoordinate; // 1 if Ypixel is the low value, 255 if Ypixel is the high value in the object texture u8 Ypixel; } tr2_object_texture_vert; XCoordinate and YCoordinate are signed 8 bit values - so you final texture co-ords will be: u=(float)((Xpixel+(i8&)XCoordinate))/255 v=(float)((Ypixel+(i8&)YCoordinate))/255 it seems they built in the edge correction because of issues with earlier vid cards and all that. should fix the horrid line issue - have fun man!! |
19-06-13, 10:00 | #127 | |
Member
Joined: Apr 2008
Posts: 368
|
Quote:
But using your formula, wouldn't that make uv edges go from 0 to (254/255)? That means, for u, the max value is a little to the left of the left side of the rightmost pixel. In the original game engine I noticed that texture coordinates were aligned to pixel centers, so I wonder if it's not more like this: u=((float)((Xpixel+(i8&)XCoordinate))/255) + (1/512) Edit: nope, that's not right either. A full tile goes from Xpixel 0 Xcoord 0 to Xpixel FF Xcoord FF Half a tile is Xpixel 0 Xcoord 0 to Xpixel 7F Xcoord FF In fact, it seems that we can throw away Xcoord, like so u_pixel_center=(Xpixel+0.5)/256 v_pixel_center=(Ypixel+0.5)/256 That way a tile goes from 1/512 to 511/512 and a half tile goes from 1/512 to 255/512 Thoughts? Last edited by meta2tr; 19-06-13 at 16:14. |
|
19-06-13, 10:16 | #128 | |
Member
Joined: Feb 2012
Posts: 56
|
Quote:
float xmul=1; float ymul=1; if (XPixel==0 !! XPixel==255) xmul=5; if (YPixel==0 !! YPixel==255) ymul=5; u=((float)((Xpixel+((i8&)XCoordinate)*xmul))/255); v=((float)((Ypixel+((i8&)YCoordinate)*ymul))/255); then convert to your atlas co-ords, something like that would probably work e.t.c. I do remember the mipping param I used if thats any help and it was glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); *edit* From my point of view XCoordinate and YCoordinate are needed - because they tell you the direction in which to shrink the UV coords, I think it was a fudge from the early days of video cards - when nobody knew what they were doing :P The Level I tested all this stuff out on was - Antartica TR3 - coz that level just really shows up all the mipping horrors right away. have fun! Last edited by shabtronic; 19-06-13 at 11:07. |
|
19-06-13, 11:26 | #129 |
Golden
Joined: Apr 2006
Posts: 16,751
|
Two things first, before anything else:
A negative LOD bias solves the bleeding issue. To try it yourself, insert glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -2.0f); in texture_atlas.cpp after the other calls to glTexParameter. This works by making sure that the higher resolution mipmap is used longer. My first instinct is that I’ll continue to use this fix until and unless someone complains. All my other discussions about this issue are purely theoretical. Is it just me, or are transparent triangles on static objects not rendered properly? That one level with the waterfall that someone mentioned (Lmwte? Sorry, thanks to slow internet it's actually rather painful to go back and check right now) shows it very clearly. Obviously that’s a bug. The question is: Is that my bug, or is that issue already present in the original engine? On to the details: The additional cost for the border per tex info is ((circumference of texinfo) * (border size) + 4 * (border size)^2) * 4 bytes. I’ve generated some statistics for BOAT.TR2. This has 1730 texinfos with a total circumference of 159078 pixels (average 91.953). With a two pixel border, I end up with 1383344 bytes (155 kB) and with four pixels, I get 2988128 additional bytes (2.84 MB) just for the borders. This is not taking into account any necessary duplication of interior pixels due to overlapping texinfos, and it assumes that I can pack all resulting padded texinfo pieces perfectly, neither of which is a realistic assumption. So I’d say about twice that sounds like a good (perhaps a little high) upper bound for classic TR levels. For high-performance TRNG levels, I believe the overhead in percent may actually be lower, since it is linear to texture size while memory use for the interior is quadratic with texture size, but of course it will be higher in total bytes. meta2tr: Thanks for the test level! I’m on a train right now, connected to the internet via my phone, so it may be quite a while before I can download the level (specifically, I hope to get it in Kassel, but it may be Frankfurt before I have it. Since Hanover, I got 9.8 MB). That dropping of Xcoord won’t work, because with your formula a full tile goes from 0.5/256 to 256.5/256 (or 1/512 to 513/512). shabtronic: TeslaRus has already implemented it like that. I think we need a new TRosettaStone document, maybe as a wiki. There are many known flaws in it, and every new programmer gets to discover them for himself from scratch every time. That’s annoying. The approach taken by TeslaRus actually adds/subtracts half a pixel. Changing that to a full pixel may help some, now that I think about it. |
19-06-13, 11:26 | #130 | |
Moderator
Joined: Jul 2003
Posts: 33,359
|
Quote:
|
|
Thread Tools | |
|
|