# vtk.js off-screen rendering

**URL:** https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045
**Category:** Web
**Created:** [December 2, 2022, 1:41pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045 "2022-12-02T13:41:16Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![JohnSkinner](https://discourse.vtk.org/user_avatar/discourse.vtk.org/johnskinner/32/6197_2.png) [@JohnSkinner](https://discourse.vtk.org/u/JohnSkinner)
#### Post date: [December 2, 2022, 1:41pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/1 "2022-12-02T13:41:16Z")

</div>

I have a need to capture a set of renderings from one of my viz app’s renderWindow, but at a different resolution.  
My current approach is to attempt to use offscreen canvas via RenderWindow’s useOffscreen=true property.  
I also use a div with hidden attribute  
as the html element containing the renderwindow.  
With this approach i am getting [.WebGL-0xblabla] GL\_INVALID\_FRAME\_BUFFER\_OPERATION: Framebuffer is incomplete Attachment has zero size.

Is there any example that uses the useOffscreen property?

I may change my approach to displaying a temporary window for the purpose of rendering if useOffscreen doesn’t work out. Any other approaches are welcome.

---

<div class="post-metadata">

### Author: ![Forrest](https://discourse.vtk.org/user_avatar/discourse.vtk.org/forrest/32/300_2.png) [@Forrest](https://discourse.vtk.org/u/Forrest)
#### Post date: [December 2, 2022, 3:56pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/2 "2022-12-02T15:56:42Z")

</div>

I will have to investigate why the offscreen property causes a webgl issue. In the meantime, I’ve done this via `createElement('div')` and not adding the element to the node tree. Using this approach, you don’t need to use the offscreen property at all.

---

<div class="post-metadata">

### Author: ![JohnSkinner](https://discourse.vtk.org/user_avatar/discourse.vtk.org/johnskinner/32/6197_2.png) [@JohnSkinner](https://discourse.vtk.org/u/JohnSkinner)
#### Post date: [December 2, 2022, 4:17pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/3 "2022-12-02T16:17:38Z")

</div>

I’ll try your suggestion not adding the div to the dom tree.  
I looked briefly at the code, maybe using an OffscreenCanvas rather than a canvas with display:none will work. It appears OffscreenCanvas supports webgl contexts from what i read on mdn.

---

<div class="post-metadata">

### Author: ![Forrest](https://discourse.vtk.org/user_avatar/discourse.vtk.org/forrest/32/300_2.png) [@Forrest](https://discourse.vtk.org/u/Forrest)
#### Post date: [December 2, 2022, 9:27pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/4 "2022-12-02T21:27:56Z")

</div>

Could you provide a minimum proof-of-concept (i.e. via CodeSandbox) that demonstrates the error?

OffscreenCanvas can also work. However, what you are trying to do should just work, and so I would like to have a repro example so I can see if it’s an actual bug.

---

<div class="post-metadata">

### Author: ![JohnSkinner](https://discourse.vtk.org/user_avatar/discourse.vtk.org/johnskinner/32/6197_2.png) [@JohnSkinner](https://discourse.vtk.org/u/JohnSkinner)
#### Post date: [December 5, 2022, 4:34pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/5 "2022-12-05T16:34:45Z")

</div>

I created a proof-of-concept that demonstrates incorrect results, although not the same issue as initially reported. It is pretty small, and somewhere along the way, and unfortunately have trouble to explain why the initial GL\_INVALID\_FRAME\_BUFFER\_OPERATION no longer appears for me. Now the issue is that the capture image is incorrect in size and content when trying to capture from off-screen rendering. With just 2 small changes, you can re-run the proof-of-concept to see correct capture when capturing ON-screen rendering.

I am having a bit of a learning curve with codeSandbox where I get the web page that just says ‘Invalid Host Header’ when running the npm run test. Maybe just a standard git clone will be acceptable for helping me.

git clone [GitHub - John-Skinner/vtkjsproto: general recreating issues with vtk.js](https://github.com/John-Skinner/vtkjsproto.git)

> **[GitHub - John-Skinner/vtkjsproto: general recreating issues with vtk.js](https://github.com/John-Skinner/vtkjsproto)**
>
> general recreating issues with vtk.js. Contribute to John-Skinner/vtkjsproto development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![JohnSkinner](https://discourse.vtk.org/user_avatar/discourse.vtk.org/johnskinner/32/6197_2.png) [@JohnSkinner](https://discourse.vtk.org/u/JohnSkinner)
#### Post date: [December 5, 2022, 4:36pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/6 "2022-12-05T16:36:06Z")

</div>

the [readme.me](http://readme.me) for the git project describes how to switch from off-screen rendering/capturing to on-screen rendering/capturing.

---

<div class="post-metadata">

### Author: ![Forrest](https://discourse.vtk.org/user_avatar/discourse.vtk.org/forrest/32/300_2.png) [@Forrest](https://discourse.vtk.org/u/Forrest)
#### Post date: [December 6, 2022, 3:13am UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/7 "2022-12-06T03:13:32Z")

</div>

Thanks for the repo. Here are a few notes:

- `useOffscreen` only exists on the vtkOpenGLRenderWindow, not the vtkRenderWindow.
- The problem you’re encountering is that the `hidden` attribute sets the element’s clientHeight and clientWidth to 0. This results in the OpenGLRenderWindow’s height/width being set to zero as well, hence why you are rendering nothing.

---

<div class="post-metadata">

### Author: ![JohnSkinner](https://discourse.vtk.org/user_avatar/discourse.vtk.org/johnskinner/32/6197_2.png) [@JohnSkinner](https://discourse.vtk.org/u/JohnSkinner)
#### Post date: [December 6, 2022, 2:32pm UTC](https://discourse.vtk.org/t/vtk-js-off-screen-rendering/10045/8 "2022-12-06T14:32:21Z")

</div>

Thanks Forrest,  
Your suggestion works and I can now do offscreen rendering.

Summarizing

1. I defined a div element that is hidden and occupies no UI space:

```auto
<div id="renderDiv" style="width:512px;height:512px" hidden>

```

1. created a render window and opengl render window as follows:

```auto
        // using the global window for simplicity, better to avoid this in practice.
        window.rw = vtkRenderWindow.newInstance();
        window.oglrw = vtkOpenGLRenderWindow.newInstance({useOffScreen:true});
        window.oglrw.setContainer(container); // container is the HTMLDivElement with id=renderDiv
        window.oglrw.setSize(512,512); // must explicitly set dimensions and not set to the div's dimensions
        window.rw.addView(window.oglrw);

```

1. I render the scene to the hidden window

```auto
    let renderer = vtkRenderer.newInstance();
    renderer.setBackground([0.1,0.1,0.2]);
    renderer.setViewport(0,0,1,1);
    window.rw.addRenderer(renderer);
 renderer.getRenderWindow().render();

```

1. Capture the hidden rendering and pasted to an element (copyDiv)

```auto
        console.log(" button clicked");
        let capturePromises = window.rw.captureImages();
        if (capturePromises.length > 0)
        {
            capturePromises[0].then((imageURL)=>
            {
                console.log(" url:" + imageURL);
                let img = new Image();
                img.src = imageURL;
                img.addEventListener('load',(e)=>
                {
                    console.log(' image loaded');
                    console.log('size:' + img.width + 'x' + img.height);
                    let copyDiv = document.getElementById('captureDiv');
                    document.body.appendChild(copyDiv);
                    copyDiv.appendChild(img);

                })

            })
        }

```
