diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index 6f638ce8c0..59eb130454 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -93,9 +93,9 @@ export class Camera extends Component { /** * Determining what to clear when rendering by a Camera. - * @defaultValue `CameraClearFlags.DepthColor` + * @defaultValue `CameraClearFlags.All` */ - clearFlags: CameraClearFlags = CameraClearFlags.DepthColor; + clearFlags: CameraClearFlags = CameraClearFlags.All; /** * Culling mask - which layers the camera renders. diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 5a687087b7..59f70254d4 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -180,7 +180,7 @@ export class BasicRenderPipeline { } else { this._opaqueQueue.render(camera, pass.replaceMaterial, pass.mask); this._alphaTestQueue.render(camera, pass.replaceMaterial, pass.mask); - if (camera.clearFlags === CameraClearFlags.DepthColor) { + if (camera.clearFlags & CameraClearFlags.Color) { if (background.mode === BackgroundMode.Sky) { this._drawSky(engine, camera, background.sky); } else if (background.mode === BackgroundMode.Texture && background.texture) { diff --git a/packages/core/src/enums/CameraClearFlags.ts b/packages/core/src/enums/CameraClearFlags.ts index 7651e1a595..7646cfbe19 100644 --- a/packages/core/src/enums/CameraClearFlags.ts +++ b/packages/core/src/enums/CameraClearFlags.ts @@ -2,10 +2,22 @@ * Camera clear flags enumeration. */ export enum CameraClearFlags { - /* Clear depth and color from background. */ - DepthColor, - /* Clear depth only. */ - Depth, /* Do nothing. */ - None + None = 0x0, + /* Clear color with scene background. */ + Color = 0x1, + /* Clear depth only. */ + Depth = 0x2, + /* Clear depth only. */ + Stencil = 0x4, + + /* Clear color with scene background and depth. */ + ColorDepth = 0x3, + /* Clear color with scene background and stencil. */ + ColorStencil = 0x5, + /* Clear depth and stencil. */ + DepthStencil = 0x6, + + /* Clear color with scene background, depth, and stencil. */ + All = 0x7 } diff --git a/packages/core/src/input/pointer/PointerManager.ts b/packages/core/src/input/pointer/PointerManager.ts index 5fef1f00dc..7132e495f8 100644 --- a/packages/core/src/input/pointer/PointerManager.ts +++ b/packages/core/src/input/pointer/PointerManager.ts @@ -244,7 +244,7 @@ export class PointerManager { // TODO: Only check which colliders have listened to the input. if (this._engine.physicsManager.raycast(camera.viewportPointToRay(point, ray), hitResult)) { return hitResult.entity; - } else if (camera.clearFlags === CameraClearFlags.DepthColor) { + } else if (camera.clearFlags & CameraClearFlags.Color) { return null; } } diff --git a/packages/rhi-webgl/src/WebGLRenderer.ts b/packages/rhi-webgl/src/WebGLRenderer.ts index ffb0181218..9e945fbed2 100644 --- a/packages/rhi-webgl/src/WebGLRenderer.ts +++ b/packages/rhi-webgl/src/WebGLRenderer.ts @@ -66,6 +66,7 @@ export class WebGLRenderer implements IHardwareRenderer { private _extensions; private _capability: GLCapability; private _isWebGL2: boolean; + private _webCanvas: WebCanvas; private _activeTextureID: number; private _activeTextures: GLTexture[] = new Array(32); @@ -73,6 +74,7 @@ export class WebGLRenderer implements IHardwareRenderer { // cache value private _lastViewport: Vector4 = new Vector4(null, null, null, null); private _lastClearColor: Color = new Color(null, null, null, null); + private _scissorEnable: boolean = false; get isWebGL2() { return this._isWebGL2; @@ -106,8 +108,7 @@ export class WebGLRenderer implements IHardwareRenderer { const option = this._options; option.alpha === undefined && (option.alpha = false); option.stencil === undefined && (option.stencil = true); - - const webCanvas = (canvas as WebCanvas)._webCanvas; + const webCanvas = (this._webCanvas = (canvas as WebCanvas)._webCanvas); const webGLMode = option.webGLMode || WebGLMode.Auto; let gl: (WebGLRenderingContext & WebGLExtension) | WebGL2RenderingContext; @@ -182,12 +183,21 @@ export class WebGLRenderer implements IHardwareRenderer { } viewport(x: number, y: number, width: number, height: number): void { - // gl.enable(gl.SCISSOR_TEST); - // gl.scissor(x, transformY, width, height); - const gl = this._gl; - const lv = this._lastViewport; - + const { _gl: gl, _lastViewport: lv } = this; if (x !== lv.x || y !== lv.y || width !== lv.z || height !== lv.w) { + const { _webCanvas: webCanvas } = this; + if (x === 0 && y === 0 && width === webCanvas.width && height === webCanvas.height) { + if (this._scissorEnable) { + gl.disable(gl.SCISSOR_TEST); + this._scissorEnable = false; + } + } else { + if (!this._scissorEnable) { + gl.enable(gl.SCISSOR_TEST); + this._scissorEnable = true; + } + gl.scissor(x, y, width, height); + } gl.viewport(x, y, width, height); lv.setValue(x, y, width, height); } @@ -197,26 +207,19 @@ export class WebGLRenderer implements IHardwareRenderer { this._gl.colorMask(r, g, b, a); } - clearRenderTarget( - engine: Engine, - clearFlags: CameraClearFlags.Depth | CameraClearFlags.DepthColor, - clearColor: Color - ) { + clearRenderTarget(engine: Engine, clearFlags: CameraClearFlags, clearColor: Color) { const gl = this._gl; const { blendState: { targetBlendState }, depthState, stencilState } = engine._lastRenderState; - - let clearFlag = gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT; - - if (clearFlags === CameraClearFlags.DepthColor) { + let clearFlag = 0; + if (clearFlags & CameraClearFlags.Color) { clearFlag |= gl.COLOR_BUFFER_BIT; const lc = this._lastClearColor; const { r, g, b, a } = clearColor; - if (clearColor && (r !== lc.r || g !== lc.g || b !== lc.b || a !== lc.a)) { gl.clearColor(r, g, b, a); lc.setValue(r, g, b, a); @@ -227,17 +230,20 @@ export class WebGLRenderer implements IHardwareRenderer { targetBlendState.colorWriteMask = ColorWriteMask.All; } } - - if (depthState.writeEnabled !== true) { - gl.depthMask(true); - depthState.writeEnabled = true; + if (clearFlags & CameraClearFlags.Depth) { + clearFlag |= gl.DEPTH_BUFFER_BIT; + if (depthState.writeEnabled !== true) { + gl.depthMask(true); + depthState.writeEnabled = true; + } } - - if (stencilState.writeMask !== 0xff) { - gl.stencilMask(0xff); - stencilState.writeMask = 0xff; + if (clearFlags & CameraClearFlags.Stencil) { + clearFlag |= gl.STENCIL_BUFFER_BIT; + if (stencilState.writeMask !== 0xff) { + gl.stencilMask(0xff); + stencilState.writeMask = 0xff; + } } - gl.clear(clearFlag); }