wcandillon / wcandillon/react-native-webgpu

Real-device WebGPU crash in directional shadow receiver path after Three shadow render completion

Open
#333 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.2k
Forks
70
Avg merge
1d 6h
Merged PRs (30d)
23

Description

Real-device WebGPU crash in directional shadow receiver path after Three shadow render completion

Summary

We reduced a WebGPU crash in our React Native / Expo app to a small repro that fails on both iOS simulator and a real iPhone, but only when a directional-light shadow receiver path is active.

What is already proven:

  • raw WebGPU passes on simulator and real device
  • raw Three WebGPU passes on simulator and real device
  • patched R3F WebGPU passes on simulator and real device
  • the reduced shadow receiver repro fails on simulator and real device
  • three completes the shadow render path on the JS side
  • the only local patch that materially changed the failure boundary was in react-native-wgpu
  • no safe local workaround is proven

Current best attribution:

  • this does not look like a generic WebGPU, generic Three, or generic R3F failure
  • this looks like a native/backend WebGPU failure on the react-native-wgpu / Dawn / Metal path during the shadow-pass submission lifecycle
  • our best current stage classification is: during_shadow_pass_submission_before_native_present_completion

Environment

  • react-native-wgpu: 0.5.8
  • react-native: 0.81.5
  • expo: ~54.0.0
  • react: 19.1.0
  • three: 0.183.2
  • @react-three/fiber: 9.5.0
  • real device used for confirmation: iPhone 16 Pro Max

Passing controls

These all pass on simulator and real device:

  • raw WebGPU
  • raw Three WebGPU
  • patched R3F WebGPU

Failing reduced repro

The failing repro is a reduced scene with a directional light and a shadow receiver.

Final narrowed failing condition:

  • receiveShadow = true
  • directionalShadow = true

This still fails across:

  • materials:
    • MeshStandardMaterial
    • MeshLambertMaterial
    • MeshBasicMaterial
  • geometries:
    • circle
    • plane
    • ring

So this is not just “standard material on a circle”.

Observed behavior

On a real iPhone:

  • the reduced repro reaches route-ready
  • the process is gone by the end of the probe window
  • deeper native trace capture could not be flushed before failure from this environment

On simulator:

  • the same reduced repro also fails

Important local findings

1. three is not the first failing layer anymore

Our engine-level source-debugging narrowed the boundary further:

  • three reaches/completes the shadow render path on the JS/engine side
  • the remaining blocker appears after that, in the native/backend path
2. A react-native-wgpu patch was the only patch that materially changed the failure boundary

We tested several local patch candidates.

Only one materially changed behavior:

  • a native present/backend guard in react-native-wgpu

That candidate:

  • made the reduced repro pass on simulator
  • made broader Doorway validation scenes pass on simulator and real device
  • but the reduced shadow repro still failed on real device in the clean confirmation rerun

This is why react-native-wgpu is now our primary issue target.

3. Warm-up / delayed shadow enable did not solve it

We also tested delayed shadow enable / warm-up gating.

Result:

  • no usable effect on real device
  • the reduced repro still failed before the gate meaningfully activated

Why we think this belongs here

At this point the evidence suggests:

  • the reduced repro is valid
  • generic WebGPU and generic Three/R3F are fine
  • the failure is in the native/backend path specific to the shadow-pass lifecycle on this stack
  • the only patch that moved the boundary at all was in react-native-wgpu

That makes react-native-wgpu the primary owner to inspect next.

Primary ask

Can you advise where to inspect next in the native/backend path for this reduced real-device shadow-pass failure?

The most relevant current question is:

  • why does the reduced directional-shadow receiver repro still die on real device after three shadow render completion, even though a native/backend guard is enough to make broader validation surfaces pass?

If there is a specific Dawn / Metal / react-native-wgpu texture, render-pass, queue-submit, or present-adjacent path that matches this pattern, that is the highest-value direction for us.

If helpful, I can provide:

  • the reduced repro surface
  • machine-readable simulator vs real-device comparison outputs
  • the exact local patch candidates we tested

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reduced directional-shadow receiver repro and the react-native-wgpu native present/backend guard, comparing simulator and iPhone behavior after Three completes shadow rendering. Trace the Dawn/Metal texture, render-pass, queue-submit, and present-adjacent stages named in the report. Done means identifying the native failure boundary and demonstrating a fix against the reduced repro on both simulator and real device.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, react-native, three.js
Domain
backend, computer-graphics, mobile
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.