UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

140 lines (139 loc) 3.7 kB
import { Tracing } from "../../core/tracing.js"; import { Color } from "../../core/math/color.js"; import { TRACEID_RENDER_PASS, TRACEID_RENDER_PASS_DETAIL } from "../../core/constants.js"; import { isIntegerPixelFormat, pixelFormatInfo } from "./constants.js"; import { FramePass } from "./frame-pass.js"; class ColorAttachmentOps { clearValue = new Color(0, 0, 0, 1); clearValueLinear = new Color(0, 0, 0, 1); clear = false; store = false; resolve = true; genMipmaps = false; } class DepthStencilAttachmentOps { clearDepthValue = 1; clearStencilValue = 0; clearDepth = false; clearStencil = false; storeDepth = false; resolveDepth = false; storeStencil = false; } class RenderPass extends FramePass { renderTarget; _options; samples = 0; colorArrayOps = []; get colorOps() { return this.colorArrayOps[0]; } depthStencilOps; requiresCubemaps = true; fullSizeClearRect = true; set scaleX(value) { this._options.scaleX = value; } get scaleX() { return this._options.scaleX; } set scaleY(value) { this._options.scaleY = value; } get scaleY() { return this._options.scaleY; } set options(value) { this._options = value; if (value) { this.scaleX = this.scaleX ?? 1; this.scaleY = this.scaleY ?? 1; } } get options() { return this._options; } init(renderTarget = null, options) { this.options = options; this.renderTarget = renderTarget; this.samples = Math.max(this.renderTarget ? this.renderTarget.samples : this.device.samples, 1); this.allocateAttachments(); this.postInit(); } allocateAttachments() { const rt = this.renderTarget; this.depthStencilOps = new DepthStencilAttachmentOps(); if (rt?.depthBuffer) { this.depthStencilOps.storeDepth = true; } const numColorOps = rt ? rt._colorBuffers?.length ?? 0 : 1; this.colorArrayOps.length = 0; for (let i = 0; i < numColorOps; i++) { const colorOps = new ColorAttachmentOps(); this.colorArrayOps[i] = colorOps; if (this.samples === 1) { colorOps.store = true; colorOps.resolve = false; } const colorBuffer = this.renderTarget?._colorBuffers?.[i]; if (this.renderTarget?.mipmaps && colorBuffer?.mipmaps) { const intFormat = isIntegerPixelFormat(colorBuffer._format); colorOps.genMipmaps = !intFormat; } } } postInit() { } frameUpdate() { if (this._options && this.renderTarget) { const resizeSource = this._options.resizeSource ?? this.device.backBuffer; const width = Math.floor(resizeSource.width * this.scaleX); const height = Math.floor(resizeSource.height * this.scaleY); this.renderTarget.resize(width, height); } } setClearColor(color) { const count = this.colorArrayOps.length; for (let i = 0; i < count; i++) { const colorOps = this.colorArrayOps[i]; if (color) { colorOps.clearValue.copy(color); colorOps.clearValueLinear.linear(color); } colorOps.clear = !!color; } } setClearDepth(depthValue) { if (depthValue !== void 0) { this.depthStencilOps.clearDepthValue = depthValue; } this.depthStencilOps.clearDepth = depthValue !== void 0; } setClearStencil(stencilValue) { if (stencilValue !== void 0) { this.depthStencilOps.clearStencilValue = stencilValue; } this.depthStencilOps.clearStencil = stencilValue !== void 0; } render() { if (this.enabled) { const device = this.device; const realPass = this.renderTarget !== void 0; this.before(); if (this.executeEnabled) { if (realPass && !this._skipStart) { device.startRenderPass(this); } this.execute(); if (realPass && !this._skipEnd) { device.endRenderPass(this); } } this.after(); device.renderPassIndex++; } } } export { RenderPass };