From cc76a39a72dd6f434a7387def8120020b9a88ff2 Mon Sep 17 00:00:00 2001 From: Leander Lauenburg Date: Sun, 16 Mar 2025 15:09:51 +0100 Subject: [PATCH 1/2] camera distance based scaling --- synanno/static/SharkViewer/shark_viewer.js | 24 ++++++++ synanno/static/shaders/ConeShader.js | 28 +++++++--- synanno/static/shaders/ParticleShader.js | 64 ++++++++++++---------- 3 files changed, 78 insertions(+), 38 deletions(-) diff --git a/synanno/static/SharkViewer/shark_viewer.js b/synanno/static/SharkViewer/shark_viewer.js index 5f0cbd9..e3ea614 100644 --- a/synanno/static/SharkViewer/shark_viewer.js +++ b/synanno/static/SharkViewer/shark_viewer.js @@ -879,6 +879,8 @@ import { } }); + this.trackControls.addEventListener("change", this.updateCameraDistance.bind(this)); + this.raycaster.params.Points.threshold = DEFAULT_POINT_THRESHOLD; this.raycaster.params.Line.threshold = DEFAULT_LINE_THRESHOLD; @@ -957,6 +959,28 @@ import { this.render(); } + getCameraDistance() { + if (!this.camera || !this.trackControls) { + return 1.0; // Fallback in case of missing camera or controls + } + return this.camera.position.distanceTo(this.trackControls.target); + } + + updateCameraDistance() { + if (!this.camera || !this.scene) return; + + const cameraDistance = this.getCameraDistance(); + + this.scene.traverse((node) => { + if (node.material?.uniforms?.cameraDistance) { + node.material.uniforms.cameraDistance.value = cameraDistance; + node.material.uniforms.cameraDistance.needsUpdate = true; // 🔥 Ensure shader update + } + }); + + console.log("Updated cameraDistance in shader:", cameraDistance); + } + // render the scene render() { if (this.postprocessing.enabled) { diff --git a/synanno/static/shaders/ConeShader.js b/synanno/static/shaders/ConeShader.js index 7c0727f..9a23245 100644 --- a/synanno/static/shaders/ConeShader.js +++ b/synanno/static/shaders/ConeShader.js @@ -1,27 +1,38 @@ const ConeShader = { uniforms: { - sphereTexture: { value: null }, // Texture for 3D shading + sphereTexture: { value: null }, + cameraDistance: { value: 1.0 }, }, vertexShader: /* glsl */ ` + uniform float cameraDistance; attribute float radius; - attribute float grey_out; // Now a per-instance attribute + attribute float grey_out; varying vec2 sphereUv; varying vec4 mvPosition; varying float depthScale; varying vec3 vColor; - varying float vGreyOut; // Pass to frprojectionMatrixagment shader + varying float vGreyOut; void main() { - vColor = color; // Keep region-based coloring - vGreyOut = grey_out; // Pass grey-out status + vColor = color; + vGreyOut = grey_out; mvPosition = modelViewMatrix * vec4(position, 1.0); vec3 cylAxis = (modelViewMatrix * vec4(normal, 0.0)).xyz; vec3 sideDir = normalize(cross(vec3(0.0,0.0,-1.0), cylAxis)); - mvPosition += vec4(radius * sideDir, 0.0); + + float clampedDistance = clamp(cameraDistance, 500.0, 100000.0); + + float t = 1.0 - exp(-((clampedDistance - 500.0) / 15000.0)); + + float baseScale = mix(120.0, 5.0, t); + + float adjustedRadius = clamp(radius * (baseScale / 100.0), 10.0, 100.0); + + mvPosition += vec4(adjustedRadius * sideDir, 0.0); gl_Position = projectionMatrix * mvPosition; sphereUv = uv - vec2(0.5, 0.5); @@ -36,7 +47,7 @@ const ConeShader = { float foreshortening = length(cylAxis) / length(cylAxis.xy); if (foreshortening > 4.0) foreshortening = 0.9; - depthScale = radius * foreshortening; + depthScale = adjustedRadius * foreshortening; } `, @@ -47,7 +58,7 @@ const ConeShader = { varying vec4 mvPosition; varying float depthScale; varying vec3 vColor; - varying float vGreyOut; // Get from vertex shader + varying float vGreyOut; void main() { @@ -59,7 +70,6 @@ const ConeShader = { float finalAlpha = sphereColors.a; - // Apply greying out if vGreyOut is active if (vGreyOut > 0.5) { highlightColor = vec3(dot(highlightColor, vec3(0.299, 0.587, 0.114))); finalAlpha *= 0.3; diff --git a/synanno/static/shaders/ParticleShader.js b/synanno/static/shaders/ParticleShader.js index 409300e..684c5a9 100644 --- a/synanno/static/shaders/ParticleShader.js +++ b/synanno/static/shaders/ParticleShader.js @@ -1,62 +1,68 @@ const ParticleShader = { uniforms: { - particleScale: { value: 1.0 }, + cameraDistance: { value: 1.0 }, // Unified distance scaling + particleScale: { value: 1.0 }, // Uniform scaling factor sphereTexture: { value: null }, abstraction_threshold: { value: 0.0 }, - }, vertexShader: /* glsl */ ` + uniform float cameraDistance; uniform float particleScale; attribute float radius; - attribute float grey_out; // Per-instance attribute + attribute float grey_out; varying vec4 mvPosition; varying vec3 vColor; - varying float vRadius; - varying float vGreyOut; // Pass to fragment shader + varying float vGreyOut; void main() { mvPosition = modelViewMatrix * vec4(position, 1.0); - gl_PointSize = radius * ((particleScale * 2.5) / length(mvPosition.z)); + + float clampedDistance = clamp(cameraDistance, 500.0, 100000.0); + + float t = 1.0 - exp(-((clampedDistance - 500.0) / 15000.0)); + + float baseScale = mix(100.0, 1.0, t); + + gl_PointSize = clamp(radius * (baseScale / 100.0), 10.0, 50.0); + + vColor = color; - vRadius = radius; - vGreyOut = grey_out; // Pass grey-out status + vGreyOut = grey_out; gl_Position = projectionMatrix * mvPosition; } `, fragmentShader: /* glsl */ ` - uniform sampler2D sphereTexture; - varying vec3 vColor; - varying vec4 mvPosition; - varying float vGreyOut; // Get from vertex shader + uniform sampler2D sphereTexture; + varying vec3 vColor; + varying float vGreyOut; + + void main() + { + vec3 baseColor = vColor; + vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y); + vec4 sphereColors = texture2D(sphereTexture, uv); - void main() - { - vec3 baseColor = vColor; - vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y); - vec4 sphereColors = texture2D(sphereTexture, uv); + if (sphereColors.a < 0.3) discard; - if (sphereColors.a < 0.3) discard; + baseColor = mix(baseColor, baseColor * sphereColors.r, 0.75); + baseColor += sphereColors.ggg * 0.6; - baseColor = mix(baseColor, baseColor * sphereColors.r, 0.75); - baseColor += sphereColors.ggg * 0.6; + float finalAlpha = sphereColors.a; - float finalAlpha = sphereColors.a; + if (vGreyOut > 0.5) { + baseColor = vec3(dot(baseColor, vec3(0.299, 0.587, 0.114))); + finalAlpha *= 0.3; + } - // Apply greying out if vGreyOut is active - if (vGreyOut > 0.5) { - baseColor = vec3(dot(baseColor, vec3(0.299, 0.587, 0.114))); - finalAlpha *= 0.3; + gl_FragColor = vec4(baseColor, finalAlpha); } - - gl_FragColor = vec4(baseColor, finalAlpha); - } -` + ` }; export { ParticleShader }; From 5f1ea7205a5179bd154dbea1ffd12379776f8d97 Mon Sep 17 00:00:00 2001 From: Leander Lauenburg Date: Sun, 16 Mar 2025 15:12:25 +0100 Subject: [PATCH 2/2] cleand up comments --- synanno/static/SharkViewer/shark_viewer.js | 4 ++-- synanno/static/shaders/ParticleShader.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/synanno/static/SharkViewer/shark_viewer.js b/synanno/static/SharkViewer/shark_viewer.js index e3ea614..7e7353e 100644 --- a/synanno/static/SharkViewer/shark_viewer.js +++ b/synanno/static/SharkViewer/shark_viewer.js @@ -961,7 +961,7 @@ import { getCameraDistance() { if (!this.camera || !this.trackControls) { - return 1.0; // Fallback in case of missing camera or controls + return 1.0; } return this.camera.position.distanceTo(this.trackControls.target); } @@ -974,7 +974,7 @@ import { this.scene.traverse((node) => { if (node.material?.uniforms?.cameraDistance) { node.material.uniforms.cameraDistance.value = cameraDistance; - node.material.uniforms.cameraDistance.needsUpdate = true; // 🔥 Ensure shader update + node.material.uniforms.cameraDistance.needsUpdate = true; } }); diff --git a/synanno/static/shaders/ParticleShader.js b/synanno/static/shaders/ParticleShader.js index 684c5a9..4731b7a 100644 --- a/synanno/static/shaders/ParticleShader.js +++ b/synanno/static/shaders/ParticleShader.js @@ -1,7 +1,7 @@ const ParticleShader = { uniforms: { - cameraDistance: { value: 1.0 }, // Unified distance scaling - particleScale: { value: 1.0 }, // Uniform scaling factor + cameraDistance: { value: 1.0 }, + particleScale: { value: 1.0 }, sphereTexture: { value: null }, abstraction_threshold: { value: 0.0 }, },