sp614x / optifine

1.8k stars 418 forks source link

Brand New Texture map system? #2454

Open Redd56 opened 5 years ago

Redd56 commented 5 years ago

This thread will be for discussing a brand new texture map system i had an idea for a few weeks back and now am starting to flesh out. But because there are two ways i thought a new texture map could work, people commenting should put at the top of the comment TYPE ONE for type 1 and TYPE TWO for type two so things stay non confusing. WHY do we need a new texture map system?: the answer is quite simple, texture packs are currently limited in size, the texture map in vanilla mc is 16kX(16k by 16k), with optifine its 32kX (32k by 32k) but only on some systems. this is fine for any fully encompassing texture pack 512x and below, but thats just in vanilla without even connective textures, connective textures make the texture map go from 16kX to 32kX. because of this lots of systems cant load it, or ones that should (ie my system which has 64 gigs of ram and 8 gigs of vram) can load it cause they dont want to. This single texture map is also the reason you dont see 2k texture packs all that often, (that and they are hard to do) but the ones you do see dont do that many textures, only as many as they can. To demonstrate this issue lets do some simple math so if we have 32k x32k and each texture takes up 2k by 2k we can start by taking away the k (aka dividing each by 1k aka 1024 which is the actual value) leaving us with a 32x32 texture map and a 2x2 texture. next we divide each by 2 for both sides 32/2=16 2/2=1 so 16x16 for each 1. so what did we figure out? exactly how many textures we can fit into the texture map concidering each texture is 2k by 2k and the map is 32k by 32k, so 16 textures across and 16 down. Now this may seem like its probably alot but its no where near enough. 16X16 is only 256. yeah 256. Now let me show you how quickly thats taken up. 1 for each wool: 1row. 1 for each concrete powder. (2 rows total), each concrete (3 rows total), one per terricotta (4 rows total 1/4 of all the textures, a whole 64 textures), one per glazed terricotta (5 rows total), 1 per stained glass (6 rows total). 1 per bed (7 rows total). 1 per shulker box (8 total rows). at just these 8 different items we are already looking at half of the texture map being used, and we are only a bit of the way through all the blocks that minecraft has.

SO whats the solution? Well i actually have 2 solutions to present to you.

TYPE ONE: type one is similar to the way it currently works and is not that hard to get your head around. The basic premises of it is to break the texture map up into much smaller chunks so that a minimal amount of stuff is loaded at a time. So what do you mean by chop it up?: What i mean is instead of having one texture map for all the blocks in the game, have tons of smaller texture maps for types of blocks, each texture map should be at most 4 textures by 4 textures, but most will be 2x2 or 4x4 or even oddly shaped. Each of these texture maps would only be loaded as needed, meaning if you didnt see any of the blocks from texture map X you wouldnt have it loaded. This option is obviously the less nice one as it will be much more basic and will need to be made by hand almost. This is due to the fact that every single texture needs to be mapped to a specific texture map, (at the time of typing id say there would be probably like 64). And in modded every mod would need to make their own texture maps eventualy, once modded updates to a version that has this feature, if it isnt put into 1.12 before modded goes to like 1.14 or whatever the good version is. example screenshot of all the blocks (duplicates represent another texture for a block ie: grass blocks which have a top and side texture.) https://imgur.com/gallery/Nct9TeX this is only to get an idea of what it would be like, this includes lots of blocks but not nearly all of the ones in 1.14+ alot of flowers and stuff like that is missing. Pros: textures that arent being used at the moment might not be loaded. Cons: textues will be loaded if another block on the micro texturemap is loaded. meaning soul sand is loaded if glowstone is etc

This was the original version that i thought of, thinking that maybe this would work, but as time went on i thought of a better way to store textures as needed, a smarter way

SOLUTION 2: As needed texture calling, with permanent storing. "What did you just call this?" Well i called it exactly what it is. A texture system that only loads what is needed when needed alongside a small size texture map. How does it work?: This one is a bit more complex and probably much less graceful to implement but in theory should be completely stable and unable to break, plus be very optimized if done right. To explain how it works im gonna have to refrence a game ive played alot of recently, borderlands2. If your not aware how its texture system works: It has a low quality texture map it loads in at first that then gets replaced as it goes with a much higher quality one. Bluring from the low to the higher. The way this system would work is kinda similar, but instead of bluring as it loads in, it would just keep a default 8x8 loaded at all times for large texture packs, and only load in the exact block textures it needs, say all you have in render distance is a stone block. LOAD ONLY STONE TEXTURE! say you see a coal load ONLY the 8k stone and coal ore texture etc (i doubt anything 8k will ever happen. Pros: it only loads what is needed like a modern day game engine. Cons: im guessing its gonna be a pain in the ass to code, litteraly a new texture engine, thats actually modern...

thats about all i have for now, if you could conciser these ideas that would be great.

Redd56 commented 5 years ago

sorry its a wall o text lol

Cadiboo commented 5 years ago

Texture Maps/Atlases are useful because they massively increase FPS by decreasing the amount of time spent swapping textures. Splitting up the texture map into smaller pieces will solve the problem you mentioned, but at the expense of FPS. You could probably find a way to optimise the way that the texture map is stitched together though. You may find this article and this blog post interesting.

Redd56 commented 5 years ago

Yes but this is meant for people with higher end equipment, and i forgot to mention it would be a toggleable thing

sp614x commented 5 years ago

The limit is the maxumum texture size supported by the GPU. This is usually 16k x 16k or 32k x 32k for some recent GPUs.

Some GUIs and some special renderers need the textures to always be available. For example the creative menu search tab or enderman renderer showing the block carried by the enderman.

Replacing the texture map with several smaller ones is not going to work as it would cause way too much problems (very complex, mod compatibility, etc.).

It may be possible to use the special render mode used by AF/AA to load only some textures in full size. I have a working prototype that can load 16k block textures limited only by VRAM size.

The main problem is that a 32k x 32k texture map takes 4GB VRAM (32768 32768 4 channels = 4GB). Additionally the game has to load entity, environment, gui and other textures + terrain data (vertex mesh). Total VRAM usage with 32k atlas is 5-6 GB, depending on many factors. A typical modern GPU comes with 8GB VRAM so there is not much space left for additional textures.

Also mipmaps increase the VRAM usage by 30% and they are practically required for HD resource packs.

A vanilla resource pack (no OF features) has about 1000 textures (blocks + items). For 16x it has atlas size 512 x 512, for 1024x the atlas size is 32k * 32k and needs 4GB VRAM. A 2048x RP would need 16GB VRAM for the vanilla textures only and realistically 20+GB VRAM for OF features and the rest of the textures. Even without the atlas limit, there are no mainstream GPUs that can load a full 2k RP.

Redd56 commented 5 years ago

Hmm true. But still, allowing dynamicly sized texture maps would allow for say 7.5 gigs of vram used on an 8ngb video card. With .5 left over for shading other programs, and video output buff3r

Redd56 commented 5 years ago

btw whats af/aa, googling it gives me airforce and some fitness thingy

sp614x commented 5 years ago

Anisotropic filtering, antialiasing

Redd56 commented 5 years ago

Sp. Let me just say. I think i have hit a new low for stupidity

Redd56 commented 5 years ago

Also for 2048 texture packs i dont think people use mipmaps. Ita already so high of a res that your monitor cant display individual pixles

Also also. Maybe allow for vector based textures? As crazy hard as it would be to impliment. Some resource packs could greatly take advantage of it

mindforger commented 5 years ago

is mipmapping not used to keep memory loading times and VRAM consumption lower during texture mapping? basically spoken an FPS increase?! i do not consider mipmapping to be an eye candy feature aside from benefits in combination with anisotropic filtering or do i misunderstand mipmapping here

sp614x commented 5 years ago

Mipmaps fix:

Mipmaps OFF: https://gfycat.com/wellwornelasticbird

Mipmaps ON: https://gfycat.com/obesemediocreabalone

All resource packs above 1x need mipmaps, the textures with more contrast (like vanilla bedrock) need it more. This is independant of the texture size.

The mipmap disadvantage is loss of texture details in some cases. This is fixed by anisotropic filtering (AF). It works together with mipmaps and restores as much details as possible without increasing the flickering.

Mipmaps + AF work well for textures, but they can't fix the jagged lines on block edges. This is fixed by antialiasing (AA) which can smooth the block edges and (depending on the implementation) also the transparent textures (grass, flowers).

GPUs don't support vector textures.

Mipmaps increase memory usage by 33% and increase texture loading times because the mipmaps have to be generated from the original texture.

Mipmaps can increase the FPS because the GPU is working with smaller textures that better fit in the texture cache.