1 Large Texture or Few Small Textures?

polycounter lvl 9
Offline / Send Message
Cyph3r polycounter lvl 9
Hey all, I just need to ask quick, I'm working on an iPhone game using most likely 'Shiva' or 'Unity' and I'm making some railings for snowboards ect to grind on and whatnot.

I've modelled the railings into 2m long 'blocks' and each block has a different shape, this is so I can combine these different small blocks to get a wide variety of different railings.

Now, should each Individual block have its own small texture? If so how big? 128? 64? Or should all the blocks be thrown onto one larger texture? 512? 1024?


  • whipSwitch
    Offline / Send Message
    whipSwitch polycounter lvl 8
    i might be talking out of turn here, but the way i always understood it was that one larger texture was smaller than 4 separate textures equaling the same amount of space.

    god, that's convoluted....

    ex. 1 1024^2 map is more efficient than 4 512^2 maps, even tho the amount of texture space is technically the same..

    as far as what size you should use would depend primarily(not completely) on the distance it's going to be viewed from most of the time.(i.e. how big is it going to be on the screen)
  • renderhjs
    Offline / Send Message
    renderhjs sublime tool
    its called a texture Atlas
    and it usually not only saves bandwidth but also performance because there are less objects to loop through and probably some other technical reasons.

    I am working on a maxscript myself soon that transfers textures via RTT from many objects into 1 big atlas texture. Alternatively there should be already some interesting scripts from Nvidia and on Scriptspot.com for max.
  • Daaark
    Always bunch up textures when you can. Because it saves on state changes and pipeline stalls.

    When renderers actually get to the part where they start drawing stuff (after deciding what needs to be drawn) the process involves looping through the materials and drawing everything that uses that material.

    To change a material means grinding everything to a halt, and then reading in a new texture and any shader programs / misc material settings to go with it, and then starting everything up again, sending a new batch of vertices. This is often the slowest part of rendering. It takes much longer to do all that, then it would have taken just to keep rendering triangles. If there are no materials to change, you can go ahead and send everything in one batch.

    After that stage, the transparent surfaces have to be drawn. They need to be sorted and drawn from furthest to nearest, regardless of what material they use. Which means that for every transparent surface drawn, a state change will have to occur. Expensive!

    Any time you can batch materials up into one sheet, do it.

    Also, anytime you can keep all your textures the same size, do that too. Because it's a lot faster and easier to just upload one texture over top of one already in memory than it is to erase the old one, reclaim that chunk of memory, and then upload the new one that is a different size, causing vram fragmentation.

    That's why some people will standardize to one texture sheet size. When it comes time to change what textures are loaded, it's simply a matter of overwriting all the ones that now unused. If each level is known more than 20 512x512 sheets, then you just need to allocate that big block once. There is no need to keep managing memory and making a mess of it.
  • TSM
    Please keep in mind hardware limitations. You`re dealing with a handheld device with a less than capable graphics card. You have severe bandwidth and pixel pushing power.

    You need to be wise on how you assign materials.

    For example, bunching texture's (atlas) isn't always the best route ::

    Object A, B, and C all have the same texture, but only B is visible, thus, the WHOLE texture atlas is sent through your bus and kept in memory. I don't know how intelligent the IPhone's graphic driver is (telling by their openGL support, not very).

    Hope that told the other side of the coin well - best to you!
  • Daaark
    TSM wrote: »
    Object A, B, and C all have the same texture, but only B is visible, thus, the WHOLE texture atlas is sent through your bus and kept in memory. I don't know how intelligent the IPhone's graphic driver is (telling by their openGL support, not very).

    Your atlas is going to have more than 3 objects on it, and usually it will have all objects on it. So you only send upload the atlas once and then don't have to keep binding it.

    Even if you have a few atlases and bind them all once each frame, the cost of those will stay constant, regardless of how many objects are visible each frame. (as opposed to wildly fluctuating render times on a per frame basis).

    I'd rather load the same texture each frame and draw a variable number of objects then have a bunch of logic to figure out a series of states changes which would be slower anyways.

    The other case would be a bit over engineered for no real gain.
  • Joshua Stubbles
    Offline / Send Message
    Joshua Stubbles polycounter lvl 14
    We did tests with this back with the PS2 and Xbox. Maybe it was just the particular engines we tried (Renderware & Gamebryo) but each one was a little bit different. Renderware preferred smaller textures while gamebryo was happier with larger sheets.
    I'd say it depends on your platform and engine pipeline, ultimately.

    These days with the current consoles though, I think most engines would be good with larger sheets or atlas'.

    On Forza 3 we used lots of textures but IIRC they were atlas'd by the engine.
  • Daaark
    Note that the XBox, like most machines now was running an actual GPU (Geforce3). The PS2 was a little bit different of a design, and it's ancient. It's running tech from the very-late 90s that is nothing like how stuff is structured today.

    I think the PS2 only did hardware accelerated triangle rasterising, while the vertices were transformed and lit in software. So throwing around textures wouldn't be as much of a bottleneck as they are on modern GPU designs.

    The iphone is running an OpenGl 2.0 compatible PowerVR GL Chip, which is a bit different in the different models.
    The 360/PS3 are running similar ATI and nVidia GPUs.

    Programming them is pretty similar other than tweaking for memory and speed.

    An engine doesn't have much say in that stuff these days, as it's mostly a collection of code that organizes how stuff is fed to the GPU. Culling, batch organizing, etc... And then it's simple a matter of calling the only functions in the API that send vertices to be drawn.

    With current GPU tech, drawing a whole scene from an atlas will always be faster than swapping out textures. But the best size for the atlas will be different from GPU to GPU, as they have their own max texture sizes. Having it all on one material also helps counter the problems of having small batches, which can also be slow in some situations.

    I wish stuff like that would standardize for a decade at a time, so these conversations wouldn't have to be filled with vaguerities. Vaguerities is a word right? Fuck it, I'm making it a word if it's isn't one already. Get Webster on it.

    Just one extra thing. For Atlases to work, your texture coordinates need to all be within the 0-1 range.
  • Microneezia
    Offline / Send Message
    Microneezia polycounter lvl 10
    in the Gamasutra article that Render links it mentions at the end that when you build a texture atlas its voids the use of tiling the textures by UVing past the 1:1 space. This is fine for unique unwraps but for environment tiling textures isnt this a problem?

    Currently Im almost entirely blowing all my environment UVs well beyond the 1:1 square in order to tile parts of the texture... is this totally incompatable with atlas style textures? How is tiling dealt with in this situation?
  • Daaark
    You can't do that because texture tiling is really just the effect of setting the clamp/repeat mode for coords that go beyond 0-1.

    If you have 100 textures that all go from 0-1, you can tile them 10x10 on an atlas, and all the texture coords just get changed based on it's textures position in the new grid. The first one is 0-0.1, the second is 0.1-0.2, etc...

    You can't do that with tiled textures because, obviously, you can't go beyond their borders, because then you've gone into a new texture's space.

    There is nothing 'special' about an atlas texture from the eyes of a GPU. It's just one big sheet that gets loaded at once to cut down on the cost of changing states.
  • Microneezia
    Offline / Send Message
    Microneezia polycounter lvl 10
    im going to ask an even more stupider question now; is it ever practical to literally tile a texture within the atlas to make use of tiling method of texturing?
  • sprunghunt
    Offline / Send Message
    sprunghunt polycounter lvl 14
    Stack the UV's on top of each other. You'll need to have enough polygon subdivisions to do this. But it shouldn't be too hard.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 14
    you can have texture tiling in current consoles for an atlas as well. As the fragment shader can do the "wrapping" of the texture coordinate, and modern instructions also help with filtering issues at the border.
    But for older pipeline, ie iphone you wouldnt have that possibility. But for unique stuff nearly all platforms these days would favor an atlas, for the reasons Daark mentioned (stall,state change).
  • Daaark
    you can have texture tiling in current consoles for an atlas as well. As the fragment shader can do the "wrapping" of the texture coordinate, and modern instructions also help with filtering issues at the border.
    Thank you. I tried to explain something to that effect in the last post, but my eyes were closing on my, and I epic failed. So I erased 2 badly written paragraphs. :poly124:

    I wrote some long winded post about state changes somewhere around here. :poly136:

    The GPU works like a factory. You tweak a few settings and then turn the machines on. They crunch away at tons of vertices simultaneously. But then as soon as you need to change the states, you have to shut down the factory and tweak all the dials on the machinery.

    Changing states is actually very fast, it's just the longest operation to complete, and nothing else is getting done while they change. So all real time renderers look to change states as few times as possible.
Sign In or Register to comment.