3D viewer: electron-microscope render mode as default (custom shader: monochrome, edge glow, raster scanlines); ?render=normal to disable

This commit is contained in:
trilium-share-gruvbox
2026-09-07 22:00:48 +02:00
parent 0c13f83c67
commit 36d4a19b70
+51 -2
View File
@@ -13,6 +13,41 @@
var STEP_PARAMS = { linearDeflection: 0.4, angularDeflection: 0.2 };
// Default render mode is the electron-microscope look; append ?render=normal to disable.
var RENDER_MODE = new URLSearchParams(window.location.search).get("render") || "em";
var EM_VERT = [
"varying vec3 vNormal;",
"varying vec3 vViewPos;",
"void main() {",
" vNormal = normalize(normalMatrix * normal);",
" vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);",
" vViewPos = mvPosition.xyz;",
" gl_Position = projectionMatrix * mvPosition;",
"}"
].join("\n");
var EM_FRAG = [
"uniform vec3 uColor;",
"uniform vec3 uLightDir;",
"varying vec3 vNormal;",
"varying vec3 vViewPos;",
"float emHash(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }",
"void main() {",
" vec3 N = normalize(vNormal);",
" vec3 L = normalize(uLightDir);",
" float diff = max(dot(N, L), 0.0);",
" float back = max(dot(N, -L), 0.0) * 0.2;",
" float lum = 0.25 + diff * 0.75 + back;",
" vec3 dN = fwidth(vNormal) * 2.0;",
" vec3 dP = fwidth(vViewPos);",
" float edge = clamp(length(dN) * 6.0 + length(dP) * 0.4, 0.0, 1.0);",
" float line = smoothstep(0.0, 0.4, mod(gl_FragCoord.y, 4.0) - 1.2);",
" float scan = 0.82 + 0.18 * line;",
" vec3 col = uColor * (lum * scan + edge * 0.6);",
" col += vec3(0.04) * (emHash(gl_FragCoord.xy) - 0.5);",
" gl_FragColor = vec4(col, 1.0);",
"}"
].join("\n");
var WORKER_SRC = [
'import { OcctKernel } from "' + OCCT_JS_ABS + '";',
"let kernel = null; let initP = null;",
@@ -234,6 +269,20 @@
renderer.setSize(initSize.w, initSize.h);
var cs = getComputedStyle(document.documentElement);
function cssVar(n, fb) { var v = (cs.getPropertyValue(n) || "").trim(); return v || fb; }
function buildMaterial() {
if (RENDER_MODE === "em") {
return new THREE.ShaderMaterial({
uniforms: {
uColor: { value: new THREE.Color(0xd6d6d6) },
uLightDir: { value: new THREE.Vector3(0.6, 0.9, 0.4).normalize() }
},
vertexShader: EM_VERT,
fragmentShader: EM_FRAG,
side: THREE.DoubleSide
});
}
return new THREE.MeshStandardMaterial({ color: cssVar("--model-viewer-color", cssVar("--background-active", "#e0a15c")), metalness: 0.2, roughness: 0.6, side: THREE.DoubleSide, flatShading: false });
}
renderer.setClearColor(cssVar("--background-primary", "#1d150f"), 1);
var scene = new THREE.Scene();
@@ -310,7 +359,7 @@
geo.setAttribute("position", new THREE.Float32BufferAttribute(e.data.positions, 3));
if (e.data.indices) geo.setIndex(new THREE.BufferAttribute(e.data.indices, 1));
fixWinding(geo);
var mat = new THREE.MeshStandardMaterial({ color: cssVar("--model-viewer-color", cssVar("--background-active", "#e0a15c")), metalness: 0.2, roughness: 0.6, side: THREE.DoubleSide, flatShading: false });
var mat = buildMaterial();
chunkGeometry(geo, group, mat);
var tris = (e.data.indices && e.data.indices.length) ? e.data.indices.length / 3 : e.data.positions.length / 9;
fit();
@@ -332,7 +381,7 @@
} else {
var geo = new THREE.STLLoader().parse(data.buffer);
geo.computeVertexNormals();
var mat = new THREE.MeshStandardMaterial({ color: cssVar("--model-viewer-color", cssVar("--background-active", "#e0a15c")), metalness: 0.25, roughness: 0.55, flatShading: true });
var mat = buildMaterial();
group.add(new THREE.Mesh(geo, mat));
fit();
showCanvas();