diff --git a/src/assets/hud/muted.png b/src/assets/hud/muted.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a15a9ea9e9125e04739214c0fad7c0226d5eca2
Binary files /dev/null and b/src/assets/hud/muted.png differ
diff --git a/src/components/2d-mute-state-indicator.css b/src/components/2d-mute-state-indicator.css
new file mode 100644
index 0000000000000000000000000000000000000000..9713edb2ee92e8b0b8e0eafb5a7e8ac41719dcac
--- /dev/null
+++ b/src/components/2d-mute-state-indicator.css
@@ -0,0 +1,12 @@
+:local(.indicator) {
+    position: absolute;
+    top: 10px;
+    left: calc(50vw - 16px);
+    width: 32px;
+    height: 32px;
+    background-size: 100%;
+}
+
+:local(.indicator.muted) {
+    background-image: url(../assets/hud/muted.png);
+}
diff --git a/src/components/2d-mute-state-indicator.js b/src/components/2d-mute-state-indicator.js
new file mode 100644
index 0000000000000000000000000000000000000000..95df937d8ded1e13e5d125bfb3295b118649a2be
--- /dev/null
+++ b/src/components/2d-mute-state-indicator.js
@@ -0,0 +1,38 @@
+import styles from "./2d-mute-state-indicator.css";
+/**
+ * Shows a 2d incicator on screen reflecting mute state
+ * @TODO this probably shouldnt be an aframe component but baring any other 2d UI handling it feels cleaner here than jsut free-flaoting
+ */
+AFRAME.registerComponent("2d-mute-state-indicator", {
+  schema: {},
+
+  init() {
+    this.onStateToggled = this.onStateToggled.bind(this);
+
+    this.muteIcon = document.createElement("div");
+    this.muteIcon.classList.add(styles.indicator);
+    document.body.appendChild(this.muteIcon);
+
+    this.updateMuteState();
+  },
+
+  play() {
+    this.el.sceneEl.addEventListener("stateadded", this.onStateToggled);
+    this.el.sceneEl.addEventListener("stateremoved", this.onStateToggled);
+  },
+
+  pause() {
+    this.el.sceneEl.removeEventListener("stateadded", this.onStateToggled);
+    this.el.sceneEl.removeEventListener("stateremoved", this.onStateToggled);
+  },
+
+  onStateToggled(e) {
+    if (!e.detail.state === "muted") return;
+    this.updateMuteState();
+  },
+
+  updateMuteState() {
+    const muted = this.el.sceneEl.is("muted");
+    this.muteIcon.classList.toggle(styles.muted, muted);
+  }
+});
diff --git a/src/room.js b/src/room.js
index 4124d5fd7f4719ccbe8fc99c0817621d2a879aa9..f5b3a8ec9f5b8df28f6e6705334fd84678037607 100644
--- a/src/room.js
+++ b/src/room.js
@@ -21,6 +21,7 @@ import "./components/mute-mic";
 import "./components/audio-feedback";
 import "./components/nametag-transform";
 import "./components/bone-mute-state-indicator";
+import "./components/2d-mute-state-indicator";
 import "./components/virtual-gamepad-controls";
 import "./components/body-controller";
 import "./components/hand-controls2";
diff --git a/templates/room.hbs b/templates/room.hbs
index 5a86966219e6648d0076302ae17d5ed28538bfca..74629e56a37e6ec5914704d958d9ced08621745c 100644
--- a/templates/room.hbs
+++ b/templates/room.hbs
@@ -40,6 +40,7 @@
                          onConnect: App.onConnect;
                          connectOnLoad: false;"
         mute-mic="eventSrc: a-scene; toggleEvents: action_mute"
+        2d-mute-state-indicator
         light="defaultLightsEnabled: false">
 
         <a-assets>