Single mesh with different textures from one texture atlas

Hello everybody,

I’m new to this forum, so I’ll send greetings around. :wink:

I’ve got some problems with a part of my current project. I have a (procedurally generated) mesh that reuses vertices to make it smooth round. It uses different textures from ONE texture atlas. The problem is that on the seems when a texture changes to another texture (two triangles side by side) the outcome is simply rubbish. It’s probably because the ccordinates of the vertices are reused from triangle to triangle and on the border from one triangle to another the UVs should change which is not possible of course, because UVs are per-vertex.

So my question: is it somehow possible to define UVs “per index”, so that a vertex used by triangle 1 uses different UV coordinates than the same vertex used by triangle 2?
As far as I understand, the terrain shader seems to use something like that because it blends several textures together. My case is a bit different because I use the same texture but just different UVs. I wouldn’t need several splat maps - just different UV coordinates.

Any help is appreciated.

Thanks in advance,

G.

PS: I’m quite an experienced programmer (C#/WPF freelancing developer in real life) so a hint in the right direction should be enough.

Unity Mesh objects have a sub mesh logic to support multiple materials. This works like what you are expecting , only one shared vertices array but for each sub mesh a unique triangles and indices array.

Hi shaderbytes,

thanks for the quick reply!
I stumbled across the sub meshes but I thought that they were just “meshes in meshes” (just organized in a hierarchy) and that that would mean that each sub mesh would require an extra draw call. But they’re different obviously…
From the documentation I figure that the UVs are still vertex-based and that would mean that each material would use the same UVs. Is that correct? So I couldn’t use the texture atlas then… :frowning:

G.

The vertex array is shared and The UVs are vertex based , but each submesh has its own UV array. This means you can have two different UV positions for a single vertex. It does have multiple materials so extra draw calls, although I have never tested pushing the same material into multiple slots : if it would then batch the submesh? I dont have time to test it right now but perhaps you can give it a bash and see or perhaps somebody else can chime in who has tried to reuse the same material in multiple slots and knows if it will batch…

Thanks again, shaderbytes!
I’ll try and post my findings here…

G.

Hello again,

I didn’t manage to get it working with sub meshes, simply because I didn’t find a way to set UVs on a sub mesh. There are functions to set triangles, indices aso. but no function to set the UVs… :frowning:
Anyway, this approach would have meant to split up my meshes into sub meshes and a lot more draw calls - that didn’t sound too good to me…

I did it completely different (and btw. went into the basics of shader programming on the way):
As a short explanation (maybe somebody finds it helpful): I’m building a voxel terrain. I’m not using the Unity terrain because I need holes, caves etc. and that is close to impossible with the Unity terrain. My terrain (at the moment 1024 x 512) is split into 16x16 chunks and written to disk. While the player moves around the corresponding chunks are read from disk and rendered to meshes as needed, so that always a 512x512 area is being generated around the player. The area behind that view range is hidden by fog.

Splitting it all up in sub meshes would have meant that I would have around 4-8x more meshes (depending on the number of terrain textures) and therefore more draw calls. I was looking for a solution to be able to render (at least) one segment in one draw call.
The current solution fills a 16x16 Texture2D per segment (via a script), which contains the UV-Rects from a texture atlas at every pixel (red=xMin, green=yMin, blue=Width, alpha=Height). It passes this texture (via the material) to the shader that I developed from the standard diffuse shader. For each position in the segment the shader reads the UV coordinates from the second texture and uses these to sample the final pixel from the MainTex.
It works like a charm! :slight_smile: And it renders a terrain segment in one draw call. And it leaves a lot of possibilities for the future…

Thanks for helping,

G.

Ah you are right , my bad there are no extra UV arrays…?? So its always a one to one relationship , yet internally when unity generates extra vertices to handle separate uv islands it somehow remains smooth shaded across that edge ??

Anyway Im glad you figured out a better solution via shaders :wink: