Beginner-Friendly Tutorials Jul 28, 2026

How to Try Bevy Contact Shadows - First Indie Soft Contact Spike 2026

How to try Bevy contact shadows in 2026 - first indie soft contact spike, ContactShadows camera component, per-light toggles, cost honesty, and a keep/hold receipt.

By GamineAI Team

How to Try Bevy Contact Shadows - First Indie Soft Contact Spike 2026

neopeaks pixel art thumbnail for Bevy contact shadows first indie soft contact spike

If you are searching bevy contact shadows, you do not need another “Bevy 0.19 has BSN now” roundup. You need a Monday path: pin Bevy ≥ 0.19, place a floor and a prop under a directional light, add the ContactShadows component to the camera, set contact_shadows_enabled on the lights you care about, capture before/after soft contact on the ground plane, then write keep / hold / rewrite before anyone promises raytraced polish on a mid-tier laptop.

On June 19, 2026, Bevy shipped 0.19 with contact shadows as a complementary fix for short-range shadow failure modes that shadow maps alone cannot solve — peter-panning and shadow acne up close (Bevy 0.19 release notes, 0.18→0.19 migration). Official framing: contact shadows help shadows capture object detail and attach properly to nearby surfaces without the cost of full raytracing.

This evening is not Bevy 0.19 BSN (bsn! scenes). It is not the 0.17 2D platformer weekend. It is not the schedule hitch debug. It is not Phaser cone lights or Godot AreaLight3D. It is the dedicated bevy contact shadows soft-contact spike on a throwaway 3D lab.

If you are… Start here Done when
Beginner Glossary → pin 0.19 → one directional + ContactShadows Soft contact visible on floor
Creator / producer Gates B1–B6 → Discord brief + receipt Keep/hold line + before/after stills
Working eng Cost formula + mid-PC FPS note Receipt JSON + light-count cap
Studio lead Diligence zip + promote condition Dual owners named

Time: about 60–90 minutes on a lab Bevy 0.19 3D project. Longer if you must migrate from 0.17/0.18 first.

Why this matters now

Three clocks make bevy contact shadows worth an evening this month:

  1. Contact shadows are first-class in 0.19. Release notes put them next to BSN and Feathers as a polish feature teams will ask about in Discord (Bevy 0.19).
  2. Shadow maps alone fail up close. Official notes explain peter-panning vs acne when casters sit near receivers — resolution bumps do not fix the geometry problem without prohibitive memory cost.
  3. Cost is measurable, not mystical. Contact shadows are toggled per light; cost scales with pixels lit by those lights × number of such lights. That sentence belongs in your receipt.

If you still need Rust/Bevy fundamentals, skim the 0.17 platformer weekend and the free Bevy resource list on a different night — tonight stays on soft contact.

Glossary - plain words

Term What it means
Contact shadows Screen-space (or complementary) short-range shadows that glue casters to nearby surfaces.
ContactShadows Camera component that enables contact-shadow computation for the view.
contact_shadows_enabled Per-light bool on directional / point / spot lights.
Shadow map Classic depth-from-light shadow technique — strong at distance, weak for tight contact.
Peter-panning Object looks like it floats because the shadow disconnects from the base.
Shadow acne Self-intersecting / noisy shadow artifacts from depth bias fights.
Solari Bevy’s higher-end GI / lighting path — contact shadows here are the non-Solari polish path called out in 0.19 notes.
Keep / hold / rewrite Keep = adopt on hero interiors; hold = lab only; rewrite = stay on shadow maps + bias tuning.

What Bevy 0.19 contact shadows actually claim (true summary)

From the Bevy 0.19 release notes:

  • Contact shadows help shadows capture object details and attach properly to nearby surfaces.
  • Outside Solari, Bevy shadows previously relied on (cascaded) shadow maps alone.
  • Shadow maps struggle when caster-to-receiver distance is small — peter-panning or acne depending on depth bias.
  • Raising shadow-map resolution only moves the failure threshold and burns memory.
  • Contact shadows fill the short-range gap with an affordable screen-space raycast from surfaces toward lights, checking for nearby occluders (per 0.19 notes).
  • Results cling to surfaces and emphasize subtle curves on props and characters.
  • Supported for directional, point, and spot lights.
  • Toggled per light via contact_shadows_enabled = true.
  • Add the ContactShadows component to your camera.
  • Tuning values on that component control how contact shadows are computed across the scene.
  • Cost scales with number of pixels on screen lit by lights with contact shadows enabled, multiplied by the number of such lights.

Honest limits: contact shadows are not full raytracing and not a substitute for art direction. They will not fix muddy materials, missing ambient, or a scene that never cast shadows. This spike does not replace Solari evaluation if that is your GI bet, and it does not replace the BSN evening if scenes are the real blocker.

Keep / hold / rewrite - Monday decisions

Decision Choose when Do not pretend
Keep Lab shows readable floor contact; mid-PC FPS acceptable with a light-count cap That contact shadows alone make lighting “AAA”
Hold Spike works but ship still on 0.17/0.18; need migration week That “we’ll bump Friday before trailer” without a pin PR
Rewrite Bias/resolution already look fine, or mobile primary SKU fails cost gate That every light in the level needs contact shadows on day one

Write the decision on the receipt before anyone enables contact shadows on every PointLight in the open world.

Prerequisites

  • Rust toolchain (rustup) and Cargo
  • A lab Bevy 0.19 3D project (throwaway crate or branch)
  • Basic mesh + material + light spawn comfort
  • About 60–90 minutes blocked calendar
  • Optional: Tracy / frame-time HUD for a mid-PC note

Beginner path - first evening (no jargon first)

1) Pin Bevy 0.19 on a lab crate

[dependencies]
bevy = "0.19"

Confirm the lock resolves to 0.19.x. Do not bump production Cargo.toml on day one.

cargo new bevy_contact_shadows_lab
cd bevy_contact_shadows_lab
# edit Cargo.toml, then:
cargo run

2) Spawn a floor, a prop, a camera, a directional light

Keep the scene boring: a ground plane, a crate or capsule resting on it, one sun-like directional light with shadows on. Goal: classic shadow-map contact that looks slightly “floaty” or acne-prone up close — that is your before shot.

3) Add ContactShadows to the camera

use bevy::prelude::*;

fn setup(mut commands: Commands) {
    commands.spawn((
        Camera3d::default(),
        ContactShadows::default(), // enable contact-shadow pass for this view
        Transform::from_xyz(4.0, 3.0, 6.0).looking_at(Vec3::ZERO, Vec3::Y),
    ));
}

If your exact 0.19 patch uses a slightly different import path for ContactShadows, follow the compiler and the 0.19 notes — the evening contract is camera component + per-light flag, not winning a docs trivia fight.

4) Enable contact shadows on the light

commands.spawn((
    DirectionalLight {
        shadows_enabled: true,
        contact_shadows_enabled: true,
        illuminance: light_consts::lux::OVERCAST_DAY,
        ..default()
    },
    Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 0.7, -0.9)),
));

Repeat the same contact_shadows_enabled: true pattern for a lab PointLight or SpotLight if you want a second still — still one primary light for the FPS gate tonight.

5) Capture before / after

Toggle contact_shadows_enabled (or remove ContactShadows from the camera) and screenshot the caster base on the floor. Soft attachment should improve without inventing a second sun.

6) Write keep / hold and stop

Do not refactor BSN, Feathers, or Solari tonight. One soft-contact proof + receipt is the spike.

Working-dev path - gates B1–B6

B1 - Pin matrix

Check Pass if
Bevy version 0.19.x in Cargo.lock
Lab isolation Spike crate / branch, not silent main bump
3D app DefaultPlugins boots a window without panic
cargo tree -p bevy -i bevy | head

B2 - Camera ContactShadows

Check Pass if
Component present Primary gameplay / lab camera has ContactShadows
Tuning noted Default first; optional note if you changed thickness/range-style fields

B3 - Per-light enable

Check Pass if
Light types At least one directional or point or spot with contact_shadows_enabled
Shadows still on Classic shadows_enabled still true where you expect maps
Cap ≤2 contact-enabled lights for the first FPS pass

B4 - Visual proof

Check Pass if
Before still Shadow-map-only contact looks weaker / floatier
After still Soft attachment reads on floor or wall
Same camera No cheating with different FOV / exposure

B5 - Cost honesty

Check Pass if
Formula written “pixels lit × contact-enabled lights” on the receipt
Mid-PC note Optional but preferred 1% lows or frame-time delta
Cap policy Written max contact-enabled lights for ship scenes

B6 - Keep/hold + owners

Artifact Required
Decision line keep / hold / rewrite
Owners Eng + art (or eng + producer)
Capture paths before/after stills or 10s clip
Promote flag promoted_to_ship: false until humans say otherwise

Receipt template - bevy_contact_shadows_receipt_v1.json

{
  "schema": "bevy_contact_shadows_receipt_v1",
  "project": "lab-contact-shadows-spike",
  "bevy_version": "0.19.x",
  "gates": {
    "B1_pin": "GREEN",
    "B2_camera_contact_shadows": "GREEN",
    "B3_per_light_enable": "GREEN",
    "B4_visual_proof": "GREEN",
    "B5_cost_honesty": "GREEN",
    "B6_capture_decision": "GREEN"
  },
  "camera_has_contact_shadows": true,
  "lights_with_contact_shadows": ["DirectionalLight"],
  "contact_enabled_light_count": 1,
  "before_capture": "artifacts/contact_before.png",
  "after_capture": "artifacts/contact_after.png",
  "fps_note": "optional mid-tier frame-time delta with 1 contact-enabled light",
  "decision": "keep",
  "decision_notes": "Floor contact readable; cap ship scenes to 1–2 contact-enabled lights until profiling expands.",
  "owners": {
    "engineering": "NAME",
    "art_or_producer": "NAME"
  },
  "promoted_to_ship": false
}

Store beside other evidence habits from BUILD_RECEIPT. Do not invent studio names — use your real owners.

Common mistakes (and fast fixes)

Mistake Symptom Fix
Forgot ContactShadows on camera Per-light flag does nothing obvious Add the camera component
Forgot contact_shadows_enabled Camera component alone looks unchanged Enable on the light(s)
Shadows disabled entirely No maps, no contact Turn shadows_enabled on first
Ten PointLights all flagged FPS cliff Cap to one hero light tonight
Comparing different exposures Fake “win” Lock camera / exposure for A/B
Expecting Solari quality Disappointment Contact shadows ≠ full GI path
Mixing BSN migration tonight Context switch chaos BSN is a separate evening
Shipping without stills Standup arguments Before/after PNGs beat vibes
Mobile SKU assumed free Surprise cost Measure the target SKU or hold
Bias fights after enable Acne returns Revisit bias; contact is complementary, not magic

Worked example - indoor prop contact (lab template)

Use as a fill-in table, not universal truth.

Setting Lab value
Scene Floor + one crate / capsule
Primary light Directional, shadows on, contact on
Secondary light Off for B5
Camera ContactShadows::default()
Capture Base of prop on floor, same FOV
Pass rule Soft attachment readable; frame-time delta under team threshold

Pass rule: if you only see improvement after enabling contact on every light in a dense interior, hold density expansion and profile — the official cost model punishes lit-pixel × light-count product (0.19 notes).

Optional - point and spot lab branch

After B1–B6 green on directional:

  1. Disable directional contact; enable one SpotLight aimed at the prop.
  2. Capture again.
  3. Note which light type sells your genre (sun exteriors vs lamp interiors).

Stop after one branch if the clock hits 90 minutes — receipt first.

Art pipeline notes (creators)

  1. Blockout with shadow maps only so composition reads before contact polish.
  2. Promote contact on hero interiors and prop close-ups — not every fill light.
  3. Keep albedo honest — soft contact will not fix muddy materials.
  4. Trailer cameras may use higher contact density; tag non_ship_lighting in receipt notes if trailer ≠ gameplay.
  5. Share a Discord brief with before/after stills — producers need the look, not only the field name.

Performance and diligence honesty

Official cost model (paraphrased from 0.19 notes):

Cost scales with pixels lit by contact-enabled lights × number of those lights.

Company diligence language: a producer zip can include the receipt JSON, Cargo.lock Bevy pin, before/after stills, and the release-notes link. That shows the team evaluated soft-contact polish without claiming Solari or raytrace parity.

Mid-PC / Deck-class targets: measure with your real resolution scale. If B5 fails with one light, do not “fix” by adding more — hold and profile overdraw.

Format ladder - same cluster, different jobs

Format Angle (do not cannibalize)
This blog Strategy + keep/hold + B1–B6 + receipt
Guide chapter (forward) One step - add ContactShadows + one light flag
Help (forward) Fix - “contact shadows not visible / missing camera component”
Resource Discovery - free Bevy lighting / profiling crates
Course lesson Milestone - soft-contact interior in a project week

Cross-engine lighting cousins stay on their keywords: Phaser cone lights, Godot AreaLight3D, Defold lights.

How this differs from other Bevy spikes

Spike Primary keyword Tonight?
BSN scene evening bevy bsn No
0.17 platformer bevy 0.17 platformer No
Schedule hitch bevy schedule / menu hitch No
Contact shadows bevy contact shadows Yes

Same keep/hold culture; different ship risk.

Stretch goals (only after B1–B6 green)

  • Tune ContactShadows fields (thickness / quality style knobs on your patch) and document defaults vs tuned.
  • One spot-lamp interior A/B for art direction.
  • Tracy capture with contact on/off for a one-line cost note.
  • Compare a Solari prototype another night — do not expand tonight’s receipt.

Stop at one stretch if the clock hits 90 minutes.

Secondary 0.19 features (park for later)

Do not expand tonight’s receipt to cover:

  • BSN / bsn!BSN evening
  • Feathers widgets
  • EditableText / richer fonts
  • App settings framework
  • Vignette / lens distortion
  • Rectangular area lights (separate lighting spike)
  • Physically based SSR

Tonight is bevy contact shadows only.

Discord / stand-up brief (copy/paste)

Bevy contact shadows spike (0.19+)
- Pin: Bevy ____
- Camera ContactShadows: yes/no
- Lights with contact: ____ (count ____)
- B1–B6: ____ / ____ / ____ / ____ / ____ / ____
- Before/after: ____
- Decision: keep | hold | rewrite
- Owners: eng ____ / art-producer ____

Paste into the stand-up channel your team already uses — do not invent a GamineAI community URL.

Key takeaways

  1. bevy contact shadows shipped in Bevy 0.19 as short-range soft contact without full raytracing.
  2. Add ContactShadows to the camera and set contact_shadows_enabled on lights.
  3. Supported light types: directional, point, spot.
  4. Shadow maps alone fail up close (peter-panning / acne) — contact is complementary.
  5. Cost scales with lit pixels × contact-enabled light count.
  6. Cap to one hero light for the first FPS gate.
  7. Gates B1–B6 make the evening auditable for eng and producers.
  8. File bevy_contact_shadows_receipt_v1.json with dual owners.
  9. Do not confuse this with BSN, platformer, or schedule-debug evenings.
  10. Cite Bevy 0.19 when API field names drift on patches.
  11. Trailer density ≠ ship density — tag non-ship lighting honestly.
  12. Before/after stills beat “it looked nicer in the editor.”

FAQ

What are Bevy contact shadows?

A Bevy 0.19 feature that improves short-range shadow attachment and detail as a complement to shadow maps, without full raytracing (release notes).

How do I enable them?

Add the ContactShadows component to your camera and set contact_shadows_enabled: true on directional, point, or spot lights.

Do I still need shadow maps?

Yes for longer-range shadows. Contact shadows address the up-close failure modes shadow maps struggle with.

Which lights support contact shadows?

Directional, point, and spot lights per the 0.19 notes.

Why is nothing changing on screen?

Usual causes: missing camera ContactShadows, light flag still false, shadows disabled entirely, or ambient so bright contact is invisible. Walk B2–B3.

Are contact shadows free?

No. Cost scales with pixels lit by contact-enabled lights multiplied by how many such lights you enable.

Is this the same as Solari?

No. Contact shadows are called out as a polish path alongside the broader 0.19 lighting toolkit; Solari remains a different evaluation if you need that GI stack.

Is this the same as Bevy BSN?

No. BSN is scene notation — see Your First Bevy 0.19 BSN Scene.

How long should the spike take?

About 60–90 minutes for pin → camera + one light → before/after → receipt.

Should we migrate production the same night?

No. Keep the lab green, schedule lighting regression, then bump ship pins with owners named on the receipt.

Related reading

Official and useful sources

Conclusion

Bevy contact shadows turn floaty prop bases into readable soft contact — ContactShadows on the camera, per-light contact_shadows_enabled, and an honest cost model — without raytrace theater. Pin 0.19 on a lab 3D crate, prove one floor contact, fill B1–B6, then let humans own the ship merge. Bookmark this keep/hold beside the Bevy 0.19 notes and keep the receipt where producers can find it.