@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,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TerrainMeshRenderer: MeshRenderer variant for terrain splat-map rendering.
|
|
3
|
+
*
|
|
4
|
+
* Uses the terrain pipeline (40B vertex stride) and binds 3 splat textures
|
|
5
|
+
* instead of the standard PBR albedo/normal/MR textures.
|
|
6
|
+
*/
|
|
7
|
+
import { Component } from '@certe/atmos-core';
|
|
8
|
+
import { Mat4 } from '@certe/atmos-math';
|
|
9
|
+
import { writeMaterialUniforms, MATERIAL_UNIFORM_SIZE } from './material.js';
|
|
10
|
+
import { getWhiteFallbackTexture } from './texture.js';
|
|
11
|
+
const OBJECT_UNIFORM_SIZE = 192;
|
|
12
|
+
export class TerrainMeshRenderer extends Component {
|
|
13
|
+
mesh = null;
|
|
14
|
+
material = null;
|
|
15
|
+
castShadow = true;
|
|
16
|
+
receiveSSAO = false;
|
|
17
|
+
splatTextures = null;
|
|
18
|
+
uniformBuffer = null;
|
|
19
|
+
bindGroup = null;
|
|
20
|
+
materialBindGroup = null;
|
|
21
|
+
_device = null;
|
|
22
|
+
_terrainPipeline = null;
|
|
23
|
+
_mvp = Mat4.create();
|
|
24
|
+
_invModel = Mat4.create();
|
|
25
|
+
_normalMat = Mat4.create();
|
|
26
|
+
_matData = new Float32Array(MATERIAL_UNIFORM_SIZE / 4);
|
|
27
|
+
_worldBoundsCenter = new Float32Array(3);
|
|
28
|
+
_worldBounds = { center: this._worldBoundsCenter, radius: 0 };
|
|
29
|
+
init(device, terrainPipeline, mesh, material, splatTextures) {
|
|
30
|
+
this._device = device;
|
|
31
|
+
this._terrainPipeline = terrainPipeline;
|
|
32
|
+
this.mesh = mesh;
|
|
33
|
+
this.material = material ?? null;
|
|
34
|
+
this.splatTextures = splatTextures ?? null;
|
|
35
|
+
this.uniformBuffer = device.createBuffer({
|
|
36
|
+
size: OBJECT_UNIFORM_SIZE,
|
|
37
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
38
|
+
});
|
|
39
|
+
this.bindGroup = device.createBindGroup({
|
|
40
|
+
layout: terrainPipeline.objectBindGroupLayout,
|
|
41
|
+
entries: [
|
|
42
|
+
{ binding: 0, resource: { buffer: this.uniformBuffer } },
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
initMaterialBindGroup(sceneBuffer) {
|
|
47
|
+
if (!this._device || !this._terrainPipeline || !this.material)
|
|
48
|
+
return;
|
|
49
|
+
if (this.materialBindGroup)
|
|
50
|
+
return;
|
|
51
|
+
if (!this.material.uniformBuffer) {
|
|
52
|
+
this.material.uniformBuffer = this._device.createBuffer({
|
|
53
|
+
size: MATERIAL_UNIFORM_SIZE,
|
|
54
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
55
|
+
});
|
|
56
|
+
this.material.dirty = true;
|
|
57
|
+
}
|
|
58
|
+
const fallback = getWhiteFallbackTexture(this._device);
|
|
59
|
+
const t0 = this.splatTextures?.[0] ?? fallback;
|
|
60
|
+
const t1 = this.splatTextures?.[1] ?? fallback;
|
|
61
|
+
const t2 = this.splatTextures?.[2] ?? fallback;
|
|
62
|
+
this.materialBindGroup = this._device.createBindGroup({
|
|
63
|
+
layout: this._terrainPipeline.materialBindGroupLayout,
|
|
64
|
+
entries: [
|
|
65
|
+
{ binding: 0, resource: { buffer: this.material.uniformBuffer } },
|
|
66
|
+
{ binding: 1, resource: { buffer: sceneBuffer } },
|
|
67
|
+
{ binding: 2, resource: t0.view },
|
|
68
|
+
{ binding: 3, resource: t1.view },
|
|
69
|
+
{ binding: 4, resource: t2.view },
|
|
70
|
+
{ binding: 5, resource: t0.sampler },
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
writeUniforms(viewProjection) {
|
|
75
|
+
if (!this._device || !this.uniformBuffer)
|
|
76
|
+
return;
|
|
77
|
+
const model = this.gameObject.transform.worldMatrix;
|
|
78
|
+
Mat4.multiply(this._mvp, viewProjection, model);
|
|
79
|
+
Mat4.invert(this._invModel, model);
|
|
80
|
+
Mat4.transpose(this._normalMat, this._invModel);
|
|
81
|
+
this._device.queue.writeBuffer(this.uniformBuffer, 0, this._mvp);
|
|
82
|
+
this._device.queue.writeBuffer(this.uniformBuffer, 64, model);
|
|
83
|
+
this._device.queue.writeBuffer(this.uniformBuffer, 128, this._normalMat);
|
|
84
|
+
if (this.material?.dirty && this.material.uniformBuffer) {
|
|
85
|
+
writeMaterialUniforms(this._matData, this.material);
|
|
86
|
+
this._device.queue.writeBuffer(this.material.uniformBuffer, 0, this._matData);
|
|
87
|
+
this.material.dirty = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
draw(pass) {
|
|
91
|
+
if (!this.mesh || !this.bindGroup || !this._terrainPipeline || !this.materialBindGroup)
|
|
92
|
+
return;
|
|
93
|
+
pass.setPipeline(this._terrainPipeline.pipeline);
|
|
94
|
+
pass.setBindGroup(0, this.bindGroup);
|
|
95
|
+
pass.setBindGroup(1, this.materialBindGroup);
|
|
96
|
+
pass.setVertexBuffer(0, this.mesh.vertexBuffer);
|
|
97
|
+
pass.setIndexBuffer(this.mesh.indexBuffer, this.mesh.indexFormat);
|
|
98
|
+
pass.drawIndexed(this.mesh.indexCount);
|
|
99
|
+
}
|
|
100
|
+
get worldBoundingSphere() {
|
|
101
|
+
const bounds = this.mesh?.bounds;
|
|
102
|
+
if (!bounds)
|
|
103
|
+
return null;
|
|
104
|
+
const model = this.gameObject.transform.worldMatrix;
|
|
105
|
+
const cx = bounds.center[0];
|
|
106
|
+
const cy = bounds.center[1];
|
|
107
|
+
const cz = bounds.center[2];
|
|
108
|
+
this._worldBoundsCenter[0] = model[0] * cx + model[4] * cy + model[8] * cz + model[12];
|
|
109
|
+
this._worldBoundsCenter[1] = model[1] * cx + model[5] * cy + model[9] * cz + model[13];
|
|
110
|
+
this._worldBoundsCenter[2] = model[2] * cx + model[6] * cy + model[10] * cz + model[14];
|
|
111
|
+
const sx = Math.sqrt(model[0] * model[0] + model[1] * model[1] + model[2] * model[2]);
|
|
112
|
+
const sy = Math.sqrt(model[4] * model[4] + model[5] * model[5] + model[6] * model[6]);
|
|
113
|
+
const sz = Math.sqrt(model[8] * model[8] + model[9] * model[9] + model[10] * model[10]);
|
|
114
|
+
this._worldBounds.radius = bounds.radius * Math.max(sx, sy, sz);
|
|
115
|
+
return this._worldBounds;
|
|
116
|
+
}
|
|
117
|
+
onDestroy() {
|
|
118
|
+
this.uniformBuffer?.destroy();
|
|
119
|
+
this.uniformBuffer = null;
|
|
120
|
+
this.bindGroup = null;
|
|
121
|
+
this.materialBindGroup = null;
|
|
122
|
+
}
|
|
123
|
+
destroyMesh() {
|
|
124
|
+
if (this.mesh) {
|
|
125
|
+
this.mesh.vertexBuffer.destroy();
|
|
126
|
+
this.mesh.indexBuffer.destroy();
|
|
127
|
+
this.mesh = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=terrain-mesh-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain-mesh-renderer.js","sourceRoot":"","sources":["../src/terrain-mesh-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terrain splat-map render pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Vertex format 40B: pos(3) + normal(3) + uv(2) + splatWeights(2) = 10 floats.
|
|
5
|
+
* Material bind group carries 3 splat textures + shared sampler instead of
|
|
6
|
+
* normal/MR maps used by the standard PBR pipeline.
|
|
7
|
+
*/
|
|
8
|
+
export declare const TERRAIN_VERTEX_STRIDE_FLOATS = 10;
|
|
9
|
+
export declare const TERRAIN_VERTEX_STRIDE_BYTES = 40;
|
|
10
|
+
export interface TerrainPipelineResources {
|
|
11
|
+
pipeline: GPURenderPipeline;
|
|
12
|
+
objectBindGroupLayout: GPUBindGroupLayout;
|
|
13
|
+
materialBindGroupLayout: GPUBindGroupLayout;
|
|
14
|
+
shadowBindGroupLayout: GPUBindGroupLayout;
|
|
15
|
+
}
|
|
16
|
+
export declare function createTerrainPipeline(device: GPUDevice, _format: GPUTextureFormat): TerrainPipelineResources;
|
|
17
|
+
//# sourceMappingURL=terrain-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain-pipeline.d.ts","sourceRoot":"","sources":["../src/terrain-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qBAAqB,EAAE,kBAAkB,CAAC;IAC1C,uBAAuB,EAAE,kBAAkB,CAAC;IAC5C,qBAAqB,EAAE,kBAAkB,CAAC;CAC3C;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,gBAAgB,GACxB,wBAAwB,CA8D1B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terrain splat-map render pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Vertex format 40B: pos(3) + normal(3) + uv(2) + splatWeights(2) = 10 floats.
|
|
5
|
+
* Material bind group carries 3 splat textures + shared sampler instead of
|
|
6
|
+
* normal/MR maps used by the standard PBR pipeline.
|
|
7
|
+
*/
|
|
8
|
+
import { TERRAIN_VERTEX_SHADER, TERRAIN_FRAGMENT_SHADER } from './terrain-shader.js';
|
|
9
|
+
import { createShadowBindGroupLayout } from './shadow-uniforms.js';
|
|
10
|
+
import { HDR_FORMAT, MSAA_SAMPLE_COUNT } from './pipeline.js';
|
|
11
|
+
export const TERRAIN_VERTEX_STRIDE_FLOATS = 10;
|
|
12
|
+
export const TERRAIN_VERTEX_STRIDE_BYTES = 40;
|
|
13
|
+
export function createTerrainPipeline(device, _format) {
|
|
14
|
+
const vertexModule = device.createShaderModule({ code: TERRAIN_VERTEX_SHADER });
|
|
15
|
+
const fragmentModule = device.createShaderModule({ code: TERRAIN_FRAGMENT_SHADER });
|
|
16
|
+
// Group 0: per-object uniforms (MVP + model + normalMatrix) – vertex stage
|
|
17
|
+
const objectBindGroupLayout = device.createBindGroupLayout({
|
|
18
|
+
entries: [
|
|
19
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
// Group 1: material UBO + scene UBO + 3 splat textures + sampler
|
|
23
|
+
const materialBindGroupLayout = device.createBindGroupLayout({
|
|
24
|
+
entries: [
|
|
25
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
|
|
26
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
|
|
27
|
+
{ binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
28
|
+
{ binding: 3, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
29
|
+
{ binding: 4, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
30
|
+
{ binding: 5, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
const shadowBindGroupLayout = createShadowBindGroupLayout(device);
|
|
34
|
+
const pipelineLayout = device.createPipelineLayout({
|
|
35
|
+
bindGroupLayouts: [objectBindGroupLayout, materialBindGroupLayout, shadowBindGroupLayout],
|
|
36
|
+
});
|
|
37
|
+
const pipeline = device.createRenderPipeline({
|
|
38
|
+
layout: pipelineLayout,
|
|
39
|
+
vertex: {
|
|
40
|
+
module: vertexModule,
|
|
41
|
+
entryPoint: 'main',
|
|
42
|
+
buffers: [{
|
|
43
|
+
arrayStride: TERRAIN_VERTEX_STRIDE_BYTES,
|
|
44
|
+
attributes: [
|
|
45
|
+
{ shaderLocation: 0, offset: 0, format: 'float32x3' }, // position
|
|
46
|
+
{ shaderLocation: 1, offset: 12, format: 'float32x3' }, // normal
|
|
47
|
+
{ shaderLocation: 2, offset: 24, format: 'float32x2' }, // uv
|
|
48
|
+
{ shaderLocation: 3, offset: 32, format: 'float32x2' }, // splatWeights
|
|
49
|
+
],
|
|
50
|
+
}],
|
|
51
|
+
},
|
|
52
|
+
fragment: {
|
|
53
|
+
module: fragmentModule,
|
|
54
|
+
entryPoint: 'main',
|
|
55
|
+
targets: [{ format: HDR_FORMAT }],
|
|
56
|
+
},
|
|
57
|
+
multisample: { count: MSAA_SAMPLE_COUNT },
|
|
58
|
+
primitive: {
|
|
59
|
+
topology: 'triangle-list',
|
|
60
|
+
cullMode: 'back',
|
|
61
|
+
},
|
|
62
|
+
depthStencil: {
|
|
63
|
+
depthWriteEnabled: true,
|
|
64
|
+
depthCompare: 'less',
|
|
65
|
+
format: 'depth24plus',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return { pipeline, objectBindGroupLayout, materialBindGroupLayout, shadowBindGroupLayout };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=terrain-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain-pipeline.js","sourceRoot":"","sources":["../src/terrain-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terrain splat-map shader: PBR lighting with 3-texture blending.
|
|
3
|
+
*
|
|
4
|
+
* Vertex format 40B: pos(3) + normal(3) + uv(2) + splatWeights(2) = 10 floats.
|
|
5
|
+
* Fragment blends 3 albedo textures using per-vertex splat weights:
|
|
6
|
+
* w0 = grass, w1 = rock, w2 = 1 - w0 - w1 (snow/dirt).
|
|
7
|
+
*/
|
|
8
|
+
export declare const TERRAIN_VERTEX_SHADER = "\nstruct ObjectUniforms {\n mvp: mat4x4<f32>,\n model: mat4x4<f32>,\n normalMatrix: mat4x4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> object: ObjectUniforms;\n\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) splatWeights: vec2<f32>,\n};\n\nstruct VertexOutput {\n @builtin(position) clipPosition: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) splatWeights: vec2<f32>,\n};\n\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n let worldPos = object.model * vec4<f32>(input.position, 1.0);\n output.clipPosition = object.mvp * vec4<f32>(input.position, 1.0);\n output.worldPosition = worldPos.xyz;\n output.worldNormal = (object.normalMatrix * vec4<f32>(input.normal, 0.0)).xyz;\n output.uv = input.uv;\n output.splatWeights = input.splatWeights;\n return output;\n}\n";
|
|
9
|
+
export declare const TERRAIN_FRAGMENT_SHADER: string;
|
|
10
|
+
//# sourceMappingURL=terrain-shader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain-shader.d.ts","sourceRoot":"","sources":["../src/terrain-shader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,eAAO,MAAM,qBAAqB,i/BAmCjC,CAAC;AAEF,eAAO,MAAM,uBAAuB,QA2GnC,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terrain splat-map shader: PBR lighting with 3-texture blending.
|
|
3
|
+
*
|
|
4
|
+
* Vertex format 40B: pos(3) + normal(3) + uv(2) + splatWeights(2) = 10 floats.
|
|
5
|
+
* Fragment blends 3 albedo textures using per-vertex splat weights:
|
|
6
|
+
* w0 = grass, w1 = rock, w2 = 1 - w0 - w1 (snow/dirt).
|
|
7
|
+
*/
|
|
8
|
+
import { SHADOW_FRAGMENT_WGSL } from './shadow-fragment-wgsl.js';
|
|
9
|
+
import { PBR_FUNCTIONS_WGSL, LIGHT_LOOP_WGSL, FOG_WGSL } from './pbr-wgsl.js';
|
|
10
|
+
export const TERRAIN_VERTEX_SHADER = /* wgsl */ `
|
|
11
|
+
struct ObjectUniforms {
|
|
12
|
+
mvp: mat4x4<f32>,
|
|
13
|
+
model: mat4x4<f32>,
|
|
14
|
+
normalMatrix: mat4x4<f32>,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
@group(0) @binding(0) var<uniform> object: ObjectUniforms;
|
|
18
|
+
|
|
19
|
+
struct VertexInput {
|
|
20
|
+
@location(0) position: vec3<f32>,
|
|
21
|
+
@location(1) normal: vec3<f32>,
|
|
22
|
+
@location(2) uv: vec2<f32>,
|
|
23
|
+
@location(3) splatWeights: vec2<f32>,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
struct VertexOutput {
|
|
27
|
+
@builtin(position) clipPosition: vec4<f32>,
|
|
28
|
+
@location(0) worldPosition: vec3<f32>,
|
|
29
|
+
@location(1) worldNormal: vec3<f32>,
|
|
30
|
+
@location(2) uv: vec2<f32>,
|
|
31
|
+
@location(3) splatWeights: vec2<f32>,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
@vertex
|
|
35
|
+
fn main(input: VertexInput) -> VertexOutput {
|
|
36
|
+
var output: VertexOutput;
|
|
37
|
+
let worldPos = object.model * vec4<f32>(input.position, 1.0);
|
|
38
|
+
output.clipPosition = object.mvp * vec4<f32>(input.position, 1.0);
|
|
39
|
+
output.worldPosition = worldPos.xyz;
|
|
40
|
+
output.worldNormal = (object.normalMatrix * vec4<f32>(input.normal, 0.0)).xyz;
|
|
41
|
+
output.uv = input.uv;
|
|
42
|
+
output.splatWeights = input.splatWeights;
|
|
43
|
+
return output;
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
export const TERRAIN_FRAGMENT_SHADER = /* wgsl */ `
|
|
47
|
+
const PI: f32 = 3.14159265359;
|
|
48
|
+
const MAX_DIR_LIGHTS: u32 = 4u;
|
|
49
|
+
const MAX_POINT_LIGHTS: u32 = 4u;
|
|
50
|
+
const MAX_SPOT_LIGHTS: u32 = 4u;
|
|
51
|
+
|
|
52
|
+
struct MaterialUniforms {
|
|
53
|
+
albedo: vec4<f32>,
|
|
54
|
+
metallic: f32,
|
|
55
|
+
roughness: f32,
|
|
56
|
+
splatSharpness: f32,
|
|
57
|
+
_pad1: f32,
|
|
58
|
+
emissive: vec4<f32>,
|
|
59
|
+
texTiling: vec2<f32>,
|
|
60
|
+
_pad2: vec2<f32>,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
struct DirLight {
|
|
64
|
+
direction: vec4<f32>,
|
|
65
|
+
color: vec4<f32>,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
struct PointLight {
|
|
69
|
+
position: vec4<f32>,
|
|
70
|
+
color: vec4<f32>,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
struct SpotLight {
|
|
74
|
+
position: vec4<f32>,
|
|
75
|
+
direction: vec4<f32>,
|
|
76
|
+
color: vec4<f32>,
|
|
77
|
+
extra: vec4<f32>,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
struct SceneUniforms {
|
|
81
|
+
cameraPos: vec4<f32>,
|
|
82
|
+
numDirLights: u32,
|
|
83
|
+
numPointLights: u32,
|
|
84
|
+
numSpotLights: u32,
|
|
85
|
+
_pad1: u32,
|
|
86
|
+
dirLights: array<DirLight, 4>,
|
|
87
|
+
pointLights: array<PointLight, 4>,
|
|
88
|
+
spotLights: array<SpotLight, 4>,
|
|
89
|
+
fogEnabled: u32,
|
|
90
|
+
fogMode: u32,
|
|
91
|
+
fogDensity: f32,
|
|
92
|
+
fogStart: f32,
|
|
93
|
+
fogEnd: f32,
|
|
94
|
+
_fogPad: f32,
|
|
95
|
+
fogColor: vec4<f32>,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
@group(1) @binding(0) var<uniform> material: MaterialUniforms;
|
|
99
|
+
@group(1) @binding(1) var<uniform> scene: SceneUniforms;
|
|
100
|
+
@group(1) @binding(2) var splatTex0: texture_2d<f32>;
|
|
101
|
+
@group(1) @binding(3) var splatTex1: texture_2d<f32>;
|
|
102
|
+
@group(1) @binding(4) var splatTex2: texture_2d<f32>;
|
|
103
|
+
@group(1) @binding(5) var splatSampler: sampler;
|
|
104
|
+
|
|
105
|
+
` + SHADOW_FRAGMENT_WGSL + PBR_FUNCTIONS_WGSL + /* wgsl */ `
|
|
106
|
+
|
|
107
|
+
struct FragmentInput {
|
|
108
|
+
@location(0) worldPosition: vec3<f32>,
|
|
109
|
+
@location(1) worldNormal: vec3<f32>,
|
|
110
|
+
@location(2) uv: vec2<f32>,
|
|
111
|
+
@location(3) splatWeights: vec2<f32>,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
@fragment
|
|
115
|
+
fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
116
|
+
// Blend 3 splat textures with sharpening
|
|
117
|
+
let uv = input.uv * material.texTiling;
|
|
118
|
+
let c0 = textureSample(splatTex0, splatSampler, uv);
|
|
119
|
+
let c1 = textureSample(splatTex1, splatSampler, uv);
|
|
120
|
+
let c2 = textureSample(splatTex2, splatSampler, uv);
|
|
121
|
+
let rw0 = max(input.splatWeights.x, 0.0);
|
|
122
|
+
let rw1 = max(input.splatWeights.y, 0.0);
|
|
123
|
+
let rw2 = max(1.0 - rw0 - rw1, 0.0);
|
|
124
|
+
// Sharpen: raise weights to power, then renormalize
|
|
125
|
+
let sharpness = max(material.splatSharpness, 1.0);
|
|
126
|
+
let sw0 = pow(rw0, sharpness);
|
|
127
|
+
let sw1 = pow(rw1, sharpness);
|
|
128
|
+
let sw2 = pow(rw2, sharpness);
|
|
129
|
+
let wSum = sw0 + sw1 + sw2 + 0.0001;
|
|
130
|
+
let w0 = sw0 / wSum;
|
|
131
|
+
let w1 = sw1 / wSum;
|
|
132
|
+
let w2 = sw2 / wSum;
|
|
133
|
+
let texColor = c0 * w0 + c1 * w1 + c2 * w2;
|
|
134
|
+
let albedo = material.albedo.rgb * texColor.rgb;
|
|
135
|
+
|
|
136
|
+
let metallic = material.metallic;
|
|
137
|
+
let roughness = material.roughness;
|
|
138
|
+
let N = normalize(input.worldNormal);
|
|
139
|
+
let V = normalize(scene.cameraPos.xyz - input.worldPosition);
|
|
140
|
+
let F0 = mix(vec3<f32>(0.04), albedo, metallic);
|
|
141
|
+
let worldPosition = input.worldPosition;
|
|
142
|
+
|
|
143
|
+
var Lo = vec3<f32>(0.0);
|
|
144
|
+
` + LIGHT_LOOP_WGSL + /* wgsl */ `
|
|
145
|
+
let ambient = vec3<f32>(0.03) * albedo;
|
|
146
|
+
var color = ambient + Lo;
|
|
147
|
+
color = color + material.emissive.rgb * material.emissive.w;
|
|
148
|
+
|
|
149
|
+
` + FOG_WGSL + /* wgsl */ `
|
|
150
|
+
|
|
151
|
+
return vec4<f32>(color, material.albedo.a);
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
//# sourceMappingURL=terrain-shader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terrain-shader.js","sourceRoot":"","sources":["../src/terrain-shader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmC9C,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DhD,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCzD,GAAG,eAAe,GAAG,UAAU,CAAA;;;;;CAK/B,GAAG,QAAQ,GAAG,UAAU,CAAA;;;;CAIxB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface GPUTextureHandle {
|
|
2
|
+
texture: GPUTexture;
|
|
3
|
+
view: GPUTextureView;
|
|
4
|
+
sampler: GPUSampler;
|
|
5
|
+
}
|
|
6
|
+
/** Returns a cached 1x1 white texture (avoids needing separate pipeline variants). */
|
|
7
|
+
export declare function getWhiteFallbackTexture(device: GPUDevice): GPUTextureHandle;
|
|
8
|
+
/** Create a GPU texture from raw RGBA pixel data with auto-generated mipmaps. */
|
|
9
|
+
export declare function createTextureFromRGBA(device: GPUDevice, data: Uint8Array, width: number, height: number): GPUTextureHandle;
|
|
10
|
+
/** Returns a cached 1x1 flat normal texture (127,127,255,255 = tangent-space up). */
|
|
11
|
+
export declare function getFlatNormalFallback(device: GPUDevice): GPUTextureHandle;
|
|
12
|
+
/** Returns a cached 1x1 white metallic-roughness fallback (uniform values override). */
|
|
13
|
+
export declare function getDefaultMetallicRoughnessFallback(device: GPUDevice): GPUTextureHandle;
|
|
14
|
+
/** Decode an image blob to RGBA pixel data using createImageBitmap. */
|
|
15
|
+
export declare function decodeImageToRGBA(blob: Blob): Promise<{
|
|
16
|
+
data: Uint8Array;
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
}>;
|
|
20
|
+
//# sourceMappingURL=texture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture.d.ts","sourceRoot":"","sources":["../src/texture.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;CACrB;AAID,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,CAuB3E;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,gBAAgB,CAwBlB;AAID,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,CAkBzE;AAID,wFAAwF;AACxF,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,CAmBvF;AAED,uEAAuE;AACvE,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,GACT,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAW9D"}
|
package/dist/texture.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { generateMipmaps } from './mipmap-generator.js';
|
|
2
|
+
let _whiteFallback = null;
|
|
3
|
+
/** Returns a cached 1x1 white texture (avoids needing separate pipeline variants). */
|
|
4
|
+
export function getWhiteFallbackTexture(device) {
|
|
5
|
+
if (_whiteFallback)
|
|
6
|
+
return _whiteFallback;
|
|
7
|
+
const texture = device.createTexture({
|
|
8
|
+
size: [1, 1],
|
|
9
|
+
format: 'rgba8unorm',
|
|
10
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
|
11
|
+
});
|
|
12
|
+
device.queue.writeTexture({ texture }, new Uint8Array([255, 255, 255, 255]), { bytesPerRow: 4 }, [1, 1]);
|
|
13
|
+
const view = texture.createView();
|
|
14
|
+
const sampler = device.createSampler({
|
|
15
|
+
magFilter: 'linear',
|
|
16
|
+
minFilter: 'linear',
|
|
17
|
+
mipmapFilter: 'linear',
|
|
18
|
+
});
|
|
19
|
+
_whiteFallback = { texture, view, sampler };
|
|
20
|
+
return _whiteFallback;
|
|
21
|
+
}
|
|
22
|
+
/** Create a GPU texture from raw RGBA pixel data with auto-generated mipmaps. */
|
|
23
|
+
export function createTextureFromRGBA(device, data, width, height) {
|
|
24
|
+
const mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1;
|
|
25
|
+
const texture = device.createTexture({
|
|
26
|
+
size: [width, height],
|
|
27
|
+
format: 'rgba8unorm',
|
|
28
|
+
mipLevelCount,
|
|
29
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
30
|
+
});
|
|
31
|
+
device.queue.writeTexture({ texture }, data, { bytesPerRow: width * 4 }, [width, height]);
|
|
32
|
+
generateMipmaps(device, texture);
|
|
33
|
+
const view = texture.createView();
|
|
34
|
+
const sampler = device.createSampler({
|
|
35
|
+
magFilter: 'linear',
|
|
36
|
+
minFilter: 'linear',
|
|
37
|
+
mipmapFilter: 'linear',
|
|
38
|
+
addressModeU: 'repeat',
|
|
39
|
+
addressModeV: 'repeat',
|
|
40
|
+
});
|
|
41
|
+
return { texture, view, sampler };
|
|
42
|
+
}
|
|
43
|
+
let _flatNormalFallback = null;
|
|
44
|
+
/** Returns a cached 1x1 flat normal texture (127,127,255,255 = tangent-space up). */
|
|
45
|
+
export function getFlatNormalFallback(device) {
|
|
46
|
+
if (_flatNormalFallback)
|
|
47
|
+
return _flatNormalFallback;
|
|
48
|
+
const texture = device.createTexture({
|
|
49
|
+
size: [1, 1],
|
|
50
|
+
format: 'rgba8unorm',
|
|
51
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
|
52
|
+
});
|
|
53
|
+
device.queue.writeTexture({ texture }, new Uint8Array([127, 127, 255, 255]), { bytesPerRow: 4 }, [1, 1]);
|
|
54
|
+
const view = texture.createView();
|
|
55
|
+
const sampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear' });
|
|
56
|
+
_flatNormalFallback = { texture, view, sampler };
|
|
57
|
+
return _flatNormalFallback;
|
|
58
|
+
}
|
|
59
|
+
let _defaultMRFallback = null;
|
|
60
|
+
/** Returns a cached 1x1 white metallic-roughness fallback (uniform values override). */
|
|
61
|
+
export function getDefaultMetallicRoughnessFallback(device) {
|
|
62
|
+
if (_defaultMRFallback)
|
|
63
|
+
return _defaultMRFallback;
|
|
64
|
+
const texture = device.createTexture({
|
|
65
|
+
size: [1, 1],
|
|
66
|
+
format: 'rgba8unorm',
|
|
67
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
|
68
|
+
});
|
|
69
|
+
// G=255 (roughness=1.0), B=255 (metallic=1.0) – multiplied by uniform values
|
|
70
|
+
device.queue.writeTexture({ texture }, new Uint8Array([255, 255, 255, 255]), { bytesPerRow: 4 }, [1, 1]);
|
|
71
|
+
const view = texture.createView();
|
|
72
|
+
const sampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear' });
|
|
73
|
+
_defaultMRFallback = { texture, view, sampler };
|
|
74
|
+
return _defaultMRFallback;
|
|
75
|
+
}
|
|
76
|
+
/** Decode an image blob to RGBA pixel data using createImageBitmap. */
|
|
77
|
+
export async function decodeImageToRGBA(blob) {
|
|
78
|
+
const bitmap = await createImageBitmap(blob);
|
|
79
|
+
const { width, height } = bitmap;
|
|
80
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
81
|
+
const ctx = canvas.getContext('2d');
|
|
82
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
83
|
+
bitmap.close();
|
|
84
|
+
const imageData = ctx.getImageData(0, 0, width, height);
|
|
85
|
+
return { data: new Uint8Array(imageData.data.buffer), width, height };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=texture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture.js","sourceRoot":"","sources":["../src/texture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
export declare class TonemapPass {
|
|
12
|
+
private readonly _device;
|
|
13
|
+
private readonly _pipeline;
|
|
14
|
+
private readonly _bgl;
|
|
15
|
+
private readonly _sampler;
|
|
16
|
+
private readonly _paramsBuffer;
|
|
17
|
+
private readonly _paramsData;
|
|
18
|
+
constructor(device: GPUDevice, outputFormat: GPUTextureFormat);
|
|
19
|
+
execute(encoder: GPUCommandEncoder, hdrView: GPUTextureView, bloomView: GPUTextureView, aoView: GPUTextureView, outputView: GPUTextureView, bloomIntensity: number, exposure: number, vignetteIntensity: number, vignetteRadius: number): void;
|
|
20
|
+
destroy(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=tonemap-pass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tonemap-pass.d.ts","sourceRoot":"","sources":["../src/tonemap-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmDH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB;IAgC7D,OAAO,CACL,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,cAAc,EACzB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,cAAc,EAC1B,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,MAAM,GACrB,IAAI;IAgCP,OAAO,IAAI,IAAI;CAGhB"}
|