Skip to content

Commit

Permalink
Change shading of meshes (#5326)
Browse files Browse the repository at this point in the history
* change shading of meshes to lambert shading

* use the same color for meshes as for isosurfaces

* fix linting

* add changelog entry
  • Loading branch information
MichaelBuessemeyer authored Mar 24, 2021
1 parent d8f3125 commit b0b7c62
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
### Changed
- webKnossos is now part of the [image.sc support community](https://forum.image.sc/tag/webknossos). [#5332](https://github.com/scalableminds/webknossos/pull/5332)
- Measured distances will be shown in voxel space, too. [#5240](https://github.com/scalableminds/webknossos/pull/5240)
- Meshes that are imported by the user in the meshes tab are now rendered the same way as generated isosurface meshes. [#5326](https://github.com/scalableminds/webknossos/pull/5326)

### Fixed
- Fixed a regression in the task search which could lead to a frontend crash. [#5267](https://github.com/scalableminds/webknossos/pull/5267)
Expand Down
66 changes: 38 additions & 28 deletions frontend/javascripts/oxalis/controller/scene_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import constants, {
} from "oxalis/constants";
import window from "libs/window";

import { jsConvertCellIdToHSLA } from "oxalis/shaders/segmentation.glsl.js";
import { jsConvertCellIdToHSLA } from "oxalis/shaders/segmentation.glsl";
import { setSceneController } from "./scene_controller_provider";

const CUBE_COLOR = 0x999999;
Expand All @@ -60,6 +60,8 @@ class SceneController {
renderer: typeof THREE.WebGLRenderer;
scene: typeof THREE.Scene;
rootGroup: typeof THREE.Object3D;
// Group for all meshes including a light.
meshesRootGroup: typeof THREE.Object3D;
stlMeshes: { [key: string]: typeof THREE.Mesh } = {};

// isosurfacesRootGroup holds lights and one group per segmentation id.
Expand Down Expand Up @@ -95,12 +97,14 @@ class SceneController {
this.rootGroup = new THREE.Object3D();
this.rootGroup.add(this.getRootNode());
this.isosurfacesRootGroup = new THREE.Group();
this.meshesRootGroup = new THREE.Group();

// The dimension(s) with the highest resolution will not be distorted
this.rootGroup.scale.copy(new THREE.Vector3(...Store.getState().dataset.dataSource.scale));
// Add scene to the group, all Geometries are then added to group
this.scene.add(this.rootGroup);
this.scene.add(this.isosurfacesRootGroup);
this.scene.add(this.meshesRootGroup);

this.rootGroup.add(new THREE.DirectionalLight());
this.addLights();
Expand Down Expand Up @@ -158,17 +162,40 @@ class SceneController {
return this.isosurfacesGroupsPerSegmentationId[cellId];
}

constructSceneMesh(cellId: number, geometry: typeof THREE.Geometry) {
const [hue] = jsConvertCellIdToHSLA(cellId);
const color = new THREE.Color().setHSL(hue, 0.5, 0.1);
const meshMaterial = new THREE.MeshLambertMaterial({ color });
meshMaterial.side = THREE.DoubleSide;
meshMaterial.transparent = true;

const mesh = new THREE.Mesh(geometry, meshMaterial);

mesh.castShadow = true;
mesh.receiveShadow = true;

const tweenAnimation = new TWEEN.Tween({ opacity: 0 });
tweenAnimation
.to({ opacity: 0.95 }, 500)
.onUpdate(function onUpdate() {
meshMaterial.opacity = this.opacity;
app.vent.trigger("rerender");
})
.start();
return mesh;
}

addSTL(meshMetaData: MeshMetaData, geometry: typeof THREE.Geometry): void {
const { id, position } = meshMetaData;
if (this.stlMeshes[id] != null) {
console.warn(`Mesh with id ${id} has already been added to the scene.`);
return;
}
geometry.computeVertexNormals();

const meshMaterial = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, meshMaterial);
this.scene.add(mesh);
geometry.computeFaceNormals();
const meshNumber = _.size(this.stlMeshes);
const mesh = this.constructSceneMesh(meshNumber, geometry);
this.meshesRootGroup.add(mesh);
this.stlMeshes[id] = mesh;
this.updateMeshPostion(id, position);
}
Expand All @@ -192,26 +219,7 @@ class SceneController {
}

addIsosurfaceFromGeometry(geometry: typeof THREE.Geometry, segmentationId: number): void {
const [hue] = jsConvertCellIdToHSLA(segmentationId);
const color = new THREE.Color().setHSL(hue, 0.5, 0.1);

const meshMaterial = new THREE.MeshLambertMaterial({ color });
meshMaterial.side = THREE.DoubleSide;
meshMaterial.transparent = true;

const mesh = new THREE.Mesh(geometry, meshMaterial);

mesh.castShadow = true;
mesh.receiveShadow = true;

const tweenAnimation = new TWEEN.Tween({ opacity: 0 });
tweenAnimation
.to({ opacity: 0.95 }, 500)
.onUpdate(function onUpdate() {
meshMaterial.opacity = this.opacity;
app.vent.trigger("rerender");
})
.start();
const mesh = this.constructSceneMesh(segmentationId, geometry);

if (this.isosurfacesGroupsPerSegmentationId[segmentationId] == null) {
const newGroup = new THREE.Group();
Expand All @@ -237,12 +245,14 @@ class SceneController {
// The PlaneView attaches a directional light directly to the TD camera,
// so that the light moves along the cam.

const ambientLight = new THREE.AmbientLight(0x404040, 15); // soft white light
this.isosurfacesRootGroup.add(ambientLight);
const ambientLightForIsosurfaces = new THREE.AmbientLight(0x404040, 15); // soft white light
this.isosurfacesRootGroup.add(ambientLightForIsosurfaces);
const ambientLightForMeshes = new THREE.AmbientLight(0x404040, 15); // soft white light
this.meshesRootGroup.add(ambientLightForMeshes);
}

removeSTL(id: string): void {
this.rootGroup.remove(this.stlMeshes[id]);
this.meshesRootGroup.remove(this.stlMeshes[id]);
}

setMeshVisibility(id: string, visibility: boolean): void {
Expand Down

0 comments on commit b0b7c62

Please sign in to comment.