Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Guilty Gear Xrd shader test

Discussion in 'Works In Progress - Archive' started by CodeKiwi, Dec 30, 2016.

  1. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119


    Just posting a shader based on Guilty Gear Xrd. This is my first Unity shader and I haven’t cleaned up the code at all. The shader was fairly easy to create. The links at the footer cover it in more detail. Basicly you just check if the surface normal is facing the light. If it is, use the light color (main texture) otherwise use the shadow color (main texture * tint texture). The outline is just a basic expanded mesh with inverted normals.The vertex colors of the outline mesh are a darker version of the character e.g coat = dark orange. The most important thing is probably getting the normals right. In this case I just used Blender and transferred the normals from simplified meshes. It handles inner lines using a special layout as mentioned in the documents. Each character also has its own directional light source. This light source is animated during special attacks. One interesting thing is that the specular area can be light or dark depending on the specular size texture channel. I also added the vertex color to make areas darker (adjusts the light normal threshold / ambient occlusion). This is required for things like folds in clothing or muscles as the normals have been simplified (smoother surfaces). Blender has an option to make a meshes vertex colors dirty e.g blacken the areas between gaps. I found manually painting the vertex colors had better results. I still need to change the outline thickness using another vertex color channel. This is required for closeups of the face or for spikey hair. It’s easy to add but I’d need to manually paint the vertex colors. The background in this example is just the normal Unity toon shader (works well with textures). I added an antialias to the camera because the edges between the light and dark areas are rough. The animations are also set to around 12 fps to have more of a hand drawn feeling. I also wasn’t able to import scaling for the animations.

    Because I don’t support line thickness in the vertex colors yet I just created a material with zero line thickness for any areas with issues e.g inner coat or face. To simplify the normals I found it easier to just create a duplicate of the mesh and use the smooth sculpting tool. I only added ambient occlusion vertex colors to the pants (material folds). The package contains a test scene with just the characters body (no weapon or head). If this has to be taken down due to copyright issues it should be easy enough to find the model elsewhere (but it will need custom normals and vertex colors).

    It might also be possible to remove some textures and just use a pallet index in the vertex color. Ideally, I’d like to use a another character as an example but I don’t really have the time for it.

    http://www.ggxrd.com/Motomura_Junya_GuiltyGearXrd.pdf
    https://blenderartists.org/forum/showthread.php?372662-Guilty-Gear-Xrd-shader-NPR-in-real-time
     

    Attached Files:

    Harran922, Alverik, XuJie645 and 17 others like this.
  2. r3ndesigner

    r3ndesigner

    Joined:
    Mar 21, 2013
    Posts:
    143
    Wow how anyone comment on this beauty/sexy shader, congratulations High_noon. Please send me your email, sometimes i need a special shader and you ll be the first option to give me a budget.
     
  3. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    Thanks r3ndesigner, I don’t normally give out my email but you can send me a private message on this forum and it will send a notification to my email.

    I recently had a question about create a new character / textures using this shading style. My main goal with this shader was to get a Guilty Gear character shaded in Unity. The following comments are based on the May character.

    Notes:
    • UV coords are mainly important for vertex colors e.g space between them isn’t used. The exceptions to this are the detail textures (e.g logo image), inner lines and shadow map texture.
    • The shadow map texture is optional (can be replaced with vertex colors)
    • The Color texture is used for the base color and is multiplied by the SSS texture to get dark areas.
    • The combined texture uses the following color channels: Green: shadow map, Red: specular intensity, Blue: specular size, Alpha: interior lines.
    • The vertex color channels are used for outline thickness and shadows
    • Interior lines use a special UV layout for smooth edges
    In the example below I changed the base color to red and kept the SSS texture the same. You could just use a shadow color texture but then you would need to update both.


    An important point is that areas tend to share the same settings e.g all verts in the pants have the same base color, SSS color, base shadow, specular intensity and specular size. So it should be ok to just replace it with one material, ignore the UV (could all be set to 0,0) and don’t use any textures. If any of the values differ then it’s a new material e.g cloth, shiny cloth.

    Ideally, you would want to use the same shader in your model editor. For the following steps I’ll assume I don’t have the shader setup in Blender.

    So, to setup a new character in Blender I would try the following.
    • Create the model and simplify the normals e.g face, cloth.
    • Assign a material to each color group e.g orange cloth, skin.
    • Paint the vertex colors for shadows and line thickness (would probably use two grey scale meshes then merge them into color channels)
    • Any inner lines would just be setup using geometry
    • Ignore UV channels (all set to 0,0). Or UV channels could be used to store other data e.g U channel => line thickness?

    Then in unity
    • Use a new toon shader per material. Each material has a base color, SSS color, base shadow strength, specular intensity and specular size.

    Extra
    After the character is set up the materials could be merged e.g use a vertex color channel for the material index and a small data lookup image e.g 64x8 texture. Could render character in one drawcall.

    Final notes
    • Don’t need any textures (should run fast on mobile)
    • Easy to setup (no UVs, can modify settings in game)
    • Can create color themes / pallets
    • Can still use detail textures / shadow textures if required (could add UV coords just for areas that require detail textures)
    • I haven’t checked how the other Xrd characters are handled, if they required gradients then this method probably wouldn’t work.
    • Could create a script to automatically convert Xrd models to this new shader format.
     
    BrandyStarbrite likes this.
  4. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Great idea.
     
  5. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    Just had an odd case where someone was selling this shader in the asset store for $30. They basically just deleted some of the commented out code.
    https://forum.unity3d.com/threads/f...ied-code-off-of-a-forums-free-project.485914/

    I’m not really familiar with licences so I thought I’d just give some examples.

    The following are ok:
    • Selling a game using the shader (but I suggest you improve it first).
    • Selling a model asset that uses the shader (with the focus being on the model).
    • Selling a shader library e.g. different toon shaders. But mention that this shader is free and can be downloaded from here.

    I shouldn’t have to say it but I don’t want anyone selling the shader like in the link above. I mainly don’t want anyone getting ripped off by paying for a shader they can get for free.

    To be honest this shader is fairly basic (it was my first Unity shader and I made it over a weekend). It could also use performance improvements and it has some bugs. If someone wants to sell a Guilty Gear shader it's easy enough to make from scratch (I recommend using a vertex/fragment shader and fixing the specular / dark areas). Personally I think it should be free as the Guilty Gear team was cool enough to give a detailed explanation of the shading methods.
     
  6. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    really cool shader big thx for it, i have a question with what tool can i create the sss Texture and the ILM texture from the orginal Texture?
     
  7. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    The sss texture is fairly easy to make. In gimp you can just add a layer over the base layer and set it to multiply. Generally red / pink colors are used for skin and purple / blue colors for cloth and metal. It might be easier to just paint the colors you want and modify the shader to not use the multiply for the dark areas.
    For the ILM texture it would probably be easier to create a shader for your modelling program. I was testing it in Blender a while back.



    As Blender doesn’t seem to paint color channels I’d probably split it into a black and white texture per channel . Then add a script to combine them on export. I’ve also found it difficult to paint the vertex colors so I’d probably just use a texture and transfer the data to the vertex colors on export as well.

    Overall I find the process a bit involved for making new characters. A lot of the processes are setup so the characters look good on close ups. I thought I’d try a similar process with a low res character and avoid close ups. This means I can use a standard uv layout instead of the complex inner lines setup. I also don’t need to modify the normals because it’s already low res. The ambient occlusion is used to give detail.



    In the following example I used a 993 verts, 1,179 tris character and the texture size is 128x256. The middle back character is using a per-vertex lighting shader from https://en.wikibooks.org/wiki/Cg_Programming/Unity/Specular_Highlights. The right back character is using a phong shader from https://en.wikibooks.org/wiki/Cg_Programming/Unity/Smooth_Specular_Highlights.
    The front left character is using the default shader. The front middle character is using a modified version of the phong shader with a ambient occlusion texture. The front right character is using a modified version of the phong shader with some toon updates.

    The colors aren’t correct (just darkens the light color instead of mixing it). For testing I’ve just taking the original image to generate four new images. The base color, a specular map, an ambient occlusion map and a temp texture for the dark outlines.
     
    Pandur1982 likes this.
  8. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    Thx for your answer i will looking with gimp,blender can i at the moment not use for the playermodel at the moment ( blender destroy on import my facerig (bones) ) so i will wait on a update of my 3d modeler.But the shader looks so cool very big thx for it and that it free.
     
  9. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    is it possibel to turn the lightning textures and settings off in the shader? i have a model with many weapons and armors but for all create a sss and a ilm texture is very mutch so here 2 screens of it and a problem for me.

    Here look it cool and right :

    but on this look it scray, i use on the material no sss or ilm texture for testing.
     
    CodeKiwi likes this.
  10. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    Awesome character, it kind of reminds me of kingdom hearts art style. This shader doesn’t really work well with multiple light sources. For this type of shading with detailed textures I’d recommend trying the shaders included with Unity-chan https://www.assetstore.unity3d.com/en/#!/content/18705. I found that I had to darken the color ramps in the Unity-chan example to get more noticeable light / dark areas.
     
    Pandur1982 likes this.
  11. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    thx for it i have buy this char from here : https://www.assetstore.unity3d.com/en/#!/content/90079 , i have test the Unity - Chan shader but i think your shader looks better as the unity chan shader.Your Shader looks more cartoon as the unity - Chan shader,here a other test with the unity chan shader :


    give it a chance that you can bring the multiple light source to your shader? Sry i am not god on shader prog.
     
  12. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    I just tried a modified version of the low res toon shader. It might work better for textured characters than the Guilty Gear Shader. It should be easier to add support for multiple light sources (I’ll probably update it tomorrow).

    The character on the left doesn’t use a SSS texture (affects shadow color) and it doesn’t use a AO texture (affects shadow area e.g. wool material, less shadows on face, more shadows on pants). The right character uses SSS and AO textures.

    This shader doesn’t include an outline. I prefer to add the mesh in blender now as shown below
    The main benefit is that it’s easy to remove unwanted lines e.g. eyes, mouth, nose. The outline mesh also uses the same UV’s so I just use a darker texture for the outline color.

    I also like to do the following:
    Avoid unconnected edges in meshes e.g. a cube with flat faces looks bad.
    Turn off receives shadows on the meshes.
    I’ve found it looks a lot better with a SSS and AO texture.
    Because this is a phong shader I’d try to avoid too many lights (once multiple lights are supported).
    The post processing stack / antialiasing helps remove the rough pixel edges.
     

    Attached Files:

    neoshaman and tapawafo like this.
  13. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    Thx for it i have test it out it looks really good the ToonB.shader i will question a friend how he can create the SSS texture and Ao Texture later.l will post a a Picture then with update.
     
  14. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    I was just trying multiple lights but it looks like it’s more difficult than I thought. Sorry, but I don’t think I’ll be able to add the feature. I also forgot to turn on motion blur and bloom in the post processing settings on the video. It looks much better with them enabled.

    The SSS texture is fairly easy. I just use a pinkish color for skin, light purple/grey for white areas, blueish for hair and the rest is mainly purple as shown in the middle image below.

    For the AO texture I just used an existing height map and lightened the face area (right image). A greyscale version of a normal map should also be ok. You might be able to get away with just using a grayscale color version of the diffuse texture.

     
  15. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    Handling multiple lights is something I've been giving a lot of thought to for my own toon shader pipeline. I'm not sure how compatible multiple coloured lights would be with this type of character shader. The lights could be combined before selecting the dark/light textures but then there is no colour influence from the light. Using one main light for the texture selection and then adding extra lights after would give the colour influence for the extra lights, but will probably look wrong in places where the dark texture is.

    In the below screenshot, the lighting on the characters and the lighting on the background seems to be separated (and reversed!). Extra light influence on the characters seems to mainly be done with bloom on bright fx. I think gradient toon shaders might be more amenable to multiple lights, perhaps giving something similar to the background elements of GGX. The green woodwork shows the type of effect I'd expect from multiple lights. The different type of barrel in the lower right kinda suggests there's a flat shader in play too.


    I'm leaning towards having an indexed colour ramp pallet and aiming for a middle ground where the ramp could be 2 colours on one index or a gradient on another to support multiple styles. This would also allow somewhat automated conversion of models to a common colour pallet and changing of styles by changing the pallet.

    If anyone wants me to consider their requirements as I work on my pipeline (which I plan to release on the asset store in a few months) feel free to PM me.
     
    Last edited: Aug 10, 2017
    evilangel89 and CodeKiwi like this.
  16. HTusa

    HTusa

    Joined:
    Aug 2, 2017
    Posts:
    9
    Thanks for the shader and inspiration, High_Noon!

    Based on that, and the GDC lecture, I rebuilt the shader to better work with my project. I used the sample Guilty Gear model High_Noon posted, and the Unity Courtyard for testing:

    animeshader.jpg

    It works with multiple lights, supports both forward and deferred (so you can use things like screen space reflections), and has individual controls for shadows, highlights, and light color contribution to albedo. You can also push the highlight value past 1, so you can get that glow on bright parts.

    Still needs a lot of work to clean up stuff, and it doesn't support outlines. And I still do need to try it with different types of meshes.
     
    evilangel89, Pandur1982 and CodeKiwi like this.
  17. HTusa

    HTusa

    Joined:
    Aug 2, 2017
    Posts:
    9
    Okay, tested the shader with the free Unity-chan mesh:

    animeshader_b.jpg
    Seems to work reasonably well. Some of the lighting in certain angles looks weird since there wasn't any vertex normals adjustment done to this mesh. There wasn't any separate SSS map used either, just the albedo. Also is missing the separate map for internal lines. And outlines, of course.
     
    Pandur1982 and CodeKiwi like this.
  18. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    Thx for it i will test it out next week when iam back at home.So i have see in a other game it call aragami can see here :
    is that a cellshader?
     
  19. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
  20. tyoungjr

    tyoungjr

    Joined:
    Nov 15, 2013
    Posts:
    5
    Thanks High_noon, I thought it would be impossible to implement this based on Motomura's GDC talk.
     
  21. evilangel89

    evilangel89

    Joined:
    Feb 8, 2017
    Posts:
    269
  22. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    ah ok i understand that
    ah ok i understand it, yes thats right is unless for my project of course.so i will see what come as next from High_noon :D
     
  23. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    I totally can't believe I missed this thread.... Been looking for something like this for a really long time now.

    I have delved into the "low-poly" anime shader territory for quite a while now, but the closest I've come is this (on the right there -- just ignore the Mixamo guy photo-bombing Link there...):

    RPG tester_Main Camera_2017-08-14-17-55-05_1600x676.png

    I've succeeded in making interior outlines (on Link there) but they're still not as even as I'd like them to be for a low-poly char, as your normals have to be perfect for the outlines to line up properly and not look like something out of Okami...


    Do you mind sharing this shader please? I would love to look it over -- been looking for something that works similar to Zelda BotW's shader.

    A more 1:1 approach to the shader used in BotW has apparently been done before though:



    As far as I can tell, Botw supports multiple lights (although I had noticed it only when I'm near a torch or something).


    Would you be willing to share your modified version of this shader also? -- I think there aren't enough games with this art style, so anything like this would be great to see more support for. I don't mind digging through dirty code -- after all, dirty code is better than no code to study after all. :)
     
    Last edited: Aug 20, 2017
  24. HTusa

    HTusa

    Joined:
    Aug 2, 2017
    Posts:
    9
    Unfortunately, my version is for a project, so I can't really share it publicly. It is however not terribly complicated. It's pretty much what was described in the GDC talk. Some vector math to see if a vertex gets lit by a given light, and then sorting the result to strict lit/unlit state with a Step function. Then just a lot of multiplys and adds to layer the shadows and highlights, and fixed values replaced with controls to better art direct the effect.

    The end result right now looks like this:

    animeshader_c.jpg
    The outline is working now. It gets blended with effects like fog and such, so that might be a pain (or work well) in some situations. But to get those multiple lights working properly instead of an ugly hack method that broke often, I changed the lighting method to custom instead of using the Standard Unity material - that resulted the Screen Space Reflections not working anymore. I have no idea why.

    So it still needs work. And it definitely needs well "groomed" vertex normals to look good, like the Guilty Gear Xrd meshes. Otherwise, you get some ugly blotches of light in some places like with that Unity-chan mesh, which breaks the effect somewhat.
     
    BrandyStarbrite and Pandur1982 like this.
  25. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    Looks very good this modified Version of the shader.
     
  26. imariagano

    imariagano

    Joined:
    Dec 20, 2012
    Posts:
    25
    can you upload this file

    I want to know how to make this scean
     
  27. imariagano

    imariagano

    Joined:
    Dec 20, 2012
    Posts:
    25

    thank you
     
  28. NarutoCC123

    NarutoCC123

    Joined:
    Aug 29, 2017
    Posts:
    2
    High_Noon can u pls help me create SSS and ILM textures for these models ill give u a link if u accept. And also everyone I'm manga game base on the anime boruto pleas reply with your skype Nam if u want to join mine is Naruto CC u can search for me wit this.
     
    Last edited: Sep 17, 2017
  29. jillval

    jillval

    Joined:
    Dec 7, 2013
    Posts:
    7
    High_Noon could you share a modified Version of the shader, like the guy did with the unitychan model that support multiple light sources? thx ,

    that way we dont have to struggle with SSS and Ilm textures. although a video tutorial of making SSS and ILM would be helpful
     
    Last edited: Sep 18, 2017
  30. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    Last edited: Sep 22, 2017
  31. NarutoCC123

    NarutoCC123

    Joined:
    Aug 29, 2017
    Posts:
    2
    Please can u make a tutorial on how to make the SSS and ILM textures please
     
  32. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    There are a couple of key things to remember about the Guilty Gear Xrd shader:
    1) It's a 3 layered threshold for its shadows. There aren't actual highlights on the model.
    It used 2 textures. One texture was the full bright color while the other is the shadowed part. They did it that way as to allow a different shadow tint between skin (blueish) and clothes (more colorful) The 3 layered threshold controls how much of the Darker texture is multiplied over the bright one.
    2) Its uses a Inversed Hull for its outer line. (This double the tries count of every model in the rendering pipeline.)
    3) Their characters have a minimum of 40,000 triangles, meaning they are about 80,000 triangles being rendered per character due to the Inversed Hull.
    4) The reason why the inner lines are so clear is because they used a "dirty" trick in the UVs. Every "black line" are flat UVs on X or Y axis and the texture has those planned out. (For example, you got a round shoulder muscle part. its uvs are squared so that any "line" part exceed onto the black part of the texture and they are "extended" flat in there.) This is one of the big reason why the character have so many triangles even if they are "flat" colored. If you were as to put some kind of detailed normal map or texture onto their model, they would look like crap. They made use of the no-pixel-based normal map (and the texture being flat color) this way as it's not apparant that the UVs islands are deformed like crazy.

    Also... If you ever wonder how they were able to have all those wonderful animated hairs and clothes... None of them are actually generated in real-time like with a cloth system... They were all bone-based animated. Each character has between 400 and 600 bones animated to control every little bits of hair, cloth and breasts, muscles, etc. If it moves "separately" from where it's connected... it's at least 1 or more bones.
     
  33. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419

    That's quite a good explanation about the GGXrd shader man! -- Lots of useful info in that post!

    Would you mind explaining the 3 layered threshold a little more? I think this is the part that's really kicking me in the head, but it seems to be the easiest to do since everyone seems to be doing it. I get how the lighting works (i.e. normal angle vs light vector and anything more than 90 degrees is shadow), but is it all stored in the vertex colors' RGB for highlights, midtones, and shadows, respectively? Even so, how do they decide how much light needs to be on a portion to be considered lit as highlight, midtone, or shadow? Do they just divide the curve by 3 or something? The reason I ask is because of things like the inside of a hood or coat/jacket should generally always be in shadow, so how do they determine this with a typical normal angle -- or is there some other trick?

    I've also not seen a decent example of this kind of lighting being done inside something like Amplify Shader Editor -- does anyone have a node graph to show how this might be done? -- Seems like it'd be a lot harder to do it in such an editor. ASE doesn't seem like it was built for custom lighting solutions, but, imho, Custom Lighting is the whole reason for writing shaders...
     
    Last edited: Nov 13, 2017
  34. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    The 3 layered threshold is as this :
    You take the Ambient light value and translate it from a float4 (or Half4) into a float value. So 0.0 being where light never shine and 1.0 being where light is 100% effective.
    After, you can easily setup how much the Shadow texture's pixel is multiplied over the Highlight texture.
    There are many ways of doing it, but I personally suggest a double Lerp(Color,Shadow,Step[]); method that add the shadowmap texture by 0.5x each time.

    With this, if you set the Threshold of highlight to a value of 0.75 and of shadows around 0.25...
    If the Shadow value returned from Unity's lighting is like 0.4, it multiply the Color pixel of the Highlight texture by 0.5x the value of the Shadow Texture's pixel (half-shadowed which is actually the "diffuse" color). If it return 0.14, it multiply the pixel value by 0.5x the Shadow texture twice (making it 2x darker than what would normally be the diffuse).

    This colorimetric difficulty of this setup is that you need to truly understand how RGB colors works when multiplied so that you can controls how the "mid-shadowed" color looks. This is why, in the case of Guilty Gears Xrd, Red Team had to build their shaders into their 3D modeling tool to test out the output being bringing it into the game engine.
    Since they had 2D color sheets of their characters, they didn't had as much difficulty at finding the right values as if you work directly in 3D. A way you can test the color manually without many tries & errors within the Engine is to use 2D as a base : Open GIMP or Photoshop, put a picture of the character in highlights only (flat light color), put 1 layers over it and set their mode into Multiply and their opacity to 50%. Paint the darkest part of the shadows. Once done, copy the layer and add the "mid-shadowed" (or equivalent of diffuse) part. Flatten the 2 shadow layer. Then controls the HUE of that shadow fused layer and, if needed, adjust the highlight layer's color until your like the resulted color. Then use the same color RGB data into your actual in-game texture for both the "Highlight" and "Shadow" texture.

    I'm currently scripting the shader myself for Unity.
     
    jincanhe and DominoM like this.
  35. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    There's some other trick. It's what I've been calling a lighting threshold offset. This is a float from -1 to 1 which is added to the n.l value, saturate the result and you have a value from 0 to 1 to use for your lighting. So the inside of the hood might be at -0.9 so it would only start coming out of shadow at 90% fully lit. A face might be at 0.8 so it only goes into shadow when lighting drops below 20%.
     
  36. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    Also, there's another trick they did in the case of Guilty Gear Xrd which... is kinda both insane and awesome in a genius way. They don't use any kind of normal map texture, but instead use the Vertex color data as the color source for the normal data. (This is another reason why their model are 40K or more in triangles. More triangles = More Vertex = More controls on the Vertex Colors based precision.)

    After all, there's no difference between the pixel's color data of a normal map and the color data of a Vertex color.
    This allowed them a higher control on the "highlight" and "shadows" which ends up being adjustable directly in the 3D modeling software in which vertex color data is managed.

    Side note :

    Each character in Guilty Gear Xrd were modeled, rigged and animated by 1 single artist and the team had a total of 4x 3D artists that were also the 3D animators. Each character took around 4 months individually, in which 2 months were requires in modeling, UVs, creating the textures, skinning & rigging, etc. and 2 other months for the actual animations and implementation into the game engine. If you wonder how they made some of the "deformed" animation, some were made with a in-house built plugin used in the engine to allow resizing of the bones (and its skinned mesh). This allowed them to "exaggerate" the movements (like in an anime) such as when a character strike, his arm and/or weapon might "stretch" for 1-3 frames. When it was heavy-duty deformation (polymorphing), they used quick-replacement of assets. (Such as Dizzy's wings or Millia's Hairs.)

    They made extensive uses of particles for explosions and debrits and attacks. They literally used the particles systems like key-frame animations for everything. Everything is custom-animated.

    One question people might wonder about is "Is what they did possible in another kind of game such as a RPG or a FPS or whatever?". The answer is "Unless you're the biggest masochist workaholic developer in the world, not everything can be used as it is." One of the thing that made it possible in the case of Guilty Gear is the fact that the camera is controlled by the developers. Pan and movement of the camera are only controlled by the players (and AI) when nothing special is happening. As soon as something special is happening, everything is scripted from A to Z. This allowed the devs to avoid you see the "weakness" of their 3D models (the uncanny valley of the 2D world).
    In a game where the player has fill controls of the camera (such as a 3rd person action game), this might not be totally possible considering the millions of possible variable and "interaction" that could occurs out of the scope of the scripts.

    That's without considering how they made most of the animation of the character with 8 to 14 frames per sec instead of the usual 30/sec. They cut most of the "smoothness" of every animation to look alike to the 2D animation style where the technique is normally used to save production time. (In their case, it's was actually taking more production time as they started with a full smoothed animation ,then cut part, made things a bit more momentous, etc.)

    If you want to achieve an Anime-like style, the animation is 50% of the job. Even with the best model and shader, if the animation is based on the used 3D methods (real-based), it will still look 3D and not 2D.
     
    CodeKiwi likes this.
  37. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    I'm replying instead of editing my last post simply to share and give an update.
    I have finished a relatively similar shader to the one from Guilty Gear Xrd.
    By relatively similar, I mean I use 90% of the same principle, with the exception of 3 features still missing which I'll surely add later, and added some new sweet controls on top of it because... well... I can! :D

    This is the test result of the shader in question. I made that Teapot really quickly. Most of the time was invested in its UVs as they were "made" the same way as GG Xrd was done with its character.

    CelShading_Toon_Shader_Preview.png
    The one on the front left is the one that uses settings really similar to GG Xrd settings.
    3 features are still missing though : The Mesh Vertex Color interpretation as normals (gotta modify that teapot mesh's vertex colors first to do it) and receiving shadows. For now, those aren't the essential of what I'm trying to do.
    The last missing feature is basically the Backface cull option which I added in the properties, but have yet to implement it. (Currently, if Back Cull is Off, which add many tries to the rendering queue. I'm still working on that part.)

    When I was "done" with it, I was like "Ok... Now, let's make it even better... for the sake of making it usable in many more situations!"

    I added the sliders :
    Highlight Value : Controls from what lighting threshold the "lack" of shadow becomes 0.
    Anything bellow is multiplied by 40% of the shadow texture.
    Shadows Threshold : Controls at what lighting value the darkest part stop being the darkest.
    Anything within that threshold get and additional 40% of the shadow texture

    So, if the color is like 0.9 where 1 is white and the shadow map is 0.1, this makes it so that the "mid-shadow part are at 0.6 and the darkest part are at around 0.2-0.3. Now, you might wonder "Why not making it at 0.1 when the shadow are the darkest" and the answer is that I added another option that allow it to push it even further past the 0 and, instead, even getting complementary colours (as you can see with the one at the back on the left). That's the Shadow Intensity slider's effect. This is the kind of shader you would actually use for an anime style like where things are getting heavy.

    The one on the back right is on where I adjusted most of the values and value's threshold just to showcase how it can be similar yet different from the default settings. This is especially useful if you want to create a material for 2 different kind of object or character. For example, if you want to put the material on a piece of iron, you use high contrast highlight like the one on the Back-Right.

    Then, I made it so that you can simply "turn" off (or almost) most of the effect. Front-right is like that.
    (The black lines on the teapot are part of its textures and not part of the shader's effects.

    Since none of those options are based on a texture, but on floats values, those are accessible and customizable within C-Sharp and Javascript.

    For now, the shader isn't well optimized to my taste yet. Mostly on the impact on the tris count. That inversed hull outerline is quite costy for that matter. The scene displayed which includes 4 teapots and 1 default cube counts 55K tris within Unity. The Teapot model has 2,300 tris in the mesh itself. The cube(ground) still have a default material and has 12 tries. Only 1 directional light in the scene.

    This means that the scene has 9212 tries, but due to the lighting and the shader, the count raise way too high.

    = EDIT =
    I adjusted a couple of stuff, fixed some other stuff.
    Now, while the shaders offers less "extreme" possibilities, it's much more stable and easy to controls.
    I also reduced the impact on the Tris count. Now, it's only double the tris count of the models that uses the shader.

    Still haven't implemented the normal-though-vertex-color part and the model won't get shadows from other object "yet".

    This is a video of how it looks with a model I'm currently working on.


    The model has, originally, approx. 4100 tris. With the shader, it reach approx. 8200 tris.
    (This is normal considering that I'm using the Reversed Hull technique. It's not an after image effect, but instead a pre-pass of the model so each tris are rendered twice on screen.)
     
    Last edited: Nov 15, 2017
    CodeKiwi likes this.
  38. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    I adjusted some new settings and made the first major change from what Guilty Gears Xrd had.

    Once I implemented a vertex-to-normal translation in the shader, I had one hell of a difficult time adjusting the color correctly. After all, normal color data isn't simple to visually express. It's a Vector3/Float3 that uses values toward all directions.
    For the sake of displaying it, this is an graphic that explain how to interpret the normal:
    Normal-Basics-Reminder.png

    Having 40K models or more like in Guilty Gears Xrd might had made it possible to use things easier with some kind of Vertex-based normal-baker plugin. That "baker" was the only tool the team behind Guilty Gears Xrd had to make (for a clear workflow). I don't have that baker and I'm not even using the same 3D software as them. This brought me, if I was to use the plugin, to problem to solve. There's another point that I'll be covered later.

    This is where I had this idea... Instead of using normal data why not just using a grayscale-based bump data in a similar fashion to how you can use a grayscale texture and turn it into a normal texture in Unity. Of course, that's less controls, but it allow anyone with an understanding that white = bump, gray (128) = no change and black = hole. It's a lot easier to setup manually a grayscale color between 0 and 255 than RGB when it comes to that. It also allow easy "paint-to-vertex" tools in any 3D software.

    Another reason is that I'm thinking of using the Blue and Green channel for, maybe, other stuff... like manipulating the highlight and shadow threshold directly through the vertex color. (That's still a work-in-progress.) Making it so that if you got a mesh of a character with, for example, armors and/or weapon that are supposedly metallic, you can "simulate" a different kind of illumination through adjusting threshold with 2 channels of the color of the vertex color data.
    Once it's done, I'll share an example as it's not a system for a common workflow in general.

    Another adjustment I have done is how the colors are handled between the 2 textures (highlight & shadows).
    I made a change where, now, it's not multiplying anymore, but instead :
    Pure shadows = Shadow texture
    Pure Highlight = Highlight Texture
    Middle between = Shadow (50%) + Highlight (50%)

    If you wonder why doing this change, here's what I have experienced.
    Multiplying the color works wonderfully if you wish to use dark shadows... but I was wonder how would it far if you want some good out-of-reality colorful shadows? What if you wish to be a bit artistic and have some complementary colors as shadows? Multiplying doesn't allow that.
    So, I made a major overhaul of the shader's color management and applied a bit of my magic.

    Here's a preview of the changes.
    ShadowsMap-Explained.png

    As you can see, I also adder an example of how the Red channel of the vertex data affect the shadows.
    The key rules of that Red Channel thing is this : If you want things to remains in shadow more often, make it black. If you want things to be highlighted more often, make it white. If you want no change, make it middle-gray (128).

    For those who look closely, I changed 1 of the options in the inspector. What was originally "Highlights Intensity" is now "Mid-Shadow Intensity". This way, it's a LOT easier to controls the colors because the highlight are 100% what you put in the Highlight texture. This slider allow you to control how much of shadow and how much of highlight the mid-shadow moves between.

    = EDIT =
    After consideration, here's how I'll implement the vertex colors into the shader:
    For RGB, their value will always be 0 = Less, 128(0.5) = No change, 255(1) = Max
    Red = Push the highlight (1) or shadows (0).
    Green = Push the Highlight Threshold higher or lower.
    Blue = Push the Shadows Threshold lower or higher.

    I will also use the Alpha of the Vertex color data. It will be used as a mask data for a an additional feature which will change the color of the Highlight and Shadows pixels (and, obviously the mid-shadow between both). If used, this mask will determine what part of the mesh can change color based on a new color selection picker in the Inspector.

    This addition came to my mind from High_Noon's post where he display May (character) in red. This reminded me of how Warframe (a game for those who haven't seen/played it yet) also uses its vertex color data to controls what parts are affected by each colors of the customization system. All that boiled in my head and I though "Hey! This could be done with the alpha channel of the vertex, right? As it's still fresh in my brain, I'm still thinking about how I'll interpret 1 color data onto the textures' data.
    I could replace the color or do a bit of mathematical magic and make it so that it only affect the HUE color of the zones affected. (For example, it would allow you to change any color into another color with the same level of saturation and lighting as the original color.)

    If anyone feel prejudiced or negatively affected by the following picture and its comments, forgive me.
    Please, consider the comment as purely comical, but based on real artistic measures.

    ShadowsMap-Explained_2.png

    This came to me while I was looking at the model and to see how much the Red channel was affecting the shadow/highlights. I was like "Damn! One is flat while the other seems much better!". Hahaha.

    I also forgot to mention one important detail about the recent changes to the shader.
    That is about how the original shader used in Guilty Gears Xrd doesn't allow much potential on low-poly models for something like Apps for mobiles and tablet. (Especially its Vertex-Color-to-Normal part... Kinda impossible to properly use with you got low amount of vertex around each other.) The changes makes the shader to be possible on mobile games. The incomplete model above has a total of 4402 tris and is registered at 8.8K with the Reversed Hull (outline) pass. For my goal (in a portfolio project of mine), it's within acceptable limits. I'm still not at the point where I can test it out with super-low poly models (like a 1K character), but that will come. (What I mean here is that this shader which I'm working on works for mobile, but I couldn't say if it works properly for games that involve small low-poly models such as a RTS game like Starcraft 2 or even lower (one of the Red Alert games has around 100 tris per character). That's still to be determined.)
     
    Last edited: Nov 16, 2017
    CodeKiwi likes this.
  39. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    Thanks for the posts, it’s cool to see what other people are working on. I haven’t done much work on this for a while but I thought I’d post a random idea I had that differs from GGXrd.

    The main toon issues I’ve had are with the normals. The problem is that when I modify the normals in the default pose it doesn’t look smooth when it animates. Because the normals are affected by the bones it can even look worse than not editing the normals.



    The image on the left is an animation that always transfers the normals from a simplified mesh while the right image only has the modified default pose (which looks smooth without animation).
    You can find the blender file here.

    I was thinking I’d have better results by using blend shapes (which will also modify the normals). It should be easy to bake the skeleton animations to static meshes. At first I thought I’d animate parts of the face but then decide it would probably be easier to just bake the entire face. The memory wasn’t as bad as I thought it would be.

    May example (not including the head).
    10,000 verts, 350 bones
    Bone matrix: 4*4 floats => 64 bytes
    Bone pose: 350 bones * 64 bytes => 22,400 bytes

    Morph: vertex and normal: 2*vector3 => 24 bytes per vert
    Morph pose: 10,000 verts * 24 bytes => 240,000 bytes

    A random sprite from Blazblue was 435*367 => 159,645 pixels / bytes

    So bones use about 22 kb (note that the frame rate is 12 fps so a normal 30 fps animation would use around 2.5 times more memory).
    A sprite game like Blazblue is around 160kb per frame.
    Morphing is about 240 kb per frame.

    I think I’ll just try morphing the entire character instead of exploring any bones. I’d still use bones for animating the main parts but might just modify the vertices for more complex shapes like Faust’s animations. It could also reduce the number of vertices required e.g. May’s weapon has multiple swing shapes, could use one shape with morphs. If I find it's too expensive I'll probably just morph the face.


    It also improves the outer lines as they’re controlled by the normals. In the image above the standard character on the right has weird lines around the eyes due to the normal. This is the one used in the video demo, it only looks ok due to the light direction.

    I think I’ll probably export a mesh per frame. Then store them to generate a scriptable object animation. The character is then a mesh (no skinning) and I’ll animate it by updating the mesh vertices and normals directly. I might use a short3 for position (in mm, can only animate within a 32m range) and a byte3 for normals => ~ 90kb per pose. Or I might just use a standard Vector3 for both => 240kb.

    Or I might keep the bone animations and just override the normals with a byte3 table => 22kb bone + 30kb normals per pose.
     
    Last edited: Nov 17, 2017
  40. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    It's a feature that the GGXrd shader already has that I described a few posts earlier as "lighting threshold offset". I actually put it on the red channel in my notes as it was the first data point mentioned in the GGXrd talks that went on the vertex colors.

    I've not added it to my toon shader yet as I wanted to get GGXrd style scalable outlines working first and I'm currently using all the vertex color channels for that. It's cool to see it works just how I was imagining in my head :)
     
    Last edited: Nov 16, 2017
    awesomedata likes this.
  41. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    This is a long image, so I'll post it as a thumbnail. ;)
    This is the overall evolution of the Shader.
    EvolutionShader-AnimeShader-MaxoWorkflow.png

    All that remains in the shader is for the mesh to receive shadows. Everything else that was planned is finished.
    I might surprise some, but that's actually my first shader I wrote from scratches... and I wrote it in 4 days. I'm surprised myself that it went that well. I only had some issues in the first day during which I actually made 3 version of the initial shading parts based on 3 methods that were explained online. (By methods, I'm not writing about something I could simply copy/paste, but more like explanation on how shader are written... Then I went wild with my imagination.)

    All I have ever done prior to this one were some minor changes to the default shaders in Unity 5.

    Now that I'm clear on the workflow and how to manage the mesh vertex data, I can continue modeling things! :p
     
    CodeKiwi likes this.
  42. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    I was just looking around for other ways to draw edges and I found an interesting article about using the geometry shader to render edges. It seems like you get more control and better results than just flipping the normals. It’s probably a bit expensive performance wise and I’m not sure how complicated it is to make a geometry shader but I might try it as a side project.
     
    awesomedata likes this.
  43. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    That does look interesting! -- I'd love to hear how it goes performance-wise!

    Seems like it could be useful, as it looks like it could do inside lines to some extent too. I wonder if you could make the inner-lines taper according to distance properly too. D:
     
  44. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    Don't forget that the general recommendation on geometry shaders is to use a compute shader instead. Apple insist on this with Metal having removed geometry shaders completely. The performance hit will vary considerably depending on the GPU - AMD use an off chip buffer so tend to be the slowest.
     
  45. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    I kind of had a feeling this might be the case, considering I've rarely seen geometry shaders mentioned. The only thing they're really useful for visually (imo) is something like this super-specific problem of 2D outlines.

    Compute shaders do seem like a better option for implementing this than geometry shaders though.

    I wonder how they might solve this outline/inline issue performance-wise (and be able to vary the line widths too). I've not really looked into how well they work for stuff like this, so it should be really exciting to see how an implementation for outlines like this goes. :D
     
  46. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    Another method to control light artistically:

    - Paint your objects using cardinal light direction on the texture, one light direction per texture (top, bottom, front, back, both side). Ideally the object is assumed centered to origin with correct axis alignment. Extra light directions for extra precision can be used, as long they are properly mirrored to all axis.

    - Infer a world space align normal map from the intensity of all texture points, simplest way is to convert the grayscale data to the proper rgb channel that encode its orientation, merging opposite into negative and positive value (for example top encode value from 255 to 128, bottom values 127 to 0 but using the inverse (1-x) gradient), resolving conflicting overlap artistically or automatically.

    - Transfer the world space normal map to tangent space.

    - enjoy it with any shader, can make realistic light look cartoony depending on the gradient style used by the artist.

    It's used for 2d sprite shading too. Can be experimented for simplicity by baking light from different lightsource and shader to test the implementation, it's also used to put real life objects scan into 3d environements.
     
  47. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    119
    I tried the geometry shader based of this outline example. Unfortunately it looks like adjacency information isn’t enabled in Unity which is required for this method.

    I'll probably have to use a compute shader as suggested by @DominoM. I find compute shaders difficult to use so it might take a while.

    @neoshaman: I haven’t tried this method before. Do you have any links to an example or tutorial?


    I was just trying the algorithm on the cpu with debug lines and it seems to work. The red lines are the outer edges and the blue lines and the inner. It looks like it should work well with areas like the face as it can exclude the inner lines but keep the outer lines. I’ll try line thickness and running the compute shader next. It feels like it won't be practical to use in a real game.
     
    Last edited: Nov 21, 2017
  48. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    Hey everyone, I have keep working on the shader as I was working on a character for one of my projects.

    I have faced some issues with definitions when in full shadow.
    Shadow_Tests.png
    As you can see, the original, when in full shadow, lost all definition for the face features. As I clearly don't want all my character to have a Krillin face, I had to do something. (For those who don't get the reference, Krillin is a character in Dragon Ball's series. He doesn't have a nose.)
    I could have worked in the shader and added some kind of new threshold and all, but the solution came to me in an even simpler manner. I simply had to edit the Shadow texture and add a bit of fake dept into it. As you can see above, the result, while still not "perfect" show that just by editing the Shadow map, I can avoid the lack of details.

    I also started to get a better hang of the Vertex Color to controls the shadows & highlights. For example, the chin, when highlighted from a certain angle, didn't appears at all. By forcing the shadow value onto the zone below the chin through the vertex color data I implemented, the chin now have much more visible definition.

    While I'm at it, if some wonders how I could get those eyes as it, I had to cheat here. Considering that I'm aiming my project for mobiles, using animated mesh-based eyes would have pushed the tris count way too high for only a small addition. So, instead of using modeled eyes, I used an additional material that has only the eyes' zone and I'm modifying the texture in that material in real-time to make the eyes animated.

    In total, the model has 3 materials:
    One material for the clothes at 1024x1024.
    One material for the hairs, boots and skin at 1024x1024.
    One material for the eyes at 256x256.

    I tried to reduce the textures to smaller sizes for the 1024x1024 textures, but I faced issues related to the lack of precision in the UVs Vector2 which uses floats. Basically, it wasn't possible to really controls the precision of the deformed UVs if the textures were smaller since some parts of the UVs, at 1024, are as small as half a pixel. This is a new limitation I faced while I was working on the character which is interesting.
    I had 2 solutions here : either I would cut the UV islands based on the desired color or I keep the UVs island "intact" and simply use higher resolution textures.
    I took note of that limitation and of the 2 solutions and plan on using one or the other based on what I'm working on.

    The final version of the model above with all body parts is 10,3K tris which ends up as 20,6K tris in Unity with the shader. Now, as I previously mentioned, the goal is to make it friendly to mobile and we all know 20.6K can be a bit high on mobile for a single character. I have to precise that the model is not really one that is shown during actual gameplay, but instead in specific scenes where I can controls the flows of mesh being rendered. The character will be used in dialogues events (think of those J-RPG which has character appearing above everything with a diialogue's box). I plan on making use of her in more than once event and have her move and act based on what's going on in the dialogue, hence why I made her "whole" and didn't cut her lower body.

    There's a picture of the results with different angle of lighting.
    HighlightResults&OutlineTests.png

    In that picture, I also added a new change I added onto the shader. As I modeled the character and decided how I was to divide the UVs and all, I faced a new issue. As, previously, the outline was controlled as a per-material option, it wasn't much of an issue if every outlines were to be of the same color (like black). But in my current project, black outlines weren't really great visually since the shadows aren't black nor even really dark unless the highlight itself dark (like for the boots). So, I faced this part where, sometimes, black outlines are okay and when other time they are not. As I was optimizing the UVs and material count for my model, I though that certain part could use a darker outline while other could use a more color-oriented outline.
    With a 1-color selection per material, the result can't be varied when you make an Atlas of parts on the same material. I could add another texture slot just for the outline color, but I wanted to avoid exceeding 2 textures per material. As I already am using the Vertex color for various other stuff, I can't do much there.
    I remembered that I didn't use the Outline Color's alpha for anything. This brought me the idea : Why not mixing 1 color with the shadow texture color? Note that I'm "not" multiplying the texture with the Outline color, but instead do a fusion of both based on the alpha value where 0 gives 100% the shadow texture while 255 gives 100% the outline color. (Make it 128 and you end up with (Shadow Texture x 50% + Outline Color x50%))

    Not only does this allow me to add some diverted colors into the outline, but it also gave me a new kind of tool for later: The ability to change the outline colors for such things as selections in a menu that involved 3D models!

    I'm planning on working on low-poly models for actual gameplay and see how the shader ends up with those.

    EDIT :
    There's a preview of the shader's latest version when animated.


    In anyone is wondering, yes I'm rotating the light with the camera. As for the bad quality of the animation, it was done within a single hour. This animation was mostly done for the sake of testing how the shader appears when animated. The model has a total of 56 bones for its animation.

    EDIT2 :
    I added the effect of light's color in the shader.
    Right now, only 1 light is active at a time on each model as the light mode is Forward Rendering (1 pass per light).
    Shader_LightAffectExample.png

    I'm not using a full light ratio here. First, the Highlight color is multiplied by the light value. That's normal. But the shadow color is actually on a ratio of 40% shadow map / 60% multiplied shadow map with the light color.
    This adjustment is because shadows aren't, technically affected by light since they are simply void of light. In this case, as the shadows aren't 100% black shadows, this means that even shadowed area are, technically, affected by light even if it just a bit. After some twinkling, I ended up seeing that the 40/60 ratio is the best general value.
    ...
    As I wrote this, I noticed something I missed which is visible in the screenshot above which is now fixed (though it's not visible above).
    I added the light impact onto the outline's color (if applicable). :)
     
    Last edited: Nov 28, 2017
    CodeKiwi likes this.
  49. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    CodeKiwi likes this.
  50. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    @neoshaman
    I have been wanting to figure out how to do that for a long time with a shader for basic textures for exactly the reason you showed above with the zombie, but with the apothecary guy (the guy with the mask) you can see how this method would work just as well with a model with a detailed normal map too.