npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

xrift-mirror

v0.4.0

Published

Switchable HQ/LQ/OFF stand mirror for XRift worlds & items — 切替スイッチ付き姿見ミラー

Readme

xrift-mirror 🪞

XRift 用の切替スイッチ付き姿見ミラー — VRChat ワールドの定番ギミック「HQ/LQ 切り替えミラー」を、XRift のワールドとアイテムの両方に持ち込んだものです。

A switchable HQ/LQ/OFF stand mirror for XRift worlds & items.

xrift-mirror

できること

  • 右端の縦スイッチで HQ / LQ / OFF の3モードを切替。モードは既定で 操作者ローカル(押した人の見え方だけ変わる)。sync を付けると全員同期(VRChat のミラースイッチ流儀)
  • HQ = 全景を映す高画質ミラー(解像度1024)/LQ = アバターだけ映る軽量ミラー(解像度512)/OFF = 鏡を外して枠だけ(描画コストゼロ)
  • LQ は VRChat の LQ ミラーと同じ発想: 鏡のコストの本命は「シーンをもう一回描くドローコール」で、解像度ではなく 映す対象をアバターだけに絞る ことでそれを削ります
  • 鏡は色を混ぜない恒等ミラー(色かぶり・脱色なし)
  • 現在のモードのスイッチが青く光る。ラベル常時表示(VR でも読める)
  • 10m 以上離れると反射レンダリングを自動停止して消灯ガラスに落とす(距離LOD・ヒステリシス付き)
  • ワールド設置版は 幅・高さを自由に指定できる

XRift ワールドに置く

npm install xrift-mirror
import { XRiftStandMirror } from 'xrift-mirror/xrift'

export const World = () => (
  <>
    {/* 任意の位置・向き・サイズで置ける。複数置くなら syncId を変える */}
    <XRiftStandMirror position={[0, 0, -3]} width={2.4} height={2.2} />
  </>
)

| prop | 既定 | 説明 | | --- | --- | --- | | position | [0, 0, 0] | 設置位置(台座の足元) | | rotationY | 0 | Y回転。鏡面は +Z を向く | | width | 1.6 | 鏡面の幅(m)。枠はこれより一回り大きい | | height | 2.2 | 鏡面の高さ(m) | | defaultMode | 'off' | 初期モード。ワールド備え付けは 'off' 推奨(Quest 配慮の VRChat ミラー作法) | | sync | false | true でモードを全員に同期。既定は操作者ローカル | | syncId | 'xrift-mirror' | ボタンid(と sync 時の同期キー)の名前空間。複数設置時は一意にする |

XRift 以外の React Three Fiber でも使える

v0.3.0 から実装を二層に分けました。本体はどの R3F プロジェクトでも動きます。

  • xrift-mirror(本体) — 依存は three / @react-three/fiber / @react-three/drei / @react-three/rapier のみ。@xrift/world-components には依存しません
    • StandMirror — スイッチ付き姿見。モードはローカル state(mode / onModeChange で外部制御も可)。スイッチは R3F のポインタイベントで反応し、renderInteract で任意のインタラクション実装に差し替え可能
    • MirrorSurface — 鏡面だけ(枠・スイッチなし)。quality="hq" | "lq"
    • LayeredReflector / tagAvatarsForMirror — 低レベルAPI(下記「実装」参照)
  • xrift-mirror/xrift(アダプタ)XRiftStandMirror。XRift の Interactable(VRコントローラ/デスクトップ両対応の操作)と、sync 指定時は useInstanceState(全員同期)を StandMirror に注入する薄い層。@xrift/world-components への依存はここだけ(optional peerDependency)
// 素の R3F プロジェクト(XRift 不要)
import { StandMirror } from 'xrift-mirror'

<StandMirror position={[0, 0, -3]} defaultMode="hq" />

アイテム版

このリポジトリは XRift アイテム「ミラー」としてもビルドされます(npm run buildxrift upload item)。アイテム版はインベントリからどのワールドにも持ち込める サイズ固定の大型ミラー(3.6m × 2.85m) で、既定モードは LQ(アバターだけ映る)です。

ワールドにミラーが備え付けてあるのが常識の VRChat に対して、「鏡を自分で持ち歩く」は XRift のアイテム機構だからできる形です。

実装 — 「アバターだけ映る」の仕組み

鏡面は three.js の Reflector(MIT)をフォークした LayeredReflector です。反射用の仮想カメラを自前で所有し、reflectLayersMask で「鏡に何を映すか」を選べます。

  • XRift のアバターは three-vrm の VRMFirstPerson 層規約(9=一人称専用・10=三人称専用)を使いますが、体の大半は layer 0 でワールドと同居しているため、既存レイヤーだけでは分離できません
  • そこでシーンを定期走査して、次の3種類のいずれかに当てはまるオブジェクトとライトに鏡専用レイヤー(30番ビット)を追加します。Layers はビットマスクなので既存のレイヤー運用に対して非破壊です
    1. SkinnedMesh(カスタムVRMアバターの体)
    2. layer 10(三人称専用)会員のオブジェクト(ホストが明示タグ付けしたパーツ)
    3. ボーン風の名前(hips/spine/chest/neck/head/shoulder/hand等)が2階層以上連続する祖先を持つMesh(XRift既定のスキン無しプレースホルダーアバター救済。体パーツごとに無名メッシュが名前付き関節にぶら下がる構造で、1・2のどちらの信号も持たないため)
  • LQ の仮想カメラはこの鏡専用レイヤーだけを描画 → 反射パスのドローコールがアバター数体分まで減ります
  • HQ は一人称専用レイヤー(9)だけを除いた全景を描画(一人称の頭・体が二重に映るのを防ぐ)

既知の限界: 上記いずれの信号も持たない非アバター装着物(剛体アクセサリ等)は LQ では映りません

クレジット

  • 参考: BOOTH HQ・LQ切り替えスイッチ付ミラー ほか VRChat のワールドギミック文化
  • 鏡面の反射数学は three.js Reflector(MIT License, Copyright 2010-2026 three.js authors)のフォーク。それ以外(レイヤー制御・アバター検出・LOD・スイッチUI)は React Three Fiber でゼロから書いています

開発

npm install
npm run dev        # DevEnvironment 上で単体プレビュー(?preview で設置プレビュー確認)
npm run build      # XRift アイテムビルド(Module Federation → dist/)
npm run build:lib  # npm ライブラリビルド(→ lib/)
npm run typecheck

dev シーンには LQ 検証用のダミーアバター(SkinnedMesh・赤)と静的な青箱が置いてあります。期待値: HQ=両方映る / LQ=赤だけ映る。

ライセンス

MIT