Skip to content

Commit

Permalink
Allow users to provide their own custom rendering function for the sc…
Browse files Browse the repository at this point in the history
  • Loading branch information
deltakosh authored Sep 30, 2024
1 parent 2e33b0e commit 5a140d5
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 50 deletions.
17 changes: 17 additions & 0 deletions packages/dev/core/src/Meshes/mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2342,6 +2342,23 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
return this;
}

/**
* Render a complete mesh by going through all submeshes
* @returns the current mesh
* #5SPY1V#2: simple test
* #5SPY1V#5: perf test
*/
public directRender(): Mesh {
if (!this.subMeshes) {
return this;
}

for (const submesh of this.subMeshes) {
this.render(submesh, false);
}
return this;
}

/**
* Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
* @param subMesh defines the subMesh to render
Expand Down
112 changes: 62 additions & 50 deletions packages/dev/core/src/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4647,6 +4647,11 @@ export class Scene implements IAnimatable, IClipPlanesHolder, IAssetContainer {
}
}

/**
* If this function is defined it will take precedence over the standard render() function.
*/
public customRenderFunction?: () => void;

/**
* Render the scene
* @param updateCameras defines a boolean indicating if cameras must update according to their inputs (true by default)
Expand Down Expand Up @@ -4721,73 +4726,80 @@ export class Scene implements IAnimatable, IClipPlanesHolder, IAssetContainer {

// Before render
this.onBeforeRenderObservable.notifyObservers(this);
// Custom render function?
if (this.customRenderFunction) {
this._renderId++;
this._engine.currentRenderPassId = Constants.RENDERPASS_MAIN;

const engine = this.getEngine();
this.customRenderFunction();
} else {
const engine = this.getEngine();

// Customs render targets
this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);
// Customs render targets
this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);

const currentActiveCamera = this.activeCameras?.length ? this.activeCameras[0] : this.activeCamera;
if (this.renderTargetsEnabled) {
Tools.StartPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
this._intermediateRendering = true;
for (let customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {
const renderTarget = this.customRenderTargets[customIndex];
if (renderTarget._shouldRender()) {
this._renderId++;
const currentActiveCamera = this.activeCameras?.length ? this.activeCameras[0] : this.activeCamera;
if (this.renderTargetsEnabled) {
Tools.StartPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
this._intermediateRendering = true;
for (let customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {
const renderTarget = this.customRenderTargets[customIndex];
if (renderTarget._shouldRender()) {
this._renderId++;

this.activeCamera = renderTarget.activeCamera || this.activeCamera;
this.activeCamera = renderTarget.activeCamera || this.activeCamera;

if (!this.activeCamera) {
throw new Error("Active camera not set");
}
if (!this.activeCamera) {
throw new Error("Active camera not set");
}

// Viewport
engine.setViewport(this.activeCamera.viewport);
// Viewport
engine.setViewport(this.activeCamera.viewport);

// Camera
this.updateTransformMatrix();
// Camera
this.updateTransformMatrix();

renderTarget.render(currentActiveCamera !== this.activeCamera, this.dumpNextRenderTargets);
renderTarget.render(currentActiveCamera !== this.activeCamera, this.dumpNextRenderTargets);
}
}
Tools.EndPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
this._intermediateRendering = false;
this._renderId++;
}
Tools.EndPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
this._intermediateRendering = false;
this._renderId++;
}

this._engine.currentRenderPassId = currentActiveCamera?.renderPassId ?? Constants.RENDERPASS_MAIN;

// Restore back buffer
this.activeCamera = currentActiveCamera;
if (this._activeCamera && this._activeCamera.cameraRigMode !== Constants.RIG_MODE_CUSTOM && !this.prePass) {
this._bindFrameBuffer(this._activeCamera, false);
}
this.onAfterRenderTargetsRenderObservable.notifyObservers(this);
this._engine.currentRenderPassId = currentActiveCamera?.renderPassId ?? Constants.RENDERPASS_MAIN;

for (const step of this._beforeClearStage) {
step.action();
}
// Restore back buffer
this.activeCamera = currentActiveCamera;
if (this._activeCamera && this._activeCamera.cameraRigMode !== Constants.RIG_MODE_CUSTOM && !this.prePass) {
this._bindFrameBuffer(this._activeCamera, false);
}
this.onAfterRenderTargetsRenderObservable.notifyObservers(this);

// Clear
this._clearFrameBuffer(this.activeCamera);
for (const step of this._beforeClearStage) {
step.action();
}

// Collects render targets from external components.
for (const step of this._gatherRenderTargetsStage) {
step.action(this._renderTargets);
}
// Clear
this._clearFrameBuffer(this.activeCamera);

// Multi-cameras?
if (this.activeCameras && this.activeCameras.length > 0) {
for (let cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
this._processSubCameras(this.activeCameras[cameraIndex], cameraIndex > 0);
}
} else {
if (!this.activeCamera) {
throw new Error("No camera defined");
// Collects render targets from external components.
for (const step of this._gatherRenderTargetsStage) {
step.action(this._renderTargets);
}

this._processSubCameras(this.activeCamera, !!this.activeCamera.outputRenderTarget);
// Multi-cameras?
if (this.activeCameras && this.activeCameras.length > 0) {
for (let cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
this._processSubCameras(this.activeCameras[cameraIndex], cameraIndex > 0);
}
} else {
if (!this.activeCamera) {
throw new Error("No camera defined");
}

this._processSubCameras(this.activeCamera, !!this.activeCamera.outputRenderTarget);
}
}

// Intersection checks
Expand Down

0 comments on commit 5a140d5

Please sign in to comment.