Three.js tile which has multiple textures using pl

2019-04-09 19:27发布

问题:

So I am trying to build a 3D based world consisting of tiles.

I have successfully managed to do this using the plane geometry and height values etc. But now I have come to a point where I possibly have to change everything.

The problem is that I want a tile to have multiple textures (using a shader because I want to blend them). I was able to do this globally (so each tile would have same textures + using some uv mapping).

However I fail to understand how I would be able to specify which tile has which textures (and I have about a 100 textures), since the plane geometry has only 1 shader material. And I am also not sure if it is a good idea to send 100 textures through a shader?

So my questions basically boil down to this:

Is there a decent/performant way to link the tile/vertices to the textures, so I can keep the plane geometry.

- If yes: how?

- if no: Should I create each tile separately (so a plane of 1x1) and merge them somehow together (performance/vertex blending?) so it acts as a single plane (in this case the merged plane consists of many 1x1 planes) and use the shader per tile (a 1x1 plane)?

How are these things generally done?

Edit:

Some extra information because it seems that my question is not really clear:

What I want is that a tile (2 faces) has multiple "materialIndexes" to say so. Currently I need to have 1 tile to have 3 textures, so I can blend them in a shader with a specific algorithm.

For example I want to have a heart shape (red heart/black background) as texture and than based on the colors I want to blend/change the other 2 textures so I can get for example wooden heart and a blue background. Or for example I should be able to blend 4 textures evenly on the square, each take 1/4 of the square. But the point here is not what has to be done with the textures, but how that i can specify such 3, 4, or more textures for my faces/tiles.

回答1:

I think you have to take a look at what is called a multi material object.

THREE.SceneUtils.createMultiMaterialObject( geometry, materials );

If you google for those you find several examples. Like this answer on a similar question.


Or take a look at THREE.MeshFaceMaterial. You can use it to assign multiple materials for the same geometry.

var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );

Where materials is an array of materials and the faces use a materialIndex paramater to get appointed the right material

Similar questions here and here


EDIT:

Here is a fiddle to demonstrate that it is possible. I used the code from one of the links.



回答2:

If your textures have all the same size, you can do the following:

  1. Create a texture 10x the size of an individual texture (you can do that automatically, create a canvas, draw the texture file on the canvas at the correct coordinates, get the texture from the canvas). This allows for 100 (10x10) textures.

  2. Assign to the tiles a base uv coordinates in the range 0 - 0.1 (since a single texture occupies 1/10th of the global texture),

  3. Add to the previous uv values the offset of the individual texture (for the second texture, offset of 0.1 in u and 0 in v, for the 3rd texture 0.2 and 0; for the 10th 0 and 0.1.