vircadia / vircadia-native-core

Vircadia open source agent-based metaverse ecosystem.
https://vircadia.com/
Other
533 stars 174 forks source link

Allow for texture splatting. Essential for texturing detailed terrains. #392

Open Aitolda opened 4 years ago

Aitolda commented 4 years ago

Texture Splatting

This allows for detailed terrain textures tiled and layered on top of each other. Essential primarily in creating high quality terrains but can be used on other models sparingly. Ideally at least 8 layers supported (16 even better for larger landscapes). To do this effectively we'd really need each layer to be a separate material. Using the Alpha channel or separate weightmap (scaled separately) to filter what material is visible, or a blend of two for smooth transitions.

-It's possible we could utilize the existing vertex color system rather than a map to do a version of this, therefore allowing this to be adjusted inworld.

JulianGro commented 3 years ago

Only after dabbling in terrain texturing I understand just how important this actually is. The only way to really put different textures that blend together on things currently (like having a rock texture on steep mountains and grass texture where stuff gets more horizontal) is by making an enormous texture for the whole terrain. Even an 8192x8192 texture which uses 64 MiB in video memory will only net you a really low resolution terrain unless you use multiple of them. Imagine a 512m² terrain: an 8k texture would net you 16 pixels per meter or 64 pixels per square meter on that. Even a 16k texture would only give you 32 pixels per meter or 128 pixel per square meter while also using 128 MiB of video memory. Obviously you might want normal, roughness and maybe even a metallic map on that, which would net you 512 MiB of video memory usage for such an extremely low resolution terrain. If you want a somewhat acceptable resolution of 128x128 pixel per square meter, you would need 16 16k textures for a 512m² terrain. Which is already 2048 MiB if you are using only albedo maps and no roughness, metallic or normal maps. Keep in mind that those 2048 MiB are already compressed as well, so the client would have to download up to 2048 MiB. All that for terrain that is still VERY low res.

TLDR: Taking it further to 1024x1024 pixel per square meter which is still a very low resolution, we are netting 128GiB for just albedo maps on 512m² terrain, showing how unreasonable it actually is to do terrain textures like that.

The best alternative I can currently think of would be to use multiple materials with greyscale textures to be able to use different textures that to not blend together and use vertex colors to have blending colors. That is going to leave you with pretty mushy lucking terrain which one might be able to spice up a little bit by adding 3d stuff like rocks and grass around.

Aitolda commented 3 years ago

Revisiting. As of Vircadia 20201.1.0 Eos this has not yet been implemented.

HifiExperiments commented 3 years ago

this is technically possible through two methods currently:

  1. polyvox entities take 3 textures and blend between them based on normal direction. obviously, this is limited, but it could work for a lot of terrain cases
  2. we could make a general purpose procedural shader that would do this, and maybe add it to the vircadia-content repo? this would give us complete control over how the different textures repeat/scale, and how they blend (via maybe a blend texture). it could also be applied to any existing model or shape, and could be customizable via uniforms in the procedural data. the only limitation here is that procedurals only support 4 textures, so you can't do full material blending.

the longer term solution is something that is already part of the plan for material entities, but will take some thought to implement: you can already apply multiple materials to a single object, which are then sorted by priority. we could add a "blend" bool to the materials to specify "I want to blend with the materials below me"...but then we need some way of specifying HOW you want to blend. this would be limited to maybe 3 or 4 materials blending at a time, but it could also be used for things like tattoos, decals, etc.

Aitolda commented 3 years ago

I lean strongly towards the longer-term option. I can imagine a couple ways to do this., one would be to use the same vertex weights you would ordinarily use on bones it would need to specify a specific vertex group name. I wonder if this might technically give us four options, with a weight of 0 being a default material and other values translated into RGB for three additional materials. You could possibly this do the same with vertex colors but then lose that ability on that particular model. I wonder if it's possible to use vertex colors and weight Maps together to total 16 possible materials on a landscape, with the vertex weight color specifying a particular group (4 groups) of materials, then the vertex color selecting one of the four materials in the particular group. EDIT: digging a little deeper this probably wouldn't be performant, but I still like the idea of vertex weight, as it would be easy to paint in blender.

Of course that might be a strange method but I was thinking about what we could do with existing channels. That also has its own limitations and as your resolution is dependent on the amount of vertices. However I think that would work fine for terrains, but not be quite as useful on other models. If you're thinking about models in general and having more detail and being able to add things like Ivy painted over the top you might want to use some sort of diffuse texture. I'm not sure what channels are supported though for that. I wonder if we'd have to sacrifice one of the existing supported channels that no one ever uses. Forgive me if this is a little messy as I am dictating to my tablet.

Edit: Leaning towards just straight vertex weight for terrain splatting, however, I wonder if splatting on other non-terrain models via a texture might be an entirely different path in the future.

JulianGro commented 3 years ago

Yeah I feel like we got to use something that we could do inside Blender. Otherwise we would have the problem of "What happens when the shape that is textured onto changes?". It would also make for an annoying workflow, since you would do modelling and UV mapping in Blender and then texture painting in Vircadia. While texture painting you could easily notice that you made a mistake on the UVs or on the mesh itself, or maybe you don't like the vertex colors anymore now that they are blended with a texture, etc.

Aitolda commented 3 years ago

So I just did a little digging in blender and there doesn't seem to be a node to send vertex weight to the diffuse to be able to preview it (within blender), but vertex color can be done so, so here is what I am wondering. Is there a way we can have multiple vertex color layers (at least 2) so that a secondary one can be used to specify material?

JulianGro commented 3 years ago

I am sure there was a way to use vertex weight for texture splatting in Blender. Though I do know if it was only for two textures or if you could use more.

stale[bot] commented 3 years ago

Hello! Is this still an issue?

JulianGro commented 3 years ago

Yes :angry:

stale[bot] commented 2 years ago

Hello! Is this still an issue?