@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
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tonemapping post-process pass.
|
|
3
|
+
* Reads HDR scene + bloom + SSAO textures. Applies:
|
|
4
|
+
* 1. SSAO (multiply AO into scene)
|
|
5
|
+
* 2. Exposure adjustment
|
|
6
|
+
* 3. ACES filmic tonemapping
|
|
7
|
+
* 4. Gamma correction
|
|
8
|
+
* 5. Vignette
|
|
9
|
+
* Outputs to the swapchain (rgba8unorm).
|
|
10
|
+
*/
|
|
11
|
+
import { FULLSCREEN_VERTEX_SHADER, drawFullscreenTriangle } from './fullscreen-quad.js';
|
|
12
|
+
const TONEMAP_SHADER = FULLSCREEN_VERTEX_SHADER + /* wgsl */ `
|
|
13
|
+
@group(0) @binding(0) var hdrTexture: texture_2d<f32>;
|
|
14
|
+
@group(0) @binding(1) var bloomTexture: texture_2d<f32>;
|
|
15
|
+
@group(0) @binding(2) var aoTexture: texture_2d<f32>;
|
|
16
|
+
@group(0) @binding(3) var texSampler: sampler;
|
|
17
|
+
@group(0) @binding(4) var<uniform> params: vec4<f32>; // x=bloomIntensity, y=exposure, z=vignetteIntensity, w=vignetteRadius
|
|
18
|
+
|
|
19
|
+
// ACES filmic tonemapping (Narkowicz 2015 fit)
|
|
20
|
+
fn ACESFilmic(x: vec3<f32>) -> vec3<f32> {
|
|
21
|
+
let a = 2.51;
|
|
22
|
+
let b = 0.03;
|
|
23
|
+
let c = 2.43;
|
|
24
|
+
let d = 0.59;
|
|
25
|
+
let e = 0.14;
|
|
26
|
+
return clamp((x * (a * x + b)) / (x * (c * x + d) + e), vec3(0.0), vec3(1.0));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@fragment
|
|
30
|
+
fn fs(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
|
|
31
|
+
let hdr = textureSample(hdrTexture, texSampler, uv).rgb;
|
|
32
|
+
let bloom = textureSample(bloomTexture, texSampler, uv).rgb;
|
|
33
|
+
let ao = textureSample(aoTexture, texSampler, uv).r;
|
|
34
|
+
|
|
35
|
+
// Apply AO + bloom + exposure
|
|
36
|
+
var color = hdr * ao + bloom * params.x;
|
|
37
|
+
color = color * params.y;
|
|
38
|
+
|
|
39
|
+
// Tonemap
|
|
40
|
+
color = ACESFilmic(color);
|
|
41
|
+
|
|
42
|
+
// Gamma correction (linear → sRGB)
|
|
43
|
+
color = pow(color, vec3(1.0 / 2.2));
|
|
44
|
+
|
|
45
|
+
// Vignette
|
|
46
|
+
let vignetteIntensity = params.z;
|
|
47
|
+
if (vignetteIntensity > 0.0) {
|
|
48
|
+
let center = uv - vec2(0.5);
|
|
49
|
+
let dist = length(center);
|
|
50
|
+
let radius = params.w;
|
|
51
|
+
let vignette = smoothstep(radius, radius - 0.35, dist);
|
|
52
|
+
color = color * mix(1.0, vignette, vignetteIntensity);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return vec4(color, 1.0);
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
export class TonemapPass {
|
|
59
|
+
_device;
|
|
60
|
+
_pipeline;
|
|
61
|
+
_bgl;
|
|
62
|
+
_sampler;
|
|
63
|
+
_paramsBuffer;
|
|
64
|
+
_paramsData = new Float32Array(4);
|
|
65
|
+
constructor(device, outputFormat) {
|
|
66
|
+
this._device = device;
|
|
67
|
+
this._sampler = device.createSampler({
|
|
68
|
+
minFilter: 'linear',
|
|
69
|
+
magFilter: 'linear',
|
|
70
|
+
});
|
|
71
|
+
this._paramsBuffer = device.createBuffer({
|
|
72
|
+
size: 16,
|
|
73
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
74
|
+
});
|
|
75
|
+
this._bgl = device.createBindGroupLayout({
|
|
76
|
+
entries: [
|
|
77
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
78
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
79
|
+
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
80
|
+
{ binding: 3, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
|
|
81
|
+
{ binding: 4, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
const module = device.createShaderModule({ code: TONEMAP_SHADER });
|
|
85
|
+
this._pipeline = device.createRenderPipeline({
|
|
86
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [this._bgl] }),
|
|
87
|
+
vertex: { module, entryPoint: 'vs' },
|
|
88
|
+
fragment: { module, entryPoint: 'fs', targets: [{ format: outputFormat }] },
|
|
89
|
+
primitive: { topology: 'triangle-list' },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
execute(encoder, hdrView, bloomView, aoView, outputView, bloomIntensity, exposure, vignetteIntensity, vignetteRadius) {
|
|
93
|
+
this._paramsData[0] = bloomIntensity;
|
|
94
|
+
this._paramsData[1] = exposure;
|
|
95
|
+
this._paramsData[2] = vignetteIntensity;
|
|
96
|
+
this._paramsData[3] = vignetteRadius;
|
|
97
|
+
this._device.queue.writeBuffer(this._paramsBuffer, 0, this._paramsData);
|
|
98
|
+
const bg = this._device.createBindGroup({
|
|
99
|
+
layout: this._bgl,
|
|
100
|
+
entries: [
|
|
101
|
+
{ binding: 0, resource: hdrView },
|
|
102
|
+
{ binding: 1, resource: bloomView },
|
|
103
|
+
{ binding: 2, resource: aoView },
|
|
104
|
+
{ binding: 3, resource: this._sampler },
|
|
105
|
+
{ binding: 4, resource: { buffer: this._paramsBuffer } },
|
|
106
|
+
],
|
|
107
|
+
});
|
|
108
|
+
const pass = encoder.beginRenderPass({
|
|
109
|
+
colorAttachments: [{
|
|
110
|
+
view: outputView,
|
|
111
|
+
loadOp: 'clear',
|
|
112
|
+
storeOp: 'store',
|
|
113
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
114
|
+
}],
|
|
115
|
+
});
|
|
116
|
+
pass.setPipeline(this._pipeline);
|
|
117
|
+
pass.setBindGroup(0, bg);
|
|
118
|
+
drawFullscreenTriangle(pass);
|
|
119
|
+
pass.end();
|
|
120
|
+
}
|
|
121
|
+
destroy() {
|
|
122
|
+
this._paramsBuffer.destroy();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=tonemap-pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonemap-pass.js","sourceRoot":"","sources":["../src/tonemap-pass.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface UnlitPipelineResources {
|
|
2
|
+
pipeline: GPURenderPipeline;
|
|
3
|
+
bindGroupLayout: GPUBindGroupLayout;
|
|
4
|
+
}
|
|
5
|
+
export interface UnlitPipelineOptions {
|
|
6
|
+
depthWrite?: boolean;
|
|
7
|
+
topology?: GPUPrimitiveTopology;
|
|
8
|
+
depthCompare?: GPUCompareFunction;
|
|
9
|
+
blend?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function createUnlitPipeline(device: GPUDevice, _format: GPUTextureFormat, opts?: UnlitPipelineOptions): UnlitPipelineResources;
|
|
12
|
+
//# sourceMappingURL=unlit-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit-pipeline.d.ts","sourceRoot":"","sources":["../src/unlit-pipeline.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,eAAe,EAAE,kBAAkB,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,gBAAgB,EACzB,IAAI,CAAC,EAAE,oBAAoB,GAC1B,sBAAsB,CA6DxB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { UNLIT_VERTEX_SHADER, UNLIT_FRAGMENT_SHADER } from './unlit-shader.js';
|
|
2
|
+
import { MSAA_SAMPLE_COUNT, HDR_FORMAT } from './pipeline.js';
|
|
3
|
+
export function createUnlitPipeline(device, _format, opts) {
|
|
4
|
+
const depthWrite = opts?.depthWrite ?? false;
|
|
5
|
+
const topology = opts?.topology ?? 'triangle-list';
|
|
6
|
+
const depthCompare = opts?.depthCompare ?? 'always';
|
|
7
|
+
const blend = opts?.blend ?? false;
|
|
8
|
+
const bindGroupLayout = device.createBindGroupLayout({
|
|
9
|
+
entries: [
|
|
10
|
+
{
|
|
11
|
+
binding: 0,
|
|
12
|
+
visibility: GPUShaderStage.VERTEX,
|
|
13
|
+
buffer: { type: 'uniform' },
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
});
|
|
17
|
+
const pipelineLayout = device.createPipelineLayout({
|
|
18
|
+
bindGroupLayouts: [bindGroupLayout],
|
|
19
|
+
});
|
|
20
|
+
const vertexModule = device.createShaderModule({ code: UNLIT_VERTEX_SHADER });
|
|
21
|
+
const fragmentModule = device.createShaderModule({ code: UNLIT_FRAGMENT_SHADER });
|
|
22
|
+
const colorTarget = { format: HDR_FORMAT };
|
|
23
|
+
if (blend) {
|
|
24
|
+
colorTarget.blend = {
|
|
25
|
+
color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },
|
|
26
|
+
alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const pipeline = device.createRenderPipeline({
|
|
30
|
+
layout: pipelineLayout,
|
|
31
|
+
vertex: {
|
|
32
|
+
module: vertexModule,
|
|
33
|
+
entryPoint: 'vs',
|
|
34
|
+
buffers: [
|
|
35
|
+
{
|
|
36
|
+
arrayStride: 24, // position(3) + color(3) = 6 floats * 4 bytes
|
|
37
|
+
attributes: [
|
|
38
|
+
{ shaderLocation: 0, offset: 0, format: 'float32x3' },
|
|
39
|
+
{ shaderLocation: 1, offset: 12, format: 'float32x3' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
fragment: {
|
|
45
|
+
module: fragmentModule,
|
|
46
|
+
entryPoint: 'fs',
|
|
47
|
+
targets: [colorTarget],
|
|
48
|
+
},
|
|
49
|
+
multisample: { count: MSAA_SAMPLE_COUNT },
|
|
50
|
+
primitive: { topology },
|
|
51
|
+
depthStencil: {
|
|
52
|
+
format: 'depth24plus',
|
|
53
|
+
depthWriteEnabled: depthWrite,
|
|
54
|
+
depthCompare,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
return { pipeline, bindGroupLayout };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=unlit-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit-pipeline.js","sourceRoot":"","sources":["../src/unlit-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAc9D,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,OAAyB,EACzB,IAA2B;IAE3B,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,eAAe,CAAC;IACnD,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,QAAQ,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC;IAEnC,MAAM,eAAe,GAAG,MAAM,CAAC,qBAAqB,CAAC;QACnD,OAAO,EAAE;YACP;gBACE,OAAO,EAAE,CAAC;gBACV,UAAU,EAAE,cAAc,CAAC,MAAM;gBACjC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;aAC5B;SACF;KACF,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAoB,CAAC;QACjD,gBAAgB,EAAE,CAAC,eAAe,CAAC;KACpC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC9E,MAAM,cAAc,GAAG,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAElF,MAAM,WAAW,GAAwB,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAChE,IAAI,KAAK,EAAE,CAAC;QACV,WAAW,CAAC,KAAK,GAAG;YAClB,KAAK,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,qBAAqB,EAAE,SAAS,EAAE,KAAK,EAAE;YACrF,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,SAAS,EAAE,KAAK,EAAE;SAChF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,oBAAoB,CAAC;QAC3C,MAAM,EAAE,cAAc;QACtB,MAAM,EAAE;YACN,MAAM,EAAE,YAAY;YACpB,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;gBACP;oBACE,WAAW,EAAE,EAAE,EAAE,8CAA8C;oBAC/D,UAAU,EAAE;wBACV,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE;wBACrD,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE;qBACvD;iBACF;aACF;SACF;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,cAAc;YACtB,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,CAAC,WAAW,CAAC;SACvB;QACD,WAAW,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE;QACzC,SAAS,EAAE,EAAE,QAAQ,EAAE;QACvB,YAAY,EAAE;YACZ,MAAM,EAAE,aAAa;YACrB,iBAAiB,EAAE,UAAU;YAC7B,YAAY;SACb;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const UNLIT_VERTEX_SHADER = "\nstruct Uniforms {\n mvp: mat4x4<f32>,\n};\n@group(0) @binding(0) var<uniform> u: Uniforms;\n\nstruct VIn {\n @location(0) position: vec3<f32>,\n @location(1) color: vec3<f32>,\n};\n\nstruct VOut {\n @builtin(position) position: vec4<f32>,\n @location(0) color: vec3<f32>,\n};\n\n@vertex fn vs(input: VIn) -> VOut {\n var out: VOut;\n out.position = u.mvp * vec4<f32>(input.position, 1.0);\n out.color = input.color;\n return out;\n}\n";
|
|
2
|
+
export declare const UNLIT_FRAGMENT_SHADER = "\nstruct FIn {\n @location(0) color: vec3<f32>,\n};\n\n@fragment fn fs(input: FIn) -> @location(0) vec4<f32> {\n return vec4<f32>(input.color, 1.0);\n}\n";
|
|
3
|
+
//# sourceMappingURL=unlit-shader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit-shader.d.ts","sourceRoot":"","sources":["../src/unlit-shader.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,kcAsB/B,CAAC;AAEF,eAAO,MAAM,qBAAqB,gKAQjC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const UNLIT_VERTEX_SHADER = /* wgsl */ `
|
|
2
|
+
struct Uniforms {
|
|
3
|
+
mvp: mat4x4<f32>,
|
|
4
|
+
};
|
|
5
|
+
@group(0) @binding(0) var<uniform> u: Uniforms;
|
|
6
|
+
|
|
7
|
+
struct VIn {
|
|
8
|
+
@location(0) position: vec3<f32>,
|
|
9
|
+
@location(1) color: vec3<f32>,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
struct VOut {
|
|
13
|
+
@builtin(position) position: vec4<f32>,
|
|
14
|
+
@location(0) color: vec3<f32>,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
@vertex fn vs(input: VIn) -> VOut {
|
|
18
|
+
var out: VOut;
|
|
19
|
+
out.position = u.mvp * vec4<f32>(input.position, 1.0);
|
|
20
|
+
out.color = input.color;
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
export const UNLIT_FRAGMENT_SHADER = /* wgsl */ `
|
|
25
|
+
struct FIn {
|
|
26
|
+
@location(0) color: vec3<f32>,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
@fragment fn fs(input: FIn) -> @location(0) vec4<f32> {
|
|
30
|
+
return vec4<f32>(input.color, 1.0);
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
//# sourceMappingURL=unlit-shader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlit-shader.js","sourceRoot":"","sources":["../src/unlit-shader.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsB7C,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAC;;;;;;;;CAQ/C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface GPUContext {
|
|
2
|
+
device: GPUDevice;
|
|
3
|
+
context: GPUCanvasContext;
|
|
4
|
+
format: GPUTextureFormat;
|
|
5
|
+
depthTexture: GPUTexture;
|
|
6
|
+
msaaTexture: GPUTexture;
|
|
7
|
+
hdrTexture: GPUTexture;
|
|
8
|
+
canvas: HTMLCanvasElement;
|
|
9
|
+
}
|
|
10
|
+
/** Resize canvas pixel buffer to match CSS display size. Recreates all render targets. */
|
|
11
|
+
export declare function resizeGPU(gpu: GPUContext): void;
|
|
12
|
+
export declare function initWebGPU(canvas: HTMLCanvasElement): Promise<GPUContext>;
|
|
13
|
+
//# sourceMappingURL=webgpu-device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgpu-device.d.ts","sourceRoot":"","sources":["../src/webgpu-device.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,UAAU,CAAC;IACzB,WAAW,EAAE,UAAU,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAgCD,0FAA0F;AAC1F,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAkB/C;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+B/E"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const HDR_FORMAT = 'rgba16float';
|
|
2
|
+
const SAMPLE_COUNT = 4;
|
|
3
|
+
function createMSAATexture(device, w, h) {
|
|
4
|
+
return device.createTexture({
|
|
5
|
+
size: { width: w, height: h },
|
|
6
|
+
format: HDR_FORMAT,
|
|
7
|
+
sampleCount: SAMPLE_COUNT,
|
|
8
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function createHDRTexture(device, w, h) {
|
|
12
|
+
return device.createTexture({
|
|
13
|
+
size: { width: w, height: h },
|
|
14
|
+
format: HDR_FORMAT,
|
|
15
|
+
sampleCount: 1,
|
|
16
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function createDepthTexture(device, w, h) {
|
|
20
|
+
return device.createTexture({
|
|
21
|
+
size: { width: w, height: h },
|
|
22
|
+
format: 'depth24plus',
|
|
23
|
+
sampleCount: SAMPLE_COUNT,
|
|
24
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Resize canvas pixel buffer to match CSS display size. Recreates all render targets. */
|
|
28
|
+
export function resizeGPU(gpu) {
|
|
29
|
+
const canvas = gpu.canvas;
|
|
30
|
+
const dpr = window.devicePixelRatio || 1;
|
|
31
|
+
const w = Math.max(1, Math.floor(canvas.clientWidth * dpr));
|
|
32
|
+
const h = Math.max(1, Math.floor(canvas.clientHeight * dpr));
|
|
33
|
+
if (canvas.width === w && canvas.height === h)
|
|
34
|
+
return;
|
|
35
|
+
canvas.width = w;
|
|
36
|
+
canvas.height = h;
|
|
37
|
+
gpu.depthTexture.destroy();
|
|
38
|
+
gpu.depthTexture = createDepthTexture(gpu.device, w, h);
|
|
39
|
+
gpu.msaaTexture.destroy();
|
|
40
|
+
gpu.msaaTexture = createMSAATexture(gpu.device, w, h);
|
|
41
|
+
gpu.hdrTexture.destroy();
|
|
42
|
+
gpu.hdrTexture = createHDRTexture(gpu.device, w, h);
|
|
43
|
+
}
|
|
44
|
+
export async function initWebGPU(canvas) {
|
|
45
|
+
if (!navigator.gpu) {
|
|
46
|
+
throw new Error('WebGPU is not supported in this browser');
|
|
47
|
+
}
|
|
48
|
+
const adapter = await navigator.gpu.requestAdapter();
|
|
49
|
+
if (!adapter) {
|
|
50
|
+
throw new Error('Failed to request WebGPU adapter');
|
|
51
|
+
}
|
|
52
|
+
const device = await adapter.requestDevice();
|
|
53
|
+
const context = canvas.getContext('webgpu');
|
|
54
|
+
if (!context) {
|
|
55
|
+
throw new Error('Failed to get WebGPU canvas context');
|
|
56
|
+
}
|
|
57
|
+
const format = navigator.gpu.getPreferredCanvasFormat();
|
|
58
|
+
context.configure({
|
|
59
|
+
device,
|
|
60
|
+
format,
|
|
61
|
+
alphaMode: 'premultiplied',
|
|
62
|
+
});
|
|
63
|
+
const w = canvas.width;
|
|
64
|
+
const h = canvas.height;
|
|
65
|
+
const depthTexture = createDepthTexture(device, w, h);
|
|
66
|
+
const msaaTexture = createMSAATexture(device, w, h);
|
|
67
|
+
const hdrTexture = createHDRTexture(device, w, h);
|
|
68
|
+
return { device, context, format, depthTexture, msaaTexture, hdrTexture, canvas };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=webgpu-device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgpu-device.js","sourceRoot":"","sources":["../src/webgpu-device.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface WireframePipelineResources {
|
|
2
|
+
pipeline: GPURenderPipeline;
|
|
3
|
+
objectBindGroupLayout: GPUBindGroupLayout;
|
|
4
|
+
colorBindGroupLayout: GPUBindGroupLayout;
|
|
5
|
+
}
|
|
6
|
+
export declare function createWireframePipeline(device: GPUDevice): WireframePipelineResources;
|
|
7
|
+
//# sourceMappingURL=wireframe-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wireframe-pipeline.d.ts","sourceRoot":"","sources":["../src/wireframe-pipeline.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qBAAqB,EAAE,kBAAkB,CAAC;IAC1C,oBAAoB,EAAE,kBAAkB,CAAC;CAC1C;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,GAChB,0BAA0B,CAkD5B"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { VERTEX_STRIDE_BYTES } from './geometry.js';
|
|
2
|
+
import { MSAA_SAMPLE_COUNT, HDR_FORMAT } from './pipeline.js';
|
|
3
|
+
const WIREFRAME_SHADER = /* wgsl */ `
|
|
4
|
+
struct Uniforms {
|
|
5
|
+
mvp: mat4x4<f32>,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
@group(0) @binding(0) var<uniform> obj: Uniforms;
|
|
9
|
+
|
|
10
|
+
struct ColorUniform {
|
|
11
|
+
color: vec4<f32>,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
@group(1) @binding(0) var<uniform> wireColor: ColorUniform;
|
|
15
|
+
|
|
16
|
+
@vertex
|
|
17
|
+
fn vs(@location(0) position: vec3<f32>) -> @builtin(position) vec4<f32> {
|
|
18
|
+
return obj.mvp * vec4<f32>(position, 1.0);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@fragment
|
|
22
|
+
fn fs() -> @location(0) vec4<f32> {
|
|
23
|
+
return wireColor.color;
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
export function createWireframePipeline(device) {
|
|
27
|
+
const shaderModule = device.createShaderModule({ code: WIREFRAME_SHADER });
|
|
28
|
+
const objectBindGroupLayout = device.createBindGroupLayout({
|
|
29
|
+
entries: [
|
|
30
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
const colorBindGroupLayout = device.createBindGroupLayout({
|
|
34
|
+
entries: [
|
|
35
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
const pipelineLayout = device.createPipelineLayout({
|
|
39
|
+
bindGroupLayouts: [objectBindGroupLayout, colorBindGroupLayout],
|
|
40
|
+
});
|
|
41
|
+
const pipeline = device.createRenderPipeline({
|
|
42
|
+
layout: pipelineLayout,
|
|
43
|
+
vertex: {
|
|
44
|
+
module: shaderModule,
|
|
45
|
+
entryPoint: 'vs',
|
|
46
|
+
buffers: [
|
|
47
|
+
{
|
|
48
|
+
arrayStride: VERTEX_STRIDE_BYTES, // reuse PBR vertex buffer, only read position
|
|
49
|
+
attributes: [
|
|
50
|
+
{ shaderLocation: 0, offset: 0, format: 'float32x3' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
fragment: {
|
|
56
|
+
module: shaderModule,
|
|
57
|
+
entryPoint: 'fs',
|
|
58
|
+
targets: [{ format: HDR_FORMAT }],
|
|
59
|
+
},
|
|
60
|
+
multisample: { count: MSAA_SAMPLE_COUNT },
|
|
61
|
+
primitive: {
|
|
62
|
+
topology: 'line-list',
|
|
63
|
+
},
|
|
64
|
+
depthStencil: {
|
|
65
|
+
format: 'depth24plus',
|
|
66
|
+
depthWriteEnabled: false,
|
|
67
|
+
depthCompare: 'less-equal',
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
return { pipeline, objectBindGroupLayout, colorBindGroupLayout };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=wireframe-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wireframe-pipeline.js","sourceRoot":"","sources":["../src/wireframe-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,gBAAgB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsBnC,CAAC;AAQF,MAAM,UAAU,uBAAuB,CACrC,MAAiB;IAEjB,MAAM,YAAY,GAAG,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAE3E,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,CAAC;QACzD,OAAO,EAAE;YACP,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;SAC/E;KACF,CAAC,CAAC;IAEH,MAAM,oBAAoB,GAAG,MAAM,CAAC,qBAAqB,CAAC;QACxD,OAAO,EAAE;YACP,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;SACjF;KACF,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAoB,CAAC;QACjD,gBAAgB,EAAE,CAAC,qBAAqB,EAAE,oBAAoB,CAAC;KAChE,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,CAAC,oBAAoB,CAAC;QAC3C,MAAM,EAAE,cAAc;QACtB,MAAM,EAAE;YACN,MAAM,EAAE,YAAY;YACpB,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;gBACP;oBACE,WAAW,EAAE,mBAAmB,EAAE,8CAA8C;oBAChF,UAAU,EAAE;wBACV,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE;qBACtD;iBACF;aACF;SACF;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,YAAY;YACpB,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;SAClC;QACD,WAAW,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE;QACzC,SAAS,EAAE;YACT,QAAQ,EAAE,WAAW;SACtB;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,aAAa;YACrB,iBAAiB,EAAE,KAAK;YACxB,YAAY,EAAE,YAAY;SAC3B;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AACnE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@certe/atmos-renderer",
|
|
3
|
+
"description": "WebGPU PBR renderer for the Atmos Engine — lights, shadows, skinning, post-processing",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/certesolutions-cyber/atmos.git",
|
|
8
|
+
"directory": "packages/renderer"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/certesolutions-cyber/atmos",
|
|
11
|
+
"license": "GPL-3.0-or-later",
|
|
12
|
+
"keywords": ["webgpu", "renderer", "pbr", "game-engine", "shadows", "bloom", "atmos"],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "src/index.ts",
|
|
15
|
+
"types": "src/index.ts",
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"types": "dist/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"files": ["dist", "!dist/__tests__", "package.json", "README.md", "LICENCE"],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@certe/atmos-core": "^0.1.0",
|
|
23
|
+
"@certe/atmos-math": "^0.1.0"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "vitest run"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export { initWebGPU, resizeGPU } from './webgpu-device.js';
|
|
2
|
+
export type { GPUContext } from './webgpu-device.js';
|
|
3
|
+
export { VERTEX_SHADER, FRAGMENT_SHADER } from './shader.js';
|
|
4
|
+
export { createRenderPipeline, HDR_FORMAT, MSAA_SAMPLE_COUNT } from './pipeline.js';
|
|
5
|
+
export type { PipelineResources } from './pipeline.js';
|
|
6
|
+
export { createMesh } from './mesh.js';
|
|
7
|
+
export type { Mesh } from './mesh.js';
|
|
8
|
+
export {
|
|
9
|
+
createCubeGeometry,
|
|
10
|
+
createPlaneGeometry,
|
|
11
|
+
createSphereGeometry,
|
|
12
|
+
createCylinderGeometry,
|
|
13
|
+
VERTEX_STRIDE_FLOATS,
|
|
14
|
+
VERTEX_STRIDE_BYTES,
|
|
15
|
+
} from './geometry.js';
|
|
16
|
+
export type { GeometryData } from './geometry.js';
|
|
17
|
+
export { createMaterial, writeMaterialUniforms, MATERIAL_UNIFORM_SIZE } from './material.js';
|
|
18
|
+
export type { Material, MaterialParams } from './material.js';
|
|
19
|
+
export { createDirectionalLight, writeSceneUniforms, SCENE_UNIFORM_SIZE, collectSceneLights } from './light.js';
|
|
20
|
+
export type { LightSettings, SceneLightData, FogSettings } from './light.js';
|
|
21
|
+
export { DirectionalLight } from './directional-light.js';
|
|
22
|
+
export { PointLight } from './point-light.js';
|
|
23
|
+
export { SpotLight } from './spot-light.js';
|
|
24
|
+
export { MeshRenderer } from './mesh-renderer.js';
|
|
25
|
+
export type { MeshRendererContext } from './mesh-renderer.js';
|
|
26
|
+
export { Camera } from './camera.js';
|
|
27
|
+
export type { ScreenToWorldProvider } from './camera.js';
|
|
28
|
+
export { SceneDepthPass } from './scene-depth.js';
|
|
29
|
+
export { RenderSystem, createDefaultCamera } from './render-system.js';
|
|
30
|
+
export type { CameraSettings, OverlayCallback } from './render-system.js';
|
|
31
|
+
export { registerRendererBuiltins } from './register-builtins.js';
|
|
32
|
+
export {
|
|
33
|
+
createDefaultMaterialAsset,
|
|
34
|
+
serializeMaterialAsset,
|
|
35
|
+
deserializeMaterialAsset,
|
|
36
|
+
} from './material-asset.js';
|
|
37
|
+
export type { ShaderType, MaterialAssetData } from './material-asset.js';
|
|
38
|
+
export { computeBoundingSphere } from './bounds.js';
|
|
39
|
+
export type { BoundingSphere } from './bounds.js';
|
|
40
|
+
export { createUnlitPipeline } from './unlit-pipeline.js';
|
|
41
|
+
export type { UnlitPipelineResources, UnlitPipelineOptions } from './unlit-pipeline.js';
|
|
42
|
+
export { GridRenderer } from './grid-renderer.js';
|
|
43
|
+
export {
|
|
44
|
+
createTextureFromRGBA,
|
|
45
|
+
decodeImageToRGBA,
|
|
46
|
+
getWhiteFallbackTexture,
|
|
47
|
+
getFlatNormalFallback,
|
|
48
|
+
getDefaultMetallicRoughnessFallback,
|
|
49
|
+
} from './texture.js';
|
|
50
|
+
export type { GPUTextureHandle } from './texture.js';
|
|
51
|
+
export { extractFrustumPlanes, isSphereInFrustum } from './frustum.js';
|
|
52
|
+
export type { FrustumPlanes } from './frustum.js';
|
|
53
|
+
export { DirectionalShadowPass, DirectionalShadowPassPair } from './shadow-pass.js';
|
|
54
|
+
export { PointShadowPass } from './point-shadow-pass.js';
|
|
55
|
+
export { SpotShadowPass } from './spot-shadow-pass.js';
|
|
56
|
+
export {
|
|
57
|
+
SHADOW_UNIFORM_SIZE,
|
|
58
|
+
MAX_DIR_SHADOW_SLOTS,
|
|
59
|
+
MAX_POINT_SHADOW_SLOTS,
|
|
60
|
+
MAX_SPOT_SHADOW_SLOTS,
|
|
61
|
+
SHADOW_SLOT_NONE,
|
|
62
|
+
createShadowBindGroupLayout,
|
|
63
|
+
} from './shadow-uniforms.js';
|
|
64
|
+
export { ShadowManager } from './shadow-manager.js';
|
|
65
|
+
export type { ShadowManagerResult } from './shadow-manager.js';
|
|
66
|
+
export { SHADOW_FRAGMENT_WGSL } from './shadow-fragment-wgsl.js';
|
|
67
|
+
export { SHADOW_VERTEX_SHADER } from './shadow-shader.js';
|
|
68
|
+
export { POINT_SHADOW_SHADER } from './point-shadow-shader.js';
|
|
69
|
+
export { generateMipmaps } from './mipmap-generator.js';
|
|
70
|
+
export { BloomPass } from './bloom-pass.js';
|
|
71
|
+
export { TonemapPass } from './tonemap-pass.js';
|
|
72
|
+
export { DepthPrepass } from './depth-prepass.js';
|
|
73
|
+
export { SSAOPass } from './ssao-pass.js';
|
|
74
|
+
export { drawFullscreenTriangle, FULLSCREEN_VERTEX_SHADER } from './fullscreen-quad.js';
|
|
75
|
+
export { createWireframePipeline } from './wireframe-pipeline.js';
|
|
76
|
+
export type { WireframePipelineResources } from './wireframe-pipeline.js';
|
|
77
|
+
export { SKINNED_VERTEX_STRIDE_FLOATS, SKINNED_VERTEX_STRIDE_BYTES, SKINNED_VERTEX_BUFFER_LAYOUT } from './skinned-geometry.js';
|
|
78
|
+
export { SKINNED_VERTEX_SHADER } from './skinned-shader.js';
|
|
79
|
+
export { SKINNED_SHADOW_VERTEX_SHADER } from './skinned-shadow-shader.js';
|
|
80
|
+
export { createSkinnedPBRPipeline } from './skinned-pipeline.js';
|
|
81
|
+
export type { SkinnedPipelineResources } from './skinned-pipeline.js';
|
|
82
|
+
export { SkinnedMeshRenderer } from './skinned-mesh-renderer.js';
|
|
83
|
+
export type { SkinnedRendererContext } from './skinned-mesh-renderer.js';
|
|
84
|
+
export { createTerrainPipeline, TERRAIN_VERTEX_STRIDE_FLOATS, TERRAIN_VERTEX_STRIDE_BYTES } from './terrain-pipeline.js';
|
|
85
|
+
export type { TerrainPipelineResources } from './terrain-pipeline.js';
|
|
86
|
+
export { TerrainMeshRenderer } from './terrain-mesh-renderer.js';
|
|
87
|
+
export { TERRAIN_VERTEX_SHADER, TERRAIN_FRAGMENT_SHADER } from './terrain-shader.js';
|