Skip to content

Commit

Permalink
[BREAKING] Remove support for Layer.renderTarget and some callbacks o…
Browse files Browse the repository at this point in the history
…n the Layer (#6888)

* [BREAKING] Remove support for Layer.renderTarget and some callbacks on the Layer

* Update src/scene/composition/layer-composition.js

Co-authored-by: Will Eastcott <will@playcanvas.com>

* Update src/scene/composition/render-action.js

Co-authored-by: Will Eastcott <will@playcanvas.com>

---------

Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
Co-authored-by: Will Eastcott <will@playcanvas.com>
  • Loading branch information
3 people authored Aug 21, 2024
1 parent 3bfbe2f commit b15e751
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 218 deletions.
34 changes: 24 additions & 10 deletions src/deprecated/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -513,16 +513,30 @@ Object.defineProperty(Scene.prototype, 'models', {
}
});

Object.defineProperty(Layer.prototype, 'renderTarget', {
set: function (rt) {
Debug.deprecated('pc.Layer#renderTarget is deprecated. Set the render target on the camera instead.');
this._renderTarget = rt;
this._dirtyComposition = true;
},
get: function () {
return this._renderTarget;
}
});
// A helper function to add deprecated set and get property on a Layer
function _removedLayerProperty(name) {
Object.defineProperty(Layer.prototype, name, {
set: function (value) {
Debug.errorOnce(`pc.Layer#${name} has been removed.`);
},
get: function () {
Debug.errorOnce(`pc.Layer#${name} has been removed.`);
return undefined;
}
});
}

_removedLayerProperty('renderTarget');
_removedLayerProperty('onPreCull');
_removedLayerProperty('onPreRender');
_removedLayerProperty('onPreRenderOpaque');
_removedLayerProperty('onPreRenderTransparent');
_removedLayerProperty('onPostCull');
_removedLayerProperty('onPostRender');
_removedLayerProperty('onPostRenderOpaque');
_removedLayerProperty('onPostRenderTransparent');
_removedLayerProperty('onDrawCall');
_removedLayerProperty('layerReference');

Object.defineProperty(Batch.prototype, 'model', {
get: function () {
Expand Down
2 changes: 0 additions & 2 deletions src/framework/app-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -1925,8 +1925,6 @@ class AppBase extends EventHandler {

this._entityIndex = {};

this.defaultLayerDepth.onPreRenderOpaque = null;
this.defaultLayerDepth.onPostRenderOpaque = null;
this.defaultLayerDepth.onDisable = null;
this.defaultLayerDepth.onEnable = null;
this.defaultLayerDepth = null;
Expand Down
20 changes: 17 additions & 3 deletions src/framework/components/camera/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,39 @@ class CameraComponent extends Component {
/**
* Custom function that is called when postprocessing should execute.
*
* @type {Function}
* @type {Function|null}
* @ignore
*/
onPostprocessing = null;

/**
* Custom function that is called before the camera renders the scene.
*
* @type {Function}
* @type {Function|null}
*/
onPreRender = null;

/**
* Custom function that is called after the camera renders the scene.
*
* @type {Function}
* @type {Function|null}
*/
onPostRender = null;

/**
* Custom function that is called before visibility culling is performed for this camera.
*
* @type {Function|null}
*/
onPreCull = null;

/**
* Custom function that is called after visibility culling is performed for this camera.
*
* @type {Function|null}
*/
onPostCull = null;

/**
* A counter of requests of depth map rendering.
*
Expand Down
28 changes: 4 additions & 24 deletions src/scene/composition/layer-composition.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,12 @@ class LayerComposition extends EventHandler {
subLayerEnabled = []; // more granular control on top of layer.enabled (ANDed)

/**
* A read-only array of {@link CameraComponent} that can be used during rendering. e.g.
* Inside {@link Layer#onPreCull}, {@link Layer#onPostCull}, {@link Layer#onPreRender},
* {@link Layer#onPostRender}.
* An array of {@link CameraComponent}s.
*
* @type {CameraComponent[]}
*/
cameras = [];

/**
* A mapping of {@link CameraComponent} to its index in {@link LayerComposition#cameras}.
*
* @type {Map<CameraComponent, number>}
* @ignore
*/
camerasMap = new Map();
cameras = [];

/**
* The actual rendering sequence, generated based on layers and cameras
Expand Down Expand Up @@ -170,12 +161,6 @@ 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 @@ -283,13 +268,8 @@ class LayerComposition extends EventHandler {
// function adds new render action to a list, while trying to limit allocation and reuse already allocated objects
addRenderAction(renderActionIndex, layer, isTransparent, camera, cameraFirstRenderAction, postProcessMarked) {

// render target from the camera takes precedence over the render target from the layer
let rt = layer.renderTarget;
if (camera && camera.renderTarget) {
if (layer.id !== LAYERID_DEPTH) { // ignore depth layer
rt = camera.renderTarget;
}
}
// camera's render target, ignoring depth layer
let rt = layer.id !== LAYERID_DEPTH ? camera.renderTarget : null;

// was camera and render target combo used already
let used = false;
Expand Down
2 changes: 1 addition & 1 deletion src/scene/composition/render-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RenderAction {
this.camera = null;

/**
* render target this render action renders to (taken from either camera or layer)
* Render target this render action renders to.
*
* @type {RenderTarget|null}
*/
Expand Down
102 changes: 1 addition & 101 deletions src/scene/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,98 +275,6 @@ class Layer {
*/
this._clearStencilBuffer = !!options.clearStencilBuffer;

/**
* Custom function that is called before visibility culling is performed for this layer.
* Useful, for example, if you want to modify camera projection while still using the same
* camera and make frustum culling work correctly with it (see
* {@link CameraComponent#calculateTransform} and {@link CameraComponent#calculateProjection}).
* This function will receive camera index as the only argument. You can get the actual
* camera being used by looking up {@link LayerComposition#cameras} with this index.
*
* @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
* this layer in {@link LayerComposition}. It will receive camera index as the only
* argument. You can get the actual camera being used by looking up
* {@link LayerComposition#cameras} with this index.
*
* @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.
* You can get the actual camera being used by looking up {@link LayerComposition#cameras}
* with this index.
*
* @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
* actual camera being used by looking up {@link LayerComposition#cameras} with this index.
*
* @type {Function}
*/
this.onPreRenderTransparent = options.onPreRenderTransparent;

/**
* Custom function that is called after visibility culling is performed for this layer.
* Useful for reverting changes done in {@link Layer#onPreCull} and determining final mesh
* instance visibility (see {@link MeshInstance#visibleThisFrame}). This function will
* receive camera index as the only argument. You can get the actual camera being used by
* looking up {@link LayerComposition#cameras} with this index.
*
* @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
* layer in {@link LayerComposition}. It will receive camera index as the only argument.
* You can get the actual camera being used by looking up {@link LayerComposition#cameras}
* with this index.
*
* @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.
* You can get the actual camera being used by looking up {@link LayerComposition#cameras}
* with this index.
*
* @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
* actual camera being used by looking up {@link LayerComposition#cameras} with this index.
*
* @type {Function}
*/
this.onPostRenderTransparent = options.onPostRenderTransparent;

/**
* Custom function that is called before every mesh instance in this layer is rendered. It
* is not recommended to set this function when rendering many objects every frame due to
* performance reasons.
*
* @type {Function}
*/
this.onDrawCall = options.onDrawCall;

/**
* Custom function that is called after the layer has been enabled. This happens when:
*
Expand Down Expand Up @@ -394,20 +302,12 @@ class Layer {
this.onEnable();
}

/**
* Make this layer render the same mesh instances that another layer does instead of having
* its own mesh instance list. Both layers must share cameras. Frustum culling is only
* performed for one layer. Useful for rendering multiple passes using different shaders.
*
* @type {Layer}
*/
this.layerReference = options.layerReference; // should use the same camera

/**
* @type {Function|null}
* @ignore
*/
this.customSortCallback = null;

/**
* @type {Function|null}
* @ignore
Expand Down
2 changes: 1 addition & 1 deletion src/scene/mesh-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ class MeshInstance {
visible = true;

/**
* Read this value in {@link Layer#onPostCull} to determine if the object is actually going to
* Read this value in {@link CameraComponent#onPostCull} to determine if the object is actually going to
* be rendered.
*
* @type {boolean}
Expand Down
2 changes: 1 addition & 1 deletion src/scene/renderer/forward-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ class ForwardRenderer extends Renderer {
visible,
splitLights,
shaderPass,
layer?.onDrawCall,
null,
layer,
flipFaces);

Expand Down
55 changes: 12 additions & 43 deletions src/scene/renderer/render-pass-forward.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ class RenderPassForward extends RenderPass {

before() {
const { renderActions } = this;
if (renderActions.length) {

// callback on the camera component before rendering with this camera for the first time
const ra = renderActions[0];
if (ra.camera.onPreRender && ra.firstCameraUse) {
ra.camera.onPreRender();
// onPreRender callbacks
for (let i = 0; i < renderActions.length; i++) {
const ra = renderActions[i];
if (ra.firstCameraUse) {
ra.camera.onPreRender?.();
}
}
}
Expand All @@ -218,12 +218,12 @@ class RenderPassForward extends RenderPass {
}

after() {
const { renderActions } = this;
if (renderActions.length) {
// callback on the camera component when we're done rendering with this camera
const ra = renderActions[renderActions.length - 1];
if (ra.camera.onPostRender && ra.lastCameraUse) {
ra.camera.onPostRender();

// onPostRender callbacks
for (let i = 0; i < this.renderActions.length; i++) {
const ra = this.renderActions[i];
if (ra.lastCameraUse) {
ra.camera.onPostRender?.();
}
}

Expand All @@ -237,34 +237,18 @@ class RenderPassForward extends RenderPass {
*/
renderRenderAction(renderAction, firstRenderAction) {

const { renderer, layerComposition } = this;
const { renderer } = this;
const device = renderer.device;

// layer
const { layer, transparent, camera } = renderAction;
const cameraPass = layerComposition.camerasMap.get(camera);

DebugGraphics.pushGpuMarker(this.device, `Camera: ${camera ? camera.entity.name : 'Unnamed'}, Layer: ${layer.name}(${transparent ? 'TRANSP' : 'OPAQUE'})`);

// #if _PROFILER
const drawTime = now();
// #endif

// Call pre-render callback if there's one
if (!transparent && layer.onPreRenderOpaque) {
layer.onPreRenderOpaque(cameraPass);
} else if (transparent && layer.onPreRenderTransparent) {
layer.onPreRenderTransparent(cameraPass);
}

// Called for the first sublayer and for every camera
if (!(layer._preRenderCalledForCameras & (1 << cameraPass))) {
if (layer.onPreRender) {
layer.onPreRender(cameraPass);
}
layer._preRenderCalledForCameras |= 1 << cameraPass;
}

if (camera) {

const options = {
Expand Down Expand Up @@ -294,21 +278,6 @@ class RenderPassForward extends RenderPass {
device.setAlphaToCoverage(false);
}

// Call layer's post-render callback if there's one
if (!transparent && layer.onPostRenderOpaque) {
layer.onPostRenderOpaque(cameraPass);
} else if (transparent && layer.onPostRenderTransparent) {
layer.onPostRenderTransparent(cameraPass);
}
if (layer.onPostRender && !(layer._postRenderCalledForCameras & (1 << cameraPass))) {
layer._postRenderCounter &= ~(transparent ? 2 : 1);
if (layer._postRenderCounter === 0) {
layer.onPostRender(cameraPass);
layer._postRenderCalledForCameras |= 1 << cameraPass;
layer._postRenderCounter = layer._postRenderCounterMax;
}
}

DebugGraphics.popGpuMarker(this.device);

// #if _PROFILER
Expand Down
Loading

0 comments on commit b15e751

Please sign in to comment.