Initial commit: Unity Needle AR Menu project with MenuScene and SampleScene web apps
Add root .gitignore for Unity Library/Temp/Logs, IDE folders, and node_modules. Include Assets, Needle TypeScript (MenuController, asset picker, WebXR), and project configuration. Made-with: Cursor
This commit is contained in:
111
.agents/skills/needle-engine/references/postprocessing.md
Normal file
111
.agents/skills/needle-engine/references/postprocessing.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Needle Engine — Post-Processing Reference
|
||||
|
||||
Needle Engine uses the [pmndrs postprocessing](https://github.com/pmndrs/postprocessing) library. Postprocessing loads asynchronously via `NEEDLE_ENGINE_MODULES.POSTPROCESSING` (same pattern as physics). Add and remove effects via `this.context.postprocessing`.
|
||||
|
||||
## API (`this.context.postprocessing`)
|
||||
```ts
|
||||
import { BloomEffect } from "@needle-tools/engine";
|
||||
|
||||
// Add/remove effects
|
||||
const bloom = new BloomEffect();
|
||||
bloom.intensity.value = 3;
|
||||
bloom.threshold.value = 0.5;
|
||||
this.context.postprocessing.addEffect(bloom);
|
||||
this.context.postprocessing.removeEffect(bloom);
|
||||
|
||||
// Other API
|
||||
this.context.postprocessing.markDirty(); // force rebuild next frame
|
||||
this.context.postprocessing.effects; // readonly array of active effects
|
||||
this.context.postprocessing.multisampling = "auto"; // "auto" or number (0 to max)
|
||||
this.context.postprocessing.adaptiveResolution = true; // reduce DPR when FPS drops
|
||||
```
|
||||
|
||||
## Built-in effects
|
||||
|
||||
All imported from `@needle-tools/engine`. Properties use `VolumeParameter` — set values with `.value`:
|
||||
|
||||
```ts
|
||||
// Bloom — glow on bright areas
|
||||
const bloom = new BloomEffect();
|
||||
bloom.threshold.value = 0.9; // brightness cutoff (default: 0.9)
|
||||
bloom.intensity.value = 1; // glow strength (default: 1)
|
||||
bloom.scatter.value = 0.7; // spread (default: 0.7)
|
||||
|
||||
// Depth of Field — focus blur
|
||||
import { DepthOfField, DepthOfFieldMode } from "@needle-tools/engine";
|
||||
const dof = new DepthOfField();
|
||||
dof.mode = DepthOfFieldMode.Bokeh; // Off, Gaussian, or Bokeh
|
||||
dof.focusDistance.value = 1; // focus distance
|
||||
dof.focalLength.value = 0.2; // focus range
|
||||
dof.aperture.value = 20; // bokeh scale
|
||||
|
||||
// Vignette — darkened edges
|
||||
const vig = new Vignette();
|
||||
vig.intensity.value = 0.5; // darkness (default: 0)
|
||||
vig.color.value = { r: 0, g: 0, b: 0, a: 1 };
|
||||
|
||||
// Color Adjustments — exposure, contrast, hue, saturation
|
||||
const ca = new ColorAdjustments();
|
||||
ca.postExposure.value = 1; // exposure (default: 1)
|
||||
ca.contrast.value = 0; // -1 to 1
|
||||
ca.hueShift.value = 0; // hue rotation
|
||||
ca.saturation.value = 0; // saturation adjustment
|
||||
|
||||
// Tonemapping
|
||||
const tm = new ToneMappingEffect();
|
||||
tm.setMode("AgX"); // ACES, AgX, Neutral, etc.
|
||||
tm.exposure.value = 1;
|
||||
|
||||
// Chromatic Aberration — color fringing
|
||||
const chr = new ChromaticAberration();
|
||||
chr.intensity.value = 0.5;
|
||||
|
||||
// Pixelation
|
||||
const pix = new PixelationEffect();
|
||||
pix.granularity.value = 10; // pixel size
|
||||
|
||||
// SSAO — ambient occlusion
|
||||
const ssao = new ScreenSpaceAmbientOcclusion();
|
||||
ssao.intensity.value = 2;
|
||||
ssao.samples.value = 9; // quality vs performance
|
||||
ssao.falloff.value = 1;
|
||||
ssao.color.value = new Color(0, 0, 0);
|
||||
|
||||
// N8AO — alternative AO (higher quality)
|
||||
import { ScreenSpaceAmbientOcclusionN8, ScreenSpaceAmbientOcclusionN8QualityMode } from "@needle-tools/engine";
|
||||
const n8ao = new ScreenSpaceAmbientOcclusionN8();
|
||||
n8ao.aoRadius.value = 1; // world-space radius
|
||||
n8ao.intensity.value = 1;
|
||||
n8ao.quality = ScreenSpaceAmbientOcclusionN8QualityMode.Medium;
|
||||
|
||||
// Antialiasing (SMAA)
|
||||
const aa = new Antialiasing();
|
||||
aa.preset.value = 2; // 0=Low, 1=Medium, 2=High, 3=Ultra
|
||||
|
||||
// Tilt Shift — miniature/diorama look
|
||||
const ts = new TiltShiftEffect();
|
||||
ts.focusArea.value = 0.4; // in-focus band size
|
||||
ts.feather.value = 0.3; // blur transition
|
||||
ts.offset.value = 0; // vertical offset
|
||||
ts.rotation.value = 0; // angle
|
||||
|
||||
// Sharpening
|
||||
const sharp = new SharpeningEffect();
|
||||
sharp.amount = 1; // strength (direct property, not VolumeParameter)
|
||||
sharp.radius = 1; // radius
|
||||
```
|
||||
|
||||
## Runtime parameter changes
|
||||
```ts
|
||||
// VolumeParameter values update the underlying shader uniforms immediately
|
||||
bloom.intensity.value = 5; // takes effect next frame, no rebuild needed
|
||||
|
||||
// Enable/disable individual effects
|
||||
bloom.enabled = false; // removes from pipeline
|
||||
```
|
||||
|
||||
## Notes
|
||||
- Post-processing is disabled during XR sessions.
|
||||
- Multisampling auto-adjusts: disabled when SMAA is present, scales down on low FPS, scales up when stable.
|
||||
- Effects are automatically ordered (Bloom before Vignette before ToneMapping, etc.). Custom effects can set `order` to control placement.
|
||||
- Alpha is preserved through the pipeline.
|
||||
Reference in New Issue
Block a user