@aics/vole-core 3.12.4
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.txt +26 -0
- package/README.md +119 -0
- package/es/Atlas2DSlice.js +224 -0
- package/es/Channel.js +264 -0
- package/es/FileSaver.js +31 -0
- package/es/FusedChannelData.js +192 -0
- package/es/Histogram.js +250 -0
- package/es/ImageInfo.js +127 -0
- package/es/Light.js +74 -0
- package/es/Lut.js +500 -0
- package/es/MarchingCubes.js +507 -0
- package/es/MeshVolume.js +334 -0
- package/es/NaiveSurfaceNets.js +251 -0
- package/es/PathTracedVolume.js +482 -0
- package/es/RayMarchedAtlasVolume.js +250 -0
- package/es/RenderToBuffer.js +31 -0
- package/es/ThreeJsPanel.js +633 -0
- package/es/Timing.js +28 -0
- package/es/TrackballControls.js +538 -0
- package/es/View3d.js +848 -0
- package/es/Volume.js +352 -0
- package/es/VolumeCache.js +161 -0
- package/es/VolumeDims.js +16 -0
- package/es/VolumeDrawable.js +702 -0
- package/es/VolumeMaker.js +101 -0
- package/es/VolumeRenderImpl.js +1 -0
- package/es/VolumeRenderSettings.js +203 -0
- package/es/constants/basicShaders.js +29 -0
- package/es/constants/colors.js +59 -0
- package/es/constants/denoiseShader.js +43 -0
- package/es/constants/lights.js +42 -0
- package/es/constants/materials.js +85 -0
- package/es/constants/pathtraceOutputShader.js +13 -0
- package/es/constants/scaleBarSVG.js +21 -0
- package/es/constants/time.js +34 -0
- package/es/constants/volumePTshader.js +153 -0
- package/es/constants/volumeRayMarchShader.js +123 -0
- package/es/constants/volumeSliceShader.js +115 -0
- package/es/index.js +21 -0
- package/es/loaders/IVolumeLoader.js +131 -0
- package/es/loaders/JsonImageInfoLoader.js +255 -0
- package/es/loaders/OmeZarrLoader.js +495 -0
- package/es/loaders/OpenCellLoader.js +65 -0
- package/es/loaders/RawArrayLoader.js +89 -0
- package/es/loaders/TiffLoader.js +219 -0
- package/es/loaders/VolumeLoadError.js +44 -0
- package/es/loaders/VolumeLoaderUtils.js +221 -0
- package/es/loaders/index.js +40 -0
- package/es/loaders/zarr_utils/ChunkPrefetchIterator.js +143 -0
- package/es/loaders/zarr_utils/WrappedStore.js +51 -0
- package/es/loaders/zarr_utils/types.js +24 -0
- package/es/loaders/zarr_utils/utils.js +225 -0
- package/es/loaders/zarr_utils/validation.js +49 -0
- package/es/test/ChunkPrefetchIterator.test.js +208 -0
- package/es/test/RequestQueue.test.js +442 -0
- package/es/test/SubscribableRequestQueue.test.js +244 -0
- package/es/test/VolumeCache.test.js +118 -0
- package/es/test/VolumeRenderSettings.test.js +71 -0
- package/es/test/lut.test.js +671 -0
- package/es/test/num_utils.test.js +140 -0
- package/es/test/volume.test.js +98 -0
- package/es/test/zarr_utils.test.js +358 -0
- package/es/types/Atlas2DSlice.d.ts +41 -0
- package/es/types/Channel.d.ts +44 -0
- package/es/types/FileSaver.d.ts +6 -0
- package/es/types/FusedChannelData.d.ts +26 -0
- package/es/types/Histogram.d.ts +57 -0
- package/es/types/ImageInfo.d.ts +87 -0
- package/es/types/Light.d.ts +27 -0
- package/es/types/Lut.d.ts +67 -0
- package/es/types/MarchingCubes.d.ts +53 -0
- package/es/types/MeshVolume.d.ts +40 -0
- package/es/types/NaiveSurfaceNets.d.ts +11 -0
- package/es/types/PathTracedVolume.d.ts +65 -0
- package/es/types/RayMarchedAtlasVolume.d.ts +41 -0
- package/es/types/RenderToBuffer.d.ts +17 -0
- package/es/types/ThreeJsPanel.d.ts +107 -0
- package/es/types/Timing.d.ts +11 -0
- package/es/types/TrackballControls.d.ts +51 -0
- package/es/types/View3d.d.ts +357 -0
- package/es/types/Volume.d.ts +152 -0
- package/es/types/VolumeCache.d.ts +43 -0
- package/es/types/VolumeDims.d.ts +28 -0
- package/es/types/VolumeDrawable.d.ts +108 -0
- package/es/types/VolumeMaker.d.ts +49 -0
- package/es/types/VolumeRenderImpl.d.ts +22 -0
- package/es/types/VolumeRenderSettings.d.ts +98 -0
- package/es/types/constants/basicShaders.d.ts +4 -0
- package/es/types/constants/colors.d.ts +2 -0
- package/es/types/constants/denoiseShader.d.ts +40 -0
- package/es/types/constants/lights.d.ts +38 -0
- package/es/types/constants/materials.d.ts +20 -0
- package/es/types/constants/pathtraceOutputShader.d.ts +11 -0
- package/es/types/constants/scaleBarSVG.d.ts +2 -0
- package/es/types/constants/time.d.ts +19 -0
- package/es/types/constants/volumePTshader.d.ts +137 -0
- package/es/types/constants/volumeRayMarchShader.d.ts +117 -0
- package/es/types/constants/volumeSliceShader.d.ts +109 -0
- package/es/types/glsl.d.js +0 -0
- package/es/types/index.d.ts +28 -0
- package/es/types/loaders/IVolumeLoader.d.ts +113 -0
- package/es/types/loaders/JsonImageInfoLoader.d.ts +80 -0
- package/es/types/loaders/OmeZarrLoader.d.ts +87 -0
- package/es/types/loaders/OpenCellLoader.d.ts +9 -0
- package/es/types/loaders/RawArrayLoader.d.ts +33 -0
- package/es/types/loaders/TiffLoader.d.ts +45 -0
- package/es/types/loaders/VolumeLoadError.d.ts +18 -0
- package/es/types/loaders/VolumeLoaderUtils.d.ts +38 -0
- package/es/types/loaders/index.d.ts +22 -0
- package/es/types/loaders/zarr_utils/ChunkPrefetchIterator.d.ts +22 -0
- package/es/types/loaders/zarr_utils/WrappedStore.d.ts +24 -0
- package/es/types/loaders/zarr_utils/types.d.ts +94 -0
- package/es/types/loaders/zarr_utils/utils.d.ts +23 -0
- package/es/types/loaders/zarr_utils/validation.d.ts +7 -0
- package/es/types/test/ChunkPrefetchIterator.test.d.ts +1 -0
- package/es/types/test/RequestQueue.test.d.ts +1 -0
- package/es/types/test/SubscribableRequestQueue.test.d.ts +1 -0
- package/es/types/test/VolumeCache.test.d.ts +1 -0
- package/es/types/test/VolumeRenderSettings.test.d.ts +1 -0
- package/es/types/test/lut.test.d.ts +1 -0
- package/es/types/test/num_utils.test.d.ts +1 -0
- package/es/types/test/volume.test.d.ts +1 -0
- package/es/types/test/zarr_utils.test.d.ts +1 -0
- package/es/types/types.d.ts +115 -0
- package/es/types/utils/RequestQueue.d.ts +112 -0
- package/es/types/utils/SubscribableRequestQueue.d.ts +52 -0
- package/es/types/utils/num_utils.d.ts +43 -0
- package/es/types/workers/VolumeLoaderContext.d.ts +106 -0
- package/es/types/workers/types.d.ts +101 -0
- package/es/types/workers/util.d.ts +3 -0
- package/es/types.js +75 -0
- package/es/typings.d.js +0 -0
- package/es/utils/RequestQueue.js +267 -0
- package/es/utils/SubscribableRequestQueue.js +187 -0
- package/es/utils/num_utils.js +231 -0
- package/es/workers/FetchTiffWorker.js +153 -0
- package/es/workers/VolumeLoadWorker.js +129 -0
- package/es/workers/VolumeLoaderContext.js +271 -0
- package/es/workers/types.js +41 -0
- package/es/workers/util.js +8 -0
- package/package.json +83 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { Box3, Box3Helper, BoxGeometry, BufferAttribute, BufferGeometry, Color, DataTexture, Group, LineBasicMaterial, LineSegments, Matrix4, Mesh, ShaderMaterial, Vector2, Vector3 } from "three";
|
|
2
|
+
import FusedChannelData from "./FusedChannelData.js";
|
|
3
|
+
import { rayMarchingVertexShaderSrc, rayMarchingFragmentShaderSrc, rayMarchingShaderUniforms } from "./constants/volumeRayMarchShader.js";
|
|
4
|
+
import { VolumeRenderSettings, SettingsFlags } from "./VolumeRenderSettings.js";
|
|
5
|
+
const BOUNDING_BOX_DEFAULT_COLOR = new Color(0xffff00);
|
|
6
|
+
export default class RayMarchedAtlasVolume {
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new RayMarchedAtlasVolume.
|
|
9
|
+
* @param volume The volume that this renderer should render data from.
|
|
10
|
+
* @param settings Optional settings object. If set, updates the renderer with
|
|
11
|
+
* the given settings. Otherwise, uses the default VolumeRenderSettings.
|
|
12
|
+
*/
|
|
13
|
+
constructor(volume, settings = new VolumeRenderSettings(volume)) {
|
|
14
|
+
this.volume = volume;
|
|
15
|
+
this.uniforms = rayMarchingShaderUniforms();
|
|
16
|
+
[this.geometry, this.geometryMesh] = this.createGeometry(this.uniforms);
|
|
17
|
+
this.boxHelper = new Box3Helper(new Box3(new Vector3(-0.5, -0.5, -0.5), new Vector3(0.5, 0.5, 0.5)), BOUNDING_BOX_DEFAULT_COLOR);
|
|
18
|
+
this.boxHelper.updateMatrixWorld();
|
|
19
|
+
this.boxHelper.visible = false;
|
|
20
|
+
this.tickMarksMesh = this.createTickMarks();
|
|
21
|
+
this.tickMarksMesh.updateMatrixWorld();
|
|
22
|
+
this.tickMarksMesh.visible = false;
|
|
23
|
+
this.geometryTransformNode = new Group();
|
|
24
|
+
this.geometryTransformNode.name = "VolumeContainerNode";
|
|
25
|
+
this.geometryTransformNode.add(this.boxHelper, this.tickMarksMesh, this.geometryMesh);
|
|
26
|
+
this.emptyPositionTex = new DataTexture(new Uint8Array(Array(16).fill(0)), 2, 2);
|
|
27
|
+
this.settings = settings;
|
|
28
|
+
this.updateSettings(settings, SettingsFlags.ALL);
|
|
29
|
+
// TODO this is doing *more* redundant work! Fix?
|
|
30
|
+
this.updateVolumeDimensions();
|
|
31
|
+
}
|
|
32
|
+
updateVolumeDimensions() {
|
|
33
|
+
const {
|
|
34
|
+
normPhysicalSize,
|
|
35
|
+
normRegionSize
|
|
36
|
+
} = this.volume;
|
|
37
|
+
// Set offset
|
|
38
|
+
this.geometryMesh.position.copy(this.volume.getContentCenter().multiply(this.settings.scale));
|
|
39
|
+
// Set scale
|
|
40
|
+
const fullRegionScale = normPhysicalSize.clone().multiply(this.settings.scale);
|
|
41
|
+
this.geometryMesh.scale.copy(fullRegionScale).multiply(normRegionSize);
|
|
42
|
+
this.setUniform("volumeScale", normPhysicalSize);
|
|
43
|
+
this.boxHelper.box.set(fullRegionScale.clone().multiplyScalar(-0.5), fullRegionScale.clone().multiplyScalar(0.5));
|
|
44
|
+
this.tickMarksMesh.scale.copy(fullRegionScale);
|
|
45
|
+
this.settings && this.updateSettings(this.settings, SettingsFlags.ROI);
|
|
46
|
+
|
|
47
|
+
// Set atlas dimension uniforms
|
|
48
|
+
const {
|
|
49
|
+
atlasTileDims,
|
|
50
|
+
subregionSize
|
|
51
|
+
} = this.volume.imageInfo;
|
|
52
|
+
const atlasSize = new Vector2(subregionSize.x, subregionSize.y).multiply(atlasTileDims);
|
|
53
|
+
this.setUniform("ATLAS_DIMS", atlasTileDims);
|
|
54
|
+
this.setUniform("textureRes", atlasSize);
|
|
55
|
+
this.setUniform("SLICES", this.volume.imageInfo.volumeSize.z);
|
|
56
|
+
|
|
57
|
+
// (re)create channel data
|
|
58
|
+
if (!this.channelData || this.channelData.width !== atlasSize.x || this.channelData.height !== atlasSize.y) {
|
|
59
|
+
this.channelData?.cleanup();
|
|
60
|
+
this.channelData = new FusedChannelData(atlasSize.x, atlasSize.y);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
viewpointMoved() {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
updateSettings(newSettings, dirtyFlags) {
|
|
67
|
+
if (dirtyFlags === undefined) {
|
|
68
|
+
dirtyFlags = SettingsFlags.ALL;
|
|
69
|
+
}
|
|
70
|
+
this.settings = newSettings;
|
|
71
|
+
if (dirtyFlags & SettingsFlags.VIEW) {
|
|
72
|
+
this.geometryMesh.visible = this.settings.visible;
|
|
73
|
+
// Configure ortho
|
|
74
|
+
this.setUniform("orthoScale", this.settings.orthoScale);
|
|
75
|
+
this.setUniform("isOrtho", this.settings.isOrtho ? 1.0 : 0.0);
|
|
76
|
+
// Ortho line thickness
|
|
77
|
+
const axis = this.settings.viewAxis;
|
|
78
|
+
if (this.settings.isOrtho && axis) {
|
|
79
|
+
// TODO: Does this code do any relevant changes?
|
|
80
|
+
const maxVal = this.settings.bounds.bmax[axis];
|
|
81
|
+
const minVal = this.settings.bounds.bmin[axis];
|
|
82
|
+
const thicknessPct = maxVal - minVal;
|
|
83
|
+
this.setUniform("orthoThickness", thicknessPct);
|
|
84
|
+
} else {
|
|
85
|
+
this.setUniform("orthoThickness", 1.0);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (dirtyFlags & SettingsFlags.VIEW || dirtyFlags & SettingsFlags.BOUNDING_BOX) {
|
|
89
|
+
// Update tick marks with either view or bounding box changes
|
|
90
|
+
this.tickMarksMesh.visible = this.settings.showBoundingBox && !this.settings.isOrtho;
|
|
91
|
+
this.setUniform("maxProject", this.settings.maxProjectMode ? 1 : 0);
|
|
92
|
+
}
|
|
93
|
+
if (dirtyFlags & SettingsFlags.BOUNDING_BOX) {
|
|
94
|
+
// Configure bounding box
|
|
95
|
+
this.boxHelper.visible = this.settings.showBoundingBox;
|
|
96
|
+
const colorVector = this.settings.boundingBoxColor;
|
|
97
|
+
const newBoxColor = new Color(colorVector[0], colorVector[1], colorVector[2]);
|
|
98
|
+
this.boxHelper.material.color = newBoxColor;
|
|
99
|
+
this.tickMarksMesh.material.color = newBoxColor;
|
|
100
|
+
}
|
|
101
|
+
if (dirtyFlags & SettingsFlags.TRANSFORM) {
|
|
102
|
+
// Set rotation and translation
|
|
103
|
+
this.geometryTransformNode.position.copy(this.settings.translation);
|
|
104
|
+
this.geometryTransformNode.rotation.copy(this.settings.rotation);
|
|
105
|
+
// TODO this does some redundant work. Including a new call to this very function! Fix?
|
|
106
|
+
this.updateVolumeDimensions();
|
|
107
|
+
this.setUniform("flipVolume", this.settings.flipAxes);
|
|
108
|
+
}
|
|
109
|
+
if (dirtyFlags & SettingsFlags.MATERIAL) {
|
|
110
|
+
this.setUniform("DENSITY", this.settings.density);
|
|
111
|
+
}
|
|
112
|
+
if (dirtyFlags & SettingsFlags.CAMERA) {
|
|
113
|
+
// TODO brightness and exposure should be the same thing?
|
|
114
|
+
this.setUniform("BRIGHTNESS", this.settings.brightness * 2.0);
|
|
115
|
+
// Gamma
|
|
116
|
+
this.setUniform("GAMMA_MIN", this.settings.gammaMin);
|
|
117
|
+
this.setUniform("GAMMA_MAX", this.settings.gammaMax);
|
|
118
|
+
this.setUniform("GAMMA_SCALE", this.settings.gammaLevel);
|
|
119
|
+
}
|
|
120
|
+
if (dirtyFlags & SettingsFlags.ROI) {
|
|
121
|
+
// Normalize and set bounds
|
|
122
|
+
const bounds = this.settings.bounds;
|
|
123
|
+
const {
|
|
124
|
+
normRegionSize,
|
|
125
|
+
normRegionOffset
|
|
126
|
+
} = this.volume;
|
|
127
|
+
const offsetToCenter = normRegionSize.clone().divideScalar(2).add(normRegionOffset).subScalar(0.5);
|
|
128
|
+
const bmin = bounds.bmin.clone().sub(offsetToCenter).divide(normRegionSize).clampScalar(-0.5, 0.5);
|
|
129
|
+
const bmax = bounds.bmax.clone().sub(offsetToCenter).divide(normRegionSize).clampScalar(-0.5, 0.5);
|
|
130
|
+
this.setUniform("AABB_CLIP_MIN", bmin);
|
|
131
|
+
this.setUniform("AABB_CLIP_MAX", bmax);
|
|
132
|
+
}
|
|
133
|
+
if (dirtyFlags & SettingsFlags.SAMPLING) {
|
|
134
|
+
this.setUniform("interpolationEnabled", this.settings.useInterpolation);
|
|
135
|
+
this.setUniform("iResolution", this.settings.resolution);
|
|
136
|
+
}
|
|
137
|
+
if (dirtyFlags & SettingsFlags.MASK_ALPHA) {
|
|
138
|
+
this.setUniform("maskAlpha", this.settings.maskChannelIndex < 0 ? 1.0 : this.settings.maskAlpha);
|
|
139
|
+
}
|
|
140
|
+
if (dirtyFlags & SettingsFlags.MASK_DATA) {
|
|
141
|
+
this.channelData.setChannelAsMask(this.settings.maskChannelIndex, this.volume.getChannel(this.settings.maskChannelIndex));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates the geometry mesh and material for rendering the volume.
|
|
147
|
+
* @param uniforms object containing uniforms to pass to the shader material.
|
|
148
|
+
* @returns the new geometry and geometry mesh.
|
|
149
|
+
*/
|
|
150
|
+
createGeometry(uniforms) {
|
|
151
|
+
const geom = new BoxGeometry(1.0, 1.0, 1.0);
|
|
152
|
+
const mesh = new Mesh(geom);
|
|
153
|
+
mesh.name = "Volume";
|
|
154
|
+
|
|
155
|
+
// shader,vtx and frag.
|
|
156
|
+
const vtxsrc = rayMarchingVertexShaderSrc;
|
|
157
|
+
const fgmtsrc = rayMarchingFragmentShaderSrc;
|
|
158
|
+
const threeMaterial = new ShaderMaterial({
|
|
159
|
+
uniforms: uniforms,
|
|
160
|
+
vertexShader: vtxsrc,
|
|
161
|
+
fragmentShader: fgmtsrc,
|
|
162
|
+
transparent: true,
|
|
163
|
+
depthTest: true,
|
|
164
|
+
depthWrite: false
|
|
165
|
+
});
|
|
166
|
+
mesh.material = threeMaterial;
|
|
167
|
+
return [geom, mesh];
|
|
168
|
+
}
|
|
169
|
+
createTickMarks() {
|
|
170
|
+
// Length of tick mark lines in world units
|
|
171
|
+
const TICK_LENGTH = 0.025;
|
|
172
|
+
const {
|
|
173
|
+
tickMarkPhysicalLength,
|
|
174
|
+
physicalScale,
|
|
175
|
+
normPhysicalSize
|
|
176
|
+
} = this.volume;
|
|
177
|
+
const numTickMarks = physicalScale / tickMarkPhysicalLength;
|
|
178
|
+
const vertices = [];
|
|
179
|
+
const tickEndY = TICK_LENGTH / normPhysicalSize.y + 0.5;
|
|
180
|
+
const tickSpacingX = 1 / (normPhysicalSize.x * numTickMarks);
|
|
181
|
+
for (let x = -0.5; x <= 0.5; x += tickSpacingX) {
|
|
182
|
+
// prettier-ignore
|
|
183
|
+
vertices.push(x, 0.5, 0.5, x, tickEndY, 0.5, x, -0.5, -0.5, x, -tickEndY, -0.5, x, 0.5, -0.5, x, tickEndY, -0.5, x, -0.5, 0.5, x, -tickEndY, 0.5);
|
|
184
|
+
}
|
|
185
|
+
const tickEndX = TICK_LENGTH / normPhysicalSize.x + 0.5;
|
|
186
|
+
const tickSpacingY = 1 / (normPhysicalSize.y * numTickMarks);
|
|
187
|
+
for (let y = 0.5; y >= -0.5; y -= tickSpacingY) {
|
|
188
|
+
// prettier-ignore
|
|
189
|
+
vertices.push(-0.5, y, 0.5, -tickEndX, y, 0.5, -0.5, y, -0.5, -tickEndX, y, -0.5, 0.5, y, -0.5, tickEndX, y, -0.5, 0.5, y, 0.5, tickEndX, y, 0.5);
|
|
190
|
+
}
|
|
191
|
+
const tickSpacingZ = 1 / (normPhysicalSize.z * numTickMarks);
|
|
192
|
+
for (let z = 0.5; z >= -0.5; z -= tickSpacingZ) {
|
|
193
|
+
// prettier-ignore
|
|
194
|
+
vertices.push(-0.5, 0.5, z, -tickEndX, 0.5, z, -0.5, -0.5, z, -tickEndX, -0.5, z, 0.5, -0.5, z, tickEndX, -0.5, z, 0.5, 0.5, z, tickEndX, 0.5, z);
|
|
195
|
+
}
|
|
196
|
+
const geometry = new BufferGeometry();
|
|
197
|
+
geometry.setAttribute("position", new BufferAttribute(new Float32Array(vertices), 3));
|
|
198
|
+
return new LineSegments(geometry, new LineBasicMaterial({
|
|
199
|
+
color: BOUNDING_BOX_DEFAULT_COLOR
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
cleanup() {
|
|
203
|
+
this.geometry.dispose();
|
|
204
|
+
this.geometryMesh.material.dispose();
|
|
205
|
+
this.channelData.cleanup();
|
|
206
|
+
}
|
|
207
|
+
doRender(renderer, camera, depthTexture) {
|
|
208
|
+
if (!this.geometryMesh.visible) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const depthTex = depthTexture ?? this.emptyPositionTex;
|
|
212
|
+
this.setUniform("textureDepth", depthTex);
|
|
213
|
+
this.setUniform("usingPositionTexture", depthTex.isDepthTexture ? 0 : 1);
|
|
214
|
+
this.setUniform("CLIP_NEAR", camera.near);
|
|
215
|
+
this.setUniform("CLIP_FAR", camera.far);
|
|
216
|
+
this.channelData.gpuFuse(renderer);
|
|
217
|
+
this.setUniform("textureAtlas", this.channelData.getFusedTexture());
|
|
218
|
+
this.geometryTransformNode.updateMatrixWorld(true);
|
|
219
|
+
const mvm = new Matrix4();
|
|
220
|
+
mvm.multiplyMatrices(camera.matrixWorldInverse, this.geometryMesh.matrixWorld);
|
|
221
|
+
mvm.invert();
|
|
222
|
+
this.setUniform("inverseModelViewMatrix", mvm);
|
|
223
|
+
this.setUniform("inverseProjMatrix", camera.projectionMatrixInverse);
|
|
224
|
+
}
|
|
225
|
+
get3dObject() {
|
|
226
|
+
return this.geometryTransformNode;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
//////////////////////////////////////////
|
|
230
|
+
//////////////////////////////////////////
|
|
231
|
+
|
|
232
|
+
setUniform(name, value) {
|
|
233
|
+
if (!this.uniforms[name]) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
this.uniforms[name].value = value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// channelcolors is array of {rgbColor, lut} and channeldata is volume.channels
|
|
240
|
+
updateActiveChannels(channelcolors, channeldata) {
|
|
241
|
+
this.channelData.fuse(channelcolors, channeldata);
|
|
242
|
+
|
|
243
|
+
// update to fused texture
|
|
244
|
+
this.setUniform("textureAtlas", this.channelData.getFusedTexture());
|
|
245
|
+
this.setUniform("textureAtlasMask", this.channelData.maskTexture);
|
|
246
|
+
}
|
|
247
|
+
setRenderUpdateListener(_listener) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Mesh, OrthographicCamera, PlaneGeometry, Scene, ShaderMaterial } from "three";
|
|
2
|
+
import { renderToBufferVertShader } from "./constants/basicShaders.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Helper for render passes that just require a fragment shader: accepts a fragment shader and its
|
|
6
|
+
* uniforms, and handles the ceremony of rendering a fullscreen quad with a simple vertex shader.
|
|
7
|
+
*/
|
|
8
|
+
export default class RenderToBuffer {
|
|
9
|
+
constructor(fragmentSrc, uniforms) {
|
|
10
|
+
this.scene = new Scene();
|
|
11
|
+
this.geometry = new PlaneGeometry(2, 2);
|
|
12
|
+
this.material = new ShaderMaterial({
|
|
13
|
+
vertexShader: renderToBufferVertShader,
|
|
14
|
+
fragmentShader: fragmentSrc,
|
|
15
|
+
uniforms
|
|
16
|
+
});
|
|
17
|
+
this.material.depthWrite = false;
|
|
18
|
+
this.material.depthTest = false;
|
|
19
|
+
this.mesh = new Mesh(this.geometry, this.material);
|
|
20
|
+
this.scene.add(this.mesh);
|
|
21
|
+
this.camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Renders this pass to `target` using `renderer`, or to the canvas if no `target` is given. */
|
|
25
|
+
render(renderer, target) {
|
|
26
|
+
renderer.setRenderTarget(target ?? null);
|
|
27
|
+
renderer.render(this.scene, this.camera);
|
|
28
|
+
// Reset the render target to the screen
|
|
29
|
+
renderer.setRenderTarget(null);
|
|
30
|
+
}
|
|
31
|
+
}
|