Search Unity

Issue with character body poking through the clothes - custom shader maybe?

Discussion in 'General Graphics' started by Original-Gamer, Nov 11, 2015.

  1. Original-Gamer

    Original-Gamer

    Joined:
    Oct 5, 2013
    Posts:
    14
    I'm creating a tool that can generate different characters, male and female with different clothing, hair and accessories. With it you could generate a different looking character in seconds, inside the unity editor! I'm using Mixamo's Fuse application to create the characters and clothes.

    Because I'm using Fuse to create the characters, there are some "issues" with the way it exports it. When I export it creates transparent space on the body wherever clothing is.



    So what I did was export a naked base model then I exported the clothed model and removed the body from it. But now I get the boobs and other body parts come through the clothing.



    Does anybody know how I can fix this? Because there are pants, shoes, gloves and shirts that can be swapped around, I cant just leave the original body active because if I swap long pants out for short shorts then there will be half the leg invisible.

    I think a shader is the way to go. Some sort of way to detect if a part of the body is penetrating and not render that specific space. But if that's the case, Ill need some advice on were to start looking as I don't know allot about shader scripting.

    Thanks in advance! :)
     
  2. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Did you check the Fuse / mixamo forum?
    I remember seeing this mentioned before - the mesh is hidden by the transparency / mesh alpha mask based on which clothes the character is using.
     
  3. premium123

    premium123

    Joined:
    Dec 13, 2016
    Posts:
    1
    Hello...

    I had the same problem and i made this solution. Its maybe not the best, but it works very good.

    All you have to to is to set the render mode in the character material to "Cutout".
    Now create for all clothes items a culling texture (same size as main texture). That is only a black and white image, white will be culled.
    I used 8bit png as save format.

    With the code below, i copy the texture of the character to a new texture (texture2DMain).
    And every time i change any clothes, i rebuild the texture2Dmodified and apply it to the character material.
    Now the white parts of the culling texture should be cut out of the character model.

    Sorry, if my English is not so good :D

    a2.png

    a3.png

    a4.png

    Here is an example for a t-shirt. Left: main texture. Right: culling texture.
     
    Last edited: Jul 15, 2017
    theANMATOR2b likes this.
  4. AMVerona

    AMVerona

    Joined:
    Apr 18, 2013
    Posts:
    2
    Thanks @premium123 ! It's working well. I've summarized your class to a function:

    static public Texture2D RebuildTexture(Texture2D sourceTexture, Texture2D[] cullingTextures, int cullFactor = 100) {
    if(sourceTexture == null) {
    Debug.LogError("Main texture is null!");
    return null;
    }

    Texture2D texture2DModified = new Texture2D(sourceTexture.width, sourceTexture.height);

    Color32[] mainPixels = sourceTexture.GetPixels32();

    Color32 alphaPixel = new Color32(0,0,0,0);

    foreach(Texture2D item in cullingTextures) {
    Color32[] cullingPixels = item.GetPixels32();

    if(mainPixels.Length != cullingPixels.Length) {
    Debug.LogError("Main texture and culling texture '" + item.name + "' are not same size!");
    continue;
    }

    for(int i = 0; i < cullingPixels.Length; i++) {
    if(cullingPixels.r > cullFactor) {
    mainPixels = alphaPixel;
    }
    }
    }

    texture2DModified.SetPixels32(mainPixels);
    texture2DModified.Apply();

    return texture2DModified;
    }


    To use it:

    //SkinnedMeshRenderer originRenderer;
    //Texture2D[] cullingTextures;

    Texture2D mainTexture = BodyTextureOcclusion.RebuildTexture((Texture2D) originRenderer.material.mainTexture, cullingTextures, 10);

    originRenderer.material.mainTexture = mainTexture;
     
  5. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    I guess it's a solution but you are really wasting performance. You are still paying the price of transforming vertices and skinning for those alpha masked parts of the model. As well as pixel shading performance.
    It seems like in a worse case you could actually be rendering half as many characters because you are basically rendering a full naked model and then rendering a full clothed model at the same location.

    A better solution would be to construct a mesh with no extra waste. This would also probably help with issues where things don't line up or are not skinned with exactly the same weights moving and leaving holes.

    If this is an offline tool I would be inclined not to use it because you are not generating optimal data and have lots of time.
    Runtime maybe but again your tool is not performing in an optimal way.

    I believe I have seen older tutorials talking about combining multiple skinned meshes into a single one.
    This would be a much better way. You could still use the clothing mask at runtime to know which verts to keep or leave out in the final mesh.