vtk-js: Slow response on rendered STL model interactions
High-level description
I’m experiencing extremely slow responses on rendered STL model user interactions. I have a React component rendering a variable number of STL models (the performance issue is even happening when rendering only 1 STL model).
Steps to reproduce
Below you can find the source code of the react component:
import { Modal } from "react-bootstrap";
import React, { useRef, useEffect } from 'react';
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';
import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';
import vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';
import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
import vtkProperty from '@kitware/vtk.js/Rendering/Core/Property';
import vtkInteractorStyleTrackballCamera from '@kitware/vtk.js/Interaction/Style/InteractorStyleTrackballCamera';
import vtkSTLReader from '@kitware/vtk.js/IO/Geometry/STLReader';
import { convertToRGB, getColorInfo } from "../../utils/Common";
export default function CaseModal({ setShowCaseModal, stlFile, layerinfo }) {
const vtkContainerRef = useRef(null);
const context = useRef(null);
useEffect(() => {
async function renderAll() {
if (!context.current) {
const files = Object.fromEntries(Object.entries(stlFile).filter(([key, value]) => {return key.match(/Model\/./g)}).map(([key, value]) => {return [key.replace('Model/', ''), value]}))
const mappers = []
const actors = []
layerinfo.forEach(layer => {
const { color_hex, opacity_percentage } = getColorInfo(layer.material_color)
const color_rgb = convertToRGB(color_hex)
const reader = vtkSTLReader.newInstance();
const mapper = vtkMapper.newInstance({ scalarVisibility: false });
const actor = vtkActor.newInstance();
const property = vtkProperty.newInstance();
property.setOpacity(opacity_percentage/100)
property.setColor(color_rgb[0]/255, color_rgb[1]/255, color_rgb[2]/255)
mapper.setInputConnection(reader.getOutputPort());
actor.setProperty(property)
actor.setMapper(mapper);
reader.parseAsArrayBuffer(files[layer.file_name].buffer)
mappers.push(mapper)
actors.push(actor)
});
const renderWindow = vtkRenderWindow.newInstance();
const renderer = vtkRenderer.newInstance({ background: [0.2, 0.3, 0.4] });
renderWindow.addRenderer(renderer);
actors.forEach(actor => {
renderer.addActor(actor);
})
renderer.resetCamera();
const openglRenderWindow = vtkOpenGLRenderWindow.newInstance();
renderWindow.addView(openglRenderWindow);
const container = vtkContainerRef.current;
openglRenderWindow.setContainer(container);
const { width, height } = container.getBoundingClientRect();
openglRenderWindow.setSize(width, height);
const interactor = vtkRenderWindowInteractor.newInstance();
interactor.setView(openglRenderWindow);
interactor.initialize();
interactor.bindEvents(container);
interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());
renderWindow.render();
context.current = {
renderer,
actors,
mappers,
};
}
return () => {
if (context.current) {
const { renderer, actors, mappers } = context.current;
actors.forEach(actor => {
actor.delete()
});
mappers.forEach(mapper => {
mapper.delete()
});
renderer.delete();
context.current = null;
}
};
}
renderAll()
}, [context, vtkContainerRef, layerinfo, stlFile]);
return (
<Modal fullscreen={true} show={true} onHide={() => setShowCaseModal(false)}>
<Modal.Header closeButton>
<Modal.Title className="primary-600">Case viewer</Modal.Title>
</Modal.Header>
<Modal.Body id="case-modal">
<div className="h-100">
<div className="h-100" ref={vtkContainerRef} />
</div>
</Modal.Body>
</Modal>
);
}
Current behavior
It seems like a GPU related issue, since it’s only happening using chrome in combination with iMac. The problem is not happening using other browsers on the same iMac or using the same chrome version on other devices (even other apple computers, like macbook). We got many of this iMac and it’s happening on all of them when using chrome.
Environment
- vtk node module: @kitware/vtk.js: 24.18.2
- browser: Version 103.0.5060.53 (Official Build) (x86_64)
- OS: macOS Monterey version 12.4
- device: iMac (Retina 4K, 21.5-inch, 2017)
- GPU: Radeon Pro 555 2 GB
- Processor: 3,6 GHz Quad-Core Intel Core i7
- Memory: 8 GB 2400 MHz DDR4
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 18
As stated by @floryst it’s a GPU backend issue, you have to switch to Metal like you did or use
--use-angle=metalin the command line otherwise you will have to wait for Chrome to make the switch as reported in crbug.com/1245448I confirm that setting “Choose ANGLE graphics backend” on “Metal” the issue is not happening anymore.
Ok, now the performance profile download worked. Here’s the full JSON (had to host it separately, because it’s too long for a github comment)
The issue is also happening with this STL, that I randomly downloaded from thingiverse.