Image to Three.js Model
img2threejs/img2threejs
Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.
Put weather into a Three.js scene that reads as weather — rain anchored inside the frustum, a storm that is the rain leaned on rather than a second system, lightning on its own light with thunder…
$ npx skills add nirholas/three.ws --skill threejs-weather -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install nirholas/three.ws threejs-weather --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/nirholas/three.ws.git skills-src && mkdir -p .claude/skills && cp -r skills-src/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather .claude/skills/threejs-weather && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "threejs-weather" agent skill from https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather into .claude/skills/threejs-weather/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "threejs-weather", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weatherType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add nirholas/three.ws --skill threejs-weather -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install nirholas/three.ws threejs-weather --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/nirholas/three.ws.git skills-src && mkdir -p .agents/skills && cp -r skills-src/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather .agents/skills/threejs-weather && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "threejs-weather" agent skill from https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather into .agents/skills/threejs-weather/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "threejs-weather", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add nirholas/three.ws --skill threejs-weather -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install nirholas/three.ws threejs-weather --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/nirholas/three.ws.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather .cursor/skills/threejs-weather && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "threejs-weather" agent skill from https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather into .cursor/skills/threejs-weather/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "threejs-weather", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/nirholas/three.ws.git --path third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add nirholas/three.ws --skill threejs-weather -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install nirholas/three.ws threejs-weather --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/nirholas/three.ws.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather .gemini/skills/threejs-weather && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "threejs-weather" agent skill from https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather into .gemini/skills/threejs-weather/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "threejs-weather", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install nirholas/three.ws threejs-weatherInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add nirholas/three.ws --skill threejs-weather -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/nirholas/three.ws.git skills-src && mkdir -p .github/skills && cp -r skills-src/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather .github/skills/threejs-weather && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "threejs-weather" agent skill from https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather into .github/skills/threejs-weather/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "threejs-weather", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add nirholas/three.ws --skill threejs-weather -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install nirholas/three.ws threejs-weather --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/nirholas/three.ws.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather .opencode/skills/threejs-weather && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "threejs-weather" agent skill from https://github.com/nirholas/three.ws/tree/main/third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather into .opencode/skills/threejs-weather/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "threejs-weather", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
threejs-weatherPut weather into a Three.js scene that reads as weather — rain anchored inside the frustum, a storm that is the rain leaned on rather than a second system, lightning on its own light with thunder…
Threejs Weather is an agent skill from nirholas/three.ws. Put weather into a Three.js scene that reads as weather — rain anchored inside the frustum, a storm that is the rain leaned on rather than a second system, lightning on its own light with thunder scheduled by distance, snow that blows up into blizzards and keeps settling until the ground goes white, wet ground with puddles and splashes, and looping ambience that has no seam. Use for scene atmosphere, seasonal states, hero backdrops, or any world where clear/rain/storm/snow needs to be a control the viewer can turn.
Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files (for example `agents/openai.yaml`, `demo/PROMPT.md` and `demo/assets/three.min.js`).
It sits in Game Development, covering 3D graphics and WebGL. It works with Three.js. The repository describes itself as: Open-source platform for 3D AI agents. Turn text or a photo into a rigged, animated GLB avatar, give it an LLM brain, memory and a wallet, and embed it anywhere with one web… The licence is Apache-2.0.
Read from SKILL.md and the folder at commit ddf6e49. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (JavaScript), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Threejs Weather loads about 2k tokens when it runs. Until then it costs about 134 tokens; SKILL.md has 912 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from nirholas/three.ws at commit ddf6e49, republished under its Apache-2.0 licence (© nirholas). 912 words, ~1,976 tokens.
.claude/skills/threejs-weather/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.Weather fails in two ways: the particles miss the camera entirely, or every state is a separate system that shares nothing. Both are avoidable.
Pairs with threejs-landscape for the ground it falls on, and threejs-towers for something to fall against.
The first version of any rain system puts a world-sized box of particles around the origin and looks empty. With a long lens the camera sees a narrow cone, so almost every drop is off-camera.
Build a small volume and carry it in front of the camera, facing the way the camera faces:
const WX_W = 17, WX_D = 50, WX_TOP = 40; // narrow, deep, tall
function anchor(o) {
const fx = -Math.sin(camAz), fz = -Math.cos(camAz);
o.position.set(cam.position.x + fx * 46, 0, cam.position.z + fz * 46);
o.rotation.y = camAz;
}Set frustumCulled = false on it — you are moving it every frame and the bounding sphere will fight you.
This one costs an afternoon. The attribute takes a copy of whatever you hand it, so the array you kept a reference to is not the one the GPU reads:
const attr = new THREE.Float32BufferAttribute(pos, 3);
attr.setUsage(THREE.DynamicDrawUsage);
geo.setAttribute('position', attr);
return { pts, pos: attr.array, n }; // keep the attribute's arraySymptom: everything is correct, nothing moves, no error anywhere.
Allocate the worst case once — a full storm, a full blizzard — and thin it by drawing less:
RAIN.geo.setDrawRange(0, Math.round(RAIN.n * density));A storm then costs no more memory than drizzle; it just stops hiding most of the drops. Reallocating buffers when weather changes causes a hitch exactly when the viewer is watching.
Do not write a second particle system. Take the rain state and push every dial:
| rain | storm | |
|---|---|---|
| drops drawn | 60% of pool | 100% |
| fall speed | ×1.0 | ×1.42 |
| slant | 2.4 | scales with speed² |
| sun | 30% | 14% |
| fog far | ×0.52 | ×0.38 |
Slant should grow faster than speed — slant = base * v * v — because that is what sells wind rather than "rain, but quicker".
Do not modify the time-of-day state to flash. Add a light nobody else touches, so a strike can flash over whatever the sky happens to be doing:
const bolt = new THREE.DirectionalLight(0xe8eeff, 0);One strike is several flashes — a leader and two or three return strokes — each an exponential decay:
function strike() {
const near = Math.random(); // 0 distant … 1 close
const s = 0.42 + near * 0.58;
pulses = [{ t: 0, a: s }];
let tt = 0;
for (let i = 0, n = 1 + (Math.random() * 2.6 | 0); i < n; i++) {
tt += 0.05 + Math.random() * 0.14;
pulses.push({ t: tt, a: s * (0.30 + Math.random() * 0.65) });
}
setTimeout(() => sfx(near > 0.5 ? 'thunder_near' : 'thunder_far',
{ gain: 0.30 + near * 0.60 }),
(0.32 + (1 - near) * 2.7) * 1000); // sound arrives late
}
function step(dt) {
let v = 0;
for (const p of pulses) if (age >= p.t) v += p.a * Math.exp(-(age - p.t) / 0.085);
bolt.intensity = v * 3.2;
skyMat.color.setScalar(1 + v * 0.80); // multiplies the sky map
flashEl.style.opacity = (v * 0.15).toFixed(3);
}Two details do most of the work. Thunder is delayed by distance and quieter the longer it takes — that single correlation is what makes a strike feel far away. And the DOM flash belongs under the type, not over it: a full-screen white overlay above your typography washes the page out, so put it directly above the canvas and keep it under about 0.18 opacity.
Reposition the light on every strike. A flash that always comes from the same side stops reading after the second one.
Snow does not fall at one rate forever. Run a cycle — calm, build, blow, ease — and modulate the snow state with it:
const BLIZ = [12, 6, 15, 8]; // seconds
function blizzardAt(t) {
let u = t % TOTAL; if (u < 0) u += TOTAL;
if (u < BLIZ[0]) return 0;
... // smoothstep in, hold, out
}During the blow, open the flake pool, thicken the flakes, drive them sideways and pull the fog in. Reset the phase clock to zero when you leave the snow state, or arriving in snow drops you into the middle of a whiteout — a negative start offset wraps into the wrong phase and looks like a bug you cannot find.
The one people forget. Track what has already landed on its own slow timer, rising while snow falls and melting back when the weather turns:
snowPack += (target - snowPack) * (target > snowPack ? dt / 24 : dt / 13);Then let it keep whitening the ground, the stones and the grass for as long as it falls. Arriving in snow and standing in it for a minute should not look the same.
If the surface colour is mixed inside a shader — instanced grass usually is — the material colour cannot reach it. Give that mix its own uniform, and let snow lie on the tips first and work down:
gBase = mix(gBase, vec3(0.60, 0.65, 0.72), uSnow * 0.86);
gTip = mix(gTip, vec3(0.90, 0.94, 1.00), uSnow);Relighting the scene is not free, and blizzard strength and snow depth drift continuously. Gate it:
const look = blizK + snowPack;
if (Math.abs(look - lastLook) > 0.006) { lastLook = look; refreshLook(); }That fires a few times a second instead of sixty, and nothing on screen can tell.
Three cheap things, in order of payoff: drop roughness and add a little metalness so the ground catches the sky; add flat translucent puddle decals in the hollows; then instance a splash ring sprite with a short life, spawned in proportion to rain intensity. The splashes are what make it read as falling rain rather than a rain texture.
Generated audio never loops cleanly. Fold the tail back over the head with an equal-power cross-fade and throw the overlap away — the clip then ends where it starts:
for i in range(f):
t = i / f
out[i] = a[i] * sin(t * pi / 2) + a[n - f + i] * cos(t * pi / 2)Fading the clip in and out instead means it dips to silence every lap, which everyone hears and nobody mentions.
Give weather its own gain bus, separate from music, and run the blizzard as a second layer swelling over the base bed rather than a cross-fade to a different clip — a hard swap in the middle of a storm is obvious.
© nirholas, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 5 other files in third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather of nirholas/three.ws.
Open the folder on GitHubat commit ddf6e49
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in nirholas/three.ws, which our catalogue first saw on October 7, 2026.
Threejs Weather next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Threejs Weather this skillnirholas/three.ws | 227 | 1 repos | ~2k | Automated safety check: Pass | Apache-2.0 | |
| Image to Three.js Modelimg2threejs/img2threejs | 18k | 1 repos | ~8.2k | Automated safety check: Pass | Apache-2.0 | |
| Web CloneJane-xiaoer/claude-skill-web-clone | 1k | 2 repos | ~2.7k | Automated safety check: Pass | MIT | |
| Threejs Game Directormajidmanzarpour/threejs-game-skills | 2.4k | — | ~2.2k | Automated safety check: Pass | MIT | |
| Threejs Gameplay Systemsvalkor-ai/loom | 1.2k | 1 repos | ~1.4k | Automated safety check: Pass | Apache-2.0 | |
| Threejs World Generationcalesthio/OpenMontage | 65k | — | ~2k | Automated safety check: Pass | AGPL-3.0 |
img2threejs/img2threejs
Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.
Jane-xiaoer/claude-skill-web-clone
网站复刻 / 克隆方法论。USE WHEN 用户说 复刻网站、克隆网站、clone website、抄个站、仿站、 照着这个站做一个、reproduce site、还原某个网页效果、把这个站搬下来改成我的、 复刻某个交互/WebGL/Canvas/Three.js 效果。提供「先拿真源码 → 判路径 → 逆向拆解 → 搭工程 → 替换内容」的可移植决策树,覆盖静态站 /…
majidmanzarpour/threejs-game-skills
Entrypoint for building, upgrading, and finishing Three.js browser games.
valkor-ai/loom
Build and iterate playable Three.js game systems: starter scaffold, architecture, design briefs, core loops, level and encounter design, entities, input, camera, collision and physics, scoring…
calesthio/OpenMontage
Build deterministic, editable, free-viewpoint Three.js worlds from text or structured briefs.
viettranx/3dviz-pro-max
Guides building an expressive 3D scene in Three.js or Blender by reasoning through intent, object construction and scientific grounding before using a catalog of recipes and kits.
nirholas/three.ws
Add the Shaders WebGPU mouse effect used for the Tidal Commons hero: a white twinkling halftone cursor trail driven by ChromaFlow, masked through a DotGrid, finished with chromatic ripples and film…
nirholas/three.ws
Package a finished local project into an intentional GitHub repository, create a strong README and visual preview, push it safely, configure a public GitHub Pages URL when the project is compatible…
nirholas/three.ws
Audit a website or digital experience against its supplied source references for originality and plagiarism risk.
nirholas/three.ws
Turn a completed daily UI inspiration capture into exactly five original landing-page builds, one per separate Codex task, using Sites.
nirholas/three.ws
Write, rewrite, review, or continuously refine X/Twitter posts in Meng To's current voice using his deduplicated authored-post corpus, personal and product context, shared resources, and Content…
nirholas/three.ws
Create polished 60 fps 4:3 4K browser screen-recording style videos from Codex in-app browser captures, with browser-only crop, natural macOS cursor styling, deliberate click choreography…
Works with
Categories
Put weather into a Three.js scene that reads as weather — rain anchored inside the frustum, a storm that is the rain leaned on rather than a second system, lightning on its own light with thunder…. ws.js scene that reads as weather — rain anchored inside the frustum, a storm that is the rain leaned on rather than a second system, lightning on its own light with thunder scheduled by distance, snow that blows up into blizzards and keeps settling until the ground goes white, wet ground with puddles and splashes, and looping ambience that has no seam.
Threejs Weather fits situations like: scene atmosphere; seasonal states; any world where clear/rain/storm/snow needs to be a control the viewer can turn.
Run `npx skills add nirholas/three.ws --skill threejs-weather -a claude-code`. Or copy the skill folder (third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather in nirholas/three.ws) into .claude/skills/threejs-weather in your project. Claude Code loads it when a task matches its description.
Run `npx skills add nirholas/three.ws --skill threejs-weather -a codex`. Or copy the skill folder (third_party/designcode-agent-skills/agent-skills/web-design/threejs-weather in nirholas/three.ws) into .agents/skills/threejs-weather in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add nirholas/three.ws --skill threejs-weather -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/threejs-weather, .gemini/skills/threejs-weather, .github/skills/threejs-weather and .opencode/skills/threejs-weather in your project.
Going by SKILL.md and its folder, Threejs Weather needs JavaScript for the scripts in its folder. Our summary lists: Python 3; Node.js.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Threejs Weather is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2k tokens (SKILL.md is roughly 7.9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Threejs Weather: Image to Three.js Model (img2threejs/img2threejs, 18k stars), Web Clone (Jane-xiaoer/claude-skill-web-clone, 1k stars), Threejs Game Director (majidmanzarpour/threejs-game-skills, 2.4k stars) and Threejs Gameplay Systems (valkor-ai/loom, 1.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
nirholas (a GitHub user) maintains it in nirholas/three.ws, which has 227 GitHub stars. The repository holds 92 skills in this directory. The repository was last updated on October 8, 2026.
Source: nirholas/three.ws on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.