본문으로 건너뛰기
CHOI HONGSU
1 min read

Shader NaN guards

 

Defended against NaN propagation from zero vectors / zero values in normalize / rcp / atan2 with a consistent pattern — blocking the mobile black-screen issue

Problem

Approach

셰이더 레벨 일관 NaN 가드

Chosen

Pros

  • Safe regardless of inputs; one fix applies broadly

Cons

  • Some functions add a branch / extra ops

머티리얼·런타임 입력값 검증 강화

Pros

  • No shader changes

Cons

  • Many input paths make full defense hard — not a root-cause fix

Why 셰이더 레벨 일관 NaN 가드: Shader inputs come from many paths — materials, VFX, runtime — and external validation alone cannot defend against all of them. The fundamental fix is making the shader itself behave safely under zero inputs.

Implementation

  1. 01

    Step 1 — Define a consistent guard pattern

    • Precision-aligned: 1e-6h (half) / 1e-6 (float)
    • Context-specific fallbacks: direction (0,0,1), angle 0.5, etc.
    • Intent annotated with // NaN guard comments

Architecture

SafeNormalize definition:

Tradeoffs & Future Work

Tradeoffs

  • Vertex-shader guards are negligible due to low vertex counts. Fragment shaders are unified on the rcp(max(...)) ALU pattern to avoid actual branching.
  • An early implementation that wrapped the whole function in `if (ru > 1e-6)` caused both fragment-level branching and a regression on the center pixel — flagged as Critical for priority fix.
  • The 1e-6 threshold is based on typical mobile environments. Tuning may be needed if extremely small-scale objects are added.