Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small internal refactor of the way camera is passed around for rendering #5656

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions src/scene/composition/layer-composition.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ class LayerComposition extends EventHandler {
*/
cameras = [];

/**
* A mapping of {@link CameraComponent} to its index in {@link LayerComposition#cameras}.
*
* @type {Map<import('../../framework/components/camera/component.js').CameraComponent, number>}
* @ignore
*/
camerasMap = new Map();

/**
* The actual rendering sequence, generated based on layers and cameras
*
Expand Down Expand Up @@ -134,6 +142,12 @@ class LayerComposition extends EventHandler {
sortPriority(this.cameras);
}

// update camera map
this.camerasMap.clear();
for (let i = 0; i < this.cameras.length; i++) {
this.camerasMap.set(this.cameras[i], i);
}

// collect a list of layers this camera renders
const cameraLayers = [];

Expand Down Expand Up @@ -181,16 +195,11 @@ class LayerComposition extends EventHandler {
}
}

// camera index in the layer array
const cameraIndex = layer.cameras.indexOf(camera);
if (cameraIndex >= 0) {

// add render action to describe rendering step
lastRenderAction = this.addRenderAction(this._renderActions, renderActionCount, layer, j, cameraIndex,
cameraFirstRenderAction, postProcessMarked);
renderActionCount++;
cameraFirstRenderAction = false;
}
// add render action to describe rendering step
lastRenderAction = this.addRenderAction(this._renderActions, renderActionCount, layer, j, camera,
cameraFirstRenderAction, postProcessMarked);
renderActionCount++;
cameraFirstRenderAction = false;
}
}
}
Expand Down Expand Up @@ -226,7 +235,7 @@ class LayerComposition extends EventHandler {
}

// function adds new render action to a list, while trying to limit allocation and reuse already allocated objects
addRenderAction(renderActions, renderActionIndex, layer, layerIndex, cameraIndex, cameraFirstRenderAction, postProcessMarked) {
addRenderAction(renderActions, renderActionIndex, layer, layerIndex, camera, cameraFirstRenderAction, postProcessMarked) {

// try and reuse object, otherwise allocate new
/** @type {RenderAction} */
Expand All @@ -237,8 +246,6 @@ class LayerComposition extends EventHandler {

// render target from the camera takes precedence over the render target from the layer
let rt = layer.renderTarget;
/** @type {import('../../framework/components/camera/component.js').CameraComponent} */
const camera = layer.cameras[cameraIndex];
if (camera && camera.renderTarget) {
if (layer.id !== LAYERID_DEPTH) { // ignore depth layer
rt = camera.renderTarget;
Expand Down Expand Up @@ -276,7 +283,6 @@ class LayerComposition extends EventHandler {
renderAction.triggerPostprocess = false;
renderAction.layerIndex = layerIndex;
renderAction.layer = layer;
renderAction.cameraIndex = cameraIndex;
renderAction.camera = camera;
renderAction.renderTarget = rt;
renderAction.clearColor = clearColor;
Expand Down Expand Up @@ -333,7 +339,7 @@ class LayerComposition extends EventHandler {
const layer = this.layerList[layerIndex];
const enabled = layer.enabled && this.subLayerEnabled[layerIndex];
const transparent = this.subLayerList[layerIndex];
const camera = layer.cameras[ra.cameraIndex];
const camera = ra.camera;
const clear = (ra.clearColor ? 'Color ' : '..... ') + (ra.clearDepth ? 'Depth ' : '..... ') + (ra.clearStencil ? 'Stencil' : '.......');

Debug.trace(TRACEID_RENDER_ACTION, i +
Expand Down
3 changes: 0 additions & 3 deletions src/scene/composition/render-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ class RenderAction {
// the layer
this.layer = null;

// index into a camera array of the layer, stored in Layer.cameras
this.cameraIndex = 0;

// camera of type CameraComponent
this.camera = null;

Expand Down
25 changes: 17 additions & 8 deletions src/scene/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,18 @@ class Layer {
* True if the objects rendered on the layer require light cube (emitters with lighting do).
*
* @type {boolean}
* @ignore
*/
requiresLightCube = false;

/**
* @type {import('../framework/components/camera/component.js').CameraComponent[]}
* @ignore
*/
cameras = [];

_dirtyCameras = false;

/**
* Create a new Layer instance.
*
Expand Down Expand Up @@ -275,6 +284,7 @@ class Layer {
* @type {Function}
*/
this.onPreCull = options.onPreCull;

/**
* Custom function that is called before this layer is rendered. Useful, for example, for
* reacting on screen size changes. This function is called before the first occurrence of
Expand All @@ -285,6 +295,7 @@ class Layer {
* @type {Function}
*/
this.onPreRender = options.onPreRender;

/**
* Custom function that is called before opaque mesh instances (not semi-transparent) in
* this layer are rendered. This function will receive camera index as the only argument.
Expand All @@ -294,6 +305,7 @@ class Layer {
* @type {Function}
*/
this.onPreRenderOpaque = options.onPreRenderOpaque;

/**
* Custom function that is called before semi-transparent mesh instances in this layer are
* rendered. This function will receive camera index as the only argument. You can get the
Expand All @@ -313,6 +325,7 @@ class Layer {
* @type {Function}
*/
this.onPostCull = options.onPostCull;

/**
* Custom function that is called after this layer is rendered. Useful to revert changes
* made in {@link Layer#onPreRender}. This function is called after the last occurrence of this
Expand All @@ -323,6 +336,7 @@ class Layer {
* @type {Function}
*/
this.onPostRender = options.onPostRender;

/**
* Custom function that is called after opaque mesh instances (not semi-transparent) in
* this layer are rendered. This function will receive camera index as the only argument.
Expand All @@ -332,6 +346,7 @@ class Layer {
* @type {Function}
*/
this.onPostRenderOpaque = options.onPostRenderOpaque;

/**
* Custom function that is called after semi-transparent mesh instances in this layer are
* rendered. This function will receive camera index as the only argument. You can get the
Expand All @@ -349,6 +364,7 @@ class Layer {
* @type {Function}
*/
this.onDrawCall = options.onDrawCall;

/**
* Custom function that is called after the layer has been enabled. This happens when:
*
Expand All @@ -361,6 +377,7 @@ class Layer {
* @type {Function}
*/
this.onEnable = options.onEnable;

/**
* Custom function that is called after the layer has been disabled. This happens when:
*
Expand Down Expand Up @@ -395,14 +412,6 @@ class Layer {
*/
this.customCalculateSortValues = null;

/**
* @type {import('../framework/components/camera/component.js').CameraComponent[]}
* @ignore
*/
this.cameras = [];

this._dirtyCameras = false;

// light hash based on the light keys
this._lightHash = 0;
this._lightHashDirty = false;
Expand Down
16 changes: 7 additions & 9 deletions src/scene/renderer/forward-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ class ForwardRenderer extends Renderer {

const renderAction = renderActions[i];
const layer = layerComposition.layerList[renderAction.layerIndex];
const camera = layer.cameras[renderAction.cameraIndex];
const camera = renderAction.camera;

// skip disabled layers
if (!renderAction.isLayerEnabled(layerComposition)) {
Expand Down Expand Up @@ -835,7 +835,7 @@ class ForwardRenderer extends Renderer {
// postprocessing
if (renderAction.triggerPostprocess && camera?.onPostprocessing) {
const renderPass = new RenderPass(this.device, () => {
this.renderPassPostprocessing(renderAction, layerComposition);
this.renderPassPostprocessing(renderAction);
});
renderPass.requiresCubemaps = false;
DebugHelper.setName(renderPass, `Postprocess`);
Expand Down Expand Up @@ -863,8 +863,7 @@ class ForwardRenderer extends Renderer {
const renderActions = layerComposition._renderActions;
const startRenderAction = renderActions[startIndex];
const endRenderAction = renderActions[endIndex];
const startLayer = layerComposition.layerList[startRenderAction.layerIndex];
const camera = startLayer.cameras[startRenderAction.cameraIndex];
const camera = startRenderAction.camera;

if (camera) {

Expand Down Expand Up @@ -948,10 +947,9 @@ class ForwardRenderer extends Renderer {
this.gpuUpdate(this.processingMeshInstances);
}

renderPassPostprocessing(renderAction, layerComposition) {
renderPassPostprocessing(renderAction) {

const layer = layerComposition.layerList[renderAction.layerIndex];
const camera = layer.cameras[renderAction.cameraIndex];
const camera = renderAction.camera;
Debug.assert(renderAction.triggerPostprocess && camera.onPostprocessing);

// trigger postprocessing for camera
Expand Down Expand Up @@ -990,8 +988,8 @@ class ForwardRenderer extends Renderer {
const layer = comp.layerList[layerIndex];
const transparent = comp.subLayerList[layerIndex];

const cameraPass = renderAction.cameraIndex;
const camera = layer.cameras[cameraPass];
const camera = renderAction.camera;
const cameraPass = comp.camerasMap.get(camera);

if (!renderAction.isLayerEnabled(comp)) {
return;
Expand Down
9 changes: 5 additions & 4 deletions src/scene/renderer/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1082,9 +1082,8 @@ class Renderer {
if (!layer.enabled || !comp.subLayerEnabled[layerIndex]) continue;

// camera
const cameraPass = renderAction.cameraIndex;
/** @type {import('../../framework/components/camera/component.js').CameraComponent} */
const camera = layer.cameras[cameraPass];
const camera = renderAction.camera;

if (camera) {

Expand All @@ -1101,13 +1100,15 @@ class Renderer {
this.cullLights(camera.camera, layer._lights);

// cull mesh instances
layer.onPreCull?.(cameraPass);
if (layer.onPreCull)
layer.onPreCull(comp.camerasMap.get(camera));

const culledInstances = layer.getCulledInstances(camera.camera);
const drawCalls = layer.meshInstances;
this.cull(camera.camera, drawCalls, culledInstances);

layer.onPostCull?.(cameraPass);
if (layer.onPostCull)
layer.onPostCull(comp.camerasMap.get(camera));
}
}

Expand Down