Weird camera behavior on setUseOffScreen

Hi,

I get a weird behavior when toggling setUseOffScreen on click, but not programmatically if I use a setTimeOut

here is my code :

import "@kitware/vtk.js/Rendering/Profiles/Geometry";
import vtkGenericRenderWindow from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow.js";
import vtkXMLPolyDataReader from "@kitware/vtk.js/IO/XML/XMLPolyDataReader";
import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";

const genericRenderWindow = vtkGenericRenderWindow.newInstance({
  listenWindowResize: false,
});

const renderer = genericRenderWindow.getRenderer();
const renderWindow = genericRenderWindow.getRenderWindow();

const container = useTemplateRef("vtk");
const { width, height } = useElementSize(container);
const { pressed } = useMousePressed({ target: container });
const { windowWidth, windowHeight } = useWindowSize();
let camera = null;

watch([windowWidth, windowHeight, height, width], () => {
  resize();
});
onMounted(async () => {
  if (process.client) {
    await nextTick();
    genericRenderWindow.setContainer(container.value.$el);
    resize();
  }
});

const reader = vtkXMLPolyDataReader.newInstance();
const textEncoder = new TextEncoder();
await reader.parseAsArrayBuffer(textEncoder.encode(data));
const polydata = reader.getOutputData(0);
const mapper = vtkMapper.newInstance();
mapper.setInputData(polydata);
const actor = vtkActor.newInstance();
actor.setMapper(mapper);
renderer.addActor(actor);
renderer.resetCamera();
renderWindow.render();
camera = renderer.getActiveCamera();
console.log("getFocalPoint", camera.getFocalPoint());
console.log("getViewUp", camera.getViewUp());
console.log("getPosition", camera.getPosition());
console.log("getViewAngle", camera.getViewAngle());
console.log("getClippingRange", camera.getClippingRange());
console.log("getDistance", camera.getDistance());

const webGLRenderWindow = genericRenderWindow.getApiSpecificRenderWindow();

setTimeout(() => {
  webGLRenderWindow.setUseOffScreen(true);
}, 5000);

setTimeout(() => {
  webGLRenderWindow.setUseOffScreen(false);
}, 7000);

async function resize() {
  const webGLRenderWindow = genericRenderWindow.getApiSpecificRenderWindow();
  const canvas = webGLRenderWindow.getCanvas();
  canvas.width = 0;
  canvas.height = 0;
  await nextTick();
  webGLRenderWindow.setSize(width.value, height.value);
  renderWindow.render();
}
watch(pressed, (value) => {
  console.log("pressed", value);
  const webGLRenderWindow = genericRenderWindow.getApiSpecificRenderWindow();
  webGLRenderWindow.setUseOffScreen(!value);
  const current_camera = renderer.getActiveCamera();

  console.log("getFocalPoint", current_camera.getFocalPoint());
  console.log("getViewUp", current_camera.getViewUp());
  console.log("getPosition", current_camera.getPosition());
  console.log("getViewAngle", current_camera.getViewAngle());
  console.log("getClippingRange", current_camera.getClippingRange());
  console.log("current_camera.getDistance", current_camera.getDistance());
});

Also my camera seems broken :

camera.getFocalPoint (3) [6.05, 4.95, 1.5]
camera.getViewUp (3) [0, 0, 0]
camera.getPosition (3) [NaN, NaN, NaN]
camera.getViewAngle 30
camera.getClippingRange (2) [NaN, NaN]
camera.getDistance NaN

Thank you for your help,
Julien

That seems like a corner-use-case to change offscreen rendering dynamically…
It does not seem very surprising that it is unstable.

@finetjul any idea where this instability may come from? We can test some ideas to make it more stable but we don’t know where to look…