@vitessce/spatial-accelerated 3.8.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/LICENSE +21 -0
- package/dist/index.js +52925 -0
- package/dist-tsc/SpatialWrapper.d.ts +2 -0
- package/dist-tsc/SpatialWrapper.d.ts.map +1 -0
- package/dist-tsc/SpatialWrapper.js +45 -0
- package/dist-tsc/VolumeDataManager.d.ts +170 -0
- package/dist-tsc/VolumeDataManager.d.ts.map +1 -0
- package/dist-tsc/VolumeDataManager.js +1273 -0
- package/dist-tsc/VolumeDataManager.test.d.ts +2 -0
- package/dist-tsc/VolumeDataManager.test.d.ts.map +1 -0
- package/dist-tsc/VolumeDataManager.test.js +164 -0
- package/dist-tsc/VolumeRenderManager.d.ts +265 -0
- package/dist-tsc/VolumeRenderManager.d.ts.map +1 -0
- package/dist-tsc/VolumeRenderManager.js +396 -0
- package/dist-tsc/VolumeShader.d.ts +262 -0
- package/dist-tsc/VolumeShader.d.ts.map +1 -0
- package/dist-tsc/VolumeShader.js +73 -0
- package/dist-tsc/VolumeView.d.ts +2 -0
- package/dist-tsc/VolumeView.d.ts.map +1 -0
- package/dist-tsc/VolumeView.js +521 -0
- package/dist-tsc/index.d.ts +2 -0
- package/dist-tsc/index.d.ts.map +1 -0
- package/dist-tsc/index.js +1 -0
- package/dist-tsc/shaders/GaussianFragmentShader.d.ts +2 -0
- package/dist-tsc/shaders/GaussianFragmentShader.d.ts.map +1 -0
- package/dist-tsc/shaders/GaussianFragmentShader.js +242 -0
- package/dist-tsc/shaders/GaussianVertexShader.d.ts +2 -0
- package/dist-tsc/shaders/GaussianVertexShader.d.ts.map +1 -0
- package/dist-tsc/shaders/GaussianVertexShader.js +51 -0
- package/dist-tsc/shaders/VolumeFragmentShader.d.ts +2 -0
- package/dist-tsc/shaders/VolumeFragmentShader.d.ts.map +1 -0
- package/dist-tsc/shaders/VolumeFragmentShader.js +1817 -0
- package/dist-tsc/shaders/VolumeVertexShader.d.ts +2 -0
- package/dist-tsc/shaders/VolumeVertexShader.d.ts.map +1 -0
- package/dist-tsc/shaders/VolumeVertexShader.js +110 -0
- package/package.json +63 -0
- package/src/SpatialWrapper.js +60 -0
- package/src/VolumeDataManager.js +1515 -0
- package/src/VolumeDataManager.test.js +180 -0
- package/src/VolumeRenderManager.js +589 -0
- package/src/VolumeShader.js +74 -0
- package/src/VolumeView.js +651 -0
- package/src/index.js +1 -0
- package/src/shaders/GaussianFragmentShader.js +243 -0
- package/src/shaders/GaussianVertexShader.js +52 -0
- package/src/shaders/VolumeFragmentShader.js +1818 -0
- package/src/shaders/VolumeVertexShader.js +111 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export const volumeVertexShader: "//\n// Output: Unnormalized ray direction from camera to each vertex\n// Used by fragment shader for ray marching through the volume\nout vec3 rayDirUnnorm;\n\n// Output: Camera position transformed into volume's local coordinate system\n// Used to calculate ray origins in the fragment shader\nout vec3 cameraCorrected;\n\n// Volume scale uniform (likely for anisotropic voxels)\nuniform vec3 u_vol_scale;\n\n// Volume size uniform\nuniform vec3 u_size;\n\n// Output: Vertex positions normalized to [0,1] range within volume bounds\n// Standard coordinate system for volume sampling\nvarying vec3 worldSpaceCoords;\n\n// Output: Texture coordinates for sampling volume data\nvarying vec2 vUv;\n\n// Output: Final clip-space position (stored for fragment shader access)\nvarying vec4 glPosition;\n\n// Volume bounding box size uniform\nuniform highp vec3 boxSize;\n\nvoid main()\n{\n // Transform vertex positions from [-0.5, 0.5] range to [0, 1] range\n // This is the standard coordinate system for volume sampling\n //\n // Mathematical transformation:\n // worldSpaceCoords = (position / boxSize) + 0.5\n // \n // Example:\n // position = (-0.5, -0.5, -0.5) → worldSpaceCoords = (0, 0, 0)\n // position = ( 0.0, 0.0, 0.0) → worldSpaceCoords = (0.5, 0.5, 0.5)\n // position = ( 0.5, 0.5, 0.5) → worldSpaceCoords = (1, 1, 1)\n worldSpaceCoords = position / boxSize + vec3(0.5, 0.5, 0.5); //move it from [-0.5;0.5] to [0,1]\n \n // Transform camera position into volume's local coordinate system\n // This gives us the ray origin in volume space\n cameraCorrected = (inverse(modelMatrix) * vec4(cameraPosition, 1.)).xyz;\n \n // Calculate unnormalized ray direction from camera to each vertex\n // Used by fragment shader for ray marching through the volume\n rayDirUnnorm = position - cameraCorrected;\n \n // Apply standard MVP transformation to get clip-space coordinates\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n \n // Store clip-space position for fragment shader access\n glPosition = gl_Position;\n \n // Pass through texture coordinates for volume sampling\n vUv = uv;\n}\n";
|
|
2
|
+
//# sourceMappingURL=VolumeVertexShader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VolumeVertexShader.d.ts","sourceRoot":"","sources":["../../src/shaders/VolumeVertexShader.js"],"names":[],"mappings":"AAmDA,oqEA2DE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Attribution: Originally written by @alexandrairger
|
|
2
|
+
// Moved from .glsl file to .js file in this commit: https://github.com/vitessce/vitessce/pull/2264/commits/7f17fc003674a4ed1a8de6140db802781871cf88
|
|
3
|
+
/*
|
|
4
|
+
|
|
5
|
+
============================================================================
|
|
6
|
+
VOLUME RENDERING PIPELINE OVERVIEW
|
|
7
|
+
============================================================================
|
|
8
|
+
|
|
9
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
10
|
+
│ Vertex Shader │───▶│ Fragment Shader │───▶│ Final Image │
|
|
11
|
+
│ (this shader) │ │ (ray marching) │ │ │
|
|
12
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
13
|
+
│ rayDirUnnorm │ sample volume
|
|
14
|
+
│ cameraCorrected │ blend voxels
|
|
15
|
+
│ worldSpaceCoords │ apply lighting
|
|
16
|
+
|
|
17
|
+
============================================================================
|
|
18
|
+
COORDINATE TRANSFORMATIONS
|
|
19
|
+
============================================================================
|
|
20
|
+
|
|
21
|
+
1. Volume Space Normalization:
|
|
22
|
+
Original: [-0.5, 0.5] Normalized: [0, 1]
|
|
23
|
+
┌─────────────┐ ┌─────────────┐
|
|
24
|
+
│ -0.5 │ │ 0 │
|
|
25
|
+
│ │ │ │
|
|
26
|
+
│ 0 │──────────▶│ 0.5 │
|
|
27
|
+
│ │ │ │
|
|
28
|
+
│ 0.5 │ │ 1 │
|
|
29
|
+
└─────────────┘ └─────────────┘
|
|
30
|
+
|
|
31
|
+
2. Camera Position Transformation:
|
|
32
|
+
World Space: Volume Space:
|
|
33
|
+
┌─────────────┐ ┌─────────────┐
|
|
34
|
+
│ Camera │ │ Camera │
|
|
35
|
+
│ Position │──▶│ Position │
|
|
36
|
+
└─────────────┘ └─────────────┘
|
|
37
|
+
(x,y,z) (x',y',z')
|
|
38
|
+
|
|
39
|
+
3. Ray Direction Calculation:
|
|
40
|
+
Camera (cameraCorrected)
|
|
41
|
+
│
|
|
42
|
+
│ rayDirUnnorm = position - cameraCorrected
|
|
43
|
+
▼
|
|
44
|
+
Vertex (position)
|
|
45
|
+
|
|
46
|
+
4. MVP Transformation Pipeline:
|
|
47
|
+
Model Space → View Space → Projection Space → Clip Space
|
|
48
|
+
(x,y,z) → (x',y',z') → (x",y",z") → (x"',y"',z"')
|
|
49
|
+
*/
|
|
50
|
+
// lang: glsl
|
|
51
|
+
export const volumeVertexShader = `//
|
|
52
|
+
// Output: Unnormalized ray direction from camera to each vertex
|
|
53
|
+
// Used by fragment shader for ray marching through the volume
|
|
54
|
+
out vec3 rayDirUnnorm;
|
|
55
|
+
|
|
56
|
+
// Output: Camera position transformed into volume's local coordinate system
|
|
57
|
+
// Used to calculate ray origins in the fragment shader
|
|
58
|
+
out vec3 cameraCorrected;
|
|
59
|
+
|
|
60
|
+
// Volume scale uniform (likely for anisotropic voxels)
|
|
61
|
+
uniform vec3 u_vol_scale;
|
|
62
|
+
|
|
63
|
+
// Volume size uniform
|
|
64
|
+
uniform vec3 u_size;
|
|
65
|
+
|
|
66
|
+
// Output: Vertex positions normalized to [0,1] range within volume bounds
|
|
67
|
+
// Standard coordinate system for volume sampling
|
|
68
|
+
varying vec3 worldSpaceCoords;
|
|
69
|
+
|
|
70
|
+
// Output: Texture coordinates for sampling volume data
|
|
71
|
+
varying vec2 vUv;
|
|
72
|
+
|
|
73
|
+
// Output: Final clip-space position (stored for fragment shader access)
|
|
74
|
+
varying vec4 glPosition;
|
|
75
|
+
|
|
76
|
+
// Volume bounding box size uniform
|
|
77
|
+
uniform highp vec3 boxSize;
|
|
78
|
+
|
|
79
|
+
void main()
|
|
80
|
+
{
|
|
81
|
+
// Transform vertex positions from [-0.5, 0.5] range to [0, 1] range
|
|
82
|
+
// This is the standard coordinate system for volume sampling
|
|
83
|
+
//
|
|
84
|
+
// Mathematical transformation:
|
|
85
|
+
// worldSpaceCoords = (position / boxSize) + 0.5
|
|
86
|
+
//
|
|
87
|
+
// Example:
|
|
88
|
+
// position = (-0.5, -0.5, -0.5) → worldSpaceCoords = (0, 0, 0)
|
|
89
|
+
// position = ( 0.0, 0.0, 0.0) → worldSpaceCoords = (0.5, 0.5, 0.5)
|
|
90
|
+
// position = ( 0.5, 0.5, 0.5) → worldSpaceCoords = (1, 1, 1)
|
|
91
|
+
worldSpaceCoords = position / boxSize + vec3(0.5, 0.5, 0.5); //move it from [-0.5;0.5] to [0,1]
|
|
92
|
+
|
|
93
|
+
// Transform camera position into volume's local coordinate system
|
|
94
|
+
// This gives us the ray origin in volume space
|
|
95
|
+
cameraCorrected = (inverse(modelMatrix) * vec4(cameraPosition, 1.)).xyz;
|
|
96
|
+
|
|
97
|
+
// Calculate unnormalized ray direction from camera to each vertex
|
|
98
|
+
// Used by fragment shader for ray marching through the volume
|
|
99
|
+
rayDirUnnorm = position - cameraCorrected;
|
|
100
|
+
|
|
101
|
+
// Apply standard MVP transformation to get clip-space coordinates
|
|
102
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
103
|
+
|
|
104
|
+
// Store clip-space position for fragment shader access
|
|
105
|
+
glPosition = gl_Position;
|
|
106
|
+
|
|
107
|
+
// Pass through texture coordinates for volume sampling
|
|
108
|
+
vUv = uv;
|
|
109
|
+
}
|
|
110
|
+
`;
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vitessce/spatial-accelerated",
|
|
3
|
+
"version": "3.8.0",
|
|
4
|
+
"author": "HIDIVE Lab at HMS",
|
|
5
|
+
"homepage": "http://vitessce.io",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/vitessce/vitessce.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"dist",
|
|
16
|
+
"dist-tsc"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@react-three/fiber": "^8.15.19",
|
|
20
|
+
"@react-three/drei": "^9.99.7",
|
|
21
|
+
"@react-three/xr": "^5.7.1",
|
|
22
|
+
"d3-array": "^2.4.0",
|
|
23
|
+
"internmap": "^2.0.3",
|
|
24
|
+
"lodash-es": "^4.17.21",
|
|
25
|
+
"math.gl": "^3.5.6",
|
|
26
|
+
"mathjs": "^9.2.0",
|
|
27
|
+
"plur": "^5.1.0",
|
|
28
|
+
"short-number": "^1.0.6",
|
|
29
|
+
"three": "^0.154.0",
|
|
30
|
+
"zarrita": "0.5.3",
|
|
31
|
+
"@vitessce/constants-internal": "3.8.0",
|
|
32
|
+
"@vitessce/gl": "3.8.0",
|
|
33
|
+
"@vitessce/legend": "3.8.0",
|
|
34
|
+
"@vitessce/sets-utils": "3.8.0",
|
|
35
|
+
"@vitessce/spatial-utils": "3.8.0",
|
|
36
|
+
"@vitessce/tooltip": "3.8.0",
|
|
37
|
+
"@vitessce/utils": "3.8.0",
|
|
38
|
+
"@vitessce/vit-s": "3.8.0",
|
|
39
|
+
"@vitessce/styles": "3.8.0",
|
|
40
|
+
"@vitessce/globals": "3.8.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/three": "^0.154.0",
|
|
44
|
+
"react": "18.3.1",
|
|
45
|
+
"react-dom": "18.3.1",
|
|
46
|
+
"vite": "^7.0.0",
|
|
47
|
+
"vitest": "^3.1.4"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"bundle": "pnpm exec vite build -c ../../../scripts/vite.config.mjs",
|
|
54
|
+
"test": "pnpm exec vitest --run -r ../../../ --dir ."
|
|
55
|
+
},
|
|
56
|
+
"module": "dist/index.js",
|
|
57
|
+
"exports": {
|
|
58
|
+
".": {
|
|
59
|
+
"types": "./dist-tsc/index.d.ts",
|
|
60
|
+
"import": "./dist/index.js"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
// Note: need to be careful about versions of RTF, Three, React, and React DOM in package.json
|
|
3
|
+
// to avoid multiple copies of RTF, since the Canvas depends on a React Context.
|
|
4
|
+
// Otherwise you may see errors such as "useThree can only be used inside the Canvas component!".
|
|
5
|
+
import { Canvas } from '@react-three/fiber';
|
|
6
|
+
import { VolumeView } from './VolumeView.js';
|
|
7
|
+
|
|
8
|
+
export function SpatialWrapper(props) {
|
|
9
|
+
// const [renderingStats, setRenderingStats] = useState({ fps: 0 });
|
|
10
|
+
// const [zarrStoreInfo, setZarrStoreInfo] = useState(null);
|
|
11
|
+
// const [deviceLimits, setDeviceLimits] = useState(null);
|
|
12
|
+
// const volumeViewRef = useRef(null);
|
|
13
|
+
|
|
14
|
+
// Handle initialization completion from VolumeView
|
|
15
|
+
/*
|
|
16
|
+
const handleInitComplete = (initData) => {
|
|
17
|
+
if (initData.zarrStoreInfo) {
|
|
18
|
+
setZarrStoreInfo(initData.zarrStoreInfo);
|
|
19
|
+
}
|
|
20
|
+
if (initData.deviceLimits) {
|
|
21
|
+
setDeviceLimits(initData.deviceLimits);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Canvas
|
|
28
|
+
frameloop="always"
|
|
29
|
+
style={{
|
|
30
|
+
position: 'absolute',
|
|
31
|
+
top: 0,
|
|
32
|
+
left: 0,
|
|
33
|
+
width: '100%',
|
|
34
|
+
height: '100%',
|
|
35
|
+
padding: 0,
|
|
36
|
+
margin: 0,
|
|
37
|
+
// backgroundColor: 'white',
|
|
38
|
+
}}
|
|
39
|
+
camera={{
|
|
40
|
+
fov: 50,
|
|
41
|
+
up: [0, 1, 0],
|
|
42
|
+
position: [0, 0, 4],
|
|
43
|
+
near: 0.01,
|
|
44
|
+
far: 15,
|
|
45
|
+
}}
|
|
46
|
+
gl={{
|
|
47
|
+
antialias: true,
|
|
48
|
+
logarithmicDepthBuffer: false,
|
|
49
|
+
preserveDrawingBuffer: false,
|
|
50
|
+
autoClear: false,
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
<VolumeView
|
|
54
|
+
{...props}
|
|
55
|
+
// forwardRef={volumeViewRef}
|
|
56
|
+
// onInitComplete={handleInitComplete}
|
|
57
|
+
/>
|
|
58
|
+
</Canvas>
|
|
59
|
+
);
|
|
60
|
+
}
|