Chisle
The coding-agent plugin that bills 52% of a bare model across 20 live tasks. Terse persona + tool-output compressor + context diet.
翻訳待ち
Oxygen is a high-performance TypeScript WebGL engine built on three.js. HDR rendering, GPGPU curl particles, closed-form springs, post-processing, and interactive scroll stories.
翻訳待ち
開発ツールTypeScript · HTMLGitHub @Tunakite03オンライン所有者未確認
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
A WebGL engine on three.js for creative websites: render pipeline, post-processing, GPU particles, physics, page transitions and adaptive quality.
翻訳待ち
Loading the full README.
Read the full README ↗@tunakite03/oxygen is a WebGL engine for creative, award-style sites on three.js. It started as the scroll-story engine of
a site rebuild and grew into a toolkit: a frame loop with ordered phases, tweens, asset loading with GPU warm-up, a
named GLSL library, a render pipeline, scroll stories, a post-processing stack, GPU particles, physics, a router with
page transitions, adaptive quality, pointer input, Web Audio and a debug panel.
It is a clean-room implementation. It contains no code, shaders or assets from any third-party framework or site; projects supply their own content on top of it.
Version 0.3.0-beta.1 is a beta release. Oxygen is available under the MIT License. See the integration and migration guide for ownership, SSR imports, accessibility, GLB/glTF, CI and release requirements. Generate the API with npm run build:docs; the embedded-scene demo covers mount/unmount and fallback behavior.
Rigid-body physics is now imported from @tunakite03/oxygen/physics; other utilities remain in the root entry.
After the package is published to npm, install it and its required peers with:
npm install @tunakite03/oxygen three zod
npm install @dimforge/rapier3d-compat # only for PhysicsWorld (rigid bodies)
The release workflow publishes the beta to npm's latest tag, so an unqualified install selects a prerelease version after publication.
Peer dependencies: three (~0.186.1), zod (4.x) and, optionally, @dimforge/rapier3d-compat (~0.21.0), which is
imported on demand by PhysicsWorld.create. three's basis_transcoder files are needed for KTX2 and Google's Draco
decoder (draco_wasm_wrapper.js, draco_decoder.wasm) for .bin geometry.
Until the package is published, depend on the repository pinned to a commit. npm clones it, installs its dev
dependencies and runs the prepare script, which builds dist/:
"dependencies": { "@tunakite03/oxygen": "git+https://github.com/Tunakite03/Oxygen.git#<commit>" }
For engine work against a site, npm link a local checkout, or alias @tunakite03/oxygen to src/index.ts in your bundler.
A scene with post-processing and adaptive quality:
import * as THREE from 'three';
import {
BloomPass, ColorGradePass, PostStack, QualityManager, createPipeline, detectGPU, onFrame, onResize,
setRenderFunction, stage, startLoop,
} from '@tunakite03/oxygen';
startLoop();
const pipeline = createPipeline(document.querySelector<HTMLElement>('.stage')!, { hdr: true });
const camera = new THREE.PerspectiveCamera(45, stage.width / stage.height, 0.1, 100);
camera.position.z = 5;
onResize(() => {
camera.aspect = stage.width / stage.height;
camera.updateProjectionMatrix();
});
const post = new PostStack(pipeline.renderer);
post.add(new BloomPass({ threshold: 0.9 }));
post.add(new ColorGradePass({ toneMapping: 'aces', outputSRGB: true }));
pipeline.setPost(post);
const quality = new QualityManager({
levels: [{ name: 'low', dpr: 1 }, { name: 'high', dpr: 2 }],
initial: { tier: detectGPU(pipeline.renderer.getContext()).tier },
});
quality.bindPipeline(pipeline);
quality.start();
const mesh = new THREE.Mesh(new THREE.TorusKnotGeometry(1, 0.3, 200, 24), new THREE.MeshStandardMaterial({ emissive: 0x3d7bff, emissiveIntensity: 4 }));
pipeline.scene.add(mesh, new THREE.HemisphereLight(0xffffff, 0x222222, 1));
onFrame((_t, delta) => (mesh.rotation.y += delta * 0.0005));
await pipeline.warmUp(camera);
setRenderFunction(() => pipeline.render(camera));
A scroll story (stacked scenes driven by a virtual scroll, with DOM sections):
import * as THREE from 'three';
import {
ScrollStory, StoryScene, createLoadProgress, createPipeline, createShaderMaterial, emit, initTextures,
loadShaderLibrary, pendingTextureLoads, setRenderFunction, startLoop,
} from '@tunakite03/oxygen';
class IntroScene extends StoryScene {
constructor() {
super('IntroScene', 0); // DOM section class "IntroUI", CSS order 0
}
protected override async create(): Promise<void> {
const material = createShaderMaterial('Gradient', { uAlpha: { value: 0 } }, { transparent: true });
this.add(new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material));
}
override animateIn(): void {
// Runs when the section scrolls into view.
}
}
async function boot(): Promise<void> {
const container = document.querySelector<HTMLElement>('.Container')!;
const root = document.querySelector<HTMLDivElement>('.Story')!;
startLoop();
const progress = createLoadProgress({ shaders: 0.2, scenes: 0.8 }, (v) => console.log('loading', v));
await loadShaderLibrary('shaders/library.glsl');
progress.report('shaders', 1, 1);
const pipeline = createPipeline(container, { clearColor: '#111111' });
initTextures(pipeline.renderer, { ktx2TranscoderPath: 'lib/basis/' });
const story = new ScrollStory(pipeline, root);
await story.load([{ scene: new IntroScene(), height: 2, mobileHeight: 1.5 }], (n, total) => progress.report('scenes', n, total));
await story.start();
await pendingTextureLoads();
await pipeline.warmUp(story.camera.camera); // compile every program and upload every texture before first scroll
setRenderFunction(() => pipeline.render(story.camera.camera));
emit('Global/loaderFinished'); // unlocks scrolling 1.5 s later
}
void boot();
The page needs a positioned container for the canvas and a story root whose children are the scenes' DOM sections:
<div class="Container"><div class="Story"></div></div>
npm run dev serves the website from website/. The homepage links to documentation, API reference and the examples gallery. npm run build:website builds the standalone site into website/dist/; npm run preview:website previews it. Live demos include:
This is the beginning of the README. Read the rest at the original. Read the full README ↗