why the eyelash for a 3D character is so huge

Godot Version

Godot4.2

Question

i create a character from the CC4(Character Creator), and export to the *.fbx, and then import the *.fbx to the godot 4.2
everything is ok but the eyelash is so huge

It’s just that there’s no alpha. CC can import to glTF?

You need to use alpha scissor cutouts and dithering for hair in the material but those Character Creator textures are usually inverted for the default Godot SpatialMaterial so you need to do a custom shader or invert them with a texture editing tool.

DAZ3D, Character Creator and other derivatives use mostly black/white cutout mask textures for alpha (and also a lot of custom, non PRB shaders).

If those mask textures are 1:1 imported into other engines that have no specialized importer tools just for those programs they are not transparent because the required custom shader does not exist.

You need a custom shader that turns the black/white textures into alpha cutouts, or first import your asset into a program with a specialized bridge tool for Character Creator that does this conversion for you, e.g. convert cutouts to alpha textures, then export to Godot from that.

In general those assets do not translate 1:1 to most game engines, reason why there are custom export / importers for Unity / Unreal that do a lot of conversion behind the scene to make it look like it works out of the box.

Also even if the import with alpha would work normal alpha does not work well for hair so stick with alpha scissors and dithering shader.

1 Like

CC can’t export to glTF, so i think i can try to import to it to blender first, and then export as glRF.

very thanks for your reply.
i read your suggestion, bu i am not sure if i understand it.
i try do it in the godot, and find i can set the alpha scissor here

what i do is:

  1. try to set the transparency to “Alpha Scissor” for the head slot of the surface material override.
  2. try to set the transparency to “Alpha Scissor” for the eyelash slot of the surface material override.

but both all above same not working, can you tell more about what can i do, thanks a lot~

i try another way:
i import the *.fbx to the blender, and set the blender mode as “alpha clip”

and then export the *glb from the blender.
the good news is i can see the alpha scissor in the eyelash
but bad news is still huge eyelash for the character

You need to either use a custom shader that works with those black/white textures from CC or you convert the texture by replacing the black with alpha because that is what the alpha scissor of the StandardMaterial expects.

For a simple test you can just use a shader and in fragment have it sample the mask texture and do (mask_tex.r == 0.0) { discard;} so every fully black part gets removed. For more detail you want to have some range or add some dithering as well.

As mentioned before you can not use actual alpha transparency material for hair parts as those will have clipping artifacts all over the place in a real time game engine. You need to do “cutouts” with e.g. discard instead of ALPHA in shaders. In a render suite like CC or DAZ or Blender it does not matter because the raytraced renderer can deal with it, that is not possible in a game engine that wants to run at 60+ fps.

1 Like

Try setting blend mode to add or subtract, might look fine for eye lashes.

I just want to point out that with this workflow, eyebrows and eyelashes are transferred to the engine correctly. Perhaps you might find that helpful.

very thanks for your reply.
i am a new guy, actually i think i can’t understand you clearly. i learn and try today, fininal i find when i set the “Blend Mode” as “Subtract”, it seems ok.
but if we see it carefully, we can see the color is not right.(in the CC4 and blender, the color is black, but in the Godot, it seems not black.)

i don’t understand why the eyelash is ok now, and also i don’t know why the color is not correct. do you know about this~~? thanks a lot

The eyelash is not ok with blend mode subtract. Any blend mode other than the default blend mode mix moves the material to the transparency pipelines. So by using that blend mode with hair-like assets you will end up in a horrible color mixup and alpha clipping issues when more things are added to the scene. See the description of the Material Blend Mode enum and transparency documentation for what they do. Standard Material 3D and ORM Material 3D — Godot Engine (stable) documentation in English

The following material settings need to be NOT USED at all time with hair assets (this is copied directly from the documentation):

  • Setting the transparency mode to Alpha.
  • Setting a blend mode other than the default Mix
  • Enabling Refraction, Proximity Fade, or Distance Fade.

The correct material setup for hair in a game engine PBR material setup was already described. Use alpha scissors with a mask texture and dithering, and enable TAA postprocessing to remove most of the grainy dithering look. Google PBR hair material with dithering and you will find plenty of info.

1 Like

i find some more infor in the google, and here is my understanding and trying, please help point if any issues?

  1. i need add a alpha channel to the eyelash texture(.png).
  2. and then, import this texture to the godot as a texture of the material
  3. set the transparency as “Alpha scissor”, and adjust the “Alpha scissor Threshold”

this seems work as you said, but not beautiful. i think this is due to the alpha channel is not good.

Yes that is correct and normal look for just alpha scissors, it is always sharp-cut (or grainy with dithering) because a pixel is either discarded or used depending on alpha scissor threshold.

This way it stays away from the transparency pipeline that will give you even more visual problems when you have an actual scene with more assets. It is a tradeoff to avoid other visual glitches that are far worse and basically impossible to fix due to how rendering pipelines work in real time game engines.

E.g. to see the visual problems try using real alpha on hair and move to a camera view where the hair surfaces start to visually overlap with other transparent parts. You will see all kind of visual glitches because due to the high polygon density of hair the alpha and depth based postprocessing does no longer know how to really sort things. E.g. it will have glitches and look like this exaggerated image:

haira_alpha_issues

If you look very closely at hair in high production value games (“AAA”) you also can spot that original sharp-cut look from using alpha scissors. E.g. here is an example from Cyberpunk 2077. They just use better cutout textures that are designed for realtime engines instead of raytraced renderer.

cyber_eyelashes

What they add on top to hide that sharp and grainy look more is local Temporal anti-aliasing (TAA) postprocessing on the mesh to blur it. In Godot you can enable TAA in the viewport world environment but it will affect everything, not just the hair.

1 Like

i learn and try more, and i think now the result is perfect.

  1. the first one is the eyalash shown in the blender(same as in the cc4)
  2. method1: the second one, it is directly use the texture(*.jpg) from CC4. it is with black / white color. and i deal it with shader scripts, and i think the result is enough good for me.
  3. method2: the second one, i deal the texture by the python to add alpha to the texture( set the black frame to alpha=0). and i think it seems more better than the above.

here is the code for the shader:

shader_type spatial;
//render_mode blend_mix, cull_disabled,diffuse_burley,specular_schlick_ggx;

uniform sampler2D texture_albedo : hint_default_white;
uniform sampler2D texture_metallic : hint_default_white;
uniform sampler2D texture_normal : hint_normal;
uniform sampler2D texture_roughness : hint_default_white;
uniform vec3 texture_color: source_color;

void fragment() {

	vec4 albedo_tex = texture(texture_albedo, UV);
	float brightness = (albedo_tex.r + albedo_tex.g + albedo_tex.b) / 3.0;
    float new_alpha = brightness;
	ALBEDO = texture_color;
	ALPHA = new_alpha;
	
}

here is the code for the python

from PIL import Image

def set_alpha_by_color(image_path):
	image = Image.open(image_path)
	image = image.convert("RGBA")
	data = image.getdata()
	new_data = [ ]
	for item in data:
		red, green, blue, alpha = item
		brightness = (red + green + blue) / 3 / 255
		new_alpha = int(brightness * 255)
		new_pixel = (0, 0, 0, new_alpha)
		new_data.append(new_pixel)
	image.putdata(new_data)
	output_path = "output.png"
	image.save(output_path)
	return output_path
input_image_path = "Std_Eyelash__Opacity.jpg"
output_image_path = set_alpha_by_color(input_image_path)

and at last, i have a question:
if the method2 is better than method1 ? i think so because the result is similar, and i think the mothod2 will cost less GPU because don’t need the GPU to deal the texture.

1 Like

It is desirable to put the code between ```, then it will look better.

    ```
    code
    ```

thanks for you suggestion, i changed it.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.