-1

I'm making a procedurally generated minecraft-like voxel terrain in Unity. Mesh generation and albedo channel texturing is flawless; however I need to apply different normal map textures for different cube faces regarding whether they're neighboring to another cube or not. Materials accepts only single normal map file and doesn't provide a sprite-sheet-editor kind of functionality for normal maps. So I have no idea about how to use selected slices out of normal map file as if they were albedo textures. I couldn't find any related resources about the problem. Any help will be appreciated. Thanks...

  • Is each block of your terrain represented as individual geometric blocks? or is there some kind of single object that represents many blocks? – rodamn Aug 26 '20 at 21:07
  • @rodamn No cubes are not seperate gameobjects, but instead whole terrain is made up of chunk objects and mesh data for each chunk is determined algorithmically by perlin noise value. Therefore normal map data for each face must be set algorithmically too, as for albedo channel texturing – user3868427 Aug 27 '20 at 08:22
  • Maybe you could create one new texture by cutting together the according pixel data from your different normal maps or something like that? – derHugo Aug 28 '20 at 08:23
  • But it is also necessary to explicitly declare it as normal map in the material. However, as far as I know API doesn't allow to enter normal map UV coordinates into the mesh data. And there will be too many combinations for albedo and normal map couplings, so creating one massive texture sheet that contains each albedo and normal map combination is impossible. – user3868427 Aug 31 '20 at 10:48

1 Answers1

0

First of all, I'm not an expert in this area, though I am going to try to help you based on my limited and incomplete understanding of parts of Unity.

If there are a finite number of "normal face maps" that can exist, I suggest something like you indicated ("sprite sheet") and create a single texture (also sometimes called a texture atlas) that contains all these normal maps.

The next step, which I'm not sure whether the Standard material shader will be to handle for your situation is to generate UV/texture coordinates for the normal map and pass those along with your vertex xyz positions to the shader. The UV coordinates need to be for each vertex of each face; they are specified as a 2-D (U, V) offset into your atlas of normal maps and are floating point values with a range of [0.0, 1.0], that map to the full X and Y coordinates of the actual normal texture. For instance, if you had an atlas with a grid of textures in 4 rows and 4 columns, a face that should use the top-left texture would have UV coords of [(0,0), (0.25,0), (0.25,0.25), (0, 0.25)].

The difficulty here may depend if you are you using UV coordinates for doing other texture mapping (e.g. in the Albedo or wherever else). If this is the case, I think the Unity Standard Shader permits two sets of texture coordinates, and if you need more, you might have to roll your own shader or find a Shader asset elsewhere that allows for more UV sets. This is where my understanding of gets shaky, as I'm not exactly sure how the shader uses these two UV coordinate sets, and whether there is some existing convention for how these UV coordinate are used, as the standard shader supports secondary/detail maps, which may mean you have to share the UV0 set with all non-detail maps, so albedo, normal, height, occlusion, etc.

rodamn
  • 2,191
  • 19
  • 24
  • Thanks for detailed explanation. However that's what I've done for setting albedo textures onto the voxels. The problem is, I think second set of texture UVs isn't automatically counted as a normal map texture, because normal map texture must be explicitly declared as normal map. That's where the things get messy. Because unity default shaders doesn't allow developers to use sprite-sheet kind of functionality over normal maps. – user3868427 Aug 31 '20 at 10:48
  • I'm confused, because I would think the normal map should align with the albedo map; i.e. if you are using an atlassed albedo map, you should be able to use create a corresponding (atlassed) normal map and utilize the regular uv coords. I'd think this would work unless there's some situations where the normal map is independent of the albedo. – rodamn Sep 03 '20 at 17:52
  • I just read the brief again. Now I remember; you want different normal maps based on proximity of other faces. This makes me call into question on how you are using normal maps; usually normal maps are tied to the albedo; so you really only have two choices: create an atlas with all the possible combinations of normal and albedos, or reduce the number of possible combinations. There is also the third possibility of rolling your own shader that takes it's own set of normal map UV coords.. – rodamn Sep 03 '20 at 17:59
  • 1
    Since there would be too many combinations of albedo and normal map textures, creating an atlas that contains all of them is very impractical, if not impossible. But as you said, proper solution seems to create a custom shader which takes coordinate parameters for tiling through code. Therefore I started studying shader graph. Thanks for your replies mate, and if there is any suggestion or tip you can share about shader graph design for that particular purpose I'ld love to hear. Cheers... – user3868427 Sep 05 '20 at 09:00