Skip to content

Surface Type

Surface Type settings

This is the first option you should check -- it is the most important setting!

Similar to the URP Lit shader's Surface Type, the NiloToon_Character shader has a Surface Type at the top of the material.

SurfaceType modifies the default value of the following properties:

  • _SrcBlend (Source Factor)
  • _DstBlend (Destination Factor)

Blending factor settings

  • _ZWrite (Write to depth buffer?)

ZWrite setting

  • _RenderOutline (Toggle of Classic Outline group)

RenderOutline toggle

  • _AlphaClip (Toggle of Alpha Clipping group)

AlphaClip toggle

  • Render Queue

Render Queue setting

We recommend selecting the correct Surface Type for the material before editing other properties.


Opaque/Outline

The default Surface Type when creating a new material -- opaque with Classic Outline. The majority of materials will use this type.

Usage examples:

  • Any fully opaque hair/body/skin/face/cloth material that needs outline and does not require semi-transparency

Opaque/Outline example

Property Default Value
_SrcBlend One (1)
_DstBlend Zero (0)
_ZWrite On (1)
_RenderOutline On (1)
_AlphaClip Off (0)
Render Queue 2000

Opaque

Same as Opaque/Outline, but without outline. Suitable for fully opaque materials that do not need outline.

Usage examples:

  • Eyes, eyebrows, mouth, teeth, nails, thin hair, thin cloth

Opaque example

Property Default Value
_SrcBlend One (1)
_DstBlend Zero (0)
_ZWrite On (1)
_RenderOutline Off (0)
_AlphaClip Off (0)
Render Queue 2000

Opaque(Alpha)/Outline

Same as Opaque/Outline, but uses semi-transparent alpha blending. Suitable for opaque materials with slight semi-transparent alpha blending.

Usage examples:

  • Semi-transparent front hair, semi-transparent cloth with mainly high alpha values (visually close to Opaque/Outline) that should cast shadow maps
Property Default Value
_SrcBlend Source Alpha (5)
_DstBlend One minus Source Alpha (10)
_ZWrite On (1)
_RenderOutline On (1)
_AlphaClip Off (0)
Render Queue 2499

Transparent

The classic Unity transparent type without ZWrite and outline. This is what most users understand as "Transparent." Suitable for transparent materials that do not need outline and do not cast shadow maps.

Usage examples:

  • Semi-transparent glass material for eyeglasses, emojis, face expressions, VFX, makeup on face hair shadow mesh, semi-transparent eye parts
Property Default Value
_SrcBlend Source Alpha (5)
_DstBlend One minus Source Alpha (10)
_ZWrite Off (0)
_RenderOutline Off (0)
_AlphaClip Off (0)
Render Queue 3000

Caution

This material will not write to the Depth Texture due to Render Queue > 2499, so effects that rely on depth will not work (e.g., Depth of Field, Decal, SSAO).


Transparent(ZWrite)/Outline

Similar to the classic Unity Transparent, but with ZWrite and outline.

Usage examples:

  • Semi-transparent plastic outer jacket/cloth with mainly very low alpha values that should not cast shadow maps
Property Default Value
_SrcBlend Source Alpha (5)
_DstBlend One minus Source Alpha (10)
_ZWrite On (1)
_RenderOutline On (1)
_AlphaClip On (1)
Render Queue 3000

Caution

This material will not write to the Depth Texture due to Render Queue > 2499, so effects that rely on depth will not work (e.g., Depth of Field, Decal, SSAO).


Outline and Alpha Clip Variants

There are many other Surface Type options, most of which are expanded variants related to Outline (on/off) and AlphaClip (on/off).

Outline and AlphaClip variant list

  • If you need to display Classic Outline, select the one with the /Outline suffix. Otherwise, select the one with the /No Outline suffix.
Property Value
_ZWrite On (1)
_RenderOutline On (1)
  • If you need to apply Alpha Clipping (Alpha CutOut), select the one with the (CutOut) suffix. Otherwise, select the one without the (CutOut) suffix.
Property Value
_AlphaClip On (1)

Render Queue Reset

Caution

Changing the SurfaceType will reset the Render Queue to the default value of the selected SurfaceType. If you need a specific Render Queue, make sure to set it again after changing the SurfaceType!

Render Queue reset warning


Config File

If you need to inspect the detailed settings of each SurfaceType, you can search for and open NiloToonCharacter_SurfaceType_LWGUI_ShaderPropertyPreset in your project.


Is Skin? / Is Face?

Is Skin / Is Face settings

This is an important setting!

Skin and face materials require special care to look good. The following groups in the material are useful for this purpose:

  • Is Skin?
  • Is Face?

Settings and Effect

Find all skin materials (e.g., face, mouth, body, hand, leg), turn on Is Skin?, and turn it off for non-skin materials. If a material mixes skin and non-skin parts, use Is Skin? > Mask to mask the appropriate areas.

Is Skin setting

Enabling Is Skin will:

  • Make the material's Shadow Color use an overridden reddish skin shadow color from the Shadow Color group (the default shadow color may not look good for skin without the Is Skin group enabled)

    Skin shadow color override

Note

To edit the skin color for materials with Is Skin enabled, use Shadow Color > Skin and Face Override.

Find all face materials (e.g., face, mouth, eye, and eyebrow), turn on Is Face?, and turn it off for non-face materials. If a material mixes face and non-face parts, use Is Face? > Mask to mask the appropriate areas.

Is Face setting

Enabling Is Face will:

  • Edit the face's shading normal in the shader (the shading normal becomes flat/round, defined by the NiloToonPerCharacterRenderController script's fix face normal slider)
  • Override to use values from the Lighting Style (face) group instead of the standard Lighting Style group
  • Make the material's Shadow Color use an overridden reddish skin shadow color from the Shadow Color group

Caution

  • Do not enable Is Skin? for non-skin materials
  • Do not enable Is Face? for non-face materials

ShadowColor Skin/Face

After marking the Skin and Face areas in the material, you can control the skin and face shadow color in the following section:

Shadow Color > Skin and Face Override

If you are not satisfied with the current skin/face shadow color:

  • Pick a suitable Color Preset (Red/Orange/Purple and their variants). This defines the shadow color's Hue and Saturation.
  • Control Brightness / Custom Tint for both skin and face. It is acceptable to lower the Brightness to 0.8-1 to make the shadow color darker, especially for male characters or characters with a more realistic style.

Skin/Face shadow color settings

Debug Skin/Face Area

You can debug the character's Skin and Face areas using NiloToon's debug window. Click: Window > NiloToonURP > Debug Window.

Open debug window

  • Select Is Face or Is Skin in the Shading Debug dropdown
  • Enable the Enable Shading Debug? toggle

Is Face debug view Is Skin debug view

You can then debug the skin and face areas as grayscale values, where marked areas are shown as white and unmarked areas as black.

Neck Shadow Split

This is an advanced topic. You can skip it if this is not a problem with your model.

Standard Solution

Both Is Skin? and Is Face? have a Mask Map feature that lets you mask out areas that should not be considered as Is Skin? or Is Face? using an extra texture.

Mask Map feature

A common problem is that the face material (IsFace enabled) and body material (IsFace disabled) split around the neck, causing shadow to appear separated around the neck (a visible line at the neck area).

Neck shadow split problem

The image above shows the shadow split problem at the neck.

Is Face debug view - bottom of head

The image above shows the current Is Face debug view. You can see that the bottom part of the head is considered as Is Face, but the neck is not.

A common solution is to use an extra mask map to make the bottom part of the head not considered as Is Face.

Face BaseMap - artist's shadow painting

The above texture is the face BaseMap. Artists usually paint shadow color at the bottom part of the head.

Is Face Mask Map example

The above texture is the extra Is Face Mask Map, where the shadow color area / bottom part of the head from the BaseMap is converted to black and the rest to white, so the bottom part of the head is no longer considered as Is Face. Adding a slight blur makes the transition smoother.

After assigning the above Is Face Mask Map, you should see better shadow rendering results. Rotate the Directional Light to ensure everything looks correct under all lighting conditions.

Shadow split problem resolved

Is Face debug view after Mask Map

Occlusion Map

In extreme light angles and neck rotations, the shadow map on the neck may look unstable or appear as a sharp cut. In this case, you can add a soft-gradient Occlusion Map to force part of the neck into shadow, easily hiding the problematic area.

Before Occlusion Map

The image above shows the result before adding an Occlusion Map. A sharp shadow split is visible due to the shape of the 3D model geometry.

After Occlusion Map

The image above shows the result after adding an Occlusion Map. Lighting from all directions looks great, and the shadow blends perfectly with the shadow map.

Painted Occlusion Map

The image above shows the newly painted Occlusion Map.

Easy Solution

The face mask and Occlusion Map from the standard solution require manual painting or tools like Photoshop or Clip Studio Paint, which may be too difficult for non-artists.

The easy solution takes the opposite approach from the Standard Solution. It hides the shadow split line by making the entire neck material also Is Face. This works well only when cloth or accessories like a collar cover the lower part of the neck. Use the neck material's Is Face mask to ensure the shadow split line appears only under the cloth or accessory, where it is invisible.

Easy solution example

In the image above, the easy solution is applied: both the neck and the head have Is Face enabled, and the shadow split line is hidden under the white cloth.

Shadow Color Sync

If all face and skin materials need the same shadow color, use the same shadow color settings for all face materials and skin materials.

Shadow Color sync example