Nodes/ComfyUI-CustomNodePacks/Layer Effect: Inner Shadow (MEC)
ComfyUI Node

Layer Effect: Inner Shadow (MEC)

Inner shadow, and why your contact shadow keeps haloing

By Code2Collapse·Created 7 months ago·Updated 2 days ago· 56
Layer Effect: Inner Shadow (MEC)
  • layer_image
  • background_image
  • layer_mask
  • image
  • effect_mask
  • report
invert_masktrue
blend_mode
opacity50
distance_x5
distance_y5
grow2
blur15
shadow_color#000000
dissolve_seed0

What it's for

The inner shadow is the "this thing sits inside something / this thing has depth" effect: a thin dark band just inside the matte edge, offset in one direction. It's how you fake a recessed panel, a hole, a patch that's stitched into fabric, or the sense that a subject is lit from one side while its edge falls off.

It's the sibling of Drop Shadow and shares the same code path - literally: in the source, InnerShadow is a subclass of DropShadow. The difference is where the footprint lands.

How it works

The matte is shifted by distance_x/distance_y, grown by grow, blurred by blur - same as the drop shadow. But instead of compositing the shadow outside the subject, the node takes the intersection of the shadow band with the layer matte. So you only get the part of the shifted, blurred shadow that falls inside the matte, which is exactly the "inner" half of the effect.

effect_mask is that intersection: the shadow band, clipped to the layer. Handy if you want to grade or grain the inner shadow separately, or feed it somewhere as a matte in its own right.

Inputs

  • layer_image - the subject. Alpha counts if you don't wire a mask.
  • layer_mask (optional) - the matte. One of the two is required; a 3-channel image with nothing wired raises needs a layer mask.
  • invert_mask - defaults to true and inverts for real. Normal ComfyUI matte plus the default = the layer is treated as the background, which puts your inner shadow in the wrong region entirely. This is the first thing to check when the effect is somewhere unexpected.
  • distance_x / distance_y - positive moves right and down, same convention as the drop shadow, and the opposite of upstream LayerStyle's sign. Defaults are 5/5, which is a subtle light-from-upper-left look.
  • grow - default 2. Small numbers here; you're shaping a band a few pixels wide, not inflating a silhouette.
  • blur - default 15. The blur is what makes it read as falloff instead of a drawn line.
  • shadow_color, blend_mode (30 modes), opacity (default 50), dissolve_seed - the dissolve mode is seeded and static here, unlike upstream, which reseeded every frame and made dissolves flicker across a sequence.

Optional background_image is the plate; without it you composite onto a transparent canvas (read: black, in the RGB output).

Outputs: image, effect_mask, report.

The halo trap

Here's the thing nobody explains about contact shadows: if the shadow band extends to the edge of the matte and then stops, you get a visible rim - the shadow appears to leak past the object silhouette. Two causes, two fixes:

  1. grow positive with a big blur. The blur spreads the band outward, past the matte, and the intersection with the matte cuts it off mid-falloff, leaving a hard line. Pull grow negative - the tooltip's own phrasing is that a negative grow "keeps a tight contact shadow from haloing", which is precisely this problem.
  2. A matte that's a pixel or two tight. Inner shadows are unforgiving of a matte that's undersized, because the band starts at the boundary. Expand the matte a hair upstream and the shadow reads as being in the material rather than painted on.

For a believable recessed-panel look: grow around -1 to 0, blur 8–12, opacity 40–60, distance 3–6 px, and a shadow colour that's a dark tint of the surface, not black.

Install

ComfyUI Manager → search "CustomNodePacks", or:

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks

Restart and check the console load line. This port is standalone - it does not need chflame163's ComfyUI_LayerStyle installed, which is the point of shipping a torch-native port rather than another wrapper (upstream is a few hundred nodes with a dependency list to match, plus API-calling nodes). Tier 1, no models. The README's warning about not blindly running pip install -r requirements.txt applies; check pip list first.

Common issues

  • Effect lands outside the subject. invert_mask is still on its default true. Flip it.
  • A hard bright rim at the matte boundary. The halo trap above: negative grow, or a slightly padded matte.
  • Nothing visible at all. At defaults this is a 5-pixel offset with a 15-pixel blur on a 50% opacity multiply - genuinely subtle on a small subject. Scale the distance with the subject size; 5px is a lot on a 256px thumbnail and nothing on a 2048px plate.
CategoryMEC/LayerEffects

Inputs (12)

NameTypeDefaultDescription
layer_imageIMAGEForeground layer whose alpha defines the cast shadow.
invert_maskBOOLEANtrueFlip mask polarity when your matte is white-on-black.
blend_modeCOMBO30 options: normal, dissolve, darken, multiply, color burn, linear burn, +24
opacityINT500–100
distance_xINT5-9999–9999Horizontal offset in pixels. Positive moves the shadow right — the opposite of the upstream LayerStyle node, which negated it.
distance_yINT5-9999–9999Vertical offset in pixels. Positive moves the shadow down — the opposite of the upstream LayerStyle node, which negated it.
growINT2-9999–9999Expand the shadow before blurring. Positive spreads it past the subject edge; negative pulls it inside, which keeps a tight contact shadow from haloing.
blurINT150–1000Gaussian blur radius on the shadow matte.
shadow_colorSTRING#000000
dissolve_seedINT00–2147483647Only used by the 'dissolve' blend mode. Upstream reseeds every frame, so a dissolve flickers through a sequence; a fixed seed here holds still.
background_imageoptIMAGEPlate; empty = transparent canvas (V3 union).
layer_maskoptMASK

Outputs (3)

NameTypeDescription
imageIMAGE
effect_maskMASK
reportSTRING