Recently, there is a requirement that we want to use our own 3D engine to render the earth logic. If we implement it from scratch, it will take a lot of time, and we need to realize tilt photography later, so we plan to use Cesium to help us do scheduling and then use our own 3D engine to render. Js to render three objects, cesium to render cesium objects, which is easier to implement. However, the problem is how to sort when a complex scene appears. Of course, many more problems are simply unsolvable. Is the so-called one mountain not allow two tigers, when the two tigers have differences listen to who that? After looking at the Cesium code, I found that cesium’s logic and rendering were well separated. The rendering of each frame was to execute the final drawCommand. I thought it could be done in a day, but it still took several days and involved some details. Now I would like to share with you the ideas and methods (currently there are one or two small points of cesium earth scheduling that have not been completely clarified, but I have chosen to skip it, which does not affect the tile logic. If you know, please welcome comments and guidance. At present, I will use three.js to express my engine.)

The rendering order is as follows:

  1. Update of frameState —– is mainly passed in various parameters needed by Cesium frameState, camera, viewPort, cone, etc

Which we need to be banned some cesium unnecessary overhead, such as shadow and so on (because the shadow we still need to use our own engine implementation), of course, because the camera also needs to implement a set of operation, the camera operation and update must be their own engines do, cesium camera also not too conforms to its own operating habits, Camera operation is not too easy, I can share it later when I have time

  1. Cesium scheduling —— is mainly the creation and update of plot data + image request and download. This part is basically the most complex, and it is necessary to completely clear Cesium logic, which needs to stop some unnecessary logic and maximize performance (for example, pick must stop, Because pick must be implemented by its own engine, it must be clear that only cesium earth is used for scheduling, so all irrelevant stops to achieve optimal performance). Of course, there is also a lot of cesium logic that needs to be disabled, such as the creation and uploading of attribute (cesium creates buffer directly, which is a waste of memory), the creation of texture sample object, and so on

  2. Render —– At this point, we get the tile of the current frame to render (it has all kinds of information such as imagery, data, etc.), and then we create the mesh and hang it under our own scene for rendering. Each frame first empties all the mesh under the Earth node, and then cesium tells us to render which mesh to hang on (this is a complete simulation of Cesium’s drawCommand logic). The mesh cache, the Material cache, the texture cache, and the uniform objects cache are all set to mesh, material cache,texture cache, and uniform objects.

Ah, said an episode, I started doing about the logic, but due to our side rendering engine rendering is complicated, cause I don’t update of cesium in the engine before rendering (I thought is to perform the above logic, ah), and then has been to reduce the flash of white pieces on both sides of problem (actually white block is because the earth did not apply colours to a drawing, That white patch is actually the atmosphere. I once suspected that cesium had rendered the first and second frames to targetBuffer and then mixed them, but I did some experiments and found that it wasn’t. Cesium was one frame faster than cesium when rendering was performed first.

Here’s how these three steps work: 1. Update frameState: Look at the frameState class and see what information needs to be passed in. It should be easy to do that, but pick, depth, postProcess, creditDisplay, shadow, we don’t need any of that logic (if we do, we’ll use our own engine, of course, No extra overhead). In fact, cesium logic can be used to calculate the fog concentration, but I implemented the fog on my side, so I also disabled the fog logic. The first step in the core is the camera and cones, specific information below frameState. Camera = {positionWC: frameState positionWC, positionCartographic: frameState.positionCartographic, directionWC:frameState.directionWC, frustum:frameState.perspectiveOffCenterFrustum, } frameState.cullingVolume = frameState.perspectiveOffCenterFrustum.computeCullingVolume(frameState.positionWC, cameraDirectionWC, cameraUpWC); (A lot of parameters can be calculated by looking at the cesium code, but pay attention to the conversion between the WebGL engine coordinate system and cesium coordinate system)

2. The second step of CESium scheduling is to first clarify the plot rendering logic of Cesium (this is not detailed for space reasons, if it is not clear, please refer to the longest frame of Cesium). At present, we just use the core part of the plot to manually adjust the interface for rendering scheduling. (1) First create QuadtreePrimitive (2)beginFrame: BeginFrame (this._surface. BeginFrame (this._framestate)), here is the main release and innovation to create level 0 tile, do not need to make changes to (3) render: Call this._surface.render(this._framestate);So we’re killing endUpdate, and really our draw is basically doing the same thing as endUpdate. Using var tilesToRenderByTextureCount = this. _tilesToRenderByTextureCount; Eventually the tilesToRenderByTextureCount data, from the inside our tiles, imagery and terrian), and, of course, pick the logic must be disposed of, The next step is to call selectTilesForRendering to get the mesh that needs to be created (although this may require some parameter changes, After all, a WebGL context like context cannot be passed into framestate, of course you can manually update it if you need to use cesium intercepting or other functions after render.) (4)endFrame: Next comes the core part: call this._surface.endFrame(this._framestate); In processTileLoadQueue, loop through all globesurfacetiles in the update queue, parse the tile data, and download the imagesTests found updateHeighs continues for a long time flight will drop frames, this I commented out first, no look, if you have know that you can leave a message, thank you The next step is GlobeSurfaceTile processStateMachine, Here will iterate through all the tiles if the state is START prepareNewTile, if it is LOADING processTerrainStateMachine, processing the terrain here to download and plot of the grid generation logic, the formation of the water. After this part of Cesium is successfully analyzed, we will directly generate the attribute. What we need to do is to skip the attribute logic and manually mark the ready state of the plot (terrain) grid. Then there is the picture to download, this part of the deal with the most complicated, I began to is to use their engines to download image resources, although no problem, but can’t use the cesium closure (can set the maximum number of requests per frame, extra requests can be stopped, so continue to fly again to solve the problem of memory leaks). Therefore, it is recommended to use cesium’s following logic, but to block the creation of the sampler, but note that the texture object needs to be bound, because it is important for Cesium to recursively find the most recent graph when a new graph has not been downloaded. The details can see TileImagery. Prototype. ProcessStateMachine logic.ReprojectTexture we don’t need it, merge it with createTexture, and then focus on the createTexture code. Change the code that created the Sampler to the code that generated the texture for our engine. The last step: the render logic of your engine, because it is a large scale rendering, so the engine first needs to implement logDepth. Then start to prepare the Earth shader (is the cesium shader look, understand the line, but pay attention to some coordinate transformation, of course, this part also has a certain difficulty, can share later). Then you can start rendering the logic. Specifically for the earth to create a node, and then clears out, each frame and then traverse the enclosing _surface. TileProvider. _tilesToRenderByTextureCount to perform rendering, pay attention to the cache tiles and material, also pay attention to the cache uniform, After this piece of implementation a smooth earth has appeared, unexpectedly the perfect implementation of a Hello world is not so easyOf course we can add various map filters: