@certe/atmos-renderer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +674 -0
- package/README.md +166 -0
- package/dist/bloom-pass.d.ts +29 -0
- package/dist/bloom-pass.d.ts.map +1 -0
- package/dist/bloom-pass.js +173 -0
- package/dist/bloom-pass.js.map +1 -0
- package/dist/bloom-shader.d.ts +9 -0
- package/dist/bloom-shader.d.ts.map +1 -0
- package/dist/bloom-shader.js +69 -0
- package/dist/bloom-shader.js.map +1 -0
- package/dist/bounds.d.ts +10 -0
- package/dist/bounds.d.ts.map +1 -0
- package/dist/bounds.js +37 -0
- package/dist/bounds.js.map +1 -0
- package/dist/camera.d.ts +31 -0
- package/dist/camera.d.ts.map +1 -0
- package/dist/camera.js +53 -0
- package/dist/camera.js.map +1 -0
- package/dist/depth-prepass.d.ts +24 -0
- package/dist/depth-prepass.d.ts.map +1 -0
- package/dist/depth-prepass.js +107 -0
- package/dist/depth-prepass.js.map +1 -0
- package/dist/directional-light.d.ts +23 -0
- package/dist/directional-light.d.ts.map +1 -0
- package/dist/directional-light.js +36 -0
- package/dist/directional-light.js.map +1 -0
- package/dist/frustum.d.ts +15 -0
- package/dist/frustum.d.ts.map +1 -0
- package/dist/frustum.js +51 -0
- package/dist/frustum.js.map +1 -0
- package/dist/fullscreen-quad.d.ts +8 -0
- package/dist/fullscreen-quad.d.ts.map +1 -0
- package/dist/fullscreen-quad.js +30 -0
- package/dist/fullscreen-quad.js.map +1 -0
- package/dist/geometry.d.ts +28 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +245 -0
- package/dist/geometry.js.map +1 -0
- package/dist/grid-renderer.d.ts +10 -0
- package/dist/grid-renderer.d.ts.map +1 -0
- package/dist/grid-renderer.js +77 -0
- package/dist/grid-renderer.js.map +1 -0
- package/dist/grid-shader.d.ts +3 -0
- package/dist/grid-shader.d.ts.map +1 -0
- package/dist/grid-shader.js +89 -0
- package/dist/grid-shader.js.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/light.d.ts +59 -0
- package/dist/light.d.ts.map +1 -0
- package/dist/light.js +184 -0
- package/dist/light.js.map +1 -0
- package/dist/material-asset.d.ts +19 -0
- package/dist/material-asset.d.ts.map +1 -0
- package/dist/material-asset.js +30 -0
- package/dist/material-asset.js.map +1 -0
- package/dist/material.d.ts +50 -0
- package/dist/material.d.ts.map +1 -0
- package/dist/material.js +48 -0
- package/dist/material.js.map +1 -0
- package/dist/mesh-renderer.d.ts +43 -0
- package/dist/mesh-renderer.d.ts.map +1 -0
- package/dist/mesh-renderer.js +162 -0
- package/dist/mesh-renderer.js.map +1 -0
- package/dist/mesh.d.ts +16 -0
- package/dist/mesh.d.ts.map +1 -0
- package/dist/mesh.js +33 -0
- package/dist/mesh.js.map +1 -0
- package/dist/mipmap-generator.d.ts +7 -0
- package/dist/mipmap-generator.d.ts.map +1 -0
- package/dist/mipmap-generator.js +96 -0
- package/dist/mipmap-generator.js.map +1 -0
- package/dist/pbr-wgsl.d.ts +12 -0
- package/dist/pbr-wgsl.d.ts.map +1 -0
- package/dist/pbr-wgsl.js +159 -0
- package/dist/pbr-wgsl.js.map +1 -0
- package/dist/pipeline.d.ts +13 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +77 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/point-light.d.ts +16 -0
- package/dist/point-light.d.ts.map +1 -0
- package/dist/point-light.js +22 -0
- package/dist/point-light.js.map +1 -0
- package/dist/point-shadow-pass.d.ts +24 -0
- package/dist/point-shadow-pass.d.ts.map +1 -0
- package/dist/point-shadow-pass.js +192 -0
- package/dist/point-shadow-pass.js.map +1 -0
- package/dist/point-shadow-shader.d.ts +12 -0
- package/dist/point-shadow-shader.d.ts.map +1 -0
- package/dist/point-shadow-shader.js +52 -0
- package/dist/point-shadow-shader.js.map +1 -0
- package/dist/register-builtins.d.ts +2 -0
- package/dist/register-builtins.d.ts.map +1 -0
- package/dist/register-builtins.js +98 -0
- package/dist/register-builtins.js.map +1 -0
- package/dist/render-system.d.ts +99 -0
- package/dist/render-system.d.ts.map +1 -0
- package/dist/render-system.js +476 -0
- package/dist/render-system.js.map +1 -0
- package/dist/scene-depth.d.ts +36 -0
- package/dist/scene-depth.d.ts.map +1 -0
- package/dist/scene-depth.js +183 -0
- package/dist/scene-depth.js.map +1 -0
- package/dist/shader.d.ts +3 -0
- package/dist/shader.d.ts.map +1 -0
- package/dist/shader.js +144 -0
- package/dist/shader.js.map +1 -0
- package/dist/shadow-fragment-wgsl.d.ts +13 -0
- package/dist/shadow-fragment-wgsl.d.ts.map +1 -0
- package/dist/shadow-fragment-wgsl.js +205 -0
- package/dist/shadow-fragment-wgsl.js.map +1 -0
- package/dist/shadow-manager.d.ts +46 -0
- package/dist/shadow-manager.d.ts.map +1 -0
- package/dist/shadow-manager.js +259 -0
- package/dist/shadow-manager.js.map +1 -0
- package/dist/shadow-pass.d.ts +31 -0
- package/dist/shadow-pass.d.ts.map +1 -0
- package/dist/shadow-pass.js +135 -0
- package/dist/shadow-pass.js.map +1 -0
- package/dist/shadow-shader.d.ts +10 -0
- package/dist/shadow-shader.d.ts.map +1 -0
- package/dist/shadow-shader.js +24 -0
- package/dist/shadow-shader.js.map +1 -0
- package/dist/shadow-uniforms.d.ts +38 -0
- package/dist/shadow-uniforms.d.ts.map +1 -0
- package/dist/shadow-uniforms.js +97 -0
- package/dist/shadow-uniforms.js.map +1 -0
- package/dist/skinned-geometry.d.ts +14 -0
- package/dist/skinned-geometry.d.ts.map +1 -0
- package/dist/skinned-geometry.js +23 -0
- package/dist/skinned-geometry.js.map +1 -0
- package/dist/skinned-mesh-renderer.d.ts +54 -0
- package/dist/skinned-mesh-renderer.d.ts.map +1 -0
- package/dist/skinned-mesh-renderer.js +177 -0
- package/dist/skinned-mesh-renderer.js.map +1 -0
- package/dist/skinned-pipeline.d.ts +16 -0
- package/dist/skinned-pipeline.d.ts.map +1 -0
- package/dist/skinned-pipeline.js +112 -0
- package/dist/skinned-pipeline.js.map +1 -0
- package/dist/skinned-shader.d.ts +7 -0
- package/dist/skinned-shader.d.ts.map +1 -0
- package/dist/skinned-shader.js +52 -0
- package/dist/skinned-shader.js.map +1 -0
- package/dist/skinned-shadow-shader.d.ts +6 -0
- package/dist/skinned-shadow-shader.d.ts.map +1 -0
- package/dist/skinned-shadow-shader.js +31 -0
- package/dist/skinned-shadow-shader.js.map +1 -0
- package/dist/spot-light.d.ts +24 -0
- package/dist/spot-light.d.ts.map +1 -0
- package/dist/spot-light.js +41 -0
- package/dist/spot-light.js.map +1 -0
- package/dist/spot-shadow-pass.d.ts +36 -0
- package/dist/spot-shadow-pass.d.ts.map +1 -0
- package/dist/spot-shadow-pass.js +144 -0
- package/dist/spot-shadow-pass.js.map +1 -0
- package/dist/ssao-pass.d.ts +37 -0
- package/dist/ssao-pass.d.ts.map +1 -0
- package/dist/ssao-pass.js +208 -0
- package/dist/ssao-pass.js.map +1 -0
- package/dist/ssao-shader.d.ts +9 -0
- package/dist/ssao-shader.d.ts.map +1 -0
- package/dist/ssao-shader.js +120 -0
- package/dist/ssao-shader.js.map +1 -0
- package/dist/terrain-mesh-renderer.d.ts +39 -0
- package/dist/terrain-mesh-renderer.d.ts.map +1 -0
- package/dist/terrain-mesh-renderer.js +131 -0
- package/dist/terrain-mesh-renderer.js.map +1 -0
- package/dist/terrain-pipeline.d.ts +17 -0
- package/dist/terrain-pipeline.d.ts.map +1 -0
- package/dist/terrain-pipeline.js +70 -0
- package/dist/terrain-pipeline.js.map +1 -0
- package/dist/terrain-shader.d.ts +10 -0
- package/dist/terrain-shader.d.ts.map +1 -0
- package/dist/terrain-shader.js +154 -0
- package/dist/terrain-shader.js.map +1 -0
- package/dist/texture.d.ts +20 -0
- package/dist/texture.d.ts.map +1 -0
- package/dist/texture.js +87 -0
- package/dist/texture.js.map +1 -0
- package/dist/tonemap-pass.d.ts +22 -0
- package/dist/tonemap-pass.d.ts.map +1 -0
- package/dist/tonemap-pass.js +125 -0
- package/dist/tonemap-pass.js.map +1 -0
- package/dist/unlit-pipeline.d.ts +12 -0
- package/dist/unlit-pipeline.d.ts.map +1 -0
- package/dist/unlit-pipeline.js +59 -0
- package/dist/unlit-pipeline.js.map +1 -0
- package/dist/unlit-shader.d.ts +3 -0
- package/dist/unlit-shader.d.ts.map +1 -0
- package/dist/unlit-shader.js +33 -0
- package/dist/unlit-shader.js.map +1 -0
- package/dist/webgpu-device.d.ts +13 -0
- package/dist/webgpu-device.d.ts.map +1 -0
- package/dist/webgpu-device.js +70 -0
- package/dist/webgpu-device.js.map +1 -0
- package/dist/wireframe-pipeline.d.ts +7 -0
- package/dist/wireframe-pipeline.d.ts.map +1 -0
- package/dist/wireframe-pipeline.js +72 -0
- package/dist/wireframe-pipeline.js.map +1 -0
- package/package.json +28 -0
- package/src/index.ts +87 -0
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# 🎨 @certe/atmos-renderer
|
|
2
|
+
|
|
3
|
+
WebGPU-first rendering package for the Atmos Engine. Handles GPU initialization, PBR shading, multi-light systems, cascaded shadow maps, skeletal animation (GPU skinning), terrain rendering, and a full HDR post-processing pipeline.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔑 Key Features
|
|
8
|
+
|
|
9
|
+
- **PBR Cook-Torrance** shading with albedo, metallic, roughness, normal, and emissive maps
|
|
10
|
+
- **3 light types** — Directional, Point, Spot (up to 4 each)
|
|
11
|
+
- **Cascaded Shadow Maps** (2-cascade CSM) + point cube shadows + spot shadows
|
|
12
|
+
- **HDR pipeline** — MSAA 4× → HDR resolve → Bloom → SSAO → Tonemapping (ACES)
|
|
13
|
+
- **GPU skinning** — separate skinned pipeline with bone matrix storage buffer
|
|
14
|
+
- **Terrain pipeline** — splat-textured terrain with 3-layer blending
|
|
15
|
+
- **Geometry primitives** — cube, sphere, cylinder, plane
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🚀 Quick Start
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { initWebGPU, createRenderPipeline, createMesh, createMaterial,
|
|
23
|
+
RenderSystem, Camera, MeshRenderer, createCubeGeometry } from '@certe/atmos-renderer';
|
|
24
|
+
|
|
25
|
+
const gpu = await initWebGPU(canvas);
|
|
26
|
+
const pipeline = createRenderPipeline(gpu);
|
|
27
|
+
|
|
28
|
+
// Create a mesh + material
|
|
29
|
+
const mesh = createMesh(gpu.device, createCubeGeometry());
|
|
30
|
+
const material = createMaterial(gpu.device, pipeline, {
|
|
31
|
+
albedo: [0.8, 0.2, 0.2, 1],
|
|
32
|
+
metallic: 0.0,
|
|
33
|
+
roughness: 0.5,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Attach to a GameObject
|
|
37
|
+
const cube = new GameObject('Cube');
|
|
38
|
+
const mr = cube.addComponent(MeshRenderer);
|
|
39
|
+
mr.init({ mesh, material, device: gpu.device, pipelineResources: pipeline });
|
|
40
|
+
|
|
41
|
+
// Render
|
|
42
|
+
const renderSystem = new RenderSystem(gpu, pipeline, scene);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 📖 API Overview
|
|
48
|
+
|
|
49
|
+
### Initialization
|
|
50
|
+
|
|
51
|
+
| Function | Description |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `initWebGPU(canvas)` | Request adapter + device, configure canvas |
|
|
54
|
+
| `resizeGPU(gpu)` | Sync canvas pixel size, recreate depth/MSAA/HDR textures |
|
|
55
|
+
| `createRenderPipeline(gpu)` | Create the PBR render pipeline + bind group layouts |
|
|
56
|
+
|
|
57
|
+
### Geometry & Mesh
|
|
58
|
+
|
|
59
|
+
| Function | Description |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `createCubeGeometry()` | 32B/vertex (pos+normal+uv) |
|
|
62
|
+
| `createSphereGeometry(seg?)` | Latitude-longitude sphere |
|
|
63
|
+
| `createCylinderGeometry(seg?)` | With top/bottom caps |
|
|
64
|
+
| `createPlaneGeometry(size?)` | XZ plane |
|
|
65
|
+
| `createMesh(device, geo)` | Upload to GPU, retains CPU data for picking |
|
|
66
|
+
|
|
67
|
+
### Materials
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const mat = createMaterial(device, pipeline, {
|
|
71
|
+
albedo: [1, 1, 1, 1],
|
|
72
|
+
metallic: 0.5,
|
|
73
|
+
roughness: 0.3,
|
|
74
|
+
emissive: [1, 0.5, 0],
|
|
75
|
+
emissiveIntensity: 2.0,
|
|
76
|
+
});
|
|
77
|
+
// Textures: mat.albedoTexture, mat.normalTexture, mat.metallicRoughnessTexture
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Lights
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// Add as components to GameObjects
|
|
84
|
+
const light = obj.addComponent(DirectionalLight);
|
|
85
|
+
light.color = new Float32Array([1, 1, 1]);
|
|
86
|
+
light.intensity = 1.5;
|
|
87
|
+
light.castShadows = true;
|
|
88
|
+
|
|
89
|
+
obj.addComponent(PointLight); // color, intensity, range
|
|
90
|
+
obj.addComponent(SpotLight); // + innerAngle, outerAngle
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Camera
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const cam = obj.addComponent(Camera);
|
|
97
|
+
cam.fov = 60;
|
|
98
|
+
cam.near = 0.1;
|
|
99
|
+
cam.far = 1000;
|
|
100
|
+
|
|
101
|
+
// Screen-to-world unprojection
|
|
102
|
+
const worldPos = Camera.screenToWorldPoint(sx, sy, depth, camera, canvas);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Post-Processing
|
|
106
|
+
|
|
107
|
+
The RenderSystem exposes controls for the full post-fx chain:
|
|
108
|
+
|
|
109
|
+
| Property | Default | Description |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| `exposure` | `1.0` | Pre-tonemap multiplier |
|
|
112
|
+
| `bloomIntensity` | `0.04` | Bloom strength |
|
|
113
|
+
| `bloomThreshold` | `1.0` | HDR threshold for bloom |
|
|
114
|
+
| `ssaoEnabled` | `false` | Toggle SSAO |
|
|
115
|
+
| `ssaoRadius` / `ssaoBias` / `ssaoIntensity` | — | SSAO tuning |
|
|
116
|
+
| `vignetteIntensity` / `vignetteRadius` | — | Screen-edge darkening |
|
|
117
|
+
|
|
118
|
+
### Render Pipeline Flow
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
Depth Pre-pass
|
|
122
|
+
Shadow Passes (CSM × 2 + Point + Spot)
|
|
123
|
+
Main Pass (MSAA 4× → HDR resolve)
|
|
124
|
+
SSAO (half-res, 16 samples)
|
|
125
|
+
Bloom (5-level downsample/upsample)
|
|
126
|
+
Tonemap (ACES + gamma 2.2 + vignette) → Swapchain
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 📁 Structure
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
packages/renderer/src/
|
|
135
|
+
index.ts # Public API
|
|
136
|
+
pipeline.ts # PBR pipeline, constants (HDR_FORMAT, MSAA_SAMPLE_COUNT)
|
|
137
|
+
shader.ts # PBR WGSL vertex + fragment shaders
|
|
138
|
+
material.ts # Material creation + uniform writes
|
|
139
|
+
camera.ts # Camera component
|
|
140
|
+
render-system.ts # Frame orchestration
|
|
141
|
+
directional-light.ts # DirectionalLight component
|
|
142
|
+
point-light.ts # PointLight component
|
|
143
|
+
spot-light.ts # SpotLight component
|
|
144
|
+
geometry.ts # Primitive factories
|
|
145
|
+
mesh.ts # GPU mesh creation
|
|
146
|
+
mesh-renderer.ts # MeshRenderer component
|
|
147
|
+
skinned-pipeline.ts # GPU skinning pipeline
|
|
148
|
+
skinned-mesh-renderer.ts # SkinnedMeshRenderer component
|
|
149
|
+
bloom-pass.ts # 5-level bloom
|
|
150
|
+
tonemap-pass.ts # ACES tonemapping + vignette
|
|
151
|
+
ssao-pass.ts # Screen-space ambient occlusion
|
|
152
|
+
depth-prepass.ts # Non-MSAA depth for SSAO
|
|
153
|
+
directional-shadow-pass.ts # Cascaded shadow maps
|
|
154
|
+
point-shadow-pass.ts # Cube shadow maps
|
|
155
|
+
spot-shadow-pass.ts # Spot light shadows
|
|
156
|
+
texture.ts # Texture creation + decoding
|
|
157
|
+
mipmap-generator.ts # Blit-based mipmap generation
|
|
158
|
+
grid-renderer.ts # Infinite XZ grid overlay
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 🔗 Dependencies
|
|
164
|
+
|
|
165
|
+
- `@certe/atmos-core` — Component, GameObject, Transform, Scene
|
|
166
|
+
- `@certe/atmos-math` — Vec3, Mat4, Quat for camera/light math
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bloom post-processing pass.
|
|
3
|
+
* Downsample chain: HDR → 1/2 → 1/4 → 1/8 → 1/16 (threshold on first pass).
|
|
4
|
+
* Upsample chain: 1/16 → 1/8 → 1/4 → 1/2 → full (additive blend).
|
|
5
|
+
* Output: full-res bloom texture.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BloomPass {
|
|
8
|
+
threshold: number;
|
|
9
|
+
intensity: number;
|
|
10
|
+
radius: number;
|
|
11
|
+
private readonly _device;
|
|
12
|
+
private readonly _downPipeline;
|
|
13
|
+
private readonly _upPipeline;
|
|
14
|
+
private readonly _sampler;
|
|
15
|
+
private readonly _downBGL;
|
|
16
|
+
private readonly _upBGL;
|
|
17
|
+
private readonly _paramsBuffer;
|
|
18
|
+
private readonly _paramsData;
|
|
19
|
+
private _mipTextures;
|
|
20
|
+
private _mipViews;
|
|
21
|
+
private _width;
|
|
22
|
+
private _height;
|
|
23
|
+
constructor(device: GPUDevice);
|
|
24
|
+
private _ensureMips;
|
|
25
|
+
/** Execute bloom and return the bloom texture view to be composited with HDR scene. */
|
|
26
|
+
execute(encoder: GPUCommandEncoder, hdrTexture: GPUTexture): GPUTextureView;
|
|
27
|
+
destroy(): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=bloom-pass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bloom-pass.d.ts","sourceRoot":"","sources":["../src/bloom-pass.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,qBAAa,SAAS;IACpB,SAAS,SAAO;IAChB,SAAS,SAAO;IAChB,MAAM,SAAO;IAEb,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAY;IAE1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IAEnD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;gBAER,MAAM,EAAE,SAAS;IAyD7B,OAAO,CAAC,WAAW;IAwBnB,uFAAuF;IACvF,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,UAAU,GAAG,cAAc;IA4E3E,OAAO,IAAI,IAAI;CAIhB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bloom post-processing pass.
|
|
3
|
+
* Downsample chain: HDR → 1/2 → 1/4 → 1/8 → 1/16 (threshold on first pass).
|
|
4
|
+
* Upsample chain: 1/16 → 1/8 → 1/4 → 1/2 → full (additive blend).
|
|
5
|
+
* Output: full-res bloom texture.
|
|
6
|
+
*/
|
|
7
|
+
import { BLOOM_DOWNSAMPLE_SHADER, BLOOM_UPSAMPLE_SHADER } from './bloom-shader.js';
|
|
8
|
+
import { drawFullscreenTriangle } from './fullscreen-quad.js';
|
|
9
|
+
const HDR_FORMAT = 'rgba16float';
|
|
10
|
+
const MIP_COUNT = 5;
|
|
11
|
+
export class BloomPass {
|
|
12
|
+
threshold = 1.0;
|
|
13
|
+
intensity = 0.5;
|
|
14
|
+
radius = 0.5;
|
|
15
|
+
_device;
|
|
16
|
+
_downPipeline;
|
|
17
|
+
_upPipeline;
|
|
18
|
+
_sampler;
|
|
19
|
+
_downBGL;
|
|
20
|
+
_upBGL;
|
|
21
|
+
_paramsBuffer;
|
|
22
|
+
_paramsData = new Float32Array(4);
|
|
23
|
+
_mipTextures = [];
|
|
24
|
+
_mipViews = [];
|
|
25
|
+
_width = 0;
|
|
26
|
+
_height = 0;
|
|
27
|
+
constructor(device) {
|
|
28
|
+
this._device = device;
|
|
29
|
+
this._sampler = device.createSampler({
|
|
30
|
+
minFilter: 'linear',
|
|
31
|
+
magFilter: 'linear',
|
|
32
|
+
});
|
|
33
|
+
this._paramsBuffer = device.createBuffer({
|
|
34
|
+
size: 16,
|
|
35
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
36
|
+
});
|
|
37
|
+
// Bind group layouts (identical for both: texture + sampler + params)
|
|
38
|
+
this._downBGL = device.createBindGroupLayout({
|
|
39
|
+
entries: [
|
|
40
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
41
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
|
|
42
|
+
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
this._upBGL = device.createBindGroupLayout({
|
|
46
|
+
entries: [
|
|
47
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
48
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
|
|
49
|
+
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
const downModule = device.createShaderModule({ code: BLOOM_DOWNSAMPLE_SHADER });
|
|
53
|
+
const upModule = device.createShaderModule({ code: BLOOM_UPSAMPLE_SHADER });
|
|
54
|
+
this._downPipeline = device.createRenderPipeline({
|
|
55
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [this._downBGL] }),
|
|
56
|
+
vertex: { module: downModule, entryPoint: 'vs' },
|
|
57
|
+
fragment: { module: downModule, entryPoint: 'fs', targets: [{ format: HDR_FORMAT }] },
|
|
58
|
+
primitive: { topology: 'triangle-list' },
|
|
59
|
+
});
|
|
60
|
+
this._upPipeline = device.createRenderPipeline({
|
|
61
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [this._upBGL] }),
|
|
62
|
+
vertex: { module: upModule, entryPoint: 'vs' },
|
|
63
|
+
fragment: {
|
|
64
|
+
module: upModule,
|
|
65
|
+
entryPoint: 'fs',
|
|
66
|
+
targets: [{
|
|
67
|
+
format: HDR_FORMAT,
|
|
68
|
+
blend: {
|
|
69
|
+
color: { srcFactor: 'one', dstFactor: 'one', operation: 'add' },
|
|
70
|
+
alpha: { srcFactor: 'one', dstFactor: 'one', operation: 'add' },
|
|
71
|
+
},
|
|
72
|
+
}],
|
|
73
|
+
},
|
|
74
|
+
primitive: { topology: 'triangle-list' },
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
_ensureMips(w, h) {
|
|
78
|
+
if (this._width === w && this._height === h)
|
|
79
|
+
return;
|
|
80
|
+
this._width = w;
|
|
81
|
+
this._height = h;
|
|
82
|
+
for (const tex of this._mipTextures)
|
|
83
|
+
tex.destroy();
|
|
84
|
+
this._mipTextures = [];
|
|
85
|
+
this._mipViews = [];
|
|
86
|
+
let mw = Math.max(1, Math.floor(w / 2));
|
|
87
|
+
let mh = Math.max(1, Math.floor(h / 2));
|
|
88
|
+
for (let i = 0; i < MIP_COUNT; i++) {
|
|
89
|
+
const tex = this._device.createTexture({
|
|
90
|
+
size: { width: mw, height: mh },
|
|
91
|
+
format: HDR_FORMAT,
|
|
92
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
93
|
+
});
|
|
94
|
+
this._mipTextures.push(tex);
|
|
95
|
+
this._mipViews.push(tex.createView());
|
|
96
|
+
mw = Math.max(1, Math.floor(mw / 2));
|
|
97
|
+
mh = Math.max(1, Math.floor(mh / 2));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Execute bloom and return the bloom texture view to be composited with HDR scene. */
|
|
101
|
+
execute(encoder, hdrTexture) {
|
|
102
|
+
const w = hdrTexture.width;
|
|
103
|
+
const h = hdrTexture.height;
|
|
104
|
+
this._ensureMips(w, h);
|
|
105
|
+
const hdrView = hdrTexture.createView();
|
|
106
|
+
// --- Downsample chain ---
|
|
107
|
+
for (let i = 0; i < MIP_COUNT; i++) {
|
|
108
|
+
const srcView = i === 0 ? hdrView : this._mipViews[i - 1];
|
|
109
|
+
const isFirst = i === 0 ? 1.0 : 0.0;
|
|
110
|
+
this._paramsData[0] = this.threshold;
|
|
111
|
+
this._paramsData[1] = isFirst;
|
|
112
|
+
this._paramsData[2] = 0;
|
|
113
|
+
this._paramsData[3] = 0;
|
|
114
|
+
this._device.queue.writeBuffer(this._paramsBuffer, 0, this._paramsData);
|
|
115
|
+
const bg = this._device.createBindGroup({
|
|
116
|
+
layout: this._downBGL,
|
|
117
|
+
entries: [
|
|
118
|
+
{ binding: 0, resource: srcView },
|
|
119
|
+
{ binding: 1, resource: this._sampler },
|
|
120
|
+
{ binding: 2, resource: { buffer: this._paramsBuffer } },
|
|
121
|
+
],
|
|
122
|
+
});
|
|
123
|
+
const pass = encoder.beginRenderPass({
|
|
124
|
+
colorAttachments: [{
|
|
125
|
+
view: this._mipViews[i],
|
|
126
|
+
loadOp: 'clear',
|
|
127
|
+
storeOp: 'store',
|
|
128
|
+
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
129
|
+
}],
|
|
130
|
+
});
|
|
131
|
+
pass.setPipeline(this._downPipeline);
|
|
132
|
+
pass.setBindGroup(0, bg);
|
|
133
|
+
drawFullscreenTriangle(pass);
|
|
134
|
+
pass.end();
|
|
135
|
+
}
|
|
136
|
+
// --- Upsample chain (additive blend) ---
|
|
137
|
+
for (let i = MIP_COUNT - 2; i >= 0; i--) {
|
|
138
|
+
const srcView = this._mipViews[i + 1];
|
|
139
|
+
this._paramsData[0] = this.radius;
|
|
140
|
+
this._paramsData[1] = 0;
|
|
141
|
+
this._paramsData[2] = 0;
|
|
142
|
+
this._paramsData[3] = 0;
|
|
143
|
+
this._device.queue.writeBuffer(this._paramsBuffer, 0, this._paramsData);
|
|
144
|
+
const bg = this._device.createBindGroup({
|
|
145
|
+
layout: this._upBGL,
|
|
146
|
+
entries: [
|
|
147
|
+
{ binding: 0, resource: srcView },
|
|
148
|
+
{ binding: 1, resource: this._sampler },
|
|
149
|
+
{ binding: 2, resource: { buffer: this._paramsBuffer } },
|
|
150
|
+
],
|
|
151
|
+
});
|
|
152
|
+
const pass = encoder.beginRenderPass({
|
|
153
|
+
colorAttachments: [{
|
|
154
|
+
view: this._mipViews[i],
|
|
155
|
+
loadOp: 'load',
|
|
156
|
+
storeOp: 'store',
|
|
157
|
+
}],
|
|
158
|
+
});
|
|
159
|
+
pass.setPipeline(this._upPipeline);
|
|
160
|
+
pass.setBindGroup(0, bg);
|
|
161
|
+
drawFullscreenTriangle(pass);
|
|
162
|
+
pass.end();
|
|
163
|
+
}
|
|
164
|
+
// Return the largest bloom mip (half-res)
|
|
165
|
+
return this._mipViews[0];
|
|
166
|
+
}
|
|
167
|
+
destroy() {
|
|
168
|
+
for (const tex of this._mipTextures)
|
|
169
|
+
tex.destroy();
|
|
170
|
+
this._paramsBuffer.destroy();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=bloom-pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bloom-pass.js","sourceRoot":"","sources":["../src/bloom-pass.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WGSL shaders for bloom post-processing.
|
|
3
|
+
* Uses shared fullscreen triangle vertex shader.
|
|
4
|
+
* Downsample applies a bright threshold on the first pass.
|
|
5
|
+
* Upsample blends additively with the previous mip level.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BLOOM_DOWNSAMPLE_SHADER: string;
|
|
8
|
+
export declare const BLOOM_UPSAMPLE_SHADER: string;
|
|
9
|
+
//# sourceMappingURL=bloom-shader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bloom-shader.d.ts","sourceRoot":"","sources":["../src/bloom-shader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,eAAO,MAAM,uBAAuB,QAoCnC,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAuBjC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WGSL shaders for bloom post-processing.
|
|
3
|
+
* Uses shared fullscreen triangle vertex shader.
|
|
4
|
+
* Downsample applies a bright threshold on the first pass.
|
|
5
|
+
* Upsample blends additively with the previous mip level.
|
|
6
|
+
*/
|
|
7
|
+
import { FULLSCREEN_VERTEX_SHADER } from './fullscreen-quad.js';
|
|
8
|
+
export const BLOOM_DOWNSAMPLE_SHADER = FULLSCREEN_VERTEX_SHADER + /* wgsl */ `
|
|
9
|
+
@group(0) @binding(0) var srcTexture: texture_2d<f32>;
|
|
10
|
+
@group(0) @binding(1) var srcSampler: sampler;
|
|
11
|
+
@group(0) @binding(2) var<uniform> params: vec4<f32>; // x=threshold, y=isFirstPass
|
|
12
|
+
|
|
13
|
+
@fragment
|
|
14
|
+
fn fs(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
|
|
15
|
+
let dims = vec2<f32>(textureDimensions(srcTexture, 0));
|
|
16
|
+
let texelSize = 1.0 / dims;
|
|
17
|
+
|
|
18
|
+
// 13-tap downsampling filter (anti-firefly, from Call of Duty presentation)
|
|
19
|
+
var color = textureSample(srcTexture, srcSampler, uv) * 0.125;
|
|
20
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-1.0, -1.0) * texelSize) * 0.03125;
|
|
21
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 1.0, -1.0) * texelSize) * 0.03125;
|
|
22
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-1.0, 1.0) * texelSize) * 0.03125;
|
|
23
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 1.0, 1.0) * texelSize) * 0.03125;
|
|
24
|
+
|
|
25
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-2.0, 0.0) * texelSize) * 0.0625;
|
|
26
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 2.0, 0.0) * texelSize) * 0.0625;
|
|
27
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 0.0, -2.0) * texelSize) * 0.0625;
|
|
28
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 0.0, 2.0) * texelSize) * 0.0625;
|
|
29
|
+
|
|
30
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-2.0, -2.0) * texelSize) * 0.03125;
|
|
31
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 2.0, -2.0) * texelSize) * 0.03125;
|
|
32
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-2.0, 2.0) * texelSize) * 0.03125;
|
|
33
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 2.0, 2.0) * texelSize) * 0.03125;
|
|
34
|
+
|
|
35
|
+
// Apply threshold on first pass only
|
|
36
|
+
if (params.y > 0.5) {
|
|
37
|
+
let brightness = max(color.r, max(color.g, color.b));
|
|
38
|
+
let contribution = max(brightness - params.x, 0.0) / max(brightness, 0.0001);
|
|
39
|
+
color = vec4(color.rgb * contribution, color.a);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return color;
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
export const BLOOM_UPSAMPLE_SHADER = FULLSCREEN_VERTEX_SHADER + /* wgsl */ `
|
|
46
|
+
@group(0) @binding(0) var srcTexture: texture_2d<f32>;
|
|
47
|
+
@group(0) @binding(1) var srcSampler: sampler;
|
|
48
|
+
@group(0) @binding(2) var<uniform> params: vec4<f32>; // x=radius
|
|
49
|
+
|
|
50
|
+
@fragment
|
|
51
|
+
fn fs(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
|
|
52
|
+
let dims = vec2<f32>(textureDimensions(srcTexture, 0));
|
|
53
|
+
let texelSize = params.x / dims;
|
|
54
|
+
|
|
55
|
+
// 9-tap tent filter for smooth upsampling
|
|
56
|
+
var color = textureSample(srcTexture, srcSampler, uv + vec2(-1.0, -1.0) * texelSize);
|
|
57
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 0.0, -1.0) * texelSize) * 2.0;
|
|
58
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 1.0, -1.0) * texelSize);
|
|
59
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-1.0, 0.0) * texelSize) * 2.0;
|
|
60
|
+
color += textureSample(srcTexture, srcSampler, uv) * 4.0;
|
|
61
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 1.0, 0.0) * texelSize) * 2.0;
|
|
62
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2(-1.0, 1.0) * texelSize);
|
|
63
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 0.0, 1.0) * texelSize) * 2.0;
|
|
64
|
+
color += textureSample(srcTexture, srcSampler, uv + vec2( 1.0, 1.0) * texelSize);
|
|
65
|
+
|
|
66
|
+
return color / 16.0;
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
//# sourceMappingURL=bloom-shader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bloom-shader.js","sourceRoot":"","sources":["../src/bloom-shader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,CAAC,MAAM,uBAAuB,GAAG,wBAAwB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoC3E,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,wBAAwB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;CAuBzE,CAAC"}
|
package/dist/bounds.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface BoundingSphere {
|
|
2
|
+
center: Float32Array;
|
|
3
|
+
radius: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Compute a bounding sphere from interleaved vertex data.
|
|
7
|
+
* Reads position from the first 3 floats of each vertex.
|
|
8
|
+
*/
|
|
9
|
+
export declare function computeBoundingSphere(vertices: Float32Array, stride: number): BoundingSphere;
|
|
10
|
+
//# sourceMappingURL=bounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounds.d.ts","sourceRoot":"","sources":["../src/bounds.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,GACb,cAAc,CAiChB"}
|
package/dist/bounds.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute a bounding sphere from interleaved vertex data.
|
|
3
|
+
* Reads position from the first 3 floats of each vertex.
|
|
4
|
+
*/
|
|
5
|
+
export function computeBoundingSphere(vertices, stride) {
|
|
6
|
+
const vertCount = Math.floor(vertices.length / stride);
|
|
7
|
+
if (vertCount === 0) {
|
|
8
|
+
return { center: new Float32Array(3), radius: 0 };
|
|
9
|
+
}
|
|
10
|
+
// Compute centroid
|
|
11
|
+
let cx = 0, cy = 0, cz = 0;
|
|
12
|
+
for (let i = 0; i < vertCount; i++) {
|
|
13
|
+
const o = i * stride;
|
|
14
|
+
cx += vertices[o];
|
|
15
|
+
cy += vertices[o + 1];
|
|
16
|
+
cz += vertices[o + 2];
|
|
17
|
+
}
|
|
18
|
+
cx /= vertCount;
|
|
19
|
+
cy /= vertCount;
|
|
20
|
+
cz /= vertCount;
|
|
21
|
+
// Find max distance from centroid
|
|
22
|
+
let maxDist2 = 0;
|
|
23
|
+
for (let i = 0; i < vertCount; i++) {
|
|
24
|
+
const o = i * stride;
|
|
25
|
+
const dx = vertices[o] - cx;
|
|
26
|
+
const dy = vertices[o + 1] - cy;
|
|
27
|
+
const dz = vertices[o + 2] - cz;
|
|
28
|
+
const dist2 = dx * dx + dy * dy + dz * dz;
|
|
29
|
+
if (dist2 > maxDist2)
|
|
30
|
+
maxDist2 = dist2;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
center: new Float32Array([cx, cy, cz]),
|
|
34
|
+
radius: Math.sqrt(maxDist2),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=bounds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounds.js","sourceRoot":"","sources":["../src/bounds.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAsB,EACtB,MAAc;IAEd,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACvD,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACpD,CAAC;IAED,mBAAmB;IACnB,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACrB,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAE,CAAC;QACnB,EAAE,IAAI,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;QACvB,EAAE,IAAI,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;IACzB,CAAC;IACD,EAAE,IAAI,SAAS,CAAC;IAChB,EAAE,IAAI,SAAS,CAAC;IAChB,EAAE,IAAI,SAAS,CAAC;IAEhB,kCAAkC;IAClC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACrB,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QAC1C,IAAI,KAAK,GAAG,QAAQ;YAAE,QAAQ,GAAG,KAAK,CAAC;IACzC,CAAC;IAED,OAAO;QACL,MAAM,EAAE,IAAI,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACtC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;KAC5B,CAAC;AACJ,CAAC"}
|
package/dist/camera.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Component, Scene } from '@certe/atmos-core';
|
|
2
|
+
import type { Mat4Type } from '@certe/atmos-math';
|
|
3
|
+
/** Loose interface to avoid circular import with RenderSystem. */
|
|
4
|
+
export interface ScreenToWorldProvider {
|
|
5
|
+
screenToWorldPoint(x: number, y: number, nearClip?: number): Promise<Float32Array | null>;
|
|
6
|
+
}
|
|
7
|
+
export declare class Camera extends Component {
|
|
8
|
+
fovY: number;
|
|
9
|
+
near: number;
|
|
10
|
+
far: number;
|
|
11
|
+
isMainCamera: boolean;
|
|
12
|
+
clearColor: Float32Array<ArrayBuffer>;
|
|
13
|
+
/** Set by RenderSystem when it activates a camera. */
|
|
14
|
+
static _renderSystem: ScreenToWorldProvider | null;
|
|
15
|
+
private readonly _viewMatrix;
|
|
16
|
+
get viewMatrix(): Mat4Type;
|
|
17
|
+
/** Compute view matrix as inverse of the camera's world transform. */
|
|
18
|
+
updateViewMatrix(): void;
|
|
19
|
+
/** Extract world-space position from the worldMatrix translation column. */
|
|
20
|
+
getWorldPosition(out: Float32Array): Float32Array;
|
|
21
|
+
/**
|
|
22
|
+
* Convert screen pixel coordinates to a world-space point using GPU depth readback.
|
|
23
|
+
* Returns null if the pixel is sky (depth >= 1.0) or closer than nearClip.
|
|
24
|
+
*/
|
|
25
|
+
screenToWorldPoint(x: number, y: number, nearClip?: number): Promise<Float32Array | null>;
|
|
26
|
+
/** Shortcut: get the main camera from the currently active scene. */
|
|
27
|
+
static get main(): Camera | null;
|
|
28
|
+
/** Find the first enabled Camera with isMainCamera=true in the scene. */
|
|
29
|
+
static getMain(scene: Scene): Camera | null;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=camera.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,kEAAkE;AAClE,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CAC3F;AAED,qBAAa,MAAO,SAAQ,SAAS;IACnC,IAAI,SAAe;IACnB,IAAI,SAAO;IACX,GAAG,SAAO;IACV,YAAY,UAAS;IACrB,UAAU,4BAA4C;IAEtD,sDAAsD;IACtD,MAAM,CAAC,aAAa,EAAE,qBAAqB,GAAG,IAAI,CAAQ;IAE1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IAEvD,IAAI,UAAU,IAAI,QAAQ,CAEzB;IAED,sEAAsE;IACtE,gBAAgB,IAAI,IAAI;IAIxB,4EAA4E;IAC5E,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY;IAQjD;;;OAGG;IACG,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAK/F,qEAAqE;IACrE,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,CAG/B;IAED,yEAAyE;IACzE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI;CAS5C"}
|
package/dist/camera.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Component, Scene } from '@certe/atmos-core';
|
|
2
|
+
import { Mat4 } from '@certe/atmos-math';
|
|
3
|
+
export class Camera extends Component {
|
|
4
|
+
fovY = Math.PI / 4;
|
|
5
|
+
near = 0.1;
|
|
6
|
+
far = 100;
|
|
7
|
+
isMainCamera = false;
|
|
8
|
+
clearColor = new Float32Array([0.05, 0.05, 0.1, 1.0]);
|
|
9
|
+
/** Set by RenderSystem when it activates a camera. */
|
|
10
|
+
static _renderSystem = null;
|
|
11
|
+
_viewMatrix = Mat4.create();
|
|
12
|
+
get viewMatrix() {
|
|
13
|
+
return this._viewMatrix;
|
|
14
|
+
}
|
|
15
|
+
/** Compute view matrix as inverse of the camera's world transform. */
|
|
16
|
+
updateViewMatrix() {
|
|
17
|
+
Mat4.invert(this._viewMatrix, this.gameObject.transform.worldMatrix);
|
|
18
|
+
}
|
|
19
|
+
/** Extract world-space position from the worldMatrix translation column. */
|
|
20
|
+
getWorldPosition(out) {
|
|
21
|
+
const m = this.gameObject.transform.worldMatrix;
|
|
22
|
+
out[0] = m[12];
|
|
23
|
+
out[1] = m[13];
|
|
24
|
+
out[2] = m[14];
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Convert screen pixel coordinates to a world-space point using GPU depth readback.
|
|
29
|
+
* Returns null if the pixel is sky (depth >= 1.0) or closer than nearClip.
|
|
30
|
+
*/
|
|
31
|
+
async screenToWorldPoint(x, y, nearClip) {
|
|
32
|
+
if (!Camera._renderSystem)
|
|
33
|
+
return null;
|
|
34
|
+
return Camera._renderSystem.screenToWorldPoint(x, y, nearClip);
|
|
35
|
+
}
|
|
36
|
+
/** Shortcut: get the main camera from the currently active scene. */
|
|
37
|
+
static get main() {
|
|
38
|
+
if (!Scene.current)
|
|
39
|
+
return null;
|
|
40
|
+
return Camera.getMain(Scene.current);
|
|
41
|
+
}
|
|
42
|
+
/** Find the first enabled Camera with isMainCamera=true in the scene. */
|
|
43
|
+
static getMain(scene) {
|
|
44
|
+
for (const obj of scene.getAllObjects()) {
|
|
45
|
+
const cam = obj.getComponent(Camera);
|
|
46
|
+
if (cam && cam.enabled && cam.isMainCamera) {
|
|
47
|
+
return cam;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=camera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQzC,MAAM,OAAO,MAAO,SAAQ,SAAS;IACnC,IAAI,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACnB,IAAI,GAAG,GAAG,CAAC;IACX,GAAG,GAAG,GAAG,CAAC;IACV,YAAY,GAAG,KAAK,CAAC;IACrB,UAAU,GAAG,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAEtD,sDAAsD;IACtD,MAAM,CAAC,aAAa,GAAiC,IAAI,CAAC;IAEzC,WAAW,GAAa,IAAI,CAAC,MAAM,EAAE,CAAC;IAEvD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,sEAAsE;IACtE,gBAAgB;QACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC;IAED,4EAA4E;IAC5E,gBAAgB,CAAC,GAAiB;QAChC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC;QAChD,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAE,CAAC;QAChB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAE,CAAC;QAChB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAE,CAAC;QAChB,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB,CAAC,CAAS,EAAE,CAAS,EAAE,QAAiB;QAC9D,IAAI,CAAC,MAAM,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IACjE,CAAC;IAED,qEAAqE;IACrE,MAAM,KAAK,IAAI;QACb,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,yEAAyE;IACzE,MAAM,CAAC,OAAO,CAAC,KAAY;QACzB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrC,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;gBAC3C,OAAO,GAAG,CAAC;YACb,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-MSAA depth pre-pass for screen-space effects (SSAO).
|
|
3
|
+
* Renders scene geometry to a depth32float texture using the camera VP matrix.
|
|
4
|
+
* The resulting texture has TEXTURE_BINDING so it can be sampled in post-processing.
|
|
5
|
+
*/
|
|
6
|
+
import type { Scene } from '@certe/atmos-core';
|
|
7
|
+
import type { Mat4Type } from '@certe/atmos-math';
|
|
8
|
+
export declare class DepthPrepass {
|
|
9
|
+
private readonly _device;
|
|
10
|
+
private readonly _pipeline;
|
|
11
|
+
private readonly _vpBuffer;
|
|
12
|
+
private readonly _vpBindGroup;
|
|
13
|
+
private _depthTexture;
|
|
14
|
+
private _depthView;
|
|
15
|
+
private _width;
|
|
16
|
+
private _height;
|
|
17
|
+
get depthView(): GPUTextureView;
|
|
18
|
+
constructor(device: GPUDevice, objectBindGroupLayout: GPUBindGroupLayout, w: number, h: number);
|
|
19
|
+
private _createTexture;
|
|
20
|
+
resize(w: number, h: number): void;
|
|
21
|
+
execute(encoder: GPUCommandEncoder, scene: Scene, cameraVP: Mat4Type, extraDraw?: (pass: GPURenderPassEncoder) => void): void;
|
|
22
|
+
destroy(): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=depth-prepass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"depth-prepass.d.ts","sourceRoot":"","sources":["../src/depth-prepass.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAKlD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;IAEpB,IAAI,SAAS,IAAI,cAAc,CAA4B;gBAE/C,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAgD9F,OAAO,CAAC,cAAc;IAQtB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IASlC,OAAO,CACL,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAC5D,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,GAC/C,IAAI;IAgCP,OAAO,IAAI,IAAI;CAIhB"}
|