## Inspiration **Augmented Perception** Remembering the past; augmented perception is a project by Janus developer bai in which he crawled and visualized the web of JanusXR virtual worlds people created and linked together ![](https://camo.githubusercontent.com/9baa4874e89ba383cc887a50f476d493760f70c3125b1eb3297e5b4d1734d8a3/68747470733a2f2f692e696d6775722e636f6d2f563666716a56472e676966) **Silk Road** Thinking about what history can teach us about how to connect disparate virtual worlds together. ![](https://hackmd.io/_uploads/rkTPt-HYh.jpg) ![](https://hackmd.io/_uploads/rJmtFZHFh.jpg) However, **Night Sky** In retrospect I think I was too heads down thinking about how to solve the metavese alignment problem. When I added this night sky shader to The Street world in Webaverse I was awestruck by the beauty on my screen. Even if the skysphere was fictional, it dawned on me how looking out into the cyberspace cosmos made me feel like I was part of something bigger. > what if the stars were distant virtual worlds? and when you look up you see constellations that visualize the links / portals connecting between some of them? [tweet](https://twitter.com/dankvr/status/1600026115409444864) ![](https://i.imgur.com/h8n20Hp.gif) > > Ancient civilizations found inspiration in the stars and constellations in the night sky. They saw them as more than just celestial bodies; they saw stories, myths, and divine beings in the heavens. The stars guided navigation, marked the passage of time, and influenced agricultural activities. They became a part of cultural identity, passed down through generations, and played a role in shaping religious beliefs and rituals. --- ## Gathering Data ### Hyperfy - https://github.com/madjin/hyperfy-archive This script formats the raw JSON into just what we need by display the URLs for all `hyperfy_portals`. Keep in mind though that traversal can happen from all sorts of other objects, such as images / zones / models. I think for now, `hyperfy_portals` has an intentional and easy to understand context better for literacy when explaining the project to others. ```python! import json import sys if len(sys.argv) != 2: print("Usage: python parse_json.py <filename>") sys.exit(1) filename = sys.argv[1] with open(filename, "r") as file: data = json.load(file) output = [] for item in data: item_data = { "id": item["id"], "title": item["title"], "description": item["description"], "image": item["image"], "slug": item["slug"] } entities = json.loads(item["entities"]) portals = [] for entity in entities: if entity["id"] == "hyperfy-portal": if "state" in entity and "$fields" in entity["state"] and "url" in entity["state"]["$fields"]: url = entity["state"]["$fields"]["url"] portals.append({ "url": url }) if portals: item_data["hyperfy_portals"] = portals output.append(item_data) # Print the output as a JSON string print(json.dumps(output, indent=2)) ``` ![](https://hackmd.io/_uploads/BJ27N7HKh.png) ![](https://hackmd.io/_uploads/HkoVNmBth.png) ## Voxels ## Decentraland --- ## Libraries - https://github.com/vasturiano/3d-force-graph - https://github.com/vasturiano/3d-force-graph-vr ![](https://hackmd.io/_uploads/r19u_ZBF3.png) ```bash! #!/bin/bash mkdir -p circle for file in *.png; do convert "${file}" \( +clone -threshold -1 -negate -fill white -draw "circle $(identify -format %w "${file}" | awk '{print $1/2}'), $(identify -format %h "${file}" | awk '{print $1/2}') $(identify -format %w "${file}" | awk '{print $1/2}'), 0" \) \ -alpha Off -compose copy_opacity -composite "circle/${file}" done ``` **img-nodes example** ```html! <!DOCTYPE html> <html> <head> <style> body, html { height: 100%; width: 100%; margin: 0; overflow: hidden; } #3d-graph { height: 100%; width: 100%; } </style> <script src="//unpkg.com/three"></script> <script src="//unpkg.com/3d-force-graph"></script> </head> <body> <div id="3d-graph"></div> <script type="importmap">{ "imports": { "three": "https://unpkg.com/three/build/three.module.js" }}</script> <script type="module"> const ORIGIN = 'https://hyperfy.io'; function urlToAbsolute(url) { if (!url) return url; if (url.startsWith('http')) { // Already an absolute URL return url; } if (url.startsWith('/')) { // Relative URL starting with "/" return ORIGIN + url; } // Assuming the URL is a slug or path return ORIGIN + '/' + url; } // Load JSON data from file fetch('data3.json') .then(response => response.json()) .then(data => { const nodes = data.map(item => { const imageName = item.image ? item.image.split('/').pop() : ''; const img = `imgs/circle/${imageName || 'placeholder.png'}`; return { id: item.id, img: img, title: item.title, slug: item.slug, hyperfy_portals: item.hyperfy_portals || [] }; }); const links = []; nodes.forEach(node => { node.hyperfy_portals.forEach(portal => { if (typeof portal.url === 'string') { const targetUrl = urlToAbsolute(portal.url); const targetNode = nodes.find(n => n.hyperfy_portals.some(p => urlToAbsolute(p.url) === targetUrl)); if (targetNode) { links.push({ source: node.id, target: targetNode.id }); } } }); }); const gData = { nodes, links }; const Graph = ForceGraph3D({ controlType: 'fly' }) (document.getElementById('3d-graph')) .nodeThreeObject(({ img }) => { const imgTexture = new THREE.TextureLoader().load(img); imgTexture.colorSpace = THREE.SRGBColorSpace; const material = new THREE.SpriteMaterial({ map: imgTexture }); const sprite = new THREE.Sprite(material); sprite.scale.set(12, 12); return sprite; }) .nodeLabel(({ title, slug }) => `Name: ${title || 'N/A'} Slug: ${slug}`) .onNodeHover(node => { if (!node) { document.body.style.cursor = 'default'; } else { document.body.style.cursor = 'pointer'; } }) .linkWidth(1) // Adjust the line thickness here .graphData(gData); const bloomPass = new UnrealBloomPass(); bloomPass.strength = 1.2; bloomPass.radius = 1; bloomPass.threshold = 0.1; Graph.postProcessingComposer().addPass(bloomPass); }) .catch(error => { console.error('Error loading data:', error); }); </script> </body> </html> ``` ---