CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.74k stars 3.45k forks source link

Integrate with other WebGL engines #648

Open pjcozzi opened 11 years ago

pjcozzi commented 11 years ago

There's been some interest in integrating Cesium with other WebGL engines.

On the Cesium side, this should be pretty straightforward. The changes will require Cesium to only own the context during a call to Scene.render, not forever. This is already mostly there since objects only access the context in update functions called from within Scene.render, but we also keep some state between frames that we'll need to change:

Also, when we do the post processing framework, we need to be mindful of when we are rendering to texture vs. the main framebuffer.

m-schuetz commented 9 years ago

Hi,

I've done a first test with cesium + three.js here: http://potree.org/demo/experimental/2015.08.19_cesium_test/examples/cesium_test.html

The basic idea is this:

Issues:

pjcozzi commented 9 years ago

Does cesium use double precision values for transformations?

Yes, see the link I sent on twitter: http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/ EDIT: Link moved here: http://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm

There will also be depth buffer compositing and perhaps precision issues with this approach.

m-schuetz commented 9 years ago

Thanks, I'll take a look at it!

m-schuetz commented 9 years ago

Found out how to render into the same canvas with the same context:

First, create a three.js renderer and pass the canvas as argument. The canvas/context was already initialized by cesium. Three.js will call getContext() for the same canvas and therefore, according to the spec, receive the same context as cesium.

three.renderer = new THREE.WebGLRenderer({alpha: true, canvas: cesium.viewer.canvas});

In the render loop, cesium has to be rendered first.

During the rendering with three.js, WebGLRenderer._currentProgram has to be set to null before using the three.js render function. Since _currentProgram is a private variable, this can only be done through WebGLRenderer.resetGLState(). resetGLState(), however, also calls state.reset which causes errors. This workaround therefore temporarily changes the state.reset function to an empty function

var resetFunc = three.renderer.state.reset;
three.renderer.state.reset = function(){};
three.renderer.resetGLState();
three.renderer.state.reset = resetFunc;

Now it's probably not that important for most cases but it would still be interesting to use the same depth buffer in threejs as well. Do you think that will be possible with the way cesium handles depth buffers? At https://cesiumjs.org/massiveworlds/ there are slides about rendering with multiple frustums in which case reusing the depth buffer is probably out of question.

pjcozzi commented 9 years ago

Thanks for the info.

Now it's probably not that important for most cases but it would still be interesting to use the same depth buffer in threejs as well.

I expect most apps will want this, e.g., depth testing points vs. Cesium's terrain. I expect this can be done by setting Three.js' camera near and far planes and explicitly rendering the Three.js scene for each frustum in Cesium. See executeCommands in Scene.js.

The jittering issue in Three.js we discussed on twitter would also need to be addressed.

brucefuqiming commented 8 years ago

We're doing a project to mix Cesium and Three, like potree. Cesium is rendered firstly,then Three's elements rendered on the Cesium's canvas.But the problem is Three's elements always block Cesium's. e.g.: there is a geometry created by Three in front of the Cesium‘s earth,it can block the Cesium‘s earth and other elements correctly, but when the scene is rotated to the backward, Three's object still block the Cesium,maybe depth buffer is the main reason,but we cannot find the solution to solve. Do you have any methods?We wanna make Cesium the part of the Three’s scene,like an ordinary geometry. Is it possible?

pjcozzi commented 8 years ago

@brucefuqiming this is because Cesium and Three have two different depth buffers and Three is being rendered second. To merge the scenes correctly, this will require core engine support in Cesium as described in this issue.

pjcozzi commented 7 years ago

For a prototype of integrating Cesium and three.js, see Section 6.2 here: https://www.cg.tuwien.ac.at/research/publications/2015/Adorjan-2015/Adorjan-2015-thesis.pdf

m-schuetz commented 7 years ago

One possibility could be to render color and depth buffers in one lib and then use the depth buffer(s) in the other lib to compose the renderings of both.

e.g.:

Vice-versa, cesium could provide a color buffer and all of its depth maps and someone can use this to do a custom compose step to merge the cesium renderings with his three.js or other renderings.

gaojunxiaowwww8888 commented 7 years ago

Hello sir, I would like to ask you about the cesium+three.js how to load the.Gltf model, and let the three.js camera with cesium camera rotation, there is no good examples of reference, thank you.

pjcozzi commented 7 years ago

@gaojunxiaowwww8888 you might want to ask the three.js community or try the Cesium forum: http://cesiumjs.org/forum.html. Just a heads up that the Cesium team doesn't yet have any three.js experience.

gaojunxiaowwww8888 commented 7 years ago

Hello sir, I want to ask is whether in the development of cesium+three by three cesium light to improve the illumination effect, three light can affect cesium light; or what is the way to change the cesium in the light effect?

gaojunxiaowwww8888 commented 7 years ago

@m-schuetz Hello sir, I want to ask is whether in the development of cesium+three by three cesium light to improve the illumination effect, three light can affect cesium light; or what is the way to change the cesium in the light effect?

gaojunxiaowwww8888 commented 7 years ago

Hello, sir. I don't know how to improve the lighting effect of cesium. Is there a good example for reference?

pjcozzi commented 7 years ago

@gaojunxiaowwww8888 please do not post the same question over and over again in this issue. As explained in CONTRIBUTING.md, the Cesium forum is the preferred place to ask question; we use GitHub issues for bugs and feature requests.

gaojunxiaowwww8888 commented 7 years ago

For the cesium+three.js development process, the three model jitter problem is solved? Now encountered this problem, I hope you can help, thank you

pjcozzi commented 7 years ago

@gaojunxiaowwww8888 please do not post the same question to the Cesium forum and this repo. Your question was answered in https://groups.google.com/forum/#!topic/cesium-dev/gCWi3BpT47U.

For jitter in three.js, your best bet is to ask the three.js community as I mentioned to you above.

pjcozzi commented 6 years ago

Related blog post: https://cesium.com/blog/2017/10/23/integrating-cesium-with-threejs/

pjcozzi commented 6 years ago

For discussion, see https://groups.google.com/forum/#!topic/cesium-dev/GX7xLXrPDsE via #6094

pjcozzi commented 6 years ago

Just adding a note to myself that we would also consider down-scoping this if it makes it easier to implement, e.g., support three.js geometries but not post-processing, etc.

pjcozzi commented 5 years ago

Related: luma.gl's WebGL state tracker

IvanLudvig commented 3 years ago

Hello. What changes need to be made in https://cesium.com/blog/2017/10/23/integrating-cesium-with-threejs/ in order to use Cesium with three.js in SCENE2D mode? I managed to get it to work in Columbus view (described it in this issue), but not 2D.

huaidanatu commented 10 months ago

一种可能性是在一个库中渲染颜色和深度缓冲区,然后使用另一库中的深度缓冲区来组合两者的渲染。

例如:

  • 用户在 Three.js 中渲染他的东西,并向 cesium 提供颜色缓冲区、深度缓冲区和投影参数。
  • Cesium 使用 Three.js 颜色和深度图作为输入进行屏幕传递(或每个平截头体一个),并丢弃所有未通过自定义深度测试的片段。自定义深度测试包括将 Three.js 深度值转换为 cesium 深度值。

反之亦然,cesium 可以提供颜色缓冲区及其所有深度图,并且有人可以使用它来执行自定义合成步骤,以将 cesium 渲染与他的 Three.js 或其他渲染合并。

我很认同,但是大佬有没有代码啊