minerva-design 1.6.0 → 1.7.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/CHANGELOG.md +13 -0
- package/dist/charts/engine/data.cjs +1 -1
- package/dist/charts/engine/data.cjs.map +1 -1
- package/dist/charts/engine/data.d.cts +2 -0
- package/dist/charts/engine/data.d.ts +2 -0
- package/dist/charts/engine/data.js +6 -4
- package/dist/charts/engine/data.js.map +1 -1
- package/dist/charts/engine/defaults.cjs +1 -1
- package/dist/charts/engine/defaults.cjs.map +1 -1
- package/dist/charts/engine/defaults.js +22 -18
- package/dist/charts/engine/defaults.js.map +1 -1
- package/dist/charts/engine/graph/chart.cjs +1 -1
- package/dist/charts/engine/graph/chart.cjs.map +1 -1
- package/dist/charts/engine/graph/chart.js +532 -493
- package/dist/charts/engine/graph/chart.js.map +1 -1
- package/dist/charts/engine/graph/geometry.cjs +1 -1
- package/dist/charts/engine/graph/geometry.cjs.map +1 -1
- package/dist/charts/engine/graph/geometry.d.cts +12 -2
- package/dist/charts/engine/graph/geometry.d.ts +12 -2
- package/dist/charts/engine/graph/geometry.js +35 -31
- package/dist/charts/engine/graph/geometry.js.map +1 -1
- package/dist/charts/engine/model.cjs +1 -1
- package/dist/charts/engine/model.cjs.map +1 -1
- package/dist/charts/engine/model.js +95 -74
- package/dist/charts/engine/model.js.map +1 -1
- package/dist/charts/engine/orderbook/field.cjs +1 -1
- package/dist/charts/engine/orderbook/field.cjs.map +1 -1
- package/dist/charts/engine/orderbook/field.d.cts +15 -2
- package/dist/charts/engine/orderbook/field.d.ts +15 -2
- package/dist/charts/engine/orderbook/field.js +21 -9
- package/dist/charts/engine/orderbook/field.js.map +1 -1
- package/dist/charts/engine/orderbook/heatmap.cjs +1 -1
- package/dist/charts/engine/orderbook/heatmap.cjs.map +1 -1
- package/dist/charts/engine/orderbook/heatmap.d.cts +29 -0
- package/dist/charts/engine/orderbook/heatmap.d.ts +29 -0
- package/dist/charts/engine/orderbook/heatmap.js +576 -453
- package/dist/charts/engine/orderbook/heatmap.js.map +1 -1
- package/dist/charts/engine/orderbook/types.d.cts +36 -11
- package/dist/charts/engine/orderbook/types.d.ts +36 -11
- package/dist/charts/engine/presets.cjs +1 -1
- package/dist/charts/engine/presets.cjs.map +1 -1
- package/dist/charts/engine/presets.d.cts +16 -3
- package/dist/charts/engine/presets.d.ts +16 -3
- package/dist/charts/engine/presets.js +42 -32
- package/dist/charts/engine/presets.js.map +1 -1
- package/dist/charts/engine/scene.cjs +1 -1
- package/dist/charts/engine/scene.cjs.map +1 -1
- package/dist/charts/engine/scene.d.cts +4 -2
- package/dist/charts/engine/scene.d.ts +4 -2
- package/dist/charts/engine/scene.js +185 -107
- package/dist/charts/engine/scene.js.map +1 -1
- package/dist/charts/engine/three-d/oit.cjs +119 -34
- package/dist/charts/engine/three-d/oit.cjs.map +1 -1
- package/dist/charts/engine/three-d/oit.d.cts +65 -10
- package/dist/charts/engine/three-d/oit.d.ts +65 -10
- package/dist/charts/engine/three-d/oit.js +119 -34
- package/dist/charts/engine/three-d/oit.js.map +1 -1
- package/dist/charts/engine/three-d/render-types.cjs.map +1 -1
- package/dist/charts/engine/three-d/render-types.d.cts +19 -0
- package/dist/charts/engine/three-d/render-types.d.ts +19 -0
- package/dist/charts/engine/three-d/render-types.js.map +1 -1
- package/dist/charts/engine/three-d/shaders.cjs +14 -6
- package/dist/charts/engine/three-d/shaders.cjs.map +1 -1
- package/dist/charts/engine/three-d/shaders.d.cts +6 -1
- package/dist/charts/engine/three-d/shaders.d.ts +6 -1
- package/dist/charts/engine/three-d/shaders.js +40 -26
- package/dist/charts/engine/three-d/shaders.js.map +1 -1
- package/dist/charts/engine/three-d/webgl.cjs +1 -1
- package/dist/charts/engine/three-d/webgl.cjs.map +1 -1
- package/dist/charts/engine/three-d/webgl.js +167 -125
- package/dist/charts/engine/three-d/webgl.js.map +1 -1
- package/dist/charts/engine/three-d/webgpu.cjs +1 -1
- package/dist/charts/engine/three-d/webgpu.cjs.map +1 -1
- package/dist/charts/engine/three-d/webgpu.js +169 -140
- package/dist/charts/engine/three-d/webgpu.js.map +1 -1
- package/dist/charts/engine/trading/chart.cjs +1 -1
- package/dist/charts/engine/trading/chart.cjs.map +1 -1
- package/dist/charts/engine/trading/chart.js +1149 -1023
- package/dist/charts/engine/trading/chart.js.map +1 -1
- package/dist/charts/engine/trading/labels.cjs +1 -1
- package/dist/charts/engine/trading/labels.cjs.map +1 -1
- package/dist/charts/engine/trading/labels.js +12 -0
- package/dist/charts/engine/trading/labels.js.map +1 -1
- package/dist/charts/engine/trading/layout.cjs +2 -0
- package/dist/charts/engine/trading/layout.cjs.map +1 -0
- package/dist/charts/engine/trading/layout.d.cts +37 -0
- package/dist/charts/engine/trading/layout.d.ts +37 -0
- package/dist/charts/engine/trading/layout.js +63 -0
- package/dist/charts/engine/trading/layout.js.map +1 -0
- package/dist/charts/engine/trading/types.d.cts +24 -7
- package/dist/charts/engine/trading/types.d.ts +24 -7
- package/dist/charts/engine/types.d.cts +21 -8
- package/dist/charts/engine/types.d.ts +21 -8
- package/dist/core/contracts.cjs +1 -1
- package/dist/core/contracts.cjs.map +1 -1
- package/dist/core/contracts.js +1 -1
- package/dist/core/contracts.js.map +1 -1
- package/dist/native/charts/src/engine/data.cjs +1 -1
- package/dist/native/charts/src/engine/data.cjs.map +1 -1
- package/dist/native/charts/src/engine/data.js +6 -4
- package/dist/native/charts/src/engine/data.js.map +1 -1
- package/dist/native/charts/src/engine/model.cjs +1 -1
- package/dist/native/charts/src/engine/model.cjs.map +1 -1
- package/dist/native/charts/src/engine/model.js +104 -83
- package/dist/native/charts/src/engine/model.js.map +1 -1
- package/dist/native/charts/src/engine/presets.cjs +1 -1
- package/dist/native/charts/src/engine/presets.cjs.map +1 -1
- package/dist/native/charts/src/engine/presets.js +42 -32
- package/dist/native/charts/src/engine/presets.js.map +1 -1
- package/dist/native/charts/src/engine/scene.cjs +1 -1
- package/dist/native/charts/src/engine/scene.cjs.map +1 -1
- package/dist/native/charts/src/engine/scene.js +185 -107
- package/dist/native/charts/src/engine/scene.js.map +1 -1
- package/dist/taro/index.js +1263 -1152
- package/dist/vue/components/Chart/OrderBookHeatmap.vue.d.ts +11 -0
- package/dist/vue/components/Chart/orderbook.d.ts +7 -0
- package/dist/vue/components/Chart/orderbook.js +2 -0
- package/dist/vue/components/Chart/orderbook.js.map +1 -1
- package/dist/weapp/charts/canvas.js +234 -58
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { writesDepth as e } from "./render-types.js";
|
|
2
|
-
import {
|
|
2
|
+
import { GLSL_FRONT as t, GLSL_OIT as n, WGSL_OIT as r, glslScreen as i } from "./oit.js";
|
|
3
3
|
//#region src/engine/three-d/shaders.ts
|
|
4
|
-
var
|
|
5
|
-
let
|
|
6
|
-
return
|
|
4
|
+
var a = (e, t, n, r, i, a, o, s) => (e.set(t, 0), e.set(n, 16), e.set(r, 20), e.set(i, 24), e.set(a, 28), e.set(o, 32), e.set(s, 36), e), o = (e, t, n) => {
|
|
5
|
+
let r = e.kind === "points" ? +!!e.perspective : e.kind === "lines" ? e.width : 0;
|
|
6
|
+
return a(n, t.viewProj, [
|
|
7
7
|
t.width,
|
|
8
8
|
t.height,
|
|
9
9
|
t.dpr,
|
|
@@ -20,7 +20,7 @@ var r = (e, t, n, r, i, a, o, s) => (e.set(t, 0), e.set(n, 16), e.set(r, 20), e.
|
|
|
20
20
|
e.kind === "points" && e.additive ? 1 : 0
|
|
21
21
|
], t.lighting, [
|
|
22
22
|
e.opacity,
|
|
23
|
-
|
|
23
|
+
r,
|
|
24
24
|
t.distance,
|
|
25
25
|
t.radius
|
|
26
26
|
], [
|
|
@@ -29,7 +29,7 @@ var r = (e, t, n, r, i, a, o, s) => (e.set(t, 0), e.set(n, 16), e.set(r, 20), e.
|
|
|
29
29
|
t.fog[2],
|
|
30
30
|
t.exposure
|
|
31
31
|
]);
|
|
32
|
-
},
|
|
32
|
+
}, s = `
|
|
33
33
|
struct U {
|
|
34
34
|
viewProj: mat4x4f,
|
|
35
35
|
viewport: vec4f,
|
|
@@ -49,7 +49,7 @@ fn depthCue(world: vec3f) -> f32 {
|
|
|
49
49
|
let near = u.params.z - u.params.w;
|
|
50
50
|
return clamp((length(world - u.eye.xyz) - near) / (2.0 * u.params.w), 0.0, 1.0);
|
|
51
51
|
}
|
|
52
|
-
${
|
|
52
|
+
${r}`, c = `${s}
|
|
53
53
|
struct Out {
|
|
54
54
|
@builtin(position) position: vec4f,
|
|
55
55
|
@location(0) offset: vec2f,
|
|
@@ -121,14 +121,19 @@ fn shade(in: Out) -> vec4f {
|
|
|
121
121
|
|
|
122
122
|
@fragment
|
|
123
123
|
fn fs(in: Out) -> @location(0) vec4f {
|
|
124
|
-
return shade(in);
|
|
124
|
+
return screenLight(shade(in));
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
@fragment
|
|
128
128
|
fn fsOit(in: Out) -> Oit {
|
|
129
|
-
return oit(shade(in), in.fog);
|
|
129
|
+
return oit(shade(in), in.fog, in.position);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@fragment
|
|
133
|
+
fn fsFront(in: Out) -> @location(0) vec4f {
|
|
134
|
+
return frontDepth(shade(in), in.fog);
|
|
130
135
|
}
|
|
131
|
-
`,
|
|
136
|
+
`, l = `${s}
|
|
132
137
|
struct Out {
|
|
133
138
|
@builtin(position) position: vec4f,
|
|
134
139
|
@location(0) world: vec3f,
|
|
@@ -170,9 +175,14 @@ fn fs(in: Out) -> @location(0) vec4f {
|
|
|
170
175
|
|
|
171
176
|
@fragment
|
|
172
177
|
fn fsOit(in: Out) -> Oit {
|
|
173
|
-
return oit(shade(in), depthCue(in.world));
|
|
178
|
+
return oit(shade(in), depthCue(in.world), in.position);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@fragment
|
|
182
|
+
fn fsFront(in: Out) -> @location(0) vec4f {
|
|
183
|
+
return frontDepth(shade(in), depthCue(in.world));
|
|
174
184
|
}
|
|
175
|
-
`,
|
|
185
|
+
`, u = `${s}
|
|
176
186
|
struct Out {
|
|
177
187
|
@builtin(position) position: vec4f,
|
|
178
188
|
@location(0) across: f32,
|
|
@@ -216,20 +226,24 @@ fn fs(in: Out) -> @location(0) vec4f {
|
|
|
216
226
|
if (alpha <= 0.0) { discard; }
|
|
217
227
|
return vec4f(in.color.rgb * alpha, alpha);
|
|
218
228
|
}
|
|
219
|
-
`,
|
|
220
|
-
vertex: `#version 300 es\n#define attribute in\n#define varying out\n${
|
|
221
|
-
fragment: `#version 300 es\nprecision highp float;\n#define varying in\n${
|
|
229
|
+
`, d = "\nuniform mat4 u_viewProj;\nuniform vec4 u_viewport;\nuniform vec4 u_eye;\nuniform vec4 u_light;\nuniform vec4 u_material;\nuniform vec4 u_params;\nuniform vec4 u_fog;\n", f = "\nattribute vec2 a_corner;\nattribute vec3 a_pos;\nattribute float a_size;\nattribute vec4 a_color;\nvarying vec2 v_offset;\nvarying float v_radius;\nvarying vec4 v_color;\nvarying float v_fog;\nvarying float v_coverage;\nvoid main() {\n vec2 corner = a_corner * 2.0 - 1.0;\n vec4 clip = u_viewProj * vec4(a_pos, 1.0);\n float factor = 1.0;\n if (u_params.y > 0.5 && u_viewport.w < 0.5) {\n factor = clamp(u_params.z / max(clip.w, 1e-6), 0.5, 2.0);\n }\n bool glow = u_eye.w > 1.5;\n float raw = max(a_size, 0.0) * u_viewport.z * factor * 0.5;\n float radius = max(raw, glow ? 0.75 : 0.5);\n float reach = glow ? radius * 2.2 + 1.0 : radius + 1.0;\n vec2 shift = corner * reach * 2.0 / u_viewport.xy * clip.w;\n gl_Position = vec4(clip.xy + shift, clip.z, clip.w);\n v_offset = corner * reach;\n v_radius = radius;\n v_color = a_color;\n float near = u_params.z - u_params.w;\n v_fog = clamp((length(a_pos - u_eye.xyz) - near) / (2.0 * u_params.w), 0.0, 1.0);\n v_coverage = min(1.0, raw * raw / (radius * radius));\n}\n", p = "\nvarying vec2 v_offset;\nvarying float v_radius;\nvarying vec4 v_color;\nvarying float v_fog;\nvarying float v_coverage;\nvoid main() {\n float d = length(v_offset);\n float r = v_radius;\n float alpha = clamp(r + 0.5 - d, 0.0, 1.0);\n vec3 rgb = v_color.rgb;\n if (u_eye.w > 1.5) {\n float core = clamp(r * 0.6 + 0.5 - d, 0.0, 1.0);\n float q = d / r;\n alpha = core + (1.0 - core) * exp(-1.2 * q * q);\n rgb = rgb + (vec3(1.0) - rgb) * (0.2 * core);\n } else if (u_eye.w < 0.5) {\n float q = min(d / r, 1.0);\n vec3 n = vec3(v_offset / r, sqrt(max(0.0, 1.0 - q * q)));\n vec3 l = normalize(vec3(-0.45, 0.55, 0.7));\n float lambert = max(dot(n, l), 0.0);\n vec3 shaded = rgb * (0.62 + 0.45 * lambert) + vec3(pow(lambert, 18.0) * 0.28);\n rgb = mix(rgb, shaded, smoothstep(1.5, 3.5, r));\n }\n if (alpha <= 0.004) discard;\n float fog = v_fog * 0.45;\n if (u_light.w > 0.5) {\n alpha = alpha * (1.0 - fog);\n rgb = rgb * u_fog.w;\n } else {\n rgb = mix(rgb, u_fog.rgb, fog);\n }\n alpha = alpha * v_coverage * v_color.a * u_params.x;\n EMIT(vec4(rgb * alpha, alpha), v_fog);\n}\n", m = "\nattribute vec3 a_pos;\nattribute vec3 a_normal;\nattribute vec4 a_color;\nvarying vec3 v_world;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvoid main() {\n gl_Position = u_viewProj * vec4(a_pos, 1.0);\n v_world = a_pos;\n v_normal = a_normal;\n v_color = a_color;\n}\n", h = "\nvarying vec3 v_world;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvoid main() {\n vec3 n = normalize(v_normal);\n vec3 v = normalize(u_eye.xyz - v_world);\n if (dot(n, v) < 0.0) n = -n;\n vec3 l = u_light.xyz;\n float diffuse = max(dot(n, l), 0.0);\n vec3 h = normalize(l + v);\n float specular = pow(max(dot(n, h), 0.0), u_material.w) * u_material.z;\n vec3 rgb = v_color.rgb * (u_material.x + u_material.y * diffuse) + vec3(specular);\n float alpha = v_color.a * u_params.x;\n float near = u_params.z - u_params.w;\n float depth = (length(v_world - u_eye.xyz) - near) / (2.0 * u_params.w);\n EMIT(vec4(rgb * alpha, alpha), depth);\n}\n", g = "\nattribute vec2 a_corner;\nattribute vec3 a_a;\nattribute vec3 a_b;\nattribute vec4 a_color;\nvarying float v_across;\nvarying vec4 v_color;\nvoid main() {\n vec4 ca = u_viewProj * vec4(a_a, 1.0);\n vec4 cb = u_viewProj * vec4(a_b, 1.0);\n vec2 halfSize = u_viewport.xy * 0.5;\n vec2 sa = ca.xy / ca.w * halfSize;\n vec2 sb = cb.xy / cb.w * halfSize;\n vec2 dir = sb - sa;\n float len = length(dir);\n dir = len > 1e-6 ? dir / len : vec2(1.0, 0.0);\n vec2 normal = vec2(-dir.y, dir.x);\n float w = max(0.5, u_params.y * u_viewport.z * 0.5) + 0.5;\n bool atEnd = a_corner.x > 0.5;\n vec4 clip = atEnd ? cb : ca;\n float side = a_corner.y * 2.0 - 1.0;\n vec2 pixel = (atEnd ? sb : sa) + dir * (a_corner.x * 2.0 - 1.0) * w + normal * side * w;\n gl_Position = vec4(pixel / halfSize * clip.w, clip.z - u_eye.w * clip.w, clip.w);\n v_across = side * w;\n v_color = a_color;\n}\n", _ = "\nvarying float v_across;\nvarying vec4 v_color;\nvoid main() {\n float core = u_params.y * u_viewport.z * 0.5;\n float coverage = clamp(max(core, 0.5) + 0.5 - abs(v_across), 0.0, 1.0) * min(1.0, core * 2.0);\n float alpha = coverage * v_color.a * u_params.x;\n if (alpha <= 0.0) discard;\n EMIT(vec4(v_color.rgb * alpha, alpha), 0.0);\n}\n", v = "\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n", y = (e, r, a, o = "plain") => a === 2 ? {
|
|
230
|
+
vertex: `#version 300 es\n#define attribute in\n#define varying out\n${d}${e}`,
|
|
231
|
+
fragment: `#version 300 es\nprecision highp float;\n#define varying in\n${d}${o === "oit" ? n : o === "front" ? t : `out vec4 fragColor;\n${i("fragColor")}`}${r}`
|
|
222
232
|
} : {
|
|
223
|
-
vertex: `${
|
|
224
|
-
fragment: `${
|
|
225
|
-
},
|
|
226
|
-
points:
|
|
227
|
-
mesh:
|
|
228
|
-
lines:
|
|
229
|
-
}),
|
|
230
|
-
points:
|
|
231
|
-
mesh:
|
|
232
|
-
|
|
233
|
+
vertex: `${d}${e}`,
|
|
234
|
+
fragment: `${v}${d}${i("gl_FragColor")}${r}`
|
|
235
|
+
}, b = (e) => ({
|
|
236
|
+
points: y(f, p, e),
|
|
237
|
+
mesh: y(m, h, e),
|
|
238
|
+
lines: y(g, _, e)
|
|
239
|
+
}), x = () => ({
|
|
240
|
+
points: y(f, p, 2, "oit"),
|
|
241
|
+
mesh: y(m, h, 2, "oit"),
|
|
242
|
+
front: {
|
|
243
|
+
points: y(f, p, 2, "front"),
|
|
244
|
+
mesh: y(m, h, 2, "front")
|
|
245
|
+
}
|
|
246
|
+
}), S = {
|
|
233
247
|
points: [
|
|
234
248
|
"a_corner",
|
|
235
249
|
"a_pos",
|
|
@@ -249,6 +263,6 @@ fn fs(in: Out) -> @location(0) vec4f {
|
|
|
249
263
|
]
|
|
250
264
|
};
|
|
251
265
|
//#endregion
|
|
252
|
-
export {
|
|
266
|
+
export { S as GLSL_ATTRIBUTES, u as WGSL_LINES, l as WGSL_MESH, c as WGSL_POINTS, x as glslOitPrograms, b as glslPrograms, o as itemUniforms, e as writesDepth };
|
|
253
267
|
|
|
254
268
|
//# sourceMappingURL=shaders.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shaders.js","names":["writeUniforms","out","viewProj","viewport","eye","light","material","params","fog","itemUniforms","second","item","frame","WGSL_UNIFORMS","WGSL_OIT","WGSL_POINTS","WGSL_MESH","WGSL_LINES","GLSL_UNIFORMS","GLSL_POINTS_VS","GLSL_POINTS_FS","GLSL_MESH_VS","GLSL_MESH_FS","GLSL_LINES_VS","GLSL_LINES_FS","PRECISION","glsl","version","vs","oit","GLSL_OIT","fs","glslPrograms","glslOitPrograms","GLSL_ATTRIBUTES","writesDepth"],"sources":["../../../../../charts/src/engine/three-d/shaders.ts"],"sourcesContent":["// Shaders of the 3D data layer: instanced point billboards (shaded spheres,\n// flat discs or glowing discs), lit triangles (two-sided Lambert +\n// Blinn-Phong) and screen-space wide line segments. WGSL for WebGPU, GLSL ES\n// 1.0 for WebGL (turned into GLSL ES 3.0 for WebGL2 by a macro prefix).\n// Outputs are premultiplied.\n//\n// Uniforms (WGSL struct, GLSL vec4 uniforms of the same names):\n// viewProj world -> clip (OpenGL depth convention)\n// viewport drawing buffer width, height (device px), dpr, orthographic\n// eye camera position, depth bias of the lines (NDC) | point style\n// light unit vector towards the light, additive points (0/1)\n// material ambient, diffuse, specular, shininess\n// params opacity, perspective sizes (0/1) | line width (CSS px), distance, radius\n// fog background color (far points fade towards it), exposure of the\n// additive light\n//\n// Points and meshes have a second fragment entry point writing the targets\n// of the order-independent transparency (`oit.ts`): `fsOit` in WGSL, the\n// `oit` variant of the GLSL programs (WebGL2).\n//\n// Point sizes are CSS pixels times the device pixel ratio (billboards: no\n// point size limit). Dots thinner than the smallest drawn radius keep their\n// energy: their alpha scales with the area they would cover.\n\nimport { GLSL_OIT, WGSL_OIT } from \"./oit\";\nimport { POINT_SPHERE, type Frame3D, type Item3D } from \"./render-types\";\n\nexport { writesDepth } from \"./render-types\";\n\n/** Bytes of the WGSL uniform struct */\nexport const UNIFORM_BYTES = 160;\n\n/** Writes the uniforms of an item in the WGSL struct layout */\nconst writeUniforms = (\n out: Float32Array,\n viewProj: Float32Array,\n viewport: readonly [number, number, number, number],\n eye: readonly [number, number, number, number],\n light: readonly [number, number, number, number],\n material: readonly [number, number, number, number],\n params: readonly [number, number, number, number],\n fog: readonly [number, number, number, number],\n): Float32Array => {\n out.set(viewProj, 0);\n out.set(viewport, 16);\n out.set(eye, 20);\n out.set(light, 24);\n out.set(material, 28);\n out.set(params, 32);\n out.set(fog, 36);\n return out;\n};\n\n/** Uniform values of an item (40 floats, the WGSL struct layout) */\nexport const itemUniforms = (\n item: Item3D,\n frame: Frame3D,\n out: Float32Array,\n): Float32Array => {\n const second =\n item.kind === \"points\"\n ? item.perspective\n ? 1\n : 0\n : item.kind === \"lines\"\n ? item.width\n : 0;\n return writeUniforms(\n out,\n frame.viewProj,\n [frame.width, frame.height, frame.dpr, frame.orthographic ? 1 : 0],\n [\n frame.eye[0],\n frame.eye[1],\n frame.eye[2],\n item.kind === \"lines\"\n ? item.bias\n : item.kind === \"points\"\n ? (item.style ?? POINT_SPHERE)\n : 0,\n ],\n [\n frame.light[0],\n frame.light[1],\n frame.light[2],\n item.kind === \"points\" && item.additive ? 1 : 0,\n ],\n frame.lighting,\n [item.opacity, second, frame.distance, frame.radius],\n [frame.fog[0], frame.fog[1], frame.fog[2], frame.exposure],\n );\n};\n\n// ------------------------------------------------------------------- WGSL\n\nconst WGSL_UNIFORMS = /* wgsl */ `\nstruct U {\n viewProj: mat4x4f,\n viewport: vec4f,\n eye: vec4f,\n light: vec4f,\n material: vec4f,\n params: vec4f,\n fog: vec4f,\n};\n@group(0) @binding(0) var<uniform> u: U;\n\nfn toWebGpuDepth(p: vec4f) -> vec4f {\n return vec4f(p.x, p.y, (p.z + p.w) * 0.5, p.w);\n}\n\nfn depthCue(world: vec3f) -> f32 {\n let near = u.params.z - u.params.w;\n return clamp((length(world - u.eye.xyz) - near) / (2.0 * u.params.w), 0.0, 1.0);\n}\n${WGSL_OIT}`;\n\nexport const WGSL_POINTS = /* wgsl */ `${WGSL_UNIFORMS}\nstruct Out {\n @builtin(position) position: vec4f,\n @location(0) offset: vec2f,\n @location(1) radius: f32,\n @location(2) color: vec4f,\n @location(3) fog: f32,\n @location(4) coverage: f32,\n};\n\n@vertex\nfn vs(\n @builtin(vertex_index) vi: u32,\n @location(0) pos: vec3f,\n @location(1) size: f32,\n @location(2) color: vec4f,\n) -> Out {\n var out: Out;\n let corner = vec2f(f32(vi & 1u), f32(vi >> 1u)) * 2.0 - 1.0;\n let clip = u.viewProj * vec4f(pos, 1.0);\n var factor = 1.0;\n if (u.params.y > 0.5 && u.viewport.w < 0.5) {\n factor = clamp(u.params.z / max(clip.w, 1e-6), 0.5, 2.0);\n }\n let glow = u.eye.w > 1.5;\n let raw = max(size, 0.0) * u.viewport.z * factor * 0.5;\n let radius = max(raw, select(0.5, 0.75, glow));\n let reach = select(radius + 1.0, radius * 2.2 + 1.0, glow);\n let shift = corner * reach * 2.0 / u.viewport.xy * clip.w;\n out.position = toWebGpuDepth(vec4f(clip.xy + shift, clip.z, clip.w));\n out.offset = corner * reach;\n out.radius = radius;\n out.color = color;\n out.fog = depthCue(pos);\n out.coverage = min(1.0, raw * raw / (radius * radius));\n return out;\n}\n\nfn shade(in: Out) -> vec4f {\n let d = length(in.offset);\n let r = in.radius;\n var alpha = clamp(r + 0.5 - d, 0.0, 1.0);\n var rgb = in.color.rgb;\n if (u.eye.w > 1.5) {\n // glow: an anti-aliased core and a gaussian halo\n let core = clamp(r * 0.6 + 0.5 - d, 0.0, 1.0);\n let q = d / r;\n alpha = core + (1.0 - core) * exp(-1.2 * q * q);\n rgb = rgb + (vec3f(1.0) - rgb) * (0.2 * core);\n } else if (u.eye.w < 0.5) {\n let q = min(d / r, 1.0);\n let n = vec3f(in.offset.x / r, in.offset.y / r, sqrt(max(0.0, 1.0 - q * q)));\n let l = normalize(vec3f(-0.45, 0.55, 0.7));\n let lambert = max(dot(n, l), 0.0);\n let shaded = rgb * (0.62 + 0.45 * lambert) + vec3f(pow(lambert, 18.0) * 0.28);\n rgb = mix(rgb, shaded, smoothstep(1.5, 3.5, r));\n }\n if (alpha <= 0.004) { discard; }\n let fog = in.fog * 0.45;\n if (u.light.w > 0.5) {\n // additive light fades with the distance\n alpha = alpha * (1.0 - fog);\n rgb = rgb * u.fog.w;\n } else {\n rgb = mix(rgb, u.fog.rgb, fog);\n }\n alpha = alpha * in.coverage * in.color.a * u.params.x;\n return vec4f(rgb * alpha, alpha);\n}\n\n@fragment\nfn fs(in: Out) -> @location(0) vec4f {\n return shade(in);\n}\n\n@fragment\nfn fsOit(in: Out) -> Oit {\n return oit(shade(in), in.fog);\n}\n`;\n\nexport const WGSL_MESH = /* wgsl */ `${WGSL_UNIFORMS}\nstruct Out {\n @builtin(position) position: vec4f,\n @location(0) world: vec3f,\n @location(1) normal: vec3f,\n @location(2) color: vec4f,\n};\n\n@vertex\nfn vs(\n @location(0) pos: vec3f,\n @location(1) normal: vec3f,\n @location(2) color: vec4f,\n) -> Out {\n var out: Out;\n out.position = toWebGpuDepth(u.viewProj * vec4f(pos, 1.0));\n out.world = pos;\n out.normal = normal;\n out.color = color;\n return out;\n}\n\nfn shade(in: Out) -> vec4f {\n var n = normalize(in.normal);\n let v = normalize(u.eye.xyz - in.world);\n if (dot(n, v) < 0.0) { n = -n; }\n let l = u.light.xyz;\n let diffuse = max(dot(n, l), 0.0);\n let h = normalize(l + v);\n let specular = pow(max(dot(n, h), 0.0), u.material.w) * u.material.z;\n let rgb = in.color.rgb * (u.material.x + u.material.y * diffuse) + vec3f(specular);\n let alpha = in.color.a * u.params.x;\n return vec4f(rgb * alpha, alpha);\n}\n\n@fragment\nfn fs(in: Out) -> @location(0) vec4f {\n return shade(in);\n}\n\n@fragment\nfn fsOit(in: Out) -> Oit {\n return oit(shade(in), depthCue(in.world));\n}\n`;\n\nexport const WGSL_LINES = /* wgsl */ `${WGSL_UNIFORMS}\nstruct Out {\n @builtin(position) position: vec4f,\n @location(0) across: f32,\n @location(1) color: vec4f,\n};\n\n@vertex\nfn vs(\n @builtin(vertex_index) vi: u32,\n @location(0) a: vec3f,\n @location(1) b: vec3f,\n @location(2) color: vec4f,\n) -> Out {\n var out: Out;\n let corner = vec2f(f32(vi & 1u), f32(vi >> 1u));\n let ca = u.viewProj * vec4f(a, 1.0);\n let cb = u.viewProj * vec4f(b, 1.0);\n let halfSize = u.viewport.xy * 0.5;\n let sa = ca.xy / ca.w * halfSize;\n let sb = cb.xy / cb.w * halfSize;\n var dir = sb - sa;\n let len = length(dir);\n dir = select(vec2f(1.0, 0.0), dir / len, len > 1e-6);\n let normal = vec2f(-dir.y, dir.x);\n let w = max(0.5, u.params.y * u.viewport.z * 0.5) + 0.5;\n let clip = select(ca, cb, corner.x > 0.5);\n let side = corner.y * 2.0 - 1.0;\n let pixel = select(sa, sb, corner.x > 0.5) + dir * (corner.x * 2.0 - 1.0) * w + normal * side * w;\n let z = clip.z - u.eye.w * clip.w;\n out.position = toWebGpuDepth(vec4f(pixel / halfSize * clip.w, z, clip.w));\n out.across = side * w;\n out.color = color;\n return out;\n}\n\n@fragment\nfn fs(in: Out) -> @location(0) vec4f {\n let core = u.params.y * u.viewport.z * 0.5;\n let coverage = clamp(max(core, 0.5) + 0.5 - abs(in.across), 0.0, 1.0) * min(1.0, core * 2.0);\n let alpha = coverage * in.color.a * u.params.x;\n if (alpha <= 0.0) { discard; }\n return vec4f(in.color.rgb * alpha, alpha);\n}\n`;\n\n// ------------------------------------------------------------------- GLSL\n\nconst GLSL_UNIFORMS = `\nuniform mat4 u_viewProj;\nuniform vec4 u_viewport;\nuniform vec4 u_eye;\nuniform vec4 u_light;\nuniform vec4 u_material;\nuniform vec4 u_params;\nuniform vec4 u_fog;\n`;\n\nconst GLSL_POINTS_VS = `\nattribute vec2 a_corner;\nattribute vec3 a_pos;\nattribute float a_size;\nattribute vec4 a_color;\nvarying vec2 v_offset;\nvarying float v_radius;\nvarying vec4 v_color;\nvarying float v_fog;\nvarying float v_coverage;\nvoid main() {\n vec2 corner = a_corner * 2.0 - 1.0;\n vec4 clip = u_viewProj * vec4(a_pos, 1.0);\n float factor = 1.0;\n if (u_params.y > 0.5 && u_viewport.w < 0.5) {\n factor = clamp(u_params.z / max(clip.w, 1e-6), 0.5, 2.0);\n }\n bool glow = u_eye.w > 1.5;\n float raw = max(a_size, 0.0) * u_viewport.z * factor * 0.5;\n float radius = max(raw, glow ? 0.75 : 0.5);\n float reach = glow ? radius * 2.2 + 1.0 : radius + 1.0;\n vec2 shift = corner * reach * 2.0 / u_viewport.xy * clip.w;\n gl_Position = vec4(clip.xy + shift, clip.z, clip.w);\n v_offset = corner * reach;\n v_radius = radius;\n v_color = a_color;\n float near = u_params.z - u_params.w;\n v_fog = clamp((length(a_pos - u_eye.xyz) - near) / (2.0 * u_params.w), 0.0, 1.0);\n v_coverage = min(1.0, raw * raw / (radius * radius));\n}\n`;\n\nconst GLSL_POINTS_FS = `\nvarying vec2 v_offset;\nvarying float v_radius;\nvarying vec4 v_color;\nvarying float v_fog;\nvarying float v_coverage;\nvoid main() {\n float d = length(v_offset);\n float r = v_radius;\n float alpha = clamp(r + 0.5 - d, 0.0, 1.0);\n vec3 rgb = v_color.rgb;\n if (u_eye.w > 1.5) {\n float core = clamp(r * 0.6 + 0.5 - d, 0.0, 1.0);\n float q = d / r;\n alpha = core + (1.0 - core) * exp(-1.2 * q * q);\n rgb = rgb + (vec3(1.0) - rgb) * (0.2 * core);\n } else if (u_eye.w < 0.5) {\n float q = min(d / r, 1.0);\n vec3 n = vec3(v_offset / r, sqrt(max(0.0, 1.0 - q * q)));\n vec3 l = normalize(vec3(-0.45, 0.55, 0.7));\n float lambert = max(dot(n, l), 0.0);\n vec3 shaded = rgb * (0.62 + 0.45 * lambert) + vec3(pow(lambert, 18.0) * 0.28);\n rgb = mix(rgb, shaded, smoothstep(1.5, 3.5, r));\n }\n if (alpha <= 0.004) discard;\n float fog = v_fog * 0.45;\n if (u_light.w > 0.5) {\n alpha = alpha * (1.0 - fog);\n rgb = rgb * u_fog.w;\n } else {\n rgb = mix(rgb, u_fog.rgb, fog);\n }\n alpha = alpha * v_coverage * v_color.a * u_params.x;\n EMIT(vec4(rgb * alpha, alpha), v_fog);\n}\n`;\n\nconst GLSL_MESH_VS = `\nattribute vec3 a_pos;\nattribute vec3 a_normal;\nattribute vec4 a_color;\nvarying vec3 v_world;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvoid main() {\n gl_Position = u_viewProj * vec4(a_pos, 1.0);\n v_world = a_pos;\n v_normal = a_normal;\n v_color = a_color;\n}\n`;\n\nconst GLSL_MESH_FS = `\nvarying vec3 v_world;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvoid main() {\n vec3 n = normalize(v_normal);\n vec3 v = normalize(u_eye.xyz - v_world);\n if (dot(n, v) < 0.0) n = -n;\n vec3 l = u_light.xyz;\n float diffuse = max(dot(n, l), 0.0);\n vec3 h = normalize(l + v);\n float specular = pow(max(dot(n, h), 0.0), u_material.w) * u_material.z;\n vec3 rgb = v_color.rgb * (u_material.x + u_material.y * diffuse) + vec3(specular);\n float alpha = v_color.a * u_params.x;\n float near = u_params.z - u_params.w;\n float depth = (length(v_world - u_eye.xyz) - near) / (2.0 * u_params.w);\n EMIT(vec4(rgb * alpha, alpha), depth);\n}\n`;\n\nconst GLSL_LINES_VS = `\nattribute vec2 a_corner;\nattribute vec3 a_a;\nattribute vec3 a_b;\nattribute vec4 a_color;\nvarying float v_across;\nvarying vec4 v_color;\nvoid main() {\n vec4 ca = u_viewProj * vec4(a_a, 1.0);\n vec4 cb = u_viewProj * vec4(a_b, 1.0);\n vec2 halfSize = u_viewport.xy * 0.5;\n vec2 sa = ca.xy / ca.w * halfSize;\n vec2 sb = cb.xy / cb.w * halfSize;\n vec2 dir = sb - sa;\n float len = length(dir);\n dir = len > 1e-6 ? dir / len : vec2(1.0, 0.0);\n vec2 normal = vec2(-dir.y, dir.x);\n float w = max(0.5, u_params.y * u_viewport.z * 0.5) + 0.5;\n bool atEnd = a_corner.x > 0.5;\n vec4 clip = atEnd ? cb : ca;\n float side = a_corner.y * 2.0 - 1.0;\n vec2 pixel = (atEnd ? sb : sa) + dir * (a_corner.x * 2.0 - 1.0) * w + normal * side * w;\n gl_Position = vec4(pixel / halfSize * clip.w, clip.z - u_eye.w * clip.w, clip.w);\n v_across = side * w;\n v_color = a_color;\n}\n`;\n\nconst GLSL_LINES_FS = `\nvarying float v_across;\nvarying vec4 v_color;\nvoid main() {\n float core = u_params.y * u_viewport.z * 0.5;\n float coverage = clamp(max(core, 0.5) + 0.5 - abs(v_across), 0.0, 1.0) * min(1.0, core * 2.0);\n float alpha = coverage * v_color.a * u_params.x;\n if (alpha <= 0.0) discard;\n EMIT(vec4(v_color.rgb * alpha, alpha), 0.0);\n}\n`;\n\nconst PRECISION = `\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n`;\n\nexport interface GlslSource {\n vertex: string;\n fragment: string;\n}\n\nconst glsl = (\n vs: string,\n fs: string,\n version: 1 | 2,\n oit = false,\n): GlslSource =>\n version === 2\n ? {\n vertex: `#version 300 es\\n#define attribute in\\n#define varying out\\n${GLSL_UNIFORMS}${vs}`,\n fragment: `#version 300 es\\nprecision highp float;\\n#define varying in\\n${GLSL_UNIFORMS}${\n oit\n ? GLSL_OIT\n : \"out vec4 fragColor;\\n#define EMIT(c, d) fragColor = (c)\\n\"\n }${fs}`,\n }\n : {\n vertex: `${GLSL_UNIFORMS}${vs}`,\n fragment: `${PRECISION}#define EMIT(c, d) gl_FragColor = (c)\\n${GLSL_UNIFORMS}${fs}`,\n };\n\n/** GLSL programs of the three primitives for WebGL (1) or WebGL2 */\nexport const glslPrograms = (version: 1 | 2) => ({\n points: glsl(GLSL_POINTS_VS, GLSL_POINTS_FS, version),\n mesh: glsl(GLSL_MESH_VS, GLSL_MESH_FS, version),\n lines: glsl(GLSL_LINES_VS, GLSL_LINES_FS, version),\n});\n\n/**\n * Variants of the points and meshes writing the targets of the\n * order-independent transparency (WebGL2)\n */\nexport const glslOitPrograms = () => ({\n points: glsl(GLSL_POINTS_VS, GLSL_POINTS_FS, 2, true),\n mesh: glsl(GLSL_MESH_VS, GLSL_MESH_FS, 2, true),\n});\n\n/** Attribute names of every program, bound to locations 0, 1, ... */\nexport const GLSL_ATTRIBUTES = {\n points: [\"a_corner\", \"a_pos\", \"a_size\", \"a_color\"],\n mesh: [\"a_pos\", \"a_normal\", \"a_color\"],\n lines: [\"a_corner\", \"a_a\", \"a_b\", \"a_color\"],\n} as const;\n"],"mappings":";;;AAiCA,IAAMA,KACJ,GACA,GACA,GACA,GACA,GACA,GACA,GACA,OAEAC,EAAI,IAAIC,GAAU,CAAC,GACnBD,EAAI,IAAIE,GAAU,EAAE,GACpBF,EAAI,IAAIG,GAAK,EAAE,GACfH,EAAI,IAAII,GAAO,EAAE,GACjBJ,EAAI,IAAIK,GAAU,EAAE,GACpBL,EAAI,IAAIM,GAAQ,EAAE,GAClBN,EAAI,IAAIO,GAAK,EAAE,GACRP,IAIIQ,KACX,GACA,GACA,MACiB;CACjB,IAAMC,IACJC,EAAK,SAAS,WACV,KAAK,cAGLA,EAAK,SAAS,UACZA,EAAK,QACL;CACR,OAAOX,EACLC,GACAW,EAAM,UACN;EAACA,EAAM;EAAOA,EAAM;EAAQA,EAAM;EAAK,KAAM;CAAoB,GACjE;EACEA,EAAM,IAAI;EACVA,EAAM,IAAI;EACVA,EAAM,IAAI;EACVD,EAAK,SAAS,UACVA,EAAK,OACLA,EAAK,SAAS,WACXA,EAAK,SAAA,IACN;CACR,GACA;EACEC,EAAM,MAAM;EACZA,EAAM,MAAM;EACZA,EAAM,MAAM;EACZD,EAAK,SAAS,YAAYA,EAAK,WAAW,IAAI;CAChD,GACAC,EAAM,UACN;EAACD,EAAK;EAASD;EAAQE,EAAM;EAAUA,EAAM;CAAM,GACnD;EAACA,EAAM,IAAI;EAAIA,EAAM,IAAI;EAAIA,EAAM,IAAI;EAAIA,EAAM;CAAQ,CAC3D;AACF,GAIMC,IAA2B;;;;;;;;;;;;;;;;;;;;EAoB/BC,KAEWC,IAAyB,GAAGF,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiF1CG,IAAuB,GAAGH,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CxCI,IAAwB,GAAGJ,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDhDK,IAAgB,6KAUhBC,IAAiB,ohCAgCjBC,IAAiB,inCAqCjBC,IAAe,0RAefC,IAAe,mpBAoBfC,IAAgB,+3BA4BhBC,IAAgB,6VAYhBC,IAAY,0GAaZC,KACJ,GACA,GACA,GACA,IAAM,OAENC,MAAY,IACR;CACE,QAAQ,+DAA+DT,IAAgBU;CACvF,UAAU,gEAAgEV,IACxEW,IACIC,IACA,8DACHC;AACL,IACA;CACE,QAAQ,GAAGb,IAAgBU;CAC3B,UAAU,GAAGH,EAAU,yCAAyCP,IAAgBa;AAClF,GAGOC,KAAgB,OAAoB;CAC/C,QAAQN,EAAKP,GAAgBC,GAAgBO,CAAO;CACpD,MAAMD,EAAKL,GAAcC,GAAcK,CAAO;CAC9C,OAAOD,EAAKH,GAAeC,GAAeG,CAAO;AACnD,IAMaM,WAAyB;CACpC,QAAQP,EAAKP,GAAgBC,GAAgB,GAAG,EAAI;CACpD,MAAMM,EAAKL,GAAcC,GAAc,GAAG,EAAI;AAChD,IAGaY,IAAkB;CAC7B,QAAQ;EAAC;EAAY;EAAS;EAAU;CAAS;CACjD,MAAM;EAAC;EAAS;EAAY;CAAS;CACrC,OAAO;EAAC;EAAY;EAAO;EAAO;CAAS;AAC7C"}
|
|
1
|
+
{"version":3,"file":"shaders.js","names":["writeUniforms","out","viewProj","viewport","eye","light","material","params","fog","itemUniforms","second","item","frame","WGSL_UNIFORMS","WGSL_OIT","WGSL_POINTS","WGSL_MESH","WGSL_LINES","GLSL_UNIFORMS","GLSL_POINTS_VS","GLSL_POINTS_FS","GLSL_MESH_VS","GLSL_MESH_FS","GLSL_LINES_VS","GLSL_LINES_FS","PRECISION","glsl","version","vs","output","GLSL_OIT","GLSL_FRONT","glslScreen","fs","glslPrograms","glslOitPrograms","GLSL_ATTRIBUTES","writesDepth"],"sources":["../../../../../charts/src/engine/three-d/shaders.ts"],"sourcesContent":["// Shaders of the 3D data layer: instanced point billboards (shaded spheres,\n// flat discs or glowing discs), lit triangles (two-sided Lambert +\n// Blinn-Phong) and screen-space wide line segments. WGSL for WebGPU, GLSL ES\n// 1.0 for WebGL (turned into GLSL ES 3.0 for WebGL2 by a macro prefix).\n// Outputs are premultiplied.\n//\n// Uniforms (WGSL struct, GLSL vec4 uniforms of the same names):\n// viewProj world -> clip (OpenGL depth convention)\n// viewport drawing buffer width, height (device px), dpr, orthographic\n// eye camera position, depth bias of the lines (NDC) | point style\n// light unit vector towards the light, additive points (0/1)\n// material ambient, diffuse, specular, shininess\n// params opacity, perspective sizes (0/1) | line width (CSS px), distance, radius\n// fog background color (far points fade towards it), exposure of the\n// additive light\n//\n// Points and meshes have two more fragment entry points for the hybrid\n// order-independent transparency (`oit.ts`): `fsOit` (the four targets) and\n// `fsFront` (the depth of the front transparent layer) in WGSL, the `oit`\n// and `front` variants of the GLSL programs (WebGL2). Elsewhere, additive\n// points are screen blended (`screenTone`: their light is tone mapped as it\n// adds up, no clipping on 8-bit framebuffers).\n//\n// Point sizes are CSS pixels times the device pixel ratio (billboards: no\n// point size limit). Dots thinner than the smallest drawn radius keep their\n// energy: their alpha scales with the area they would cover.\n\nimport { GLSL_FRONT, GLSL_OIT, WGSL_OIT, glslScreen } from \"./oit\";\nimport { POINT_SPHERE, type Frame3D, type Item3D } from \"./render-types\";\n\nexport { writesDepth } from \"./render-types\";\n\n/** Bytes of the WGSL uniform struct */\nexport const UNIFORM_BYTES = 160;\n\n/** Writes the uniforms of an item in the WGSL struct layout */\nconst writeUniforms = (\n out: Float32Array,\n viewProj: Float32Array,\n viewport: readonly [number, number, number, number],\n eye: readonly [number, number, number, number],\n light: readonly [number, number, number, number],\n material: readonly [number, number, number, number],\n params: readonly [number, number, number, number],\n fog: readonly [number, number, number, number],\n): Float32Array => {\n out.set(viewProj, 0);\n out.set(viewport, 16);\n out.set(eye, 20);\n out.set(light, 24);\n out.set(material, 28);\n out.set(params, 32);\n out.set(fog, 36);\n return out;\n};\n\n/** Uniform values of an item (40 floats, the WGSL struct layout) */\nexport const itemUniforms = (\n item: Item3D,\n frame: Frame3D,\n out: Float32Array,\n): Float32Array => {\n const second =\n item.kind === \"points\"\n ? item.perspective\n ? 1\n : 0\n : item.kind === \"lines\"\n ? item.width\n : 0;\n return writeUniforms(\n out,\n frame.viewProj,\n [frame.width, frame.height, frame.dpr, frame.orthographic ? 1 : 0],\n [\n frame.eye[0],\n frame.eye[1],\n frame.eye[2],\n item.kind === \"lines\"\n ? item.bias\n : item.kind === \"points\"\n ? (item.style ?? POINT_SPHERE)\n : 0,\n ],\n [\n frame.light[0],\n frame.light[1],\n frame.light[2],\n item.kind === \"points\" && item.additive ? 1 : 0,\n ],\n frame.lighting,\n [item.opacity, second, frame.distance, frame.radius],\n [frame.fog[0], frame.fog[1], frame.fog[2], frame.exposure],\n );\n};\n\n// ------------------------------------------------------------------- WGSL\n\nconst WGSL_UNIFORMS = /* wgsl */ `\nstruct U {\n viewProj: mat4x4f,\n viewport: vec4f,\n eye: vec4f,\n light: vec4f,\n material: vec4f,\n params: vec4f,\n fog: vec4f,\n};\n@group(0) @binding(0) var<uniform> u: U;\n\nfn toWebGpuDepth(p: vec4f) -> vec4f {\n return vec4f(p.x, p.y, (p.z + p.w) * 0.5, p.w);\n}\n\nfn depthCue(world: vec3f) -> f32 {\n let near = u.params.z - u.params.w;\n return clamp((length(world - u.eye.xyz) - near) / (2.0 * u.params.w), 0.0, 1.0);\n}\n${WGSL_OIT}`;\n\nexport const WGSL_POINTS = /* wgsl */ `${WGSL_UNIFORMS}\nstruct Out {\n @builtin(position) position: vec4f,\n @location(0) offset: vec2f,\n @location(1) radius: f32,\n @location(2) color: vec4f,\n @location(3) fog: f32,\n @location(4) coverage: f32,\n};\n\n@vertex\nfn vs(\n @builtin(vertex_index) vi: u32,\n @location(0) pos: vec3f,\n @location(1) size: f32,\n @location(2) color: vec4f,\n) -> Out {\n var out: Out;\n let corner = vec2f(f32(vi & 1u), f32(vi >> 1u)) * 2.0 - 1.0;\n let clip = u.viewProj * vec4f(pos, 1.0);\n var factor = 1.0;\n if (u.params.y > 0.5 && u.viewport.w < 0.5) {\n factor = clamp(u.params.z / max(clip.w, 1e-6), 0.5, 2.0);\n }\n let glow = u.eye.w > 1.5;\n let raw = max(size, 0.0) * u.viewport.z * factor * 0.5;\n let radius = max(raw, select(0.5, 0.75, glow));\n let reach = select(radius + 1.0, radius * 2.2 + 1.0, glow);\n let shift = corner * reach * 2.0 / u.viewport.xy * clip.w;\n out.position = toWebGpuDepth(vec4f(clip.xy + shift, clip.z, clip.w));\n out.offset = corner * reach;\n out.radius = radius;\n out.color = color;\n out.fog = depthCue(pos);\n out.coverage = min(1.0, raw * raw / (radius * radius));\n return out;\n}\n\nfn shade(in: Out) -> vec4f {\n let d = length(in.offset);\n let r = in.radius;\n var alpha = clamp(r + 0.5 - d, 0.0, 1.0);\n var rgb = in.color.rgb;\n if (u.eye.w > 1.5) {\n // glow: an anti-aliased core and a gaussian halo\n let core = clamp(r * 0.6 + 0.5 - d, 0.0, 1.0);\n let q = d / r;\n alpha = core + (1.0 - core) * exp(-1.2 * q * q);\n rgb = rgb + (vec3f(1.0) - rgb) * (0.2 * core);\n } else if (u.eye.w < 0.5) {\n let q = min(d / r, 1.0);\n let n = vec3f(in.offset.x / r, in.offset.y / r, sqrt(max(0.0, 1.0 - q * q)));\n let l = normalize(vec3f(-0.45, 0.55, 0.7));\n let lambert = max(dot(n, l), 0.0);\n let shaded = rgb * (0.62 + 0.45 * lambert) + vec3f(pow(lambert, 18.0) * 0.28);\n rgb = mix(rgb, shaded, smoothstep(1.5, 3.5, r));\n }\n if (alpha <= 0.004) { discard; }\n let fog = in.fog * 0.45;\n if (u.light.w > 0.5) {\n // additive light fades with the distance\n alpha = alpha * (1.0 - fog);\n rgb = rgb * u.fog.w;\n } else {\n rgb = mix(rgb, u.fog.rgb, fog);\n }\n alpha = alpha * in.coverage * in.color.a * u.params.x;\n return vec4f(rgb * alpha, alpha);\n}\n\n@fragment\nfn fs(in: Out) -> @location(0) vec4f {\n return screenLight(shade(in));\n}\n\n@fragment\nfn fsOit(in: Out) -> Oit {\n return oit(shade(in), in.fog, in.position);\n}\n\n@fragment\nfn fsFront(in: Out) -> @location(0) vec4f {\n return frontDepth(shade(in), in.fog);\n}\n`;\n\nexport const WGSL_MESH = /* wgsl */ `${WGSL_UNIFORMS}\nstruct Out {\n @builtin(position) position: vec4f,\n @location(0) world: vec3f,\n @location(1) normal: vec3f,\n @location(2) color: vec4f,\n};\n\n@vertex\nfn vs(\n @location(0) pos: vec3f,\n @location(1) normal: vec3f,\n @location(2) color: vec4f,\n) -> Out {\n var out: Out;\n out.position = toWebGpuDepth(u.viewProj * vec4f(pos, 1.0));\n out.world = pos;\n out.normal = normal;\n out.color = color;\n return out;\n}\n\nfn shade(in: Out) -> vec4f {\n var n = normalize(in.normal);\n let v = normalize(u.eye.xyz - in.world);\n if (dot(n, v) < 0.0) { n = -n; }\n let l = u.light.xyz;\n let diffuse = max(dot(n, l), 0.0);\n let h = normalize(l + v);\n let specular = pow(max(dot(n, h), 0.0), u.material.w) * u.material.z;\n let rgb = in.color.rgb * (u.material.x + u.material.y * diffuse) + vec3f(specular);\n let alpha = in.color.a * u.params.x;\n return vec4f(rgb * alpha, alpha);\n}\n\n@fragment\nfn fs(in: Out) -> @location(0) vec4f {\n return shade(in);\n}\n\n@fragment\nfn fsOit(in: Out) -> Oit {\n return oit(shade(in), depthCue(in.world), in.position);\n}\n\n@fragment\nfn fsFront(in: Out) -> @location(0) vec4f {\n return frontDepth(shade(in), depthCue(in.world));\n}\n`;\n\nexport const WGSL_LINES = /* wgsl */ `${WGSL_UNIFORMS}\nstruct Out {\n @builtin(position) position: vec4f,\n @location(0) across: f32,\n @location(1) color: vec4f,\n};\n\n@vertex\nfn vs(\n @builtin(vertex_index) vi: u32,\n @location(0) a: vec3f,\n @location(1) b: vec3f,\n @location(2) color: vec4f,\n) -> Out {\n var out: Out;\n let corner = vec2f(f32(vi & 1u), f32(vi >> 1u));\n let ca = u.viewProj * vec4f(a, 1.0);\n let cb = u.viewProj * vec4f(b, 1.0);\n let halfSize = u.viewport.xy * 0.5;\n let sa = ca.xy / ca.w * halfSize;\n let sb = cb.xy / cb.w * halfSize;\n var dir = sb - sa;\n let len = length(dir);\n dir = select(vec2f(1.0, 0.0), dir / len, len > 1e-6);\n let normal = vec2f(-dir.y, dir.x);\n let w = max(0.5, u.params.y * u.viewport.z * 0.5) + 0.5;\n let clip = select(ca, cb, corner.x > 0.5);\n let side = corner.y * 2.0 - 1.0;\n let pixel = select(sa, sb, corner.x > 0.5) + dir * (corner.x * 2.0 - 1.0) * w + normal * side * w;\n let z = clip.z - u.eye.w * clip.w;\n out.position = toWebGpuDepth(vec4f(pixel / halfSize * clip.w, z, clip.w));\n out.across = side * w;\n out.color = color;\n return out;\n}\n\n@fragment\nfn fs(in: Out) -> @location(0) vec4f {\n let core = u.params.y * u.viewport.z * 0.5;\n let coverage = clamp(max(core, 0.5) + 0.5 - abs(in.across), 0.0, 1.0) * min(1.0, core * 2.0);\n let alpha = coverage * in.color.a * u.params.x;\n if (alpha <= 0.0) { discard; }\n return vec4f(in.color.rgb * alpha, alpha);\n}\n`;\n\n// ------------------------------------------------------------------- GLSL\n\nconst GLSL_UNIFORMS = `\nuniform mat4 u_viewProj;\nuniform vec4 u_viewport;\nuniform vec4 u_eye;\nuniform vec4 u_light;\nuniform vec4 u_material;\nuniform vec4 u_params;\nuniform vec4 u_fog;\n`;\n\nconst GLSL_POINTS_VS = `\nattribute vec2 a_corner;\nattribute vec3 a_pos;\nattribute float a_size;\nattribute vec4 a_color;\nvarying vec2 v_offset;\nvarying float v_radius;\nvarying vec4 v_color;\nvarying float v_fog;\nvarying float v_coverage;\nvoid main() {\n vec2 corner = a_corner * 2.0 - 1.0;\n vec4 clip = u_viewProj * vec4(a_pos, 1.0);\n float factor = 1.0;\n if (u_params.y > 0.5 && u_viewport.w < 0.5) {\n factor = clamp(u_params.z / max(clip.w, 1e-6), 0.5, 2.0);\n }\n bool glow = u_eye.w > 1.5;\n float raw = max(a_size, 0.0) * u_viewport.z * factor * 0.5;\n float radius = max(raw, glow ? 0.75 : 0.5);\n float reach = glow ? radius * 2.2 + 1.0 : radius + 1.0;\n vec2 shift = corner * reach * 2.0 / u_viewport.xy * clip.w;\n gl_Position = vec4(clip.xy + shift, clip.z, clip.w);\n v_offset = corner * reach;\n v_radius = radius;\n v_color = a_color;\n float near = u_params.z - u_params.w;\n v_fog = clamp((length(a_pos - u_eye.xyz) - near) / (2.0 * u_params.w), 0.0, 1.0);\n v_coverage = min(1.0, raw * raw / (radius * radius));\n}\n`;\n\nconst GLSL_POINTS_FS = `\nvarying vec2 v_offset;\nvarying float v_radius;\nvarying vec4 v_color;\nvarying float v_fog;\nvarying float v_coverage;\nvoid main() {\n float d = length(v_offset);\n float r = v_radius;\n float alpha = clamp(r + 0.5 - d, 0.0, 1.0);\n vec3 rgb = v_color.rgb;\n if (u_eye.w > 1.5) {\n float core = clamp(r * 0.6 + 0.5 - d, 0.0, 1.0);\n float q = d / r;\n alpha = core + (1.0 - core) * exp(-1.2 * q * q);\n rgb = rgb + (vec3(1.0) - rgb) * (0.2 * core);\n } else if (u_eye.w < 0.5) {\n float q = min(d / r, 1.0);\n vec3 n = vec3(v_offset / r, sqrt(max(0.0, 1.0 - q * q)));\n vec3 l = normalize(vec3(-0.45, 0.55, 0.7));\n float lambert = max(dot(n, l), 0.0);\n vec3 shaded = rgb * (0.62 + 0.45 * lambert) + vec3(pow(lambert, 18.0) * 0.28);\n rgb = mix(rgb, shaded, smoothstep(1.5, 3.5, r));\n }\n if (alpha <= 0.004) discard;\n float fog = v_fog * 0.45;\n if (u_light.w > 0.5) {\n alpha = alpha * (1.0 - fog);\n rgb = rgb * u_fog.w;\n } else {\n rgb = mix(rgb, u_fog.rgb, fog);\n }\n alpha = alpha * v_coverage * v_color.a * u_params.x;\n EMIT(vec4(rgb * alpha, alpha), v_fog);\n}\n`;\n\nconst GLSL_MESH_VS = `\nattribute vec3 a_pos;\nattribute vec3 a_normal;\nattribute vec4 a_color;\nvarying vec3 v_world;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvoid main() {\n gl_Position = u_viewProj * vec4(a_pos, 1.0);\n v_world = a_pos;\n v_normal = a_normal;\n v_color = a_color;\n}\n`;\n\nconst GLSL_MESH_FS = `\nvarying vec3 v_world;\nvarying vec3 v_normal;\nvarying vec4 v_color;\nvoid main() {\n vec3 n = normalize(v_normal);\n vec3 v = normalize(u_eye.xyz - v_world);\n if (dot(n, v) < 0.0) n = -n;\n vec3 l = u_light.xyz;\n float diffuse = max(dot(n, l), 0.0);\n vec3 h = normalize(l + v);\n float specular = pow(max(dot(n, h), 0.0), u_material.w) * u_material.z;\n vec3 rgb = v_color.rgb * (u_material.x + u_material.y * diffuse) + vec3(specular);\n float alpha = v_color.a * u_params.x;\n float near = u_params.z - u_params.w;\n float depth = (length(v_world - u_eye.xyz) - near) / (2.0 * u_params.w);\n EMIT(vec4(rgb * alpha, alpha), depth);\n}\n`;\n\nconst GLSL_LINES_VS = `\nattribute vec2 a_corner;\nattribute vec3 a_a;\nattribute vec3 a_b;\nattribute vec4 a_color;\nvarying float v_across;\nvarying vec4 v_color;\nvoid main() {\n vec4 ca = u_viewProj * vec4(a_a, 1.0);\n vec4 cb = u_viewProj * vec4(a_b, 1.0);\n vec2 halfSize = u_viewport.xy * 0.5;\n vec2 sa = ca.xy / ca.w * halfSize;\n vec2 sb = cb.xy / cb.w * halfSize;\n vec2 dir = sb - sa;\n float len = length(dir);\n dir = len > 1e-6 ? dir / len : vec2(1.0, 0.0);\n vec2 normal = vec2(-dir.y, dir.x);\n float w = max(0.5, u_params.y * u_viewport.z * 0.5) + 0.5;\n bool atEnd = a_corner.x > 0.5;\n vec4 clip = atEnd ? cb : ca;\n float side = a_corner.y * 2.0 - 1.0;\n vec2 pixel = (atEnd ? sb : sa) + dir * (a_corner.x * 2.0 - 1.0) * w + normal * side * w;\n gl_Position = vec4(pixel / halfSize * clip.w, clip.z - u_eye.w * clip.w, clip.w);\n v_across = side * w;\n v_color = a_color;\n}\n`;\n\nconst GLSL_LINES_FS = `\nvarying float v_across;\nvarying vec4 v_color;\nvoid main() {\n float core = u_params.y * u_viewport.z * 0.5;\n float coverage = clamp(max(core, 0.5) + 0.5 - abs(v_across), 0.0, 1.0) * min(1.0, core * 2.0);\n float alpha = coverage * v_color.a * u_params.x;\n if (alpha <= 0.0) discard;\n EMIT(vec4(v_color.rgb * alpha, alpha), 0.0);\n}\n`;\n\nconst PRECISION = `\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n`;\n\nexport interface GlslSource {\n vertex: string;\n fragment: string;\n}\n\n/**\n * Output of a GLSL program: the color (`plain`), the transparency targets\n * (`oit`, WebGL2) or the depth of the front transparent layer (`front`, WebGL2)\n */\ntype GlslOutput = \"plain\" | \"oit\" | \"front\";\n\nconst glsl = (\n vs: string,\n fs: string,\n version: 1 | 2,\n output: GlslOutput = \"plain\",\n): GlslSource =>\n version === 2\n ? {\n vertex: `#version 300 es\\n#define attribute in\\n#define varying out\\n${GLSL_UNIFORMS}${vs}`,\n fragment: `#version 300 es\\nprecision highp float;\\n#define varying in\\n${GLSL_UNIFORMS}${\n output === \"oit\"\n ? GLSL_OIT\n : output === \"front\"\n ? GLSL_FRONT\n : `out vec4 fragColor;\\n${glslScreen(\"fragColor\")}`\n }${fs}`,\n }\n : {\n vertex: `${GLSL_UNIFORMS}${vs}`,\n fragment: `${PRECISION}${GLSL_UNIFORMS}${glslScreen(\"gl_FragColor\")}${fs}`,\n };\n\n/** GLSL programs of the three primitives for WebGL (1) or WebGL2 */\nexport const glslPrograms = (version: 1 | 2) => ({\n points: glsl(GLSL_POINTS_VS, GLSL_POINTS_FS, version),\n mesh: glsl(GLSL_MESH_VS, GLSL_MESH_FS, version),\n lines: glsl(GLSL_LINES_VS, GLSL_LINES_FS, version),\n});\n\n/**\n * Variants of the points and meshes writing the targets of the\n * order-independent transparency (WebGL2), and the front depth of the\n * transparent layers (`front`)\n */\nexport const glslOitPrograms = () => ({\n points: glsl(GLSL_POINTS_VS, GLSL_POINTS_FS, 2, \"oit\"),\n mesh: glsl(GLSL_MESH_VS, GLSL_MESH_FS, 2, \"oit\"),\n front: {\n points: glsl(GLSL_POINTS_VS, GLSL_POINTS_FS, 2, \"front\"),\n mesh: glsl(GLSL_MESH_VS, GLSL_MESH_FS, 2, \"front\"),\n },\n});\n\n/** Attribute names of every program, bound to locations 0, 1, ... */\nexport const GLSL_ATTRIBUTES = {\n points: [\"a_corner\", \"a_pos\", \"a_size\", \"a_color\"],\n mesh: [\"a_pos\", \"a_normal\", \"a_color\"],\n lines: [\"a_corner\", \"a_a\", \"a_b\", \"a_color\"],\n} as const;\n"],"mappings":";;;AAoCA,IAAMA,KACJ,GACA,GACA,GACA,GACA,GACA,GACA,GACA,OAEAC,EAAI,IAAIC,GAAU,CAAC,GACnBD,EAAI,IAAIE,GAAU,EAAE,GACpBF,EAAI,IAAIG,GAAK,EAAE,GACfH,EAAI,IAAII,GAAO,EAAE,GACjBJ,EAAI,IAAIK,GAAU,EAAE,GACpBL,EAAI,IAAIM,GAAQ,EAAE,GAClBN,EAAI,IAAIO,GAAK,EAAE,GACRP,IAIIQ,KACX,GACA,GACA,MACiB;CACjB,IAAMC,IACJC,EAAK,SAAS,WACV,KAAK,cAGLA,EAAK,SAAS,UACZA,EAAK,QACL;CACR,OAAOX,EACLC,GACAW,EAAM,UACN;EAACA,EAAM;EAAOA,EAAM;EAAQA,EAAM;EAAK,KAAM;CAAoB,GACjE;EACEA,EAAM,IAAI;EACVA,EAAM,IAAI;EACVA,EAAM,IAAI;EACVD,EAAK,SAAS,UACVA,EAAK,OACLA,EAAK,SAAS,WACXA,EAAK,SAAA,IACN;CACR,GACA;EACEC,EAAM,MAAM;EACZA,EAAM,MAAM;EACZA,EAAM,MAAM;EACZD,EAAK,SAAS,YAAYA,EAAK,WAAW,IAAI;CAChD,GACAC,EAAM,UACN;EAACD,EAAK;EAASD;EAAQE,EAAM;EAAUA,EAAM;CAAM,GACnD;EAACA,EAAM,IAAI;EAAIA,EAAM,IAAI;EAAIA,EAAM,IAAI;EAAIA,EAAM;CAAQ,CAC3D;AACF,GAIMC,IAA2B;;;;;;;;;;;;;;;;;;;;EAoB/BC,KAEWC,IAAyB,GAAGF,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsF1CG,IAAuB,GAAGH,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDxCI,IAAwB,GAAGJ,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDhDK,IAAgB,6KAUhBC,IAAiB,ohCAgCjBC,IAAiB,inCAqCjBC,IAAe,0RAefC,IAAe,mpBAoBfC,IAAgB,+3BA4BhBC,IAAgB,6VAYhBC,IAAY,0GAmBZC,KACJ,GACA,GACA,GACA,IAAqB,YAErBC,MAAY,IACR;CACE,QAAQ,+DAA+DT,IAAgBU;CACvF,UAAU,gEAAgEV,IACxEW,MAAW,QACPC,IACAD,MAAW,UACTE,IACA,wBAAwBC,EAAW,WAAW,MACnDC;AACL,IACA;CACE,QAAQ,GAAGf,IAAgBU;CAC3B,UAAU,GAAGH,IAAYP,IAAgBc,EAAW,cAAc,IAAIC;AACxE,GAGOC,KAAgB,OAAoB;CAC/C,QAAQR,EAAKP,GAAgBC,GAAgBO,CAAO;CACpD,MAAMD,EAAKL,GAAcC,GAAcK,CAAO;CAC9C,OAAOD,EAAKH,GAAeC,GAAeG,CAAO;AACnD,IAOaQ,WAAyB;CACpC,QAAQT,EAAKP,GAAgBC,GAAgB,GAAG,KAAK;CACrD,MAAMM,EAAKL,GAAcC,GAAc,GAAG,KAAK;CAC/C,OAAO;EACL,QAAQI,EAAKP,GAAgBC,GAAgB,GAAG,OAAO;EACvD,MAAMM,EAAKL,GAAcC,GAAc,GAAG,OAAO;CACnD;AACF,IAGac,IAAkB;CAC7B,QAAQ;EAAC;EAAY;EAAS;EAAU;CAAS;CACjD,MAAM;EAAC;EAAS;EAAY;CAAS;CACrC,OAAO;EAAC;EAAY;EAAO;EAAO;CAAS;AAC7C"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../renderers/gl-budget.cjs"),t=require("./render-types.cjs"),n=require("./oit.cjs"),r=require("./shaders.cjs");var i=/swiftshader|llvmpipe|softpipe|software|basic render driver|microsoft basic/i,a=e=>{let t=e.getExtension(`WEBGL_debug_renderer_info`),n=t?e.getParameter(t.UNMASKED_RENDERER_WEBGL):e.getParameter(e.RENDERER);return i.test(String(n??``))},o=[`u_viewProj`,`u_viewport`,`u_eye`,`u_light`,`u_material`,`u_params`,`u_fog`],s=(e,t,n)=>{let r=(t,n)=>{let r=e.createShader(t);return r?(e.shaderSource(r,n),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(e.deleteShader(r),null)):null},i=r(e.VERTEX_SHADER,t.vertex),a=r(e.FRAGMENT_SHADER,t.fragment),s=e.createProgram();if(!i||!a||!s)return null;if(e.attachShader(s,i),e.attachShader(s,a),n.forEach((t,n)=>e.bindAttribLocation(s,n,t)),e.linkProgram(s),e.deleteShader(i),e.deleteShader(a),!e.getProgramParameter(s,e.LINK_STATUS))return e.deleteProgram(s),null;let c={};for(let t of o)c[t]=e.getUniformLocation(s,t);return{program:s,uniforms:c}},c=new Float32Array([0,0,1,0,0,1,1,1]),l=4,u=4,d=e=>{let t=Number(e.getParameter(e.MAX_SAMPLES))||0,n=Math.max(0,Math.min(u,t));if(!e.getExtension(`EXT_color_buffer_float`))return{samples:n,orderIndependent:!1};let r=e.getInternalformatParameter(e.RENDERBUFFER,e.RGBA16F,e.SAMPLES),i=0;for(let e=0;e<(r?.length??0);e++)i=Math.max(i,r?.[e]??0);return n>1&&i<2?{samples:n,orderIndependent:!1}:{samples:Math.min(n,i||n),orderIndependent:!0}},f=(i,o,u,f=!1)=>{let p={alpha:!0,premultipliedAlpha:!0,antialias:o===1,depth:!0,stencil:!1,preserveDrawingBuffer:!1,failIfMajorPerformanceCaveat:f},m=i.getContext(o===2?`webgl2`:`webgl`,p);if(!m)return null;let h=()=>m.getExtension(`WEBGL_lose_context`)?.loseContext(),g=o===2?m:null;if(f&&a(m))return h(),null;let _=null,v=(e,t)=>{g?g.vertexAttribDivisor(e,t):_?.vertexAttribDivisorANGLE(e,t)},y=e=>{g?g.drawArraysInstanced(m.TRIANGLE_STRIP,0,4,e):_?.drawArraysInstancedANGLE(m.TRIANGLE_STRIP,0,4,e)},b=null,x=null,S={samples:0,orderIndependent:!1},C=null,w=null,T=()=>{b=null,x=null,C=null,w=null,_=g?null:m.getExtension(`ANGLE_instanced_arrays`);let e=g?!0:!!m.getExtension(`OES_element_index_uint`);if(!g&&(!_||!e))return!1;let t=r.glslPrograms(o),i=s(m,t.points,r.GLSL_ATTRIBUTES.points),a=s(m,t.mesh,r.GLSL_ATTRIBUTES.mesh),l=s(m,t.lines,r.GLSL_ATTRIBUTES.lines),u=m.createBuffer();if(!i||!a||!l||!u)return!1;if(b={points:i,mesh:a,lines:l},x=u,m.bindBuffer(m.ARRAY_BUFFER,x),m.bufferData(m.ARRAY_BUFFER,c,m.STATIC_DRAW),S=g?d(g):{samples:0,orderIndependent:!1},g&&S.orderIndependent){let e=r.glslOitPrograms(),t=s(m,e.points,r.GLSL_ATTRIBUTES.points),i=s(m,e.mesh,r.GLSL_ATTRIBUTES.mesh),a=s(m,n.GLSL_COMPOSITE,[]);if(t&&i&&a)C={points:t,mesh:i,composite:a.program},m.useProgram(a.program),m.uniform1i(m.getUniformLocation(a.program,`u_accum`),0),m.uniform1i(m.getUniformLocation(a.program,`u_extra`),1);else for(let e of[t,i,a])e&&m.deleteProgram(e.program)}return!0};if(!T())return h(),null;let E=e=>{if(e.oit){m.deleteFramebuffer(e.oit.fbo);for(let t of e.oit.buffers)m.deleteRenderbuffer(t);for(let t of e.oit.resolved)m.deleteFramebuffer(t);for(let t of e.oit.textures)m.deleteTexture(t);e.oit=null}},D=()=>{w&&(E(w),m.deleteFramebuffer(w.main),m.deleteRenderbuffer(w.color),m.deleteRenderbuffer(w.depth),w=null)},O=(e,t,n)=>{let r=m.createRenderbuffer();return!g||!r?r:(m.bindRenderbuffer(m.RENDERBUFFER,r),S.samples>1?g.renderbufferStorageMultisample(m.RENDERBUFFER,S.samples,e,t,n):m.renderbufferStorage(m.RENDERBUFFER,e,t,n),r)},k=()=>m.checkFramebufferStatus(m.FRAMEBUFFER)===m.FRAMEBUFFER_COMPLETE,A=()=>{if(!g)return null;let{width:e,height:t}=i;if(w?.width===e&&w.height===t)return w;D();let n=m.createFramebuffer(),r=O(g.RGBA8,e,t),a=O(g.DEPTH_COMPONENT24,e,t);return!n||!r||!a?null:(m.bindFramebuffer(m.FRAMEBUFFER,n),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,m.RENDERBUFFER,r),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,a),w={width:e,height:t,main:n,color:r,depth:a,oit:null},k()?w:(D(),null))},j=e=>{if(e.oit||!g)return e.oit;let{width:t,height:n}=e,r=m.createFramebuffer(),i=O(g.RGBA16F,t,n),a=O(g.RGBA16F,t,n),o=[m.createFramebuffer(),m.createFramebuffer()],s=[m.createTexture(),m.createTexture()],[c,l]=o,[u,d]=s;if(!r||!i||!a||!c||!l||!u||!d)return null;e.oit={fbo:r,buffers:[i,a],resolved:[c,l],textures:[u,d]},m.bindFramebuffer(m.FRAMEBUFFER,r),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,m.RENDERBUFFER,i),m.framebufferRenderbuffer(m.FRAMEBUFFER,g.COLOR_ATTACHMENT1,m.RENDERBUFFER,a),m.framebufferRenderbuffer(m.FRAMEBUFFER,m.DEPTH_ATTACHMENT,m.RENDERBUFFER,e.depth),g.drawBuffers([m.COLOR_ATTACHMENT0,g.COLOR_ATTACHMENT1]);let f=k();return e.oit.textures.forEach((r,i)=>{m.bindTexture(m.TEXTURE_2D,r),g.texStorage2D(m.TEXTURE_2D,1,g.RGBA16F,t,n),m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST),m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST),m.bindFramebuffer(m.FRAMEBUFFER,e.oit.resolved[i]),m.framebufferTexture2D(m.FRAMEBUFFER,m.COLOR_ATTACHMENT0,m.TEXTURE_2D,r,0),f&&(f=k())}),m.bindTexture(m.TEXTURE_2D,null),f||(E(e),C=null),e.oit},M=!1,N=null,P=new Map,F=e.claimGlSlot(i,m,{suspend:()=>{P.clear(),b=null,C=null,x=null,w=null},restore:()=>{M||(T()?N&&H(N.items,N.frame):(M=!0,u()))},lost:()=>{M=!0,u()}}),I=new Float32Array(40),L=(e,t,n,r,i,a)=>{m.enableVertexAttribArray(e),m.vertexAttribPointer(e,t,n,n===m.UNSIGNED_BYTE,r,i),v(e,+!!a)},R=(e,t)=>{let n=m.FLOAT,r=m.UNSIGNED_BYTE,i;e.kind===`mesh`?(m.bindBuffer(m.ARRAY_BUFFER,t.vertex),L(0,3,n,28,0,!1),L(1,3,n,28,12,!1),L(2,4,r,28,24,!1),i=3):(m.bindBuffer(m.ARRAY_BUFFER,x),L(0,2,n,0,0,!1),m.bindBuffer(m.ARRAY_BUFFER,t.vertex),e.kind===`points`?(L(1,3,n,20,0,!0),L(2,1,n,20,12,!0),L(3,4,r,20,16,!0)):(L(1,3,n,28,0,!0),L(2,3,n,28,12,!0),L(3,4,r,28,24,!0)),i=4);for(let e=i;e<l;e++)m.disableVertexAttribArray(e),v(e,0)},z=e=>{let t=P.get(e.key);if(t&&t.version===e.version&&t.kind===e.kind)return e.kind===`mesh`&&t.index&&(e.order??0)!==t.order&&(m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,t.index),m.bufferSubData(m.ELEMENT_ARRAY_BUFFER,0,e.indices),t.order=e.order??0),t;t&&(m.deleteBuffer(t.vertex),t.index&&m.deleteBuffer(t.index),P.delete(e.key));let n=m.createBuffer();if(!n)return null;m.bindBuffer(m.ARRAY_BUFFER,n),m.bufferData(m.ARRAY_BUFFER,e.kind===`mesh`?e.vertices:e.data,m.STATIC_DRAW);let r=null;if(e.kind===`mesh`){if(r=m.createBuffer(),!r)return m.deleteBuffer(n),null;m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,r),m.bufferData(m.ELEMENT_ARRAY_BUFFER,e.indices,e.order===void 0?m.STATIC_DRAW:m.DYNAMIC_DRAW)}let i={version:e.version,kind:e.kind,vertex:n,index:r,order:e.kind===`mesh`?e.order??0:0};return P.set(e.key,i),i},B=(e,t,n,i)=>{i.add(e.key);let a=e.kind===`mesh`?e.indices.length:e.count;if(a<=0)return;let o=z(e);if(!o)return;m.useProgram(t.program);let s=r.itemUniforms(e,n,I),c=t.uniforms;m.uniformMatrix4fv(c.u_viewProj,!1,s.subarray(0,16)),m.uniform4fv(c.u_viewport,s.subarray(16,20)),m.uniform4fv(c.u_eye,s.subarray(20,24)),m.uniform4fv(c.u_light,s.subarray(24,28)),m.uniform4fv(c.u_material,s.subarray(28,32)),m.uniform4fv(c.u_params,s.subarray(32,36)),m.uniform4fv(c.u_fog,s.subarray(36,40)),R(e,o),e.kind===`mesh`?(m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,o.index),m.drawElements(m.TRIANGLES,a,m.UNSIGNED_INT,0)):y(a)},V=(e,t,n,r,i)=>{if(!g||!C)return;let{width:a,height:o}=e;m.bindFramebuffer(m.FRAMEBUFFER,t.fbo),g.clearBufferfv(g.COLOR,0,[0,0,0,0]),g.clearBufferfv(g.COLOR,1,[0,0,0,0]),m.depthMask(!1),m.blendFunc(m.ONE,m.ONE);for(let e of n)e.kind!==`lines`&&B(e,C[e.kind],r,i);m.bindFramebuffer(g.READ_FRAMEBUFFER,t.fbo),t.resolved.forEach((e,t)=>{g.readBuffer(t===0?m.COLOR_ATTACHMENT0:g.COLOR_ATTACHMENT1),m.bindFramebuffer(g.DRAW_FRAMEBUFFER,e),g.blitFramebuffer(0,0,a,o,0,0,a,o,m.COLOR_BUFFER_BIT,m.NEAREST)}),m.bindFramebuffer(m.FRAMEBUFFER,e.main),m.blendFunc(m.ONE,m.ONE_MINUS_SRC_ALPHA),m.disable(m.DEPTH_TEST);for(let e=0;e<l;e++)m.disableVertexAttribArray(e),v(e,0);m.useProgram(C.composite),t.textures.forEach((e,t)=>{m.activeTexture(m.TEXTURE0+t),m.bindTexture(m.TEXTURE_2D,e)}),m.drawArrays(m.TRIANGLES,0,3),m.bindTexture(m.TEXTURE_2D,null),m.activeTexture(m.TEXTURE0),m.bindTexture(m.TEXTURE_2D,null),m.enable(m.DEPTH_TEST)},H=(e,n)=>{let r=b;if(!r)return;let a=A();m.bindFramebuffer(m.FRAMEBUFFER,a?a.main:null),m.viewport(0,0,i.width,i.height),m.clearColor(0,0,0,0),m.clearDepth(1),m.depthMask(!0),m.clear(m.COLOR_BUFFER_BIT|m.DEPTH_BUFFER_BIT),m.enable(m.BLEND),m.blendFunc(m.ONE,m.ONE_MINUS_SRC_ALPHA),m.enable(m.DEPTH_TEST),m.depthFunc(m.LEQUAL),m.disable(m.CULL_FACE);let o=new Set,s=t.drawOrder(e),c=s.filter(e=>t.drawRank(e)===2),l=a&&C&&c.length>0?j(a):null,u=!1,d=!l;for(let e of s){let i=t.drawRank(e);if(l&&i===2)continue;a&&l&&i===3&&!d&&(V(a,l,c,n,o),d=!0,u=!1),m.depthMask(t.writesDepth(e));let s=e.kind===`points`&&!!e.additive;s!==u&&(s?m.blendFuncSeparate(m.ONE,m.ONE,m.ONE,m.ONE_MINUS_SRC_ALPHA):m.blendFunc(m.ONE,m.ONE_MINUS_SRC_ALPHA),u=s),B(e,r[e.kind],n,o)}a&&l&&!d&&(V(a,l,c,n,o),u=!1),m.depthMask(!0),u&&m.blendFunc(m.ONE,m.ONE_MINUS_SRC_ALPHA),a&&g&&(m.bindFramebuffer(g.READ_FRAMEBUFFER,a.main),m.bindFramebuffer(g.DRAW_FRAMEBUFFER,null),g.blitFramebuffer(0,0,a.width,a.height,0,0,a.width,a.height,m.COLOR_BUFFER_BIT,m.NEAREST),m.bindFramebuffer(m.FRAMEBUFFER,null));for(let[e,t]of P)o.has(e)||(m.deleteBuffer(t.vertex),t.index&&m.deleteBuffer(t.index),P.delete(e))};return{kind:o===2?`webgl2`:`webgl`,canvas:i,get orderIndependent(){return!!C},resize(e,t){i.width=Math.max(1,e),i.height=Math.max(1,t)},render(e,t){N={items:e,frame:t},!(M||!F.use()||m.isContextLost())&&H(e,t)},destroy(){if(F.release(),N=null,!m.isContextLost()){for(let e of P.values())m.deleteBuffer(e.vertex),e.index&&m.deleteBuffer(e.index);for(let e of Object.values(b??{}))m.deleteProgram(e.program);C&&(m.deleteProgram(C.points.program),m.deleteProgram(C.mesh.program),m.deleteProgram(C.composite)),D(),m.deleteBuffer(x)}C=null,b=null,x=null,w=null,P.clear(),h()}}};exports.SOFTWARE_RENDERER=i,exports.createWebGl3D=f,exports.isSoftwareRenderer=a,exports.webGl2Capabilities=d;
|
|
1
|
+
const e=require("../renderers/gl-budget.cjs"),t=require("./render-types.cjs"),n=require("./oit.cjs"),r=require("./shaders.cjs");var i=/swiftshader|llvmpipe|softpipe|software|basic render driver|microsoft basic/i,a=e=>{let t=e.getExtension(`WEBGL_debug_renderer_info`),n=t?e.getParameter(t.UNMASKED_RENDERER_WEBGL):e.getParameter(e.RENDERER);return i.test(String(n??``))},o=[`u_viewProj`,`u_viewport`,`u_eye`,`u_light`,`u_material`,`u_params`,`u_fog`],s=(e,t,n)=>{let r=(t,n)=>{let r=e.createShader(t);return r?(e.shaderSource(r,n),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(e.deleteShader(r),null)):null},i=r(e.VERTEX_SHADER,t.vertex),a=r(e.FRAGMENT_SHADER,t.fragment),s=e.createProgram();if(!i||!a||!s)return null;if(e.attachShader(s,i),e.attachShader(s,a),n.forEach((t,n)=>e.bindAttribLocation(s,n,t)),e.linkProgram(s),e.deleteShader(i),e.deleteShader(a),!e.getProgramParameter(s,e.LINK_STATUS))return e.deleteProgram(s),null;let c={};for(let t of o)c[t]=e.getUniformLocation(s,t);return{program:s,uniforms:c}},c=new Float32Array([0,0,1,0,0,1,1,1]),l=4,u=4,d=e=>{let t=Number(e.getParameter(e.MAX_SAMPLES))||0,n=Math.max(0,Math.min(u,t));if(!e.getExtension(`EXT_color_buffer_float`))return{samples:n,orderIndependent:!1};let r=e.getInternalformatParameter(e.RENDERBUFFER,e.RGBA16F,e.SAMPLES),i=0;for(let e=0;e<(r?.length??0);e++)i=Math.max(i,r?.[e]??0);return n>1&&i<2?{samples:n,orderIndependent:!1}:{samples:Math.min(n,i||n),orderIndependent:!0}},f=4,p=(i,o,u,p=!1)=>{let m={alpha:!0,premultipliedAlpha:!0,antialias:o===1,depth:!0,stencil:!1,preserveDrawingBuffer:!1,failIfMajorPerformanceCaveat:p},h=i.getContext(o===2?`webgl2`:`webgl`,m);if(!h)return null;let g=()=>h.getExtension(`WEBGL_lose_context`)?.loseContext(),_=o===2?h:null;if(p&&a(h))return g(),null;let v=null,y=(e,t)=>{_?_.vertexAttribDivisor(e,t):v?.vertexAttribDivisorANGLE(e,t)},b=e=>{_?_.drawArraysInstanced(h.TRIANGLE_STRIP,0,4,e):v?.drawArraysInstancedANGLE(h.TRIANGLE_STRIP,0,4,e)},x=null,S=null,C={samples:0,orderIndependent:!1},w=null,T=null,E=()=>{x=null,S=null,w=null,T=null,v=_?null:h.getExtension(`ANGLE_instanced_arrays`);let e=_?!0:!!h.getExtension(`OES_element_index_uint`);if(!_&&(!v||!e))return!1;let t=r.glslPrograms(o),i=s(h,t.points,r.GLSL_ATTRIBUTES.points),a=s(h,t.mesh,r.GLSL_ATTRIBUTES.mesh),l=s(h,t.lines,r.GLSL_ATTRIBUTES.lines),u=h.createBuffer();if(!i||!a||!l||!u)return!1;if(x={points:i,mesh:a,lines:l},S=u,h.bindBuffer(h.ARRAY_BUFFER,S),h.bufferData(h.ARRAY_BUFFER,c,h.STATIC_DRAW),C=_?d(_):{samples:0,orderIndependent:!1},_&&C.orderIndependent){let e=r.glslOitPrograms(),t=s(h,e.points,r.GLSL_ATTRIBUTES.points),i=s(h,e.mesh,r.GLSL_ATTRIBUTES.mesh),a=s(h,e.front.points,r.GLSL_ATTRIBUTES.points),o=s(h,e.front.mesh,r.GLSL_ATTRIBUTES.mesh),c=s(h,n.GLSL_COMPOSITE,[]);if(t&&i&&a&&o&&c){w={points:t,mesh:i,front:{points:a,mesh:o},composite:c.program};for(let e of[t,i])h.useProgram(e.program),h.uniform1i(h.getUniformLocation(e.program,`u_front`),0);h.useProgram(c.program),[`u_frontColor`,`u_accum`,`u_extra`,`u_behind`].forEach((e,t)=>h.uniform1i(h.getUniformLocation(c.program,e),t))}else for(let e of[t,i,a,o,c])e&&h.deleteProgram(e.program)}return!0};if(!E())return g(),null;let D=e=>{if(e.oit){h.deleteFramebuffer(e.oit.fbo);for(let t of e.oit.buffers)h.deleteRenderbuffer(t);for(let t of e.oit.resolved)h.deleteFramebuffer(t);for(let t of e.oit.textures)h.deleteTexture(t);h.deleteFramebuffer(e.oit.frontFbo),h.deleteTexture(e.oit.frontDepth),e.oit=null}},O=()=>{T&&(D(T),h.deleteFramebuffer(T.main),h.deleteRenderbuffer(T.color),h.deleteRenderbuffer(T.depth),T=null)},k=(e,t,n)=>{let r=h.createRenderbuffer();return!_||!r?r:(h.bindRenderbuffer(h.RENDERBUFFER,r),C.samples>1?_.renderbufferStorageMultisample(h.RENDERBUFFER,C.samples,e,t,n):h.renderbufferStorage(h.RENDERBUFFER,e,t,n),r)},A=()=>h.checkFramebufferStatus(h.FRAMEBUFFER)===h.FRAMEBUFFER_COMPLETE,j=()=>{if(!_)return null;let{width:e,height:t}=i;if(T?.width===e&&T.height===t)return T;O();let n=h.createFramebuffer(),r=k(_.RGBA8,e,t),a=k(_.DEPTH_COMPONENT24,e,t);return!n||!r||!a?null:(h.bindFramebuffer(h.FRAMEBUFFER,n),h.framebufferRenderbuffer(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.RENDERBUFFER,r),h.framebufferRenderbuffer(h.FRAMEBUFFER,h.DEPTH_ATTACHMENT,h.RENDERBUFFER,a),T={width:e,height:t,main:n,color:r,depth:a,oit:null},A()?T:(O(),null))},M=e=>{if(e.oit||!_)return e.oit;let{width:t,height:n}=e,r=h.createFramebuffer(),i=h.createFramebuffer(),a=h.createTexture(),o=[],s=[],c=[];for(let e=0;e<f;e++){let e=k(_.RGBA16F,t,n),r=h.createFramebuffer(),i=h.createTexture();e&&o.push(e),r&&s.push(r),i&&c.push(i)}if(e.oit={fbo:r,buffers:o,resolved:s,textures:c,frontFbo:i,frontDepth:a},!r||!i||!a||o.length<f||s.length<f||c.length<f)return D(e),w=null,null;let l=o.map((e,t)=>h.COLOR_ATTACHMENT0+t);h.bindFramebuffer(h.FRAMEBUFFER,r),o.forEach((e,t)=>h.framebufferRenderbuffer(h.FRAMEBUFFER,l[t],h.RENDERBUFFER,e)),h.framebufferRenderbuffer(h.FRAMEBUFFER,h.DEPTH_ATTACHMENT,h.RENDERBUFFER,e.depth),_.drawBuffers(l);let u=A(),d=(e,r,i)=>{h.bindTexture(h.TEXTURE_2D,r),_.texStorage2D(h.TEXTURE_2D,1,i,t,n),h.texParameteri(h.TEXTURE_2D,h.TEXTURE_MIN_FILTER,h.NEAREST),h.texParameteri(h.TEXTURE_2D,h.TEXTURE_MAG_FILTER,h.NEAREST),h.bindFramebuffer(h.FRAMEBUFFER,e),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,r,0),u&&(u=A())};return c.forEach((e,t)=>d(s[t],e,_.RGBA16F)),d(i,a,_.R16F),h.bindTexture(h.TEXTURE_2D,null),u||(D(e),w=null),e.oit},N=!1,P=null,F=new Map,I=e.claimGlSlot(i,h,{suspend:()=>{F.clear(),x=null,w=null,S=null,T=null},restore:()=>{N||(E()?P&&U(P.items,P.frame):(N=!0,u()))},lost:()=>{N=!0,u()}}),L=new Float32Array(40),R=(e,t,n,r,i,a)=>{h.enableVertexAttribArray(e),h.vertexAttribPointer(e,t,n,n===h.UNSIGNED_BYTE,r,i),y(e,+!!a)},z=(e,t,n)=>{let r=h.FLOAT,i=h.UNSIGNED_BYTE,a;if(e.kind===`mesh`)h.bindBuffer(h.ARRAY_BUFFER,t.vertex),R(0,3,r,28,0,!1),R(1,3,r,28,12,!1),R(2,4,i,28,24,!1),a=3;else{if(h.bindBuffer(h.ARRAY_BUFFER,S),R(0,2,r,0,0,!1),h.bindBuffer(h.ARRAY_BUFFER,t.vertex),e.kind===`points`){let e=n*20;R(1,3,r,20,e,!0),R(2,1,r,20,e+12,!0),R(3,4,i,20,e+16,!0)}else R(1,3,r,28,0,!0),R(2,3,r,28,12,!0),R(3,4,i,28,24,!0);a=4}for(let e=a;e<l;e++)h.disableVertexAttribArray(e),y(e,0)},B=e=>{let t=F.get(e.key);if(t&&t.version===e.version&&t.kind===e.kind){let n=e.kind===`lines`?0:e.order??0;return e.kind!==`lines`&&n!==t.order&&(e.kind===`mesh`&&t.index?(h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,t.index),h.bufferSubData(h.ELEMENT_ARRAY_BUFFER,0,e.indices)):e.kind===`points`&&(h.bindBuffer(h.ARRAY_BUFFER,t.vertex),h.bufferSubData(h.ARRAY_BUFFER,0,e.data)),t.order=n),t}t&&(h.deleteBuffer(t.vertex),t.index&&h.deleteBuffer(t.index),F.delete(e.key));let n=h.createBuffer();if(!n)return null;h.bindBuffer(h.ARRAY_BUFFER,n),h.bufferData(h.ARRAY_BUFFER,e.kind===`mesh`?e.vertices:e.data,e.kind===`points`&&e.order!==void 0?h.DYNAMIC_DRAW:h.STATIC_DRAW);let r=null;if(e.kind===`mesh`){if(r=h.createBuffer(),!r)return h.deleteBuffer(n),null;h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,r),h.bufferData(h.ELEMENT_ARRAY_BUFFER,e.indices,e.order===void 0?h.STATIC_DRAW:h.DYNAMIC_DRAW)}let i={version:e.version,kind:e.kind,vertex:n,index:r,order:e.kind===`lines`?0:e.order??0};return F.set(e.key,i),i},V=(e,t,n,i)=>{i.add(e.key);let a=e.kind===`mesh`?e.indices.length:e.count,o=e.kind===`lines`?void 0:e.range,s=o?Math.max(0,Math.min(a,o.first)):0,c=o?Math.max(0,Math.min(a-s,o.count)):a;if(c<=0)return;let l=B(e);if(!l)return;h.useProgram(t.program);let u=r.itemUniforms(e,n,L),d=t.uniforms;h.uniformMatrix4fv(d.u_viewProj,!1,u.subarray(0,16)),h.uniform4fv(d.u_viewport,u.subarray(16,20)),h.uniform4fv(d.u_eye,u.subarray(20,24)),h.uniform4fv(d.u_light,u.subarray(24,28)),h.uniform4fv(d.u_material,u.subarray(28,32)),h.uniform4fv(d.u_params,u.subarray(32,36)),h.uniform4fv(d.u_fog,u.subarray(36,40)),z(e,l,e.kind===`points`?s:0),e.kind===`mesh`?(h.bindBuffer(h.ELEMENT_ARRAY_BUFFER,l.index),h.drawElements(h.TRIANGLES,c,h.UNSIGNED_INT,s*4)):b(c)},H=(e,t,n,r,i)=>{if(!_||!w)return;let{width:a,height:o}=e,s=()=>{for(let e=3;e>=0;e--)h.activeTexture(h.TEXTURE0+e),h.bindTexture(h.TEXTURE_2D,null)};h.bindFramebuffer(h.FRAMEBUFFER,t.frontFbo),_.clearBufferfv(_.COLOR,0,[4,4,4,4]);let c=n.filter(e=>e.kind!==`lines`&&!(e.kind===`points`&&e.additive));if(h.depthMask(!1),c.length){h.disable(h.DEPTH_TEST),_.blendEquation(_.MIN),h.blendFunc(h.ONE,h.ONE);for(let e of c)e.kind!==`lines`&&V(e,w.front[e.kind],r,i);_.blendEquation(h.FUNC_ADD),h.enable(h.DEPTH_TEST)}h.bindFramebuffer(h.FRAMEBUFFER,t.fbo);for(let e=0;e<f;e++)_.clearBufferfv(_.COLOR,e,[0,0,0,0]);h.blendFunc(h.ONE,h.ONE),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,t.frontDepth);for(let e of n)e.kind!==`lines`&&V(e,w[e.kind],r,i);h.bindTexture(h.TEXTURE_2D,null),h.bindFramebuffer(_.READ_FRAMEBUFFER,t.fbo),t.resolved.forEach((e,t)=>{_.readBuffer(h.COLOR_ATTACHMENT0+t),h.bindFramebuffer(_.DRAW_FRAMEBUFFER,e),_.blitFramebuffer(0,0,a,o,0,0,a,o,h.COLOR_BUFFER_BIT,h.NEAREST)}),h.bindFramebuffer(h.FRAMEBUFFER,e.main),h.blendFunc(h.ONE,h.ONE_MINUS_SRC_ALPHA),h.disable(h.DEPTH_TEST);for(let e=0;e<l;e++)h.disableVertexAttribArray(e),y(e,0);h.useProgram(w.composite),t.textures.forEach((e,t)=>{h.activeTexture(h.TEXTURE0+t),h.bindTexture(h.TEXTURE_2D,e)}),h.drawArrays(h.TRIANGLES,0,3),s(),h.enable(h.DEPTH_TEST)},U=(e,n)=>{let r=x;if(!r)return;let a=j();h.bindFramebuffer(h.FRAMEBUFFER,a?a.main:null),h.viewport(0,0,i.width,i.height),h.clearColor(0,0,0,0),h.clearDepth(1),h.depthMask(!0),h.clear(h.COLOR_BUFFER_BIT|h.DEPTH_BUFFER_BIT),h.enable(h.BLEND),h.blendFunc(h.ONE,h.ONE_MINUS_SRC_ALPHA),h.enable(h.DEPTH_TEST),h.depthFunc(h.LEQUAL),h.disable(h.CULL_FACE);let o=new Set,s=t.drawOrder(e),c=s.filter(e=>t.drawRank(e)===2),l=a&&w&&c.length>0?M(a):null,u=!1,d=!l;for(let e of s){let i=t.drawRank(e);if(l&&i===2)continue;a&&l&&i===3&&!d&&(H(a,l,c,n,o),d=!0,u=!1),h.depthMask(t.writesDepth(e));let s=e.kind===`points`&&!!e.additive;s!==u&&(s?h.blendFuncSeparate(h.ONE,h.ONE_MINUS_SRC_COLOR,h.ONE,h.ONE_MINUS_SRC_ALPHA):h.blendFunc(h.ONE,h.ONE_MINUS_SRC_ALPHA),u=s),V(e,r[e.kind],n,o)}a&&l&&!d&&(H(a,l,c,n,o),u=!1),h.depthMask(!0),u&&h.blendFunc(h.ONE,h.ONE_MINUS_SRC_ALPHA),a&&_&&(h.bindFramebuffer(_.READ_FRAMEBUFFER,a.main),h.bindFramebuffer(_.DRAW_FRAMEBUFFER,null),_.blitFramebuffer(0,0,a.width,a.height,0,0,a.width,a.height,h.COLOR_BUFFER_BIT,h.NEAREST),h.bindFramebuffer(h.FRAMEBUFFER,null));for(let[e,t]of F)o.has(e)||(h.deleteBuffer(t.vertex),t.index&&h.deleteBuffer(t.index),F.delete(e))};return{kind:o===2?`webgl2`:`webgl`,canvas:i,get orderIndependent(){return!!w},resize(e,t){i.width=Math.max(1,e),i.height=Math.max(1,t)},render(e,t){P={items:e,frame:t},!(N||!I.use()||h.isContextLost())&&U(e,t)},destroy(){if(I.release(),P=null,!h.isContextLost()){for(let e of F.values())h.deleteBuffer(e.vertex),e.index&&h.deleteBuffer(e.index);for(let e of Object.values(x??{}))h.deleteProgram(e.program);w&&(h.deleteProgram(w.points.program),h.deleteProgram(w.mesh.program),h.deleteProgram(w.front.points.program),h.deleteProgram(w.front.mesh.program),h.deleteProgram(w.composite)),O(),h.deleteBuffer(S)}w=null,x=null,S=null,T=null,F.clear(),g()}}};exports.SOFTWARE_RENDERER=i,exports.createWebGl3D=p,exports.isSoftwareRenderer=a,exports.webGl2Capabilities=d;
|
|
2
2
|
//# sourceMappingURL=webgl.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgl.cjs","names":["glslPrograms","GLSL_ATTRIBUTES","glslOitPrograms","GLSL_COMPOSITE","claimGlSlot","itemUniforms","drawOrder","drawRank","writesDepth","require_gl_budget","require_render_types","require_oit","require_shaders","SOFTWARE_RENDERER","isSoftwareRenderer","info","gl","name","UNIFORMS","compile","shader","s","type","code","vs","source","fs","program","attributes","i","uniforms","CORNERS","MAX_LOCATIONS","MAX_SAMPLES","webGl2Capabilities","max","samples","counts","floatMax","createWebGl3D","version","requireHardware","canvas","loseContext","gl2","angle","divisor","location","value","drawInstanced","count","programs","corners","capabilities","oitPrograms","framebuffers","build","uint","sources","points","mesh","lines","buffer","oit","p","m","c","deleteOit","fb","b","f","deleteFramebuffers","renderbuffer","rb","format","width","height","complete","mainFramebuffer","main","color","depth","oitFramebuffers","fbo","accum","extra","resolved","textures","r0","r1","t0","t1","ok","texture","lost","last","resources","slot","renderFrame","onLost","uniformData","attribute","size","stride","offset","bind","F","U8","used","item","res","upload","existing","vertex","index","draw","seen","u","frame","loc","drawTransparent","blended","target","progs","ordered","items","additive","composited","rank","add","key"],"sources":["../../../../../charts/src/engine/three-d/webgl.ts"],"sourcesContent":["// WebGL2 / WebGL (1) backend of the 3D charts: the same GLSL for both\n// (a macro prefix makes it GLSL ES 3.0), instancing through WebGL2 or\n// ANGLE_instanced_arrays, 32-bit indices through WebGL2 or\n// OES_element_index_uint. Attributes are bound for every draw (no vertex\n// array objects in WebGL 1): a few calls per item.\n//\n// WebGL2 draws into its own multisampled framebuffer, blitted to the canvas.\n// With EXT_color_buffer_float (multisampled RGBA16F), the blended items go\n// through the weighted blended order-independent transparency (`oit.ts`):\n// opaque items, then the blended ones into two float targets sharing the\n// depth buffer (resolved into textures by blits), their composite, then the\n// lines. Otherwise (and on WebGL 1) the blended items are drawn sorted.\n//\n// The context is part of the page-wide budget (`gl-budget.ts`): when it is\n// suspended off-screen, its GPU objects go; the restore builds the programs\n// again (the framebuffers and buffers follow lazily) and redraws the last\n// frame. A suspension is not a loss: only real losses reach `onLost`.\n\nimport type { RendererLostHandler } from \"../renderers/types\";\nimport { claimGlSlot } from \"../renderers/gl-budget\";\nimport { GLSL_COMPOSITE } from \"./oit\";\nimport {\n POINT_STRIDE,\n SEGMENT_STRIDE,\n VERTEX_STRIDE,\n drawOrder,\n drawRank,\n type Frame3D,\n type Item3D,\n type Renderer3D,\n} from \"./render-types\";\nimport {\n GLSL_ATTRIBUTES,\n glslOitPrograms,\n glslPrograms,\n itemUniforms,\n writesDepth,\n type GlslSource,\n} from \"./shaders\";\n\ntype Gl = WebGLRenderingContext | WebGL2RenderingContext;\n\n/** Software rasterizers behind a WebGL context */\nexport const SOFTWARE_RENDERER =\n /swiftshader|llvmpipe|softpipe|software|basic render driver|microsoft basic/i;\n\nexport const isSoftwareRenderer = (gl: Gl): boolean => {\n const info = gl.getExtension(\"WEBGL_debug_renderer_info\");\n const name = info\n ? gl.getParameter(info.UNMASKED_RENDERER_WEBGL)\n : gl.getParameter(gl.RENDERER);\n return SOFTWARE_RENDERER.test(String(name ?? \"\"));\n};\n\nconst UNIFORMS = [\n \"u_viewProj\",\n \"u_viewport\",\n \"u_eye\",\n \"u_light\",\n \"u_material\",\n \"u_params\",\n \"u_fog\",\n] as const;\n\ninterface Program {\n program: WebGLProgram;\n uniforms: Record<(typeof UNIFORMS)[number], WebGLUniformLocation | null>;\n}\n\nconst compile = (\n gl: Gl,\n source: GlslSource,\n attributes: readonly string[],\n): Program | null => {\n const shader = (type: number, code: string) => {\n const s = gl.createShader(type);\n if (!s) return null;\n gl.shaderSource(s, code);\n gl.compileShader(s);\n if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {\n gl.deleteShader(s);\n return null;\n }\n return s;\n };\n const vs = shader(gl.VERTEX_SHADER, source.vertex);\n const fs = shader(gl.FRAGMENT_SHADER, source.fragment);\n const program = gl.createProgram();\n if (!vs || !fs || !program) return null;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n attributes.forEach((name, i) => gl.bindAttribLocation(program, i, name));\n gl.linkProgram(program);\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n gl.deleteProgram(program);\n return null;\n }\n const uniforms = {} as Program[\"uniforms\"];\n for (const name of UNIFORMS)\n uniforms[name] = gl.getUniformLocation(program, name);\n return { program, uniforms };\n};\n\ninterface ItemResources {\n version: number;\n kind: Item3D[\"kind\"];\n vertex: WebGLBuffer;\n index: WebGLBuffer | null;\n /** `order` of the uploaded indices (meshes) */\n order: number;\n}\n\n/** Corners of the triangle strip of a billboard / segment */\nconst CORNERS = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\nconst MAX_LOCATIONS = 4;\nconst MAX_SAMPLES = 4;\n\n/**\n * Samples of the WebGL2 framebuffers and whether the order-independent\n * transparency is possible: float color buffers (EXT_color_buffer_float)\n * that can be multisampled as much as the color\n */\nexport const webGl2Capabilities = (\n gl: WebGL2RenderingContext,\n): { samples: number; orderIndependent: boolean } => {\n const max = Number(gl.getParameter(gl.MAX_SAMPLES)) || 0;\n const samples = Math.max(0, Math.min(MAX_SAMPLES, max));\n if (!gl.getExtension(\"EXT_color_buffer_float\"))\n return { samples, orderIndependent: false };\n const counts = gl.getInternalformatParameter(\n gl.RENDERBUFFER,\n gl.RGBA16F,\n gl.SAMPLES,\n ) as ArrayLike<number> | null;\n let floatMax = 0;\n for (let i = 0; i < (counts?.length ?? 0); i++)\n floatMax = Math.max(floatMax, counts?.[i] ?? 0);\n // single-sampled framebuffers: any float support is enough\n if (samples > 1 && floatMax < 2) return { samples, orderIndependent: false };\n return {\n samples: Math.min(samples, floatMax || samples),\n orderIndependent: true,\n };\n};\n\ninterface Framebuffers {\n width: number;\n height: number;\n main: WebGLFramebuffer;\n color: WebGLRenderbuffer;\n depth: WebGLRenderbuffer;\n /** Transparency targets, created on first use */\n oit: {\n fbo: WebGLFramebuffer;\n buffers: [WebGLRenderbuffer, WebGLRenderbuffer];\n resolved: [WebGLFramebuffer, WebGLFramebuffer];\n textures: [WebGLTexture, WebGLTexture];\n } | null;\n}\n\nexport const createWebGl3D = (\n canvas: HTMLCanvasElement,\n version: 1 | 2,\n onLost: RendererLostHandler,\n /** Refuses software rendering: the decimating Canvas2D backend is faster there */\n requireHardware = false,\n): Renderer3D | null => {\n const attributes: WebGLContextAttributes = {\n alpha: true,\n premultipliedAlpha: true,\n // WebGL2 multisamples its own framebuffer\n antialias: version === 1,\n depth: true,\n stencil: false,\n preserveDrawingBuffer: false,\n failIfMajorPerformanceCaveat: requireHardware,\n };\n const gl = canvas.getContext(\n version === 2 ? \"webgl2\" : \"webgl\",\n attributes,\n ) as Gl | null;\n if (!gl) return null;\n const loseContext = () =>\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n const gl2 = version === 2 ? (gl as WebGL2RenderingContext) : null;\n if (requireHardware && isSoftwareRenderer(gl)) {\n loseContext();\n return null;\n }\n let angle: ANGLE_instanced_arrays | null = null;\n const divisor = (location: number, value: number) => {\n if (gl2) gl2.vertexAttribDivisor(location, value);\n else angle?.vertexAttribDivisorANGLE(location, value);\n };\n const drawInstanced = (count: number) => {\n if (gl2) gl2.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, count);\n else angle?.drawArraysInstancedANGLE(gl.TRIANGLE_STRIP, 0, 4, count);\n };\n\n let programs: Record<Item3D[\"kind\"], Program> | null = null;\n let corners: WebGLBuffer | null = null;\n let capabilities = { samples: 0, orderIndependent: false };\n let oitPrograms: {\n points: Program;\n mesh: Program;\n composite: WebGLProgram;\n } | null = null;\n let framebuffers: Framebuffers | null = null;\n\n /**\n * Extensions, programs, the corner buffer and the transparency programs:\n * at creation and again after a restore (GL objects and extension objects\n * don't survive the context). False when the context can't draw.\n */\n const build = (): boolean => {\n programs = null;\n corners = null;\n oitPrograms = null;\n // recreated lazily at the next draw\n framebuffers = null;\n angle = gl2 ? null : gl.getExtension(\"ANGLE_instanced_arrays\");\n const uint = gl2 ? true : !!gl.getExtension(\"OES_element_index_uint\");\n if (!gl2 && (!angle || !uint)) return false;\n const sources = glslPrograms(version);\n const points = compile(gl, sources.points, GLSL_ATTRIBUTES.points);\n const mesh = compile(gl, sources.mesh, GLSL_ATTRIBUTES.mesh);\n const lines = compile(gl, sources.lines, GLSL_ATTRIBUTES.lines);\n const buffer = gl.createBuffer();\n if (!points || !mesh || !lines || !buffer) return false;\n programs = { points, mesh, lines };\n corners = buffer;\n gl.bindBuffer(gl.ARRAY_BUFFER, corners);\n gl.bufferData(gl.ARRAY_BUFFER, CORNERS, gl.STATIC_DRAW);\n\n // order-independent transparency (WebGL2 with float color buffers)\n capabilities = gl2\n ? webGl2Capabilities(gl2)\n : { samples: 0, orderIndependent: false };\n if (gl2 && capabilities.orderIndependent) {\n const oit = glslOitPrograms();\n const p = compile(gl, oit.points, GLSL_ATTRIBUTES.points);\n const m = compile(gl, oit.mesh, GLSL_ATTRIBUTES.mesh);\n const c = compile(gl, GLSL_COMPOSITE, []);\n if (p && m && c) {\n oitPrograms = { points: p, mesh: m, composite: c.program };\n gl.useProgram(c.program);\n gl.uniform1i(gl.getUniformLocation(c.program, \"u_accum\"), 0);\n gl.uniform1i(gl.getUniformLocation(c.program, \"u_extra\"), 1);\n } else {\n for (const program of [p, m, c])\n if (program) gl.deleteProgram(program.program);\n }\n }\n return true;\n };\n if (!build()) {\n loseContext();\n return null;\n }\n const deleteOit = (fb: Framebuffers) => {\n if (!fb.oit) return;\n gl.deleteFramebuffer(fb.oit.fbo);\n for (const b of fb.oit.buffers) gl.deleteRenderbuffer(b);\n for (const f of fb.oit.resolved) gl.deleteFramebuffer(f);\n for (const t of fb.oit.textures) gl.deleteTexture(t);\n fb.oit = null;\n };\n const deleteFramebuffers = () => {\n if (!framebuffers) return;\n deleteOit(framebuffers);\n gl.deleteFramebuffer(framebuffers.main);\n gl.deleteRenderbuffer(framebuffers.color);\n gl.deleteRenderbuffer(framebuffers.depth);\n framebuffers = null;\n };\n const renderbuffer = (format: number, width: number, height: number) => {\n const rb = gl.createRenderbuffer();\n if (!gl2 || !rb) return rb;\n gl.bindRenderbuffer(gl.RENDERBUFFER, rb);\n if (capabilities.samples > 1)\n gl2.renderbufferStorageMultisample(\n gl.RENDERBUFFER,\n capabilities.samples,\n format,\n width,\n height,\n );\n else gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height);\n return rb;\n };\n const complete = () =>\n gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;\n /** The multisampled framebuffer of WebGL2 (null: draw into the canvas) */\n const mainFramebuffer = (): Framebuffers | null => {\n if (!gl2) return null;\n const { width, height } = canvas;\n if (framebuffers?.width === width && framebuffers.height === height)\n return framebuffers;\n deleteFramebuffers();\n const main = gl.createFramebuffer();\n const color = renderbuffer(gl2.RGBA8, width, height);\n const depth = renderbuffer(gl2.DEPTH_COMPONENT24, width, height);\n if (!main || !color || !depth) return null;\n gl.bindFramebuffer(gl.FRAMEBUFFER, main);\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.RENDERBUFFER,\n color,\n );\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.DEPTH_ATTACHMENT,\n gl.RENDERBUFFER,\n depth,\n );\n framebuffers = { width, height, main, color, depth, oit: null };\n if (!complete()) {\n deleteFramebuffers();\n return null;\n }\n return framebuffers;\n };\n /** The transparency targets sharing the depth of `fb` */\n const oitFramebuffers = (fb: Framebuffers) => {\n if (fb.oit || !gl2) return fb.oit;\n const { width, height } = fb;\n const fbo = gl.createFramebuffer();\n const accum = renderbuffer(gl2.RGBA16F, width, height);\n const extra = renderbuffer(gl2.RGBA16F, width, height);\n const resolved = [gl.createFramebuffer(), gl.createFramebuffer()];\n const textures = [gl.createTexture(), gl.createTexture()];\n const [r0, r1] = resolved;\n const [t0, t1] = textures;\n if (!fbo || !accum || !extra || !r0 || !r1 || !t0 || !t1) return null;\n fb.oit = {\n fbo,\n buffers: [accum, extra],\n resolved: [r0, r1],\n textures: [t0, t1],\n };\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.RENDERBUFFER,\n accum,\n );\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl2.COLOR_ATTACHMENT1,\n gl.RENDERBUFFER,\n extra,\n );\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.DEPTH_ATTACHMENT,\n gl.RENDERBUFFER,\n fb.depth,\n );\n gl2.drawBuffers([gl.COLOR_ATTACHMENT0, gl2.COLOR_ATTACHMENT1]);\n let ok = complete();\n fb.oit.textures.forEach((texture, i) => {\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl2.texStorage2D(gl.TEXTURE_2D, 1, gl2.RGBA16F, width, height);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.bindFramebuffer(gl.FRAMEBUFFER, fb.oit!.resolved[i]!);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0,\n );\n ok &&= complete();\n });\n gl.bindTexture(gl.TEXTURE_2D, null);\n if (!ok) {\n deleteOit(fb);\n oitPrograms = null;\n }\n return fb.oit;\n };\n\n let lost = false;\n let last: { items: readonly Item3D[]; frame: Frame3D } | null = null;\n const resources = new Map<string, ItemResources>();\n // past the page-wide context budget, the context may be suspended while\n // off-screen (not a failure): its GPU objects go, and come back with the\n // context, which then redraws its last frame\n const slot = claimGlSlot(canvas, gl, {\n suspend: () => {\n resources.clear();\n programs = null;\n oitPrograms = null;\n corners = null;\n framebuffers = null;\n },\n restore: () => {\n if (lost) return;\n if (!build()) {\n lost = true;\n onLost();\n } else if (last) renderFrame(last.items, last.frame);\n },\n lost: () => {\n lost = true;\n onLost();\n },\n });\n const uniformData = new Float32Array(40);\n\n const attribute = (\n location: number,\n size: number,\n type: number,\n stride: number,\n offset: number,\n perInstance: boolean,\n ) => {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(\n location,\n size,\n type,\n type === gl.UNSIGNED_BYTE,\n stride,\n offset,\n );\n divisor(location, perInstance ? 1 : 0);\n };\n\n const bind = (item: Item3D, res: ItemResources) => {\n const F = gl.FLOAT;\n const U8 = gl.UNSIGNED_BYTE;\n let used: number;\n if (item.kind === \"mesh\") {\n gl.bindBuffer(gl.ARRAY_BUFFER, res.vertex);\n attribute(0, 3, F, VERTEX_STRIDE, 0, false);\n attribute(1, 3, F, VERTEX_STRIDE, 12, false);\n attribute(2, 4, U8, VERTEX_STRIDE, 24, false);\n used = 3;\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, corners);\n attribute(0, 2, F, 0, 0, false);\n gl.bindBuffer(gl.ARRAY_BUFFER, res.vertex);\n if (item.kind === \"points\") {\n attribute(1, 3, F, POINT_STRIDE, 0, true);\n attribute(2, 1, F, POINT_STRIDE, 12, true);\n attribute(3, 4, U8, POINT_STRIDE, 16, true);\n } else {\n attribute(1, 3, F, SEGMENT_STRIDE, 0, true);\n attribute(2, 3, F, SEGMENT_STRIDE, 12, true);\n attribute(3, 4, U8, SEGMENT_STRIDE, 24, true);\n }\n used = 4;\n }\n for (let i = used; i < MAX_LOCATIONS; i++) {\n gl.disableVertexAttribArray(i);\n divisor(i, 0);\n }\n };\n\n const upload = (item: Item3D): ItemResources | null => {\n const existing = resources.get(item.key);\n if (\n existing &&\n existing.version === item.version &&\n existing.kind === item.kind\n ) {\n // same mesh, triangles in a new order (transparent, sorted by depth)\n if (\n item.kind === \"mesh\" &&\n existing.index &&\n (item.order ?? 0) !== existing.order\n ) {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, existing.index);\n gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, item.indices);\n existing.order = item.order ?? 0;\n }\n return existing;\n }\n if (existing) {\n gl.deleteBuffer(existing.vertex);\n if (existing.index) gl.deleteBuffer(existing.index);\n resources.delete(item.key);\n }\n const vertex = gl.createBuffer();\n if (!vertex) return null;\n gl.bindBuffer(gl.ARRAY_BUFFER, vertex);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n item.kind === \"mesh\" ? item.vertices : item.data,\n gl.STATIC_DRAW,\n );\n let index: WebGLBuffer | null = null;\n if (item.kind === \"mesh\") {\n index = gl.createBuffer();\n if (!index) {\n gl.deleteBuffer(vertex);\n return null;\n }\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index);\n gl.bufferData(\n gl.ELEMENT_ARRAY_BUFFER,\n item.indices,\n item.order === undefined ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW,\n );\n }\n const res = {\n version: item.version,\n kind: item.kind,\n vertex,\n index,\n order: item.kind === \"mesh\" ? (item.order ?? 0) : 0,\n };\n resources.set(item.key, res);\n return res;\n };\n\n /** Sets the uniforms of an item and draws it */\n const draw = (\n item: Item3D,\n program: Program,\n frame: Frame3D,\n seen: Set<string>,\n ) => {\n seen.add(item.key);\n const count = item.kind === \"mesh\" ? item.indices.length : item.count;\n if (count <= 0) return;\n const res = upload(item);\n if (!res) return;\n gl.useProgram(program.program);\n const u = itemUniforms(item, frame, uniformData);\n const loc = program.uniforms;\n gl.uniformMatrix4fv(loc.u_viewProj, false, u.subarray(0, 16));\n gl.uniform4fv(loc.u_viewport, u.subarray(16, 20));\n gl.uniform4fv(loc.u_eye, u.subarray(20, 24));\n gl.uniform4fv(loc.u_light, u.subarray(24, 28));\n gl.uniform4fv(loc.u_material, u.subarray(28, 32));\n gl.uniform4fv(loc.u_params, u.subarray(32, 36));\n gl.uniform4fv(loc.u_fog, u.subarray(36, 40));\n bind(item, res);\n if (item.kind === \"mesh\") {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, res.index);\n gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_INT, 0);\n } else {\n drawInstanced(count);\n }\n };\n\n /** Blended items into the transparency targets, then their composite */\n const drawTransparent = (\n fb: Framebuffers,\n oit: NonNullable<Framebuffers[\"oit\"]>,\n blended: readonly Item3D[],\n frame: Frame3D,\n seen: Set<string>,\n ) => {\n if (!gl2 || !oitPrograms) return;\n const { width, height } = fb;\n gl.bindFramebuffer(gl.FRAMEBUFFER, oit.fbo);\n gl2.clearBufferfv(gl2.COLOR, 0, [0, 0, 0, 0]);\n gl2.clearBufferfv(gl2.COLOR, 1, [0, 0, 0, 0]);\n gl.depthMask(false);\n gl.blendFunc(gl.ONE, gl.ONE);\n for (const item of blended) {\n if (item.kind !== \"lines\")\n draw(item, oitPrograms[item.kind], frame, seen);\n }\n // resolve the samples into the textures read by the composite\n gl.bindFramebuffer(gl2.READ_FRAMEBUFFER, oit.fbo);\n oit.resolved.forEach((target, i) => {\n gl2.readBuffer(i === 0 ? gl.COLOR_ATTACHMENT0 : gl2.COLOR_ATTACHMENT1);\n gl.bindFramebuffer(gl2.DRAW_FRAMEBUFFER, target);\n gl2.blitFramebuffer(\n 0,\n 0,\n width,\n height,\n 0,\n 0,\n width,\n height,\n gl.COLOR_BUFFER_BIT,\n gl.NEAREST,\n );\n });\n gl.bindFramebuffer(gl.FRAMEBUFFER, fb.main);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.disable(gl.DEPTH_TEST);\n for (let i = 0; i < MAX_LOCATIONS; i++) {\n gl.disableVertexAttribArray(i);\n divisor(i, 0);\n }\n gl.useProgram(oitPrograms.composite);\n oit.textures.forEach((texture, i) => {\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n });\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.enable(gl.DEPTH_TEST);\n };\n\n /** Draws a frame (the context is live) */\n const renderFrame = (items: readonly Item3D[], frame: Frame3D) => {\n const progs = programs;\n if (!progs) return;\n const fb = mainFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, fb ? fb.main : null);\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.clearColor(0, 0, 0, 0);\n gl.clearDepth(1);\n gl.depthMask(true);\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.enable(gl.DEPTH_TEST);\n gl.depthFunc(gl.LEQUAL);\n gl.disable(gl.CULL_FACE);\n const seen = new Set<string>();\n const ordered = drawOrder(items);\n const blended = ordered.filter((item) => drawRank(item) === 2);\n const oit =\n fb && oitPrograms && blended.length > 0 ? oitFramebuffers(fb) : null;\n let additive = false;\n let composited = !oit;\n for (const item of ordered) {\n const rank = drawRank(item);\n if (oit && rank === 2) continue;\n if (fb && oit && rank === 3 && !composited) {\n drawTransparent(fb, oit, blended, frame, seen);\n composited = true;\n additive = false;\n }\n gl.depthMask(writesDepth(item));\n const add = item.kind === \"points\" && !!item.additive;\n if (add !== additive) {\n // additive points: the colors add up, the coverage composites as usual\n if (add)\n gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n else gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n additive = add;\n }\n draw(item, progs[item.kind], frame, seen);\n }\n if (fb && oit && !composited) {\n drawTransparent(fb, oit, blended, frame, seen);\n additive = false;\n }\n gl.depthMask(true);\n if (additive) gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n if (fb && gl2) {\n // the samples resolved into the canvas\n gl.bindFramebuffer(gl2.READ_FRAMEBUFFER, fb.main);\n gl.bindFramebuffer(gl2.DRAW_FRAMEBUFFER, null);\n gl2.blitFramebuffer(\n 0,\n 0,\n fb.width,\n fb.height,\n 0,\n 0,\n fb.width,\n fb.height,\n gl.COLOR_BUFFER_BIT,\n gl.NEAREST,\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n for (const [key, res] of resources) {\n if (!seen.has(key)) {\n gl.deleteBuffer(res.vertex);\n if (res.index) gl.deleteBuffer(res.index);\n resources.delete(key);\n }\n }\n };\n\n return {\n kind: version === 2 ? \"webgl2\" : \"webgl\",\n canvas,\n get orderIndependent() {\n return !!oitPrograms;\n },\n resize(width, height) {\n canvas.width = Math.max(1, width);\n canvas.height = Math.max(1, height);\n },\n render(items, frame) {\n last = { items, frame };\n // suspended by the context budget: redrawn by the restore\n if (lost || !slot.use() || gl.isContextLost()) return;\n renderFrame(items, frame);\n },\n destroy() {\n slot.release();\n last = null;\n if (!gl.isContextLost()) {\n for (const res of resources.values()) {\n gl.deleteBuffer(res.vertex);\n if (res.index) gl.deleteBuffer(res.index);\n }\n for (const p of Object.values(programs ?? {})) {\n gl.deleteProgram(p.program);\n }\n if (oitPrograms) {\n gl.deleteProgram(oitPrograms.points.program);\n gl.deleteProgram(oitPrograms.mesh.program);\n gl.deleteProgram(oitPrograms.composite);\n }\n deleteFramebuffers();\n gl.deleteBuffer(corners);\n }\n oitPrograms = null;\n programs = null;\n corners = null;\n framebuffers = null;\n resources.clear();\n loseContext();\n },\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"webgl.cjs","names":["glslPrograms","GLSL_ATTRIBUTES","glslOitPrograms","GLSL_COMPOSITE","claimGlSlot","itemUniforms","drawOrder","drawRank","writesDepth","require_gl_budget","require_render_types","require_oit","require_shaders","SOFTWARE_RENDERER","isSoftwareRenderer","info","gl","name","UNIFORMS","compile","shader","s","type","code","vs","source","fs","program","attributes","i","uniforms","CORNERS","MAX_LOCATIONS","MAX_SAMPLES","webGl2Capabilities","max","samples","counts","floatMax","OIT_TARGETS","createWebGl3D","version","requireHardware","canvas","loseContext","gl2","angle","divisor","location","value","drawInstanced","count","programs","corners","capabilities","oitPrograms","framebuffers","build","uint","sources","points","mesh","lines","buffer","oit","p","m","fp","fm","deleteOit","fb","b","f","deleteFramebuffers","renderbuffer","rb","format","width","height","complete","mainFramebuffer","main","color","depth","oitFramebuffers","fbo","frontFbo","frontDepth","buffers","resolved","textures","t","attachments","ok","attach","texture","target","lost","last","resources","slot","renderFrame","onLost","uniformData","attribute","size","stride","offset","bind","F","U8","used","item","res","base","first","upload","existing","order","vertex","index","draw","seen","total","range","frame","loc","drawTransparent","unbind","layered","blended","progs","ordered","items","additive","composited","rank","add","key"],"sources":["../../../../../charts/src/engine/three-d/webgl.ts"],"sourcesContent":["// WebGL2 / WebGL (1) backend of the 3D charts: the same GLSL for both\n// (a macro prefix makes it GLSL ES 3.0), instancing through WebGL2 or\n// ANGLE_instanced_arrays, 32-bit indices through WebGL2 or\n// OES_element_index_uint. Attributes are bound for every draw (no vertex\n// array objects in WebGL 1): a few calls per item.\n//\n// WebGL2 draws into its own multisampled framebuffer, blitted to the canvas.\n// With EXT_color_buffer_float (multisampled RGBA16F, R16F), the blended items\n// go through the hybrid order-independent transparency (`oit.ts`): opaque\n// items; the depth of the front transparent layer (R16F, `min` blending);\n// the blended items into four float targets sharing the depth buffer\n// (resolved into textures by blits); their composite; then the lines.\n// Otherwise (and on WebGL 1) the blended items come sorted back to front\n// (`sort.ts`, possibly as ranges of their buffers interleaved together) and\n// the additive light is screen blended.\n//\n// The context is part of the page-wide budget (`gl-budget.ts`): when it is\n// suspended off-screen, its GPU objects go; the restore builds the programs\n// again (the framebuffers and buffers follow lazily) and redraws the last\n// frame. A suspension is not a loss: only real losses reach `onLost`.\n\nimport type { RendererLostHandler } from \"../renderers/types\";\nimport { claimGlSlot } from \"../renderers/gl-budget\";\nimport { FRONT_CLEAR, GLSL_COMPOSITE } from \"./oit\";\nimport {\n POINT_STRIDE,\n SEGMENT_STRIDE,\n VERTEX_STRIDE,\n drawOrder,\n drawRank,\n type Frame3D,\n type Item3D,\n type Renderer3D,\n} from \"./render-types\";\nimport {\n GLSL_ATTRIBUTES,\n glslOitPrograms,\n glslPrograms,\n itemUniforms,\n writesDepth,\n type GlslSource,\n} from \"./shaders\";\n\ntype Gl = WebGLRenderingContext | WebGL2RenderingContext;\n\n/** Software rasterizers behind a WebGL context */\nexport const SOFTWARE_RENDERER =\n /swiftshader|llvmpipe|softpipe|software|basic render driver|microsoft basic/i;\n\nexport const isSoftwareRenderer = (gl: Gl): boolean => {\n const info = gl.getExtension(\"WEBGL_debug_renderer_info\");\n const name = info\n ? gl.getParameter(info.UNMASKED_RENDERER_WEBGL)\n : gl.getParameter(gl.RENDERER);\n return SOFTWARE_RENDERER.test(String(name ?? \"\"));\n};\n\nconst UNIFORMS = [\n \"u_viewProj\",\n \"u_viewport\",\n \"u_eye\",\n \"u_light\",\n \"u_material\",\n \"u_params\",\n \"u_fog\",\n] as const;\n\ninterface Program {\n program: WebGLProgram;\n uniforms: Record<(typeof UNIFORMS)[number], WebGLUniformLocation | null>;\n}\n\nconst compile = (\n gl: Gl,\n source: GlslSource,\n attributes: readonly string[],\n): Program | null => {\n const shader = (type: number, code: string) => {\n const s = gl.createShader(type);\n if (!s) return null;\n gl.shaderSource(s, code);\n gl.compileShader(s);\n if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {\n gl.deleteShader(s);\n return null;\n }\n return s;\n };\n const vs = shader(gl.VERTEX_SHADER, source.vertex);\n const fs = shader(gl.FRAGMENT_SHADER, source.fragment);\n const program = gl.createProgram();\n if (!vs || !fs || !program) return null;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n attributes.forEach((name, i) => gl.bindAttribLocation(program, i, name));\n gl.linkProgram(program);\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n gl.deleteProgram(program);\n return null;\n }\n const uniforms = {} as Program[\"uniforms\"];\n for (const name of UNIFORMS)\n uniforms[name] = gl.getUniformLocation(program, name);\n return { program, uniforms };\n};\n\ninterface ItemResources {\n version: number;\n kind: Item3D[\"kind\"];\n vertex: WebGLBuffer;\n index: WebGLBuffer | null;\n /** `order` of the uploaded indices (meshes) or points */\n order: number;\n}\n\n/** Corners of the triangle strip of a billboard / segment */\nconst CORNERS = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\nconst MAX_LOCATIONS = 4;\nconst MAX_SAMPLES = 4;\n\n/**\n * Samples of the WebGL2 framebuffers and whether the order-independent\n * transparency is possible: float color buffers (EXT_color_buffer_float)\n * that can be multisampled as much as the color\n */\nexport const webGl2Capabilities = (\n gl: WebGL2RenderingContext,\n): { samples: number; orderIndependent: boolean } => {\n const max = Number(gl.getParameter(gl.MAX_SAMPLES)) || 0;\n const samples = Math.max(0, Math.min(MAX_SAMPLES, max));\n if (!gl.getExtension(\"EXT_color_buffer_float\"))\n return { samples, orderIndependent: false };\n const counts = gl.getInternalformatParameter(\n gl.RENDERBUFFER,\n gl.RGBA16F,\n gl.SAMPLES,\n ) as ArrayLike<number> | null;\n let floatMax = 0;\n for (let i = 0; i < (counts?.length ?? 0); i++)\n floatMax = Math.max(floatMax, counts?.[i] ?? 0);\n // single-sampled framebuffers: any float support is enough\n if (samples > 1 && floatMax < 2) return { samples, orderIndependent: false };\n return {\n samples: Math.min(samples, floatMax || samples),\n orderIndependent: true,\n };\n};\n\ninterface Framebuffers {\n width: number;\n height: number;\n main: WebGLFramebuffer;\n color: WebGLRenderbuffer;\n depth: WebGLRenderbuffer;\n /** Transparency targets, created on first use */\n oit: {\n /** front color, accum, extra, behind (multisampled, sharing the depth) */\n fbo: WebGLFramebuffer;\n buffers: WebGLRenderbuffer[];\n /** Their resolved textures, read by the composite */\n resolved: WebGLFramebuffer[];\n textures: WebGLTexture[];\n /** Depth of the front transparent layer (single-sampled R16F) */\n frontFbo: WebGLFramebuffer;\n frontDepth: WebGLTexture;\n } | null;\n}\n\n/** Targets of the transparency pass (`oit.ts`) */\nconst OIT_TARGETS = 4;\n\nexport const createWebGl3D = (\n canvas: HTMLCanvasElement,\n version: 1 | 2,\n onLost: RendererLostHandler,\n /** Refuses software rendering: the decimating Canvas2D backend is faster there */\n requireHardware = false,\n): Renderer3D | null => {\n const attributes: WebGLContextAttributes = {\n alpha: true,\n premultipliedAlpha: true,\n // WebGL2 multisamples its own framebuffer\n antialias: version === 1,\n depth: true,\n stencil: false,\n preserveDrawingBuffer: false,\n failIfMajorPerformanceCaveat: requireHardware,\n };\n const gl = canvas.getContext(\n version === 2 ? \"webgl2\" : \"webgl\",\n attributes,\n ) as Gl | null;\n if (!gl) return null;\n const loseContext = () =>\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n const gl2 = version === 2 ? (gl as WebGL2RenderingContext) : null;\n if (requireHardware && isSoftwareRenderer(gl)) {\n loseContext();\n return null;\n }\n let angle: ANGLE_instanced_arrays | null = null;\n const divisor = (location: number, value: number) => {\n if (gl2) gl2.vertexAttribDivisor(location, value);\n else angle?.vertexAttribDivisorANGLE(location, value);\n };\n const drawInstanced = (count: number) => {\n if (gl2) gl2.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, count);\n else angle?.drawArraysInstancedANGLE(gl.TRIANGLE_STRIP, 0, 4, count);\n };\n\n let programs: Record<Item3D[\"kind\"], Program> | null = null;\n let corners: WebGLBuffer | null = null;\n let capabilities = { samples: 0, orderIndependent: false };\n let oitPrograms: {\n points: Program;\n mesh: Program;\n front: { points: Program; mesh: Program };\n composite: WebGLProgram;\n } | null = null;\n let framebuffers: Framebuffers | null = null;\n\n /**\n * Extensions, programs, the corner buffer and the transparency programs:\n * at creation and again after a restore (GL objects and extension objects\n * don't survive the context). False when the context can't draw.\n */\n const build = (): boolean => {\n programs = null;\n corners = null;\n oitPrograms = null;\n // recreated lazily at the next draw\n framebuffers = null;\n angle = gl2 ? null : gl.getExtension(\"ANGLE_instanced_arrays\");\n const uint = gl2 ? true : !!gl.getExtension(\"OES_element_index_uint\");\n if (!gl2 && (!angle || !uint)) return false;\n const sources = glslPrograms(version);\n const points = compile(gl, sources.points, GLSL_ATTRIBUTES.points);\n const mesh = compile(gl, sources.mesh, GLSL_ATTRIBUTES.mesh);\n const lines = compile(gl, sources.lines, GLSL_ATTRIBUTES.lines);\n const buffer = gl.createBuffer();\n if (!points || !mesh || !lines || !buffer) return false;\n programs = { points, mesh, lines };\n corners = buffer;\n gl.bindBuffer(gl.ARRAY_BUFFER, corners);\n gl.bufferData(gl.ARRAY_BUFFER, CORNERS, gl.STATIC_DRAW);\n\n // order-independent transparency (WebGL2 with float color buffers)\n capabilities = gl2\n ? webGl2Capabilities(gl2)\n : { samples: 0, orderIndependent: false };\n if (gl2 && capabilities.orderIndependent) {\n const oit = glslOitPrograms();\n const p = compile(gl, oit.points, GLSL_ATTRIBUTES.points);\n const m = compile(gl, oit.mesh, GLSL_ATTRIBUTES.mesh);\n const fp = compile(gl, oit.front.points, GLSL_ATTRIBUTES.points);\n const fm = compile(gl, oit.front.mesh, GLSL_ATTRIBUTES.mesh);\n const c = compile(gl, GLSL_COMPOSITE, []);\n if (p && m && fp && fm && c) {\n oitPrograms = {\n points: p,\n mesh: m,\n front: { points: fp, mesh: fm },\n composite: c.program,\n };\n // the front depth at unit 0 in the transparency pass\n for (const program of [p, m]) {\n gl.useProgram(program.program);\n gl.uniform1i(gl.getUniformLocation(program.program, \"u_front\"), 0);\n }\n gl.useProgram(c.program);\n [\"u_frontColor\", \"u_accum\", \"u_extra\", \"u_behind\"].forEach((name, i) =>\n gl.uniform1i(gl.getUniformLocation(c.program, name), i),\n );\n } else {\n for (const program of [p, m, fp, fm, c])\n if (program) gl.deleteProgram(program.program);\n }\n }\n return true;\n };\n if (!build()) {\n loseContext();\n return null;\n }\n const deleteOit = (fb: Framebuffers) => {\n if (!fb.oit) return;\n gl.deleteFramebuffer(fb.oit.fbo);\n for (const b of fb.oit.buffers) gl.deleteRenderbuffer(b);\n for (const f of fb.oit.resolved) gl.deleteFramebuffer(f);\n for (const t of fb.oit.textures) gl.deleteTexture(t);\n gl.deleteFramebuffer(fb.oit.frontFbo);\n gl.deleteTexture(fb.oit.frontDepth);\n fb.oit = null;\n };\n const deleteFramebuffers = () => {\n if (!framebuffers) return;\n deleteOit(framebuffers);\n gl.deleteFramebuffer(framebuffers.main);\n gl.deleteRenderbuffer(framebuffers.color);\n gl.deleteRenderbuffer(framebuffers.depth);\n framebuffers = null;\n };\n const renderbuffer = (format: number, width: number, height: number) => {\n const rb = gl.createRenderbuffer();\n if (!gl2 || !rb) return rb;\n gl.bindRenderbuffer(gl.RENDERBUFFER, rb);\n if (capabilities.samples > 1)\n gl2.renderbufferStorageMultisample(\n gl.RENDERBUFFER,\n capabilities.samples,\n format,\n width,\n height,\n );\n else gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height);\n return rb;\n };\n const complete = () =>\n gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;\n /** The multisampled framebuffer of WebGL2 (null: draw into the canvas) */\n const mainFramebuffer = (): Framebuffers | null => {\n if (!gl2) return null;\n const { width, height } = canvas;\n if (framebuffers?.width === width && framebuffers.height === height)\n return framebuffers;\n deleteFramebuffers();\n const main = gl.createFramebuffer();\n const color = renderbuffer(gl2.RGBA8, width, height);\n const depth = renderbuffer(gl2.DEPTH_COMPONENT24, width, height);\n if (!main || !color || !depth) return null;\n gl.bindFramebuffer(gl.FRAMEBUFFER, main);\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.RENDERBUFFER,\n color,\n );\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.DEPTH_ATTACHMENT,\n gl.RENDERBUFFER,\n depth,\n );\n framebuffers = { width, height, main, color, depth, oit: null };\n if (!complete()) {\n deleteFramebuffers();\n return null;\n }\n return framebuffers;\n };\n /** The transparency targets sharing the depth of `fb` */\n const oitFramebuffers = (fb: Framebuffers) => {\n if (fb.oit || !gl2) return fb.oit;\n const { width, height } = fb;\n const fbo = gl.createFramebuffer();\n const frontFbo = gl.createFramebuffer();\n const frontDepth = gl.createTexture();\n const buffers: WebGLRenderbuffer[] = [];\n const resolved: WebGLFramebuffer[] = [];\n const textures: WebGLTexture[] = [];\n for (let i = 0; i < OIT_TARGETS; i++) {\n const b = renderbuffer(gl2.RGBA16F, width, height);\n const r = gl.createFramebuffer();\n const t = gl.createTexture();\n if (b) buffers.push(b);\n if (r) resolved.push(r);\n if (t) textures.push(t);\n }\n fb.oit = {\n fbo: fbo!,\n buffers,\n resolved,\n textures,\n frontFbo: frontFbo!,\n frontDepth: frontDepth!,\n };\n if (\n !fbo ||\n !frontFbo ||\n !frontDepth ||\n buffers.length < OIT_TARGETS ||\n resolved.length < OIT_TARGETS ||\n textures.length < OIT_TARGETS\n ) {\n deleteOit(fb);\n oitPrograms = null;\n return null;\n }\n const attachments = buffers.map((_, i) => gl.COLOR_ATTACHMENT0 + i);\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n buffers.forEach((b, i) =>\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n attachments[i]!,\n gl.RENDERBUFFER,\n b,\n ),\n );\n gl.framebufferRenderbuffer(\n gl.FRAMEBUFFER,\n gl.DEPTH_ATTACHMENT,\n gl.RENDERBUFFER,\n fb.depth,\n );\n gl2.drawBuffers(attachments);\n let ok = complete();\n const attach = (\n target: WebGLFramebuffer,\n texture: WebGLTexture,\n format: number,\n ) => {\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl2.texStorage2D(gl.TEXTURE_2D, 1, format, width, height);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.bindFramebuffer(gl.FRAMEBUFFER, target);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n texture,\n 0,\n );\n ok &&= complete();\n };\n textures.forEach((texture, i) =>\n attach(resolved[i]!, texture, gl2.RGBA16F),\n );\n attach(frontFbo, frontDepth, gl2.R16F);\n gl.bindTexture(gl.TEXTURE_2D, null);\n if (!ok) {\n deleteOit(fb);\n oitPrograms = null;\n }\n return fb.oit;\n };\n\n let lost = false;\n let last: { items: readonly Item3D[]; frame: Frame3D } | null = null;\n const resources = new Map<string, ItemResources>();\n // past the page-wide context budget, the context may be suspended while\n // off-screen (not a failure): its GPU objects go, and come back with the\n // context, which then redraws its last frame\n const slot = claimGlSlot(canvas, gl, {\n suspend: () => {\n resources.clear();\n programs = null;\n oitPrograms = null;\n corners = null;\n framebuffers = null;\n },\n restore: () => {\n if (lost) return;\n if (!build()) {\n lost = true;\n onLost();\n } else if (last) renderFrame(last.items, last.frame);\n },\n lost: () => {\n lost = true;\n onLost();\n },\n });\n const uniformData = new Float32Array(40);\n\n const attribute = (\n location: number,\n size: number,\n type: number,\n stride: number,\n offset: number,\n perInstance: boolean,\n ) => {\n gl.enableVertexAttribArray(location);\n gl.vertexAttribPointer(\n location,\n size,\n type,\n type === gl.UNSIGNED_BYTE,\n stride,\n offset,\n );\n divisor(location, perInstance ? 1 : 0);\n };\n\n const bind = (item: Item3D, res: ItemResources, first: number) => {\n const F = gl.FLOAT;\n const U8 = gl.UNSIGNED_BYTE;\n let used: number;\n if (item.kind === \"mesh\") {\n gl.bindBuffer(gl.ARRAY_BUFFER, res.vertex);\n attribute(0, 3, F, VERTEX_STRIDE, 0, false);\n attribute(1, 3, F, VERTEX_STRIDE, 12, false);\n attribute(2, 4, U8, VERTEX_STRIDE, 24, false);\n used = 3;\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, corners);\n attribute(0, 2, F, 0, 0, false);\n gl.bindBuffer(gl.ARRAY_BUFFER, res.vertex);\n if (item.kind === \"points\") {\n // a range of the instances: the attributes start at its first one\n const base = first * POINT_STRIDE;\n attribute(1, 3, F, POINT_STRIDE, base, true);\n attribute(2, 1, F, POINT_STRIDE, base + 12, true);\n attribute(3, 4, U8, POINT_STRIDE, base + 16, true);\n } else {\n attribute(1, 3, F, SEGMENT_STRIDE, 0, true);\n attribute(2, 3, F, SEGMENT_STRIDE, 12, true);\n attribute(3, 4, U8, SEGMENT_STRIDE, 24, true);\n }\n used = 4;\n }\n for (let i = used; i < MAX_LOCATIONS; i++) {\n gl.disableVertexAttribArray(i);\n divisor(i, 0);\n }\n };\n\n const upload = (item: Item3D): ItemResources | null => {\n const existing = resources.get(item.key);\n if (\n existing &&\n existing.version === item.version &&\n existing.kind === item.kind\n ) {\n // same buffers in a new order (sorted back to front): rewritten\n const order = item.kind === \"lines\" ? 0 : (item.order ?? 0);\n if (item.kind !== \"lines\" && order !== existing.order) {\n if (item.kind === \"mesh\" && existing.index) {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, existing.index);\n gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, item.indices);\n } else if (item.kind === \"points\") {\n gl.bindBuffer(gl.ARRAY_BUFFER, existing.vertex);\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, item.data);\n }\n existing.order = order;\n }\n return existing;\n }\n if (existing) {\n gl.deleteBuffer(existing.vertex);\n if (existing.index) gl.deleteBuffer(existing.index);\n resources.delete(item.key);\n }\n const vertex = gl.createBuffer();\n if (!vertex) return null;\n gl.bindBuffer(gl.ARRAY_BUFFER, vertex);\n gl.bufferData(\n gl.ARRAY_BUFFER,\n item.kind === \"mesh\" ? item.vertices : item.data,\n item.kind === \"points\" && item.order !== undefined\n ? gl.DYNAMIC_DRAW\n : gl.STATIC_DRAW,\n );\n let index: WebGLBuffer | null = null;\n if (item.kind === \"mesh\") {\n index = gl.createBuffer();\n if (!index) {\n gl.deleteBuffer(vertex);\n return null;\n }\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index);\n gl.bufferData(\n gl.ELEMENT_ARRAY_BUFFER,\n item.indices,\n item.order === undefined ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW,\n );\n }\n const res = {\n version: item.version,\n kind: item.kind,\n vertex,\n index,\n order: item.kind === \"lines\" ? 0 : (item.order ?? 0),\n };\n resources.set(item.key, res);\n return res;\n };\n\n /** Sets the uniforms of an item and draws it */\n const draw = (\n item: Item3D,\n program: Program,\n frame: Frame3D,\n seen: Set<string>,\n ) => {\n seen.add(item.key);\n const total = item.kind === \"mesh\" ? item.indices.length : item.count;\n const range = item.kind === \"lines\" ? undefined : item.range;\n const first = range ? Math.max(0, Math.min(total, range.first)) : 0;\n const count = range\n ? Math.max(0, Math.min(total - first, range.count))\n : total;\n if (count <= 0) return;\n const res = upload(item);\n if (!res) return;\n gl.useProgram(program.program);\n const u = itemUniforms(item, frame, uniformData);\n const loc = program.uniforms;\n gl.uniformMatrix4fv(loc.u_viewProj, false, u.subarray(0, 16));\n gl.uniform4fv(loc.u_viewport, u.subarray(16, 20));\n gl.uniform4fv(loc.u_eye, u.subarray(20, 24));\n gl.uniform4fv(loc.u_light, u.subarray(24, 28));\n gl.uniform4fv(loc.u_material, u.subarray(28, 32));\n gl.uniform4fv(loc.u_params, u.subarray(32, 36));\n gl.uniform4fv(loc.u_fog, u.subarray(36, 40));\n bind(item, res, item.kind === \"points\" ? first : 0);\n if (item.kind === \"mesh\") {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, res.index);\n gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_INT, first * 4);\n } else {\n drawInstanced(count);\n }\n };\n\n /**\n * Blended items into the transparency targets (`oit.ts`): the depth of the\n * front layer first, then the four targets; their composite\n */\n const drawTransparent = (\n fb: Framebuffers,\n oit: NonNullable<Framebuffers[\"oit\"]>,\n blended: readonly Item3D[],\n frame: Frame3D,\n seen: Set<string>,\n ) => {\n if (!gl2 || !oitPrograms) return;\n const { width, height } = fb;\n const unbind = () => {\n for (let i = OIT_TARGETS - 1; i >= 0; i--) {\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n };\n // front pass: the nearest visible depth of the non-additive items\n gl.bindFramebuffer(gl.FRAMEBUFFER, oit.frontFbo);\n gl2.clearBufferfv(gl2.COLOR, 0, [\n FRONT_CLEAR,\n FRONT_CLEAR,\n FRONT_CLEAR,\n FRONT_CLEAR,\n ]);\n const layered = blended.filter(\n (item) =>\n item.kind !== \"lines\" && !(item.kind === \"points\" && item.additive),\n );\n gl.depthMask(false);\n if (layered.length) {\n gl.disable(gl.DEPTH_TEST);\n gl2.blendEquation(gl2.MIN);\n gl.blendFunc(gl.ONE, gl.ONE);\n for (const item of layered) {\n if (item.kind !== \"lines\")\n draw(item, oitPrograms.front[item.kind], frame, seen);\n }\n gl2.blendEquation(gl.FUNC_ADD);\n gl.enable(gl.DEPTH_TEST);\n }\n // main pass: every blended item, testing the opaque depth\n gl.bindFramebuffer(gl.FRAMEBUFFER, oit.fbo);\n for (let i = 0; i < OIT_TARGETS; i++)\n gl2.clearBufferfv(gl2.COLOR, i, [0, 0, 0, 0]);\n gl.blendFunc(gl.ONE, gl.ONE);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, oit.frontDepth);\n for (const item of blended) {\n if (item.kind !== \"lines\")\n draw(item, oitPrograms[item.kind], frame, seen);\n }\n gl.bindTexture(gl.TEXTURE_2D, null);\n // resolve the samples into the textures read by the composite\n gl.bindFramebuffer(gl2.READ_FRAMEBUFFER, oit.fbo);\n oit.resolved.forEach((target, i) => {\n gl2.readBuffer(gl.COLOR_ATTACHMENT0 + i);\n gl.bindFramebuffer(gl2.DRAW_FRAMEBUFFER, target);\n gl2.blitFramebuffer(\n 0,\n 0,\n width,\n height,\n 0,\n 0,\n width,\n height,\n gl.COLOR_BUFFER_BIT,\n gl.NEAREST,\n );\n });\n gl.bindFramebuffer(gl.FRAMEBUFFER, fb.main);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.disable(gl.DEPTH_TEST);\n for (let i = 0; i < MAX_LOCATIONS; i++) {\n gl.disableVertexAttribArray(i);\n divisor(i, 0);\n }\n gl.useProgram(oitPrograms.composite);\n oit.textures.forEach((texture, i) => {\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n });\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n unbind();\n gl.enable(gl.DEPTH_TEST);\n };\n\n /** Draws a frame (the context is live) */\n const renderFrame = (items: readonly Item3D[], frame: Frame3D) => {\n const progs = programs;\n if (!progs) return;\n const fb = mainFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, fb ? fb.main : null);\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.clearColor(0, 0, 0, 0);\n gl.clearDepth(1);\n gl.depthMask(true);\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.enable(gl.DEPTH_TEST);\n gl.depthFunc(gl.LEQUAL);\n gl.disable(gl.CULL_FACE);\n const seen = new Set<string>();\n const ordered = drawOrder(items);\n const blended = ordered.filter((item) => drawRank(item) === 2);\n const oit =\n fb && oitPrograms && blended.length > 0 ? oitFramebuffers(fb) : null;\n let additive = false;\n let composited = !oit;\n for (const item of ordered) {\n const rank = drawRank(item);\n if (oit && rank === 2) continue;\n if (fb && oit && rank === 3 && !composited) {\n drawTransparent(fb, oit, blended, frame, seen);\n composited = true;\n additive = false;\n }\n gl.depthMask(writesDepth(item));\n const add = item.kind === \"points\" && !!item.additive;\n if (add !== additive) {\n // additive points: their light screen blended (tone mapped as it\n // adds up, `screenTone`), the coverage composites as usual\n if (add)\n gl.blendFuncSeparate(\n gl.ONE,\n gl.ONE_MINUS_SRC_COLOR,\n gl.ONE,\n gl.ONE_MINUS_SRC_ALPHA,\n );\n else gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n additive = add;\n }\n draw(item, progs[item.kind], frame, seen);\n }\n if (fb && oit && !composited) {\n drawTransparent(fb, oit, blended, frame, seen);\n additive = false;\n }\n gl.depthMask(true);\n if (additive) gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n if (fb && gl2) {\n // the samples resolved into the canvas\n gl.bindFramebuffer(gl2.READ_FRAMEBUFFER, fb.main);\n gl.bindFramebuffer(gl2.DRAW_FRAMEBUFFER, null);\n gl2.blitFramebuffer(\n 0,\n 0,\n fb.width,\n fb.height,\n 0,\n 0,\n fb.width,\n fb.height,\n gl.COLOR_BUFFER_BIT,\n gl.NEAREST,\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n for (const [key, res] of resources) {\n if (!seen.has(key)) {\n gl.deleteBuffer(res.vertex);\n if (res.index) gl.deleteBuffer(res.index);\n resources.delete(key);\n }\n }\n };\n\n return {\n kind: version === 2 ? \"webgl2\" : \"webgl\",\n canvas,\n get orderIndependent() {\n return !!oitPrograms;\n },\n resize(width, height) {\n canvas.width = Math.max(1, width);\n canvas.height = Math.max(1, height);\n },\n render(items, frame) {\n last = { items, frame };\n // suspended by the context budget: redrawn by the restore\n if (lost || !slot.use() || gl.isContextLost()) return;\n renderFrame(items, frame);\n },\n destroy() {\n slot.release();\n last = null;\n if (!gl.isContextLost()) {\n for (const res of resources.values()) {\n gl.deleteBuffer(res.vertex);\n if (res.index) gl.deleteBuffer(res.index);\n }\n for (const p of Object.values(programs ?? {})) {\n gl.deleteProgram(p.program);\n }\n if (oitPrograms) {\n gl.deleteProgram(oitPrograms.points.program);\n gl.deleteProgram(oitPrograms.mesh.program);\n gl.deleteProgram(oitPrograms.front.points.program);\n gl.deleteProgram(oitPrograms.front.mesh.program);\n gl.deleteProgram(oitPrograms.composite);\n }\n deleteFramebuffers();\n gl.deleteBuffer(corners);\n }\n oitPrograms = null;\n programs = null;\n corners = null;\n framebuffers = null;\n resources.clear();\n loseContext();\n },\n };\n};\n"],"mappings":"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"}
|