[HS] Hair Importing Guidelines

 

hair_strand_top_second

I did these guidelines using a live example as a test case.

This section assumes some things:

  • You already know the basics of Blender, and you’ve exported/imported things from/into the game using Blender and SB3UGUI.
  • You already know how to set textures to materials in SB3UGUI.
  • That you’ve already adapted the hair for your head, so it should be at the same position as the head already.
  • That you already know what parts will go to the corresponding front hair, back hair and side hair categories.

Things we’ll need:

  • Rigged custom or vanilla head in one layer of the scene, along with its skeleton.

Things this guide won’t cover:

  • Proper weighting of your hair. This is very dependant on the mesh, some hairs will be easy, some won’t.

This works for the vanilla head as well as for custom ones, and it works for any hair. It’s all the same.

The first thing we’ll do is make sure the hair parts have their origin at the same place as the head, which should be 0,0,0.
Do as always, select the head in object mode, set the cursor at its position, then select the hair parts in object mode, and go to Object->Transform->Origin to 3D Cursor.

A trick to know if everything is at the same origin, is to first, select the head in object mode and then set the cursor to its position, then select all the hair parts plus the head in object mode. If they’re all in the same position, the white border that represents the origin will be perfectly around the cursor.
If it’s not, then one of your hair parts is not at the same point of origin. So fix that. Notice how in my case everything’s fine:

hairposition

Now for all the hair parts (and accesories if you have any):

  • If you had any modifications with a skeleton, apply the armature modifier and remove the skeleton.
  • Remove all vertex groups.
  • Add a new vertex group called cf_J_FaceRoot.
  • Enter edit mode, select all vertices, and assign them with 1.000 strength to the cf_J_FaceRoot vertex group.
  • Parent to the HS head skeleton.

hair_vertex_group

Now, import the HS body with its skeleton in another layer.

bodyimport

Select the body skeleton, enter pose mode, select the cf_J_Head bone (or the cf_J_Head_s bone, both will do), and set the cursor to its position.

body_headbone_cursor

Go to the head skeleton, enter pose mode, search for the bone cf_J_FaceRoot. Select it, then set snap it to the cursor.

head_bone_to_cursor

Now, you should end with your head, and hair, on top of the body, and the head’s neck edge should be perfectly aligned with the body neck edge.

head_and_hair_on_body

At this point, fix any clipping your hair might have with the body. Mine has clipping on the side bangs, but I won’t fix that right now, maybe later.

Now go to SB3UGUI, open any of the vanilla hair asset bundles, and search for one that is similar to your hair.

vanilla_front_similar

Export it all. Do the same for the back and side hairs.

Import these in Blender. Usual settings.

Now, duplicate all the hair parts and their respective skeletons to a safe layer. Remember that layer contains these duplicates, but don’t touch that layer until I say so.

Go to the head skeleton, get in pose mode, select the bone cf_J_FaceUp_ty and snap the cursor there.

head_skeleton_faceupty_cursor

Going back to the hairs, do this for each piece you have (front, back, sides):

  • Select the skeleton
  • Pose mode
  • Select the main bone, should be called something like cf_N_J_hairXXX_YY, XXX being either front, side or back, and YY being a number. The bone p_cf_hair_XX_YYY should work too, XX is a number, YYY is either front, side or back.
  • Snap the selection to cursor.
  • Apply the armature modifier.

Once done with each hair piece, select each hair skeleton, CTRL+A->Apply rotation and scale, go into pose mode, select all bones, click on Pose-> Apply -> Apply pose as rest pose.

hs_hairs_first_apply_pose

Now reparent everything to their respective skeletons.

hs_hairs_first_reparent

If you’re doing this for the vanilla head, it should fit perfectly. If you’re doing it for a custom head, don’t worry if it doesn’t unless you need it to because you’re adapting these hairs to it.

hs_hairs_positioned_to_head

Now, let’s go back to our new hairs.

Apply the armature to each hair part.

new_hairs_apply_head_armature

Now remove the cf_J_FaceRoot vertex group from each of the new hair meshes. Thei should stay up at the same position as the head.

At this point, you can continue fixing clipping and then weight the hair. This is the part where I weight the hair.

hair_finished_weighting

After you’re done weighting and fixing clipping with the body, we’re getting the hair to the original hair position. Remember the duplicates of the original hairs we created? We’ll be using the main bone position of these to get the skeleton back to its correct rest pose.

For now, go back to the original hair corresponding to the piece you’re working on (front/side/back)

Select its skeleton, get into Pose Mode, select the main bone (cf_N_J_hairXXX_YY maybe?), and snap the cursor there.

hair_dup_selected_main_bone

Exit pose mode. Go to the skeleton you edited before, enter pose mode, select the same main bone, and this time snap the selection to the cursor.

new_hair_hs_position

Notice how it goes down to the position of the duplicate. Now, for your new hair, for each mesh, apply the armature modifier. Afterwards, set its skeleton into pose mode, select all the bones, and apply that new pose as the rest pose.
Finally, reparent every mesh to the skeleton.

new_hair_hs_position_reparented

Go back to the layer where you have the duplicate, and select any of its meshes. Snap the cursor to its position.

snap_cursor_to_hs_hair_position

Back to the layer with your new hair. Select every mesh, and transform its origin to the cursor.

new_hair_hs_origin

Finally, make sure the hair meshes are rotated in -90x, like every other mesh needs to be for this game.

new_hair_lessx_90_rotation

That’s it, you’re ready to export. We won’t be separating the strands of hair yet, because we need to see if everything went well.
Export with the usual FBX export settings for Illusion games.

Since mine is a front piece, I will be creating a new front hair.

Beginning with the list. Do the usual, get the list from an existing one, delete all lines except the first one, and edit that one.

hairlist

The ID must of course be a free one. Use HS_SlotID by DillDoe to search for free IDs.
The animator should be named the same as the one you used to weight the hair.

Now we have to copy the animator(s) to a new, empty file. Create an empty file like I’ve explained before, save it with whatever name you put in the list, remember to change the CABinet.

Don’t close this yet. Open mat_cha_00.unity3d from abdata. It takes a bit of time opening. Leave it be.

Let’s search for the hair animator we used for the front. Open the animator and go to the material tab.

animator_required_materials

You need to copy these materials too from mat_cha_00.unity3d. So go to its tab, search for them, and mark them to be copied too. You need to search for them and ctrl+click each, since with the mark for copying function, anything not selected gets unmarked.

mark_material_for_copying

Done marking the materials, leave mat_cha_00.unity3d opened. Go back to the file where your hair animator is.

Now while selecting said animator, go to Assets->Mark for copying.

mark_for_copying

Now go back to the file where you’ll paste the animator (the empty one you just created) and go to Assets->Paste all marked

paste_all_marked

new_hair_animator

Save your file. You’ve just copied the animator and its required materials and shaders.

Now close the original hair bundle and the material bundle, you no longer need them.

Back to our new bundle, open that new animator, and select a mesh.

must_select_material

Notice it has no material assigned. So assign one. Do so for every mesh.

material_set

Once done, go ingame and see if the new file works.

added_hair

There we go. Now let’s replace these meshes. Close the game, back to your new animator, open your previously exported FBX.

opened_hair_fbx

Start replacing. If you don’t have enough free frames, do this:

add_frame

And then change the new frame’s name to something the game uses. Don’t add dots to the name, it crashes the game.

To replace meshes in existing frames, use this:

replace_mesh_in_existing_frame

Do this for each of your hair meshes. After importing, disable any leftover frames you won’t need.

disable_frame

Go through every mesh, calculate its normals and set their material. Also, for any newly added frame, remember to set the mesh renderer’s attributes to the same values as any other mesh renderers in the whole structure. This is to avoid shading issues.

Let’s test ingame.

imported_meshes_work

There we go. It looks weird because of many reasons, including we have not set the right textures. If you set the right textures, you get this:

after_texture_replacement

Of course, I can’t cover how to get the textures edited since that will vary from texture to texture. But the overall requirement is for the texture to be gray hair, so that the coloring works well ingame.

Also, you might need more than one material. My example needed 3 or 4. You can duplicate existing materials like this:

copy_material

Then saving the game. Afterwards, you can rename said material and reassign its textures.

Same goes for the specularity.

NOTE: Something regarding materials. Some materials might have a scale in one of the texture slots. Most of the time it’s both the specularity and occlusion map, because these use a single, tiled texture.
In these cases, you must change the scale from, say, “8,1” to “1,1”. See:

texture_scale

It might also have an offset. You’d ideally use these only if you know what you’re doing, otherwise they must be set to 1,1.

Now, as you’ve probably noticed by checking the hair ingame, the transparency is all weird. To fix that, you need to go back into Blender, and separate the hair in strands.

I recommend separating whatever looks like it’s overlapping with other parts of the mesh. Like this:

First, for this, working with solid shading might be easier, because you can see the raw meshes without textures, so the overlapping is more obvious.

solid_overlap

Select any of your meshes with alpha channel, and enter edit mode:

edit_mode_overlap

See how the strands are all together? Let’s try separating the frontmost one. Select one of its vertices, then press CTRL+L to select linked vertices:

select_linked_edit_mode

Now press P, and separate the selection:

separate_selected

Now it’s separated from the rest of the mesh:

separated_selection

Do this for the rest of the strands. You can actually leave some merged, like the ones that mirror in X, you shouldn’t be able to see them overlapping anyways.

all_separated

Now, let’s create the backside meshes. These are the ones you see when the camera is behind the meshes. Unless you use a cull off material, which often means no alpha blending so it’s ugly, you need these.

For each mesh that isn’t “solid” (see, a mesh that doesn’t close everywhere, like a full sphere):

  • Select it
  • Duplicate it
  • Go to the new duplicate
  • Enter edit mode
  • Select all faces
  • CTRL+F->Flip Normals

This will make the mesh look darker in solid shading. This means, the normals are now facing inwards, and this mesh will work so that you see something when looking at the back of the faces.

back_faces

Here’s the final result of the back faces:

back_faces_finished

Notice I also did some spheres there. This is because these in particular use alpha channel. So without backfaces, the other side of the sphere would be empty for the camera.

Now, let’s rename our meshes to something meaningfull. Let’s begin with the front faces.

I rename them in order of priority. Meaning, the one on the top of the batch, that one gets named something like hairfront.01, then the one behind it hairfront.02.

Use dots because the FBX exporter loves to merge meshes with other naming schemes. I hope they fix that sometime.

hair_strand_top hair_strand_top_second

Once that’s done, rename the back faces too, each with the same name as their respective front face, but put a _u at the end of the name to differentiate them from the front faces. This is so we know what order to import them in.

back_faces_renaming

Once done, export front and back faces separatedly (each with their own skeleton) or together, whatever you feel is better.

Open them in SB3UGUI, with your hair animator opened, and start replacing. Go in Ascending order, meaning the lowest number on the top and the higher number on the bottom.

Also go like this: fronthair.01->fronthair.01_u->fronthair.02->fronthair.02_u

In the event that you need more frames, remember this:

add_frame

added_frames

Now let’s rename them in the Frame tab->Transform Name. Use the same format the original frames use. Mine use cf_O_hair_s06_XX(_u), and since I already had up to 03, I continue with 04, and so on.

renamed_frames

Now start recalculating normals and assigning materials.

After you’re done with that, go to the frame, and set the Tag to 4E29 for every hair part that needs coloring, then activate the frame (mark isActive).

color_tag

Once done, we’re going to fix alpha layering. This is where you see why I told you to import in order.

Open a workspace with CTRL+W.

Some of your frames should have, besides the SkinnedMeshRenderer, a Monobehaviour. Drag and drop that Monobehaviour in the workspace.

workspace

That same one, drag and drop it to any frame with a mesh that will use transparency but doesn’t have a Monobehaviour already.

workspace_to_anim

Do this for the rest.

all_behaviours

Now, double click on the first one.

transp_mono

I marked there the value that defines the order the screen will draw this object in. Ideally, the mesh at the front should have a higher number than that of the mesh which is behind it.

Once done, check ingame.

ordering_fixed

Good, got it working decently. You might have to edit some sortings for your particular project, I had to, so heres a short explanation of how this sorting stuff works:

Let’s say we have two meshes, mesh_a and mesh_b. Both use transparency.

We see that mesh_a goes on top of mesh_b. But, the computer doesn’t know this. The computer is dumb. We need to somehow tell the computer that mesh_a goes on top of mesh_b.

If we don’t tell the computer what order to draw them in, we get alpha clipping, which is what we call it when there’s transparency in two meshes, but we can see everything behind them, unlike being able to see what is in mesh_b behind mesh_a.

This is what we use the SetRenderQueue Monobehaviour for. With the value I marked before, it tells the game “this is the order of the mesh”.

So, if we put a SetRenderQueue MB for mesh_b, set its value to 0, then put another SetRenderQueue MB for mesh_a, and set its value to 1, we’re telling the game:

The render queue is: First mesh_a, then mesh_b.

This avoids alpha clipping, because mesh_b has already been drawn before mesh_a starts being drawn.

With this in mind, if you find yourself in need to edit the order, have in mind that whatever mesh you need drawn first (inner), must have a lower number in its Monobehaviour than that of the second (outer mesh).

Visually:
mesh_a>mesh_b>mesh_c

Logically (MB Value):
3>2>1

Now that we’re done with the order, some additional things and we’re done with the hair:

To make the hair colorable: If you’ve added frames, these new frames should have as their tag the value 4E29.
To make accesories colorable, or separate strands for different coloring: The frame should have as its tag the value 4E2A.
To make a certain hair part to not be colorable: Its frame should have as its tag the value 0.

Here’s where you set the tag value:

tag_value

And, last but not less important: Remember to enable any frames you may have disabled for tests!

re_enable

That’s all. If I’ve forgot something, please tell me in the comments.

Comments are closed.