Skip to content

Commit

Permalink
CameraFrame render pass rendering supports stencil buffer (#7031)
Browse files Browse the repository at this point in the history
* CameraFrame render pass rendering supports stencil buffer

* removed temp code

---------

Co-authored-by: Martin Valigursky <[email protected]>
  • Loading branch information
mvaligursky and Martin Valigursky authored Oct 14, 2024
1 parent 788ebe8 commit d50705d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
3 changes: 3 additions & 0 deletions examples/assets/scripts/misc/camera-frame.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class Rendering {
*/
renderFormatFallback1 = RenderFormat.RGBA32;

stencil = false;

/**
* @attribute
* @range [0.1, 1]
Expand Down Expand Up @@ -372,6 +374,7 @@ class CameraFrame extends Script {
updateOptions() {

const { options, rendering, bloom, taa, ssao } = this;
options.stencil = rendering.stencil;
options.samples = rendering.samples;
options.sceneColorMap = rendering.sceneColorMap;
options.prepassEnabled = rendering.sceneDepthMap;
Expand Down
15 changes: 14 additions & 1 deletion examples/src/examples/graphics/portal.example.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as pc from 'playcanvas';
import { deviceType, rootPath } from 'examples/utils';
import { deviceType, rootPath, fileImport } from 'examples/utils';
const { CameraFrame } = await fileImport(rootPath + '/static/assets/scripts/misc/camera-frame.mjs');

const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById('application-canvas'));
window.focus();
Expand Down Expand Up @@ -156,6 +157,18 @@ assetListLoader.load(() => {
camera.setLocalEulerAngles(-27, 45, 0);
app.root.addChild(camera);

// ------ Custom render passes set up ------

camera.addComponent('script');
/** @type { CameraFrame } */
const cameraFrame = camera.script.create(CameraFrame);

cameraFrame.rendering.stencil = true;
cameraFrame.rendering.samples = 4;
cameraFrame.rendering.toneMapping = pc.TONEMAP_ACES2;

// ------------------------------------------

// Create an Entity with a directional light component
const light = new pc.Entity();
light.addComponent('light', {
Expand Down
15 changes: 11 additions & 4 deletions src/extras/render-passes/render-pass-camera-frame.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LAYERID_SKYBOX, LAYERID_IMMEDIATE, TONEMAP_NONE, GAMMA_NONE } from '../../scene/constants.js';
import {
ADDRESS_CLAMP_TO_EDGE, FILTER_LINEAR, FILTER_NEAREST,
PIXELFORMAT_DEPTH, PIXELFORMAT_R32F, PIXELFORMAT_RGBA8
PIXELFORMAT_DEPTH, PIXELFORMAT_DEPTHSTENCIL, PIXELFORMAT_R32F, PIXELFORMAT_RGBA8
} from '../../platform/graphics/constants.js';
import { Texture } from '../../platform/graphics/texture.js';
import { RenderPass } from '../../platform/graphics/render-pass.js';
Expand All @@ -23,6 +23,8 @@ export const SSAOTYPE_COMBINE = 'combine';
class CameraFrameOptions {
formats;

stencil = false;

samples = 1;

sceneColorMap = false;
Expand Down Expand Up @@ -158,6 +160,7 @@ class RenderPassCameraFrame extends RenderPass {
options.ssaoBlurEnabled !== currentOptions.ssaoBlurEnabled ||
options.taaEnabled !== currentOptions.taaEnabled ||
options.samples !== currentOptions.samples ||
options.stencil !== currentOptions.stencil ||
options.bloomEnabled !== currentOptions.bloomEnabled ||
options.prepassEnabled !== currentOptions.prepassEnabled ||
options.sceneColorMap !== currentOptions.sceneColorMap ||
Expand Down Expand Up @@ -217,8 +220,7 @@ class RenderPassCameraFrame extends RenderPass {
addressV: ADDRESS_CLAMP_TO_EDGE
});

// TODO: handle stencil support
let depthFormat = PIXELFORMAT_DEPTH;
let depthFormat = options.stencil ? PIXELFORMAT_DEPTHSTENCIL : PIXELFORMAT_DEPTH;
if (options.prepassEnabled && device.isWebGPU && options.samples > 1) {
// on WebGPU the depth format cannot be resolved, so we need to use a float format in that case
// TODO: ideally we expose this using some option or similar public API to hide this implementation detail
Expand Down Expand Up @@ -313,7 +315,12 @@ class RenderPassCameraFrame extends RenderPass {

// if prepass is enabled, do not clear the depth buffer when rendering the scene, and preserve it
if (options.prepassEnabled) {
this.scenePass.noDepthClear = true;
if (!options.stencil) {
// when stencil is used, the depth buffer might not be correct as the prepass does not
// handle stencil, so we need to clear it - in this case, depth prepass does not give
// us any benefit
this.scenePass.noDepthClear = true;
}
this.scenePass.depthStencilOps.storeDepth = true;
}

Expand Down
1 change: 1 addition & 0 deletions src/extras/render-passes/render-pass-prepass.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class RenderPassPrepass extends RenderPass {
});

this.init(renderTarget, options);
this.depthStencilOps.clearStencil = true;
this.depthStencilOps.storeDepth = true;

if (resolveDepth) {
Expand Down

0 comments on commit d50705d

Please sign in to comment.