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.
1 Like
Thank you
into the code… 
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…

what is this
look again… 
Someone once said, if you want to know the code then go into it…
1 Like
I think it’s rendering
1 Like