Different textures for different ranges of VBO

Started by geakstr, February 05, 2015, 14:34:17

Previous topic - Next topic

geakstr

Hello! I'm writing a clone of minecraft just for fun. I split world to chunks with 16 * 16 * 16 sizes, do some optimizations on cubes in chunks and write vertices to VBO, then drawing each chunk with one call. How can i assign different textures for cubes in chunk?

This is render method: https://github.com/geakstr/voxel-moxel/blob/master/src/me/geakstr/voxel/model/Mesh.java#L41

I fill tbo (array of textures coords) there: https://github.com/geakstr/voxel-moxel/blob/master/src/me/geakstr/voxel/model/Chunk.java#L113

The best way is use texture atlas?

Kai

Yes, I would build a texture atlas from all of your needed textures.

It's minecraft, so they won't be using too much space to become huge.
Then, you would give the vertices of each face of your boxes different texture coordinates according to the image in the texture atlas that you want to be applied at that face of the box.

Another approach is kind of like the texture atlas but without texture filtering/bleeding issues (especially when using mipmapping), to use an array texture with each layer of the array being a different texture.
For this, you are going to need a shader to sample the relevant layer for a face of your box.
Therefore, you must feed the shader information about the layer that should apply to a face of the box.
You can pack this information in with your vertices, as a generic vertex attribute, via glVertexAttribPointer.

geakstr

Thank you. But I implemented follow optimisation: if cubes located as parallelepiped, I manually build each of sides with only two triangles (for example, if area is 6x6 stones this allows build sides with 2 triangles, instead 72) and for texturing i use manually build texture coords with GL_REPEAT.

With atlas this is possible? (i never used atlas before)

Kai

I woudn't do that kind of optimization for two reasons:
1. Unless you are really going to display like ten million cubes (literally) or so, your program would very likely not be vertex-transformation-bound.
2. Your optimization would require you to dynamically build a texture atlas for each of your optimized "huge faces" (so to call), because, as you know, those big faces can contain many different textures/materials.

What I would do, is first of course frustum culling, then render only the "outer" boxes, which are not occluded by other boxes "inside" and third (if you like) do hardware occlusion culling (like in http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter06.html), to help in not rendering "mountains" that are occluded by other mountains in front of you.

This will give you a pretty damn good optimization.

geakstr

Oh, i doesn't mean Ã,«manuallyÃ,» literally, i build this with code by scale x, y, z coords :)

Item 2 I don't understand fully. Is not possible to scale and to repeat one concrete texture from atlas without building new scaled atlas?

Kai

Quote from: geakstr on February 05, 2015, 16:49:14
Is not possible to scale and to repeat one concrete texture from atlas without building new scaled atlas?

Yes, that is possible. And there was kind of a misunderstanding on my part, because I overread that you are using that only for the same texture/material. So, yes, it is possible, if all of your boxes have the same material/texture applied to them and further if your texture atlas only contains that single texture (i.e. not being an atlas at all :)

Otherwise, you are going to need a shader to repeat the fractional texture coordinates yourself.

geakstr

Ok, thank you. I will read about repeating texture in shader.

Kai

Hmm... that was not really meant as an advice, to do it this way. :)
And it is actually quite complex to do it right, as pointed out here: http://stackoverflow.com/questions/14540137/texture-repeating-and-clamping-in-shader.
So, your best bet would probably be, just using a texture atlas and not trying to repeat the texture over multiple boxes using the texture filtering mechanisms via GL_REPEAT. But instead just put all of your boxes of a single chunk (your 16Ã,³ boxes, and only the outer/visible boxes) in a single VBO and render that VBO with texture atlas and the cube faces having texture coordinates for the respective image inside the texture atlas.

geakstr

Why? I implemented this with shaders and it's worked! (screenshot attached) :) Yes, I read about Ã,«color bleedingÃ,» and it's pity ââ,¬â€ sometimes I see lines on edges of cubes. But I found this: http://www.dfworkshop.net/?p=1529 With special builded texture atlas it's may be fixed.


Kai