three.ws

@three-ws/viewer-presets

Tuned light rig, floor reflection, and bloom presets for three.ws avatar viewers - visage-derived, framework-agnostic.

npm downloads license node

Install · Usage · Presets · API · three.ws


@three-ws/viewer-presets is a small, data-first package of visual presets for 3D avatar viewers: a five-light rig, floor-reflection parameters, and a bloom configuration. The tuning values are derived from Ready Player Me's open-source visage viewer (MIT) and re-tuned for three.ws, so avatars render color-accurate to that reference setup. It's framework-agnostic: presets are plain frozen objects, and the one factory (buildLightRig) takes your THREE namespace as an argument instead of importing Three.js itself.

Install

npm install @three-ws/viewer-presets

three (>=0.150.0) is an optional peer dependency - only buildLightRig() touches it, and you pass your own THREE namespace in. The preset constants and the floorReflectionConfig / bloomConfig helpers are pure data and need nothing.

Usage

import * as THREE from 'three';
import { buildLightRig, floorReflectionConfig, bloomConfig } from '@three-ws/viewer-presets';

// 1. Build the five-light avatar rig as a THREE.Group and add it to your scene.
const { group, headTarget, shoeTarget } = buildLightRig(THREE);
scene.add(group);

// 2. Floor reflection config - `color` must match your canvas background.
const floor = floorReflectionConfig({ color: '#0b0b12' });
// feed `floor` into MeshReflectorMaterial (or your own reflector)

// 3. Bloom config - feed into the `postprocessing` Bloom effect (or equivalent).
const bloom = bloomConfig({ intensity: 0.15 });

You can also import each preset from its own subpath:

import { LIGHT_CONFIG, buildLightRig } from '@three-ws/viewer-presets/lights';
import { FLOOR_REFLECTION_DEFAULTS, floorReflectionConfig } from '@three-ws/viewer-presets/floor';
import { BLOOM_DEFAULTS, bloomConfig } from '@three-ws/viewer-presets/bloom';

Presets

Light rig (./lights)

buildLightRig(THREE, overrides?) returns a THREE.Group containing five spotlights - fill (blue rim), back (warm rim), key (soft face fill), lift (body/shoe wash), and silhouette (arms/legs) - plus a head target and shoe target the lights aim at. Positions, angles, intensities, and colors come from LIGHT_CONFIG; overrides patches the defaults block (e.g. keyLightIntensity, fillLightColor, backLightPosition, lightTarget).

Floor reflection (./floor)

FLOOR_REFLECTION_DEFAULTS holds reflector parameters (resolution, mixBlur, mixStrength, blur, mirror, depth thresholds, planeSize, fog range, …) using the same names as visage's FloorReflection component. floorReflectionConfig(props) merges your overrides; color is required and should match the canvas background so the plane fades in seamlessly.

Bloom (./bloom)

BLOOM_DEFAULTS is a verbatim-tuned bloom config (luminanceThreshold, luminanceSmoothing, mipmapBlur, intensity, kernelSize). bloomConfig(overrides?) merges your changes over it.

Materials (./materials)

Where the rig above tunes how a scene is lit, this module tunes how a model's surfaces read. MATERIAL_PRESETS is a curated set of physically-plausible looks - chrome, gold, copper, brushedSteel, gunmetal, matte, glossy, rubber, ceramic, glass, realGlass, wood, stone, fabric, skin, carPaint, neon, holographic - each a frozen parameter set.

Most presets are plain MeshStandardMaterial fields (color, metalness, roughness, emissive, envMapIntensity, transparency for the legacy glass). A few use measured, physically-real MeshPhysicalMaterial-only fields - applyMaterialPreset writes these when the target material has the field and silently skips them on a plain Standard material:

Preset Physical fields Real-world basis
skin sheen, sheenColor, sheenRoughness, specularIntensity roughness 0.45 - 0.6 (measured bare-skin range), 0 metalness, sheen approximates subsurface scattering, specular F0 below the 0.04 default (skin reflects ~2.8%)
carPaint clearcoat, clearcoatRoughness KHR_materials_clearcoat - a near-mirror lacquer layer over a metallic base coat
realGlass transmission, thickness, ior, attenuationColor, attenuationDistance KHR_materials_transmission - real refraction, not alpha blending; ior: 1.45 is soda-lime glass
brushedSteel anisotropy, anisotropyRotation KHR_materials_anisotropy - directional micro-groove scattering from brushing
fabric sheen, sheenColor, sheenRoughness soft grazing-angle highlight woven cloth shows

realGlass and glass are deliberately both kept: glass is the cheap opacity-blend look (works on any renderer, any material type); realGlass needs a MeshPhysicalMaterial and the renderer's transmission pass but actually refracts what's behind it.

import { applyMaterialPreset, materialVariants } from '@three-ws/viewer-presets/materials';

// Re-skin every standard material on a loaded glTF, non-destructively:
const handle = applyMaterialPreset(THREE, gltf.scene, 'chrome');
// … later, put it back exactly as it was:
handle.restore();

// Fan a base look out into reproducible colorway variants (same seed → same set):
const variants = materialVariants('gold', { seed: 42, count: 6 });
variants.forEach((v) => console.log(v.label, v.config.color));

applyMaterialPreset only touches materials that expose the standard PBR knobs (a MeshBasicMaterial, sprite, or line material is skipped), captures the prior values, and hands back a restore() - so edits are a reversible layer over the original asset. materialVariants is pure and deterministic per seed, aligning with Forge's seed semantics so a variant set is shareable by number.

API

Export Signature
buildLightRig(THREE, overrides?) (THREE, Partial<LightingOverrides>) => { group, headTarget, shoeTarget }
LIGHT_CONFIG Frozen LightConfig (angles, positions, and a defaults overrides block).
floorReflectionConfig(props) (Partial<FloorReflectionProps> & { color }) => FloorReflectionProps; throws if color is missing.
FLOOR_REFLECTION_DEFAULTS Frozen floor-reflection defaults (no color).
bloomConfig(overrides?) (Partial<BloomProps>) => BloomProps
BLOOM_DEFAULTS Frozen bloom defaults.
MATERIAL_PRESETS / MATERIAL_PRESET_NAMES Frozen map of PBR presets, and their ids in order.
materialPreset(idOrConfig, overrides?) (string | Partial<MaterialPreset>, overrides?) => MaterialPreset; throws on unknown id.
applyMaterialPreset(THREE, root, idOrConfig, opts?) (THREE, Object3D, preset) => { restore(), count } - non-destructive.
materialVariants(base, opts?) (preset, { seed, count, hueSpread, jitter }) => MaterialVariant[] - seeded, reproducible.

Requirements

Attribution

Preset values are derived from Ready Player Me's visage viewer (MIT) and re-tuned for three.ws. See NOTICE for details. This package is distributed under the Apache-2.0 license; see LICENSE.

Related packages

Links


Part of the three.ws SDK suite - 3D AI agents, on-chain identity, and agent payments.
Website · Changelog · GitHub


Part of three.ws, the open-source platform for 3D AI agents. This repository is exported from the monorepo, which is the source of truth: open issues here, and send larger changes there.