在多个画布上显示不同的场景共享资源 [英] Display different scenes sharing resources on multiple canvases

查看:21
本文介绍了在多个画布上显示不同的场景共享资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Three.js 创建一个交互式 Web 应用程序,但我遇到了一个小绊脚石:

I'm using three.js to create an interactive web application, and I've run into a little stumbling block:

我在页面上的可拖动 div 中包含了许多画布.我希望在每个画布中显示一个应用了不同材质的未点亮的 3D 对象(每种材质都使用自定义着色器).所有这些材料都具有相同的纹理(一种可能是蓝色的,一种可能是去饱和的,等等).

I have a number of canvases contained in draggable divs on the page. In each canvas I hope to display an unlit 3D object with a different material applied (each material is using custom shaders). All of those materials work off the same texture (one might be blue-tinted, one might be desaturated, etc.).

页面上画布的数量可能会有所不同,但我预计该数量通常会达到/超过 20 个画布,因此共享资源(尤其是大纹理)将非常有益.

The number of canvases on the page can vary, but I expect the number to commonly reach/exceed 20 canvases, and as such sharing resources (particularly for large textures) would be very beneficial.

到目前为止,我一直在使用多个渲染器、相机和场景,这些效果很好,直到我开始尝试在多个场景中使用相同的纹理.

Up until now I have been using multiple renderers, cameras and scenes which has worked fine until I started trying to use the same texture in multiple scenes.

大多数材料共享制服和属性以避免重复信息,并使所有材料彼此保持同步(例如,当某些材料随时间发生变化时,它们都应该以相同的方式变化)方式).

Most of the materials share uniforms and attributes to avoid having to duplicate the information, and also so that all of the materials stay in sync with one another (e.g. when some of the materials change over time they should all change in the same way).

我想知道是否有办法在场景/渲染器/画布之间共享纹理?当我尝试时,出现以下错误:

I was wondering if there was a way I would be able to share textures between the scenes/renderers/canvases? When I try I get the following error:

WebGL: INVALID_OPERATION: bindTexture: object not from this context 

在我试图为这个问题找到解决方案的研究中,我发现可以通过创建多个视口来解决这个问题的建议,但是我不知道如何在不同的画布上显示不同的视口.

In my research trying to find a solution for this problem I came across the suggestion that this could be solved by creating multiple viewports, however I do not know how to display different viewports over different canvases.

TL/DR;

我可以:

  • 在不同的画布上显示相同的场景?
  • 在不同的场景、渲染器和/或画布上使用相同的制服(包括纹理制服)?

提前致谢!

狮鹫

推荐答案

很遗憾,您(还)不能跨画布共享资源.几个选项

Unfortunately you can not (yet) share resources across canvases. A couple of options

  1. 在同一画布的不同部分渲染不同的视口.

  1. Render the different viewports in different parts of the same canvas.

示例:http://webglsamples.org/multiple-views/multiple-views.html

制作一个覆盖整个窗口的画布,使用占位符元素确定绘制位置,使用 getClientBoundingRect 设置视口 &在每个元素中绘制场景的剪刀设置

Make a canvas that covers the entire window, use place holder elements to figure out where to draw, use getClientBoundingRect to set the viewport & scissor settings to draw scenes in each element

示例:是否可以在 THREE.js 中启用无限数量的渲染器?

将场景渲染到屏幕外的画布,然后将其绘制到可见的画布中.

Render the scene to an offscreen canvas then draw it into a visible canvases.

<canvas id="c1"></canvas>
<canvas id="c2"></canvas>
<script>
var webglCanvas = document.createElement("canvas");
var canvas1 = document.getElementById("c1");
var ctx1 = canvas1.getContext("2d");
var canvas2 = document.getElementById("c1");
var ctx2 = canvas1.getContext("2d");

...从一个视图将场景绘制到 webglCanvas 中...

... draw scene into webglCanvas from one view...

// copy scene to canvas1
ctx1.drawImage(webglCanvas, 0, 0);

...从另一个视图将场景绘制到 webglCanvas 中...

... draw scene into webglCanvas from another view...

// copy scene to canvas2
ctx2.drawImage(webglCanvas, 0, 0);

这是一个活生生的例子(注意:它很慢在 Windows 上的 Chrome26、FF20,希望这将在未来的浏览器中修复)

Here's a live example (note: It's slow on Windows in Chrome26, FF20, Hopefully that will be fixed in future browsers)

使用 OffscreenCanvas、transferToImageBitmap 等...(注意:截至 2018 年 1 月 8 日,此功能尚未在任何浏览器中提供,但它在 Firefox 的标志后面可用)

Use OffscreenCanvas, transferToImageBitmap etc... (note: this feature has not shipped in any browser as of 2018/1/8 but it's available behind a flag on Firefox)

const one = document.getElementById("one").getContext("bitmaprenderer"); 
const two = document.getElementById("two").getContext("bitmaprenderer");

const offscreen = new OffscreenCanvas(256, 256);
constr gl = offscreen.getContext('webgl');

// ... some drawing for the first canvas using the gl context ...
gl.clearColor(1,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);

// Commit rendering to the first canvas
let bitmapOne = offscreen.transferToImageBitmap();
one.transferImageBitmap(bitmapOne);

// ... some more drawing for the second canvas using the gl context ...
gl.clearColor(0,1,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);

// Commit rendering to the second canvas 
let bitmapTwo = offscreen.transferToImageBitmap();
two.transferImageBitmap(bitmapTwo);

<canvas id="one"></canvas>
<canvas id="two"></canvas>

这篇关于在多个画布上显示不同的场景共享资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆