makehumancommunity / mpfb2

MPFB2 is a free and open source human generator for Blender
http://static.makehumancommunity.org/mpfb.html
Other
277 stars 32 forks source link

Seamless custom shaders.... How? #187

Open emberlightstudios opened 1 month ago

emberlightstudios commented 1 month ago

This is not an issue with your software.

As you know we are porting this into a plugin for the godot game engine. I'm just wondering how you managed to generate procedural materials which do not show seams. Every time I try to make one in godot the seams are very obvious, but in mpfb there are no seams at all.

I tried looking through your shaders a bit and I noticed you use the texture coordinate node with the "object" output. I don't know if this is related or what it does really. How did you manage to get the noise textures to line up perfectly at the seams as if it were a texture painted directly on the mesh? I'm just completely baffled.

joepal1976 commented 1 month ago

Actually, "seamless" and "procedural" is partly an illusion. There are seams (although blended) and their borders are controlled using static image masks.

If you take a look here: https://github.com/makehumancommunity/mpfb2/tree/master/src/mpfb/data/textures

... You will see for example the face mask. The base texture is body, but then there is a mix to the face texture. The strength is controlled by the grayscale value of the face mask.

So the trick is mainly to chain the mix nodes using different masks as strength value.

If you zoom in enough on a border region by, for example, the lips, you will see how the different procedural textures blend into one another.

As a side note, these image masks are CC0 same as the rest of the assets, so if you need to do something similar elsewhere, it'd make sense to use these masks as a start.

emberlightstudios commented 1 month ago

I was making an attempt to do something similar. I started with a solid black texture then filled the character with white, took the b&w texture to gimp and put a gaussian blur on it to get some gray around the seams to use for blending. It was tricky but it kind of worked for what i was trying to do. I think these textures will be very useful. Thanks.

emberlightstudios commented 1 month ago

Yes I can see the lips being blended to the base body. If you are using 2 different textures that's pretty straightforward. The UVs are still continuous across that boundary. I'm talking about the seams from unwrapping the body. I don't quite understand how you got rid of the big seam down the middle of his neck/back area, or on the back of his arms, where the base body texture meets itself from the other side, and there's a sudden jump in UV space. What is being blended here? I don't see any mask for this area.

My goal in my test shader was just to use the gray around the seams texture I created to have the noise effect fade away as it approached the seams. It didn't extend all the way into and across the seams as yours does. I see veins and the pattern in the epidermis crossing right over his back seams with no breaks in the pattern. Using UV coordinates on the noise texture inputs should cause a discontinuity at these seams, so it's still a mystery to me how you achieved this.

joepal1976 commented 1 month ago

Ah, that seam.

That's because there is no seam there, from the point of view of the texture. The image textures and the zone masks use UV coordinates, but the procedural aspects mostly use "generated" or "object" coordinates.

This is particularly visible in the breasts area. If you look at a character with D-cup breasts, you will see that an image texture is stretched to fill the space. But the procedural pore bumps remain the same size rather than stretching.

If you navigate down through the group nodes in the shader tree, you will eventually find a few nodes of the "texture coordinates" type where you'll see that different output sockets are used depending on what aspect of the shader the coordinates are for.

emberlightstudios commented 1 month ago

That's what I was afraid of. I don't really understand object or generated coordinates, but I assume such ideas are not implemented in Godot's shader system. I guess we can always bake out textures from cycles at least.

Actually I'll try playing around with triplanar mapping. See if I can't get some reasonable results that way.

Vidyut commented 3 weeks ago

Hi @matt-seaton I'd found this video helpful https://www.youtube.com/watch?v=tydrEVlHRb4

(assuming what I was struggling with and what you want to know are similar) Then @joepal1976's map suggestion should work?

emberlightstudios commented 3 weeks ago

Yes it works in blender, but Godot has no such texture coordinates. And, unfortunately, the shader and mesh skinning pipelines are not amenable to this workflow, so I can't use techniques like triplanar mapping because it works on vertex world position which moves as the model is animated. I thought I could freeze the model in time for a second, but there's no easy way to get texture maps out of a shader in their material system.

So what I'm being forced to do is implement my own mapping from UV space to object space in a compute shader, which I have done, and use that to transfer a world space shader using 3d noise into UV space for texture baking, which i have yet to do.