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

Simplify RenderPassDepth to use automatic render target resizing provided by the base class #6029

Merged
merged 1 commit into from
Jan 31, 2024
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
29 changes: 19 additions & 10 deletions src/platform/graphics/render-pass.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class RenderPass {
/**
* The options specified when the render target was initialized.
*/
options;
_options;

/**
* Number of samples. 0 if no render target, otherwise number of samples from the render target,
Expand Down Expand Up @@ -198,6 +198,20 @@ class RenderPass {
this.device = graphicsDevice;
}

set options(value) {
this._options = value;

// sanitize options
if (value) {
this._options.scaleX = this._options.scaleX ?? 1;
this._options.scaleY = this._options.scaleY ?? 1;
}
}

get options() {
return this._options;
}

/**
* @param {import('../graphics/render-target.js').RenderTarget|null} [renderTarget] - The render
* target to render into (output). This function should be called only for render passes which
Expand All @@ -206,12 +220,7 @@ class RenderPass {
*/
init(renderTarget = null, options = null) {

// sanitize options
this.options = options;
if (options) {
this.options.scaleX = this.options.scaleX ?? 1;
this.options.scaleY = this.options.scaleY ?? 1;
}

// null represents the default framebuffer
this.renderTarget = renderTarget;
Expand Down Expand Up @@ -252,10 +261,10 @@ class RenderPass {

frameUpdate() {
// resize the render target if needed
if (this.options && this.renderTarget) {
const resizeSource = this.options.resizeSource ?? this.device.backBuffer;
const width = Math.floor(resizeSource.width * this.options.scaleX);
const height = Math.floor(resizeSource.height * this.options.scaleY);
if (this._options && this.renderTarget) {
const resizeSource = this._options.resizeSource ?? this.device.backBuffer;
const width = Math.floor(resizeSource.width * this._options.scaleX);
const height = Math.floor(resizeSource.height * this._options.scaleY);
this.renderTarget.resize(width, height);
}
}
Expand Down
78 changes: 17 additions & 61 deletions src/scene/graphics/render-pass-depth.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class RenderPassDepth extends RenderPass {
super(device);
this.renderer = renderer;
this.camera = camera;

this.setupRenderTarget();
}

destroy() {
Expand All @@ -35,84 +37,38 @@ class RenderPassDepth extends RenderPass {
this.scene = scene;
}

shouldReallocate(targetRT, sourceRT) {

// need to reallocate if dimensions don't match
const width = sourceRT.width;
const height = sourceRT.height;
return !targetRT || width !== targetRT.width || height !== targetRT.height;
}

allocateRenderTarget(renderTarget, sourceRT, device) {
setupRenderTarget() {

// allocate texture buffer
const texture = new Texture(device, {
const texture = new Texture(this.device, {
name: _depthUniformNames[0],
format: PIXELFORMAT_RGBA8,
width: sourceRT?.width ?? this.device.width,
height: sourceRT?.height ?? this.device.height,
width: 4,
height: 4,
mipmaps: false,
minFilter: FILTER_NEAREST,
magFilter: FILTER_NEAREST,
addressU: ADDRESS_CLAMP_TO_EDGE,
addressV: ADDRESS_CLAMP_TO_EDGE
});

if (renderTarget) {

// if reallocating RT size, release previous framebuffer
renderTarget.destroyFrameBuffers();

// assign new texture
renderTarget._colorBuffer = texture;
renderTarget._colorBuffers = [texture];

} else {

// create new render target with the texture
renderTarget = new RenderTarget({
name: `${_depthUniformNames[0]}RT}`,
colorBuffer: texture,
depth: true,
stencil: false
});
}

return renderTarget;
}
const renderTarget = new RenderTarget({
name: `${_depthUniformNames[0]}RT}`,
colorBuffer: texture,
depth: true,
stencil: false
});

releaseRenderTarget(rt) {
this.init(renderTarget, {});

if (rt) {
rt.destroyTextureBuffers();
rt.destroy();
}
// webgl1 depth rendering clear values
this.setClearColor(webgl1DepthClearColor);
this.setClearDepth(1.0);
}

before() {

const camera = this.camera;
const device = this.device;
const sourceRT = camera.renderTarget ?? device.backBuffer;

// reallocate RT if needed
if (this.shouldReallocate(this.renderTarget, sourceRT)) {
this.renderTarget?.destroyTextureBuffers();
const renderTarget = this.allocateRenderTarget(this.renderTarget, camera.renderTarget, device);

if (!this.renderTarget) {
this.init(renderTarget);

// webgl1 depth rendering clear values
this.setClearColor(webgl1DepthClearColor);
this.setClearDepth(1.0);

} else {
this.renderTarget = renderTarget;
}
}

// assign uniform
const device = this.device;
const colorBuffer = this.renderTarget.colorBuffer;
_depthUniformNames.forEach(name => device.scope.resolve(name).setValue(colorBuffer));
}
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 @@ -761,7 +761,7 @@ class ForwardRenderer extends Renderer {
// on webgl1, depth pass renders ahead of the main camera instead of the middle of the frame
const depthPass = camera.camera.renderPassDepthGrab;
if (depthPass && webgl1 && renderAction.firstCameraUse) {

depthPass.options.resizeSource = camera.camera.renderTarget;
depthPass.update(this.scene);
frameGraph.addRenderPass(depthPass);
}
Expand Down