by adom
0402 SMD Red LED · 2.1 V drop · 25 mA max
← Commit history
Match Colby's viewer ground and sky exactly (per his current native /viewer/3d build): the sky is the 3d-viewer-design steel-blue (clearColor #2a3340, environmentIntensity 1.0, no skybox mesh) and the ground is his soft radial-fade circle (256px groundFadeTex, alpha 0.2 ALPHABLEND, PBR baseColor 0.15) instead of our opaque grey rectangle. Updates the characterization-page hero viewer and the README embed.
2 files changed
+78
IN-S42ATR-viewer.html+39@@ -101,6 +101,44 @@ const scene = viewer.getScene(); scene.animationGroups.slice().forEach(g => g.dispose()); // we drive our own motion + // Match Colby's CURRENT viewer EXACTLY (native /viewer/3d/, build ?v=20260717e). The shipped bundle+ // is older and differs two ways, both verified live against his native scene:+ // SKY — ships a flat grey (clearColor + skybox primaryColor 0.75, environmentIntensity 1.5) plus a+ // BackgroundSkybox mesh. His current build has NO skybox mesh: just clearColor = SKILL_BG_BOTTOM+ // (#2a3340) + environmentIntensity 1.0 + the studio env for PBR reflections.+ // GROUND — ships an opaque square shadowGround (the "grey rectangle"). His is the same square GroundMesh+ // + PBR groundMat (baseColor 0.15) but with a 256px radial-fade baseTexture + alpha 0.2+ // (ALPHABLEND), so it reads as a soft CIRCLE. We rebuild that fade texture here.+ const bgBot = new B.Color3(0.165, 0.200, 0.251); // SKILL_BG_BOTTOM = #2a3340+ const Color4 = scene.clearColor && scene.clearColor.constructor; // Color4 isn't on the bundle's B — harvest it+ let _groundFade = null;+ const groundFadeTex = () => { // his radial fade: opaque centre -> transparent rim+ if (_groundFade) return _groundFade;+ const t = new B.DynamicTexture('groundFadeTex', 256, scene, true);+ const c = t.getContext();+ const g = c.createRadialGradient(128,128,6, 128,128,128);+ g.addColorStop(0.0, 'rgba(255,255,255,1)');+ g.addColorStop(0.55,'rgba(255,255,255,0.6)');+ g.addColorStop(1.0, 'rgba(255,255,255,0)');+ c.fillStyle = g; c.fillRect(0,0,256,256); t.update(); t.hasAlpha = true;+ _groundFade = t; return t;+ };+ const matchColby = () => { // idempotent; also called after each re-frame+ if (Color4) scene.clearColor = new Color4(bgBot.r, bgBot.g, bgBot.b, 1);+ scene.environmentIntensity = 1.0;+ scene.meshes.filter(m => /^Background/.test(m.name)).forEach(m => m.setEnabled(false)); // no skybox, like his native+ const gnd = scene.getMeshByName('shadowGround');+ if (gnd && gnd.material) {+ const m = gnd.material;+ if (!(m.baseTexture && m.baseTexture.name === 'groundFadeTex')) {+ if ('baseTexture' in m) m.baseTexture = groundFadeTex();+ m.alpha = 0.2; m.transparencyMode = 2; m.backFaceCulling = false; // his soft ALPHABLEND circle+ }+ gnd.receiveShadows = true;+ }+ };+ matchColby();+ const led = scene.getNodeByName('IN-S42ATR'); if (led) led.rotationQuaternion = null; // glTF sets a quaternion that would ignore rotation.z — use Euler const ledLit = scene.getNodeByName('LED_lit');@@ -330,6 +368,7 @@ c.alpha = 1.05; c.beta = 1.0; if (mode === 'pnp') { c.target.copyFromFloats(0.003, 0, 0.0006); c.radius = 0.026; } else { c.target.copyFromFloats(0, 0, -0.0002); c.radius = 0.0065; }+ matchColby(); // frameModel may rebuild the ground/skybox — re-apply his ground fade + no-skybox } // 6) Mode switching — ghosts are a content root only in P&P (so Static frames just the part).
README.html+39@@ -135,6 +135,44 @@ const scene = viewer.getScene(); scene.animationGroups.slice().forEach(g => g.dispose()); // we drive our own motion + // Match Colby's CURRENT viewer EXACTLY (native /viewer/3d/, build ?v=20260717e). The shipped bundle+ // is older and differs two ways, both verified live against his native scene:+ // SKY — ships a flat grey (clearColor + skybox primaryColor 0.75, environmentIntensity 1.5) plus a+ // BackgroundSkybox mesh. His current build has NO skybox mesh: just clearColor = SKILL_BG_BOTTOM+ // (#2a3340) + environmentIntensity 1.0 + the studio env for PBR reflections.+ // GROUND — ships an opaque square shadowGround (the "grey rectangle"). His is the same square GroundMesh+ // + PBR groundMat (baseColor 0.15) but with a 256px radial-fade baseTexture + alpha 0.2+ // (ALPHABLEND), so it reads as a soft CIRCLE. We rebuild that fade texture here.+ const bgBot = new B.Color3(0.165, 0.200, 0.251); // SKILL_BG_BOTTOM = #2a3340+ const Color4 = scene.clearColor && scene.clearColor.constructor; // Color4 isn't on the bundle's B — harvest it+ let _groundFade = null;+ const groundFadeTex = () => { // his radial fade: opaque centre -> transparent rim+ if (_groundFade) return _groundFade;+ const t = new B.DynamicTexture('groundFadeTex', 256, scene, true);+ const c = t.getContext();+ const g = c.createRadialGradient(128,128,6, 128,128,128);+ g.addColorStop(0.0, 'rgba(255,255,255,1)');+ g.addColorStop(0.55,'rgba(255,255,255,0.6)');+ g.addColorStop(1.0, 'rgba(255,255,255,0)');+ c.fillStyle = g; c.fillRect(0,0,256,256); t.update(); t.hasAlpha = true;+ _groundFade = t; return t;+ };+ const matchColby = () => { // idempotent; also called after each re-frame+ if (Color4) scene.clearColor = new Color4(bgBot.r, bgBot.g, bgBot.b, 1);+ scene.environmentIntensity = 1.0;+ scene.meshes.filter(m => /^Background/.test(m.name)).forEach(m => m.setEnabled(false)); // no skybox, like his native+ const gnd = scene.getMeshByName('shadowGround');+ if (gnd && gnd.material) {+ const m = gnd.material;+ if (!(m.baseTexture && m.baseTexture.name === 'groundFadeTex')) {+ if ('baseTexture' in m) m.baseTexture = groundFadeTex();+ m.alpha = 0.2; m.transparencyMode = 2; m.backFaceCulling = false; // his soft ALPHABLEND circle+ }+ gnd.receiveShadows = true;+ }+ };+ matchColby();+ const led = scene.getNodeByName('IN-S42ATR'); if (led) led.rotationQuaternion = null; // glTF sets a quaternion that would ignore rotation.z — use Euler const ledLit = scene.getNodeByName('LED_lit');@@ -364,6 +402,7 @@ c.alpha = 1.05; c.beta = 1.0; if (mode === 'pnp') { c.target.copyFromFloats(0.003, 0, 0.0006); c.radius = 0.026; } else { c.target.copyFromFloats(0, 0, -0.0002); c.radius = 0.0065; }+ matchColby(); // frameModel may rebuild the ground/skybox — re-apply his ground fade + no-skybox } // 6) Mode switching — ghosts are a content root only in P&P (so Static frames just the part).