Babylon, the framework

Hi, I want to know the internal frame description of BabylonJS and the scene rendering process

1 Like

A description of the rendering process, like this?

The renderLoop class is made of four parts:
engine.beginFrame: Starts a new frame.
scene.render: Asks the scene for rendering object.
engine.endFrame: Present the current frame to the canvas after closing it.
QueueNewFrame: Registers a new frame.

Source

The Quick Learn Way to Creating a 3D Object With Babylon.js

1 Like

Thank you

into the code… :grin:

From 3.0:

        /**
         * stop executing a render loop function and remove it from the execution array
         * @param {Function} [renderFunction] the function to be removed. If not provided all functions will be removed.
         */
        Engine.prototype.stopRenderLoop = function (renderFunction) {
            if (!renderFunction) {
                this._activeRenderLoops = [];
                return;
            }
            var index = this._activeRenderLoops.indexOf(renderFunction);
            if (index >= 0) {
                this._activeRenderLoops.splice(index, 1);
            }
        };
        Engine.prototype._renderLoop = function () {
            var shouldRender = true;
            if (!this.renderEvenInBackground && this._windowIsBackground) {
                shouldRender = false;
            }
            if (shouldRender) {
                // Start new frame
                this.beginFrame();
                for (var index = 0; index < this._activeRenderLoops.length; index++) {
                    var renderFunction = this._activeRenderLoops[index];
                    renderFunction();
                }
                // Present
                this.endFrame();
            }
            if (this._activeRenderLoops.length > 0) {
                // Register new frame
                BABYLON.Tools.QueueNewFrame(this._bindedRenderFunction, this._vrDisplayEnabled);
            }
            else {
                this._renderingQueueLaunched = false;
            }
        };
        /**
         * Register and execute a render loop. The engine can have more than one render function.
         * @param {Function} renderFunction - the function to continuously execute starting the next render loop.
         * @example
         * engine.runRenderLoop(function () {
         *      scene.render()
         * })
         */
        Engine.prototype.runRenderLoop = function (renderFunction) {
            if (this._activeRenderLoops.indexOf(renderFunction) !== -1) {
                return;
            }
            this._activeRenderLoops.push(renderFunction);
            if (!this._renderingQueueLaunched) {
                this._renderingQueueLaunched = true;
                this._bindedRenderFunction = this._renderLoop.bind(this);
                BABYLON.Tools.QueueNewFrame(this._bindedRenderFunction);
            }
        };


          this._afterRender = function () {
                if (!_this._init)
                    return;
                if (_this._toRemoveGeometryArray.length == 0 && _this._toRemoveMeshesArray.length == 0 && Object.keys(_this._addUpdateGeometriesList).length == 0 && Object.keys(_this._addUpdateMeshesList).length == 0) {
                    return;
                }
                //5 concurrent updates were sent to the web worker and were not yet processed. Abort next update.
                //TODO make sure update runs as fast as possible to be able to update 60 FPS.
                if (_this._runningUpdated > 4) {
                    return;
                }
                ++_this._runningUpdated;
                var payload = {
                    updatedMeshes: _this._addUpdateMeshesList,
                    updatedGeometries: _this._addUpdateGeometriesList,
                    removedGeometries: _this._toRemoveGeometryArray,
                    removedMeshes: _this._toRemoveMeshesArray
                };
                var message = {
                    payload: payload,
                    taskType: WorkerTaskType.UPDATE
                };
                var serializable = [];
                for (var id in payload.updatedGeometries) {
                    if (payload.updatedGeometries.hasOwnProperty(id)) {
                        //prepare transferables
                        serializable.push(message.payload.updatedGeometries[id].indices.buffer);
                        serializable.push(message.payload.updatedGeometries[id].normals.buffer);
                        serializable.push(message.payload.updatedGeometries[id].positions.buffer);
                    }
                }
                _this._worker.postMessage(message, serializable);
                _this._addUpdateMeshesList = {};
                _this._addUpdateGeometriesList = {};
                _this._toRemoveGeometryArray = [];
                _this._toRemoveMeshesArray = [];
            };
            this._onMessageFromWorker = function (e) {
                var returnData = e.data;
                if (returnData.error != WorkerReplyType.SUCCESS) {

So completely elegant.

            if (shouldRender) {
                // Start new frame
                this.beginFrame();
                for (var index = 0; index < this._activeRenderLoops.length; index++) {
                    var renderFunction = this._activeRenderLoops[index];
                    renderFunction();
                }
                // Present
                this.endFrame();
            }

And probably optimized already. Look at those Workers!

Great question, and insight from @Modos . Thanks…

:eagle:

what is this

look again… :grin:

Someone once said, if you want to know the code then go into it…

1 Like

I think it’s rendering

1 Like