From b6613a0bded3fe9ab0bff15c0581fbe839780337 Mon Sep 17 00:00:00 2001 From: cptbtptpbcptdtptp Date: Mon, 27 Jun 2022 17:51:13 +0800 Subject: [PATCH 1/6] feat(core): add ability to clear stencil buffer --- packages/core/src/Camera.ts | 4 +- .../src/RenderPipeline/BasicRenderPipeline.ts | 2 +- packages/core/src/enums/CameraClearFlags.ts | 22 +++++++--- .../core/src/input/pointer/PointerManager.ts | 2 +- packages/rhi-webgl/src/WebGLRenderer.ts | 42 +++++++++---------- 5 files changed, 42 insertions(+), 30 deletions(-) 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..715f8859fa 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 = 0, + /* Clear color only. */ + Color = 1, + /* Clear depth only. */ + Depth = 2, + /* Clear depth only. */ + Stencil = 4, + + /* Clear color and depth from background. */ + ColorDepth = 3, + /* Clear color and stencil from background. */ + ColorStencil = 5, + /* Clear depth and stencil from background. */ + DepthStencil = 6, + + /** Clear stencil, depth and color from background. */ + All = 7 } diff --git a/packages/core/src/input/pointer/PointerManager.ts b/packages/core/src/input/pointer/PointerManager.ts index 5fef1f00dc..e602b14aed 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..159c4f0e04 100644 --- a/packages/rhi-webgl/src/WebGLRenderer.ts +++ b/packages/rhi-webgl/src/WebGLRenderer.ts @@ -73,6 +73,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; @@ -182,12 +183,15 @@ 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; if (x !== lv.x || y !== lv.y || width !== lv.z || height !== lv.w) { + 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 +201,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 +224,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); } From 999296efdbb5fdb5d7a2b6a80251b8a1e3fdf550 Mon Sep 17 00:00:00 2001 From: cptbtptpbcptdtptp Date: Mon, 27 Jun 2022 17:56:05 +0800 Subject: [PATCH 2/6] feat(core): add ability to clear stencil buffer --- packages/rhi-webgl/src/GLRenderStates.ts | 1 + packages/rhi-webgl/src/WebGLRenderer.ts | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/rhi-webgl/src/GLRenderStates.ts b/packages/rhi-webgl/src/GLRenderStates.ts index c7e75057bc..4dafb1541a 100644 --- a/packages/rhi-webgl/src/GLRenderStates.ts +++ b/packages/rhi-webgl/src/GLRenderStates.ts @@ -39,6 +39,7 @@ export class GLRenderStates { gl.stencilMask(0xff); // init raster state same as RasterState default value. + gl.enable(gl.SCISSOR_TEST); gl.enable(gl.CULL_FACE); gl.cullFace(gl.BACK); gl.disable(gl.POLYGON_OFFSET_FILL); diff --git a/packages/rhi-webgl/src/WebGLRenderer.ts b/packages/rhi-webgl/src/WebGLRenderer.ts index 159c4f0e04..7f5f4d723c 100644 --- a/packages/rhi-webgl/src/WebGLRenderer.ts +++ b/packages/rhi-webgl/src/WebGLRenderer.ts @@ -73,7 +73,6 @@ 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; @@ -187,10 +186,6 @@ export class WebGLRenderer implements IHardwareRenderer { const lv = this._lastViewport; if (x !== lv.x || y !== lv.y || width !== lv.z || height !== lv.w) { - 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); From b58fd05050aac2a86ea341e59520fd64fd9cae53 Mon Sep 17 00:00:00 2001 From: cptbtptpbcptdtptp Date: Mon, 27 Jun 2022 18:24:39 +0800 Subject: [PATCH 3/6] feat(core): add ability to clear stencil buffer --- packages/rhi-webgl/src/GLRenderStates.ts | 1 - packages/rhi-webgl/src/WebGLRenderer.ts | 23 +++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/rhi-webgl/src/GLRenderStates.ts b/packages/rhi-webgl/src/GLRenderStates.ts index 4dafb1541a..c7e75057bc 100644 --- a/packages/rhi-webgl/src/GLRenderStates.ts +++ b/packages/rhi-webgl/src/GLRenderStates.ts @@ -39,7 +39,6 @@ export class GLRenderStates { gl.stencilMask(0xff); // init raster state same as RasterState default value. - gl.enable(gl.SCISSOR_TEST); gl.enable(gl.CULL_FACE); gl.cullFace(gl.BACK); gl.disable(gl.POLYGON_OFFSET_FILL); diff --git a/packages/rhi-webgl/src/WebGLRenderer.ts b/packages/rhi-webgl/src/WebGLRenderer.ts index 7f5f4d723c..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,11 +183,21 @@ export class WebGLRenderer implements IHardwareRenderer { } viewport(x: number, y: number, width: number, height: number): void { - 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) { - gl.scissor(x, y, width, height); + 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); } From a039bfad0d6d1be48ce7055f5bdddecef6c366e9 Mon Sep 17 00:00:00 2001 From: cptbtptpbcptdtptp Date: Wed, 29 Jun 2022 14:40:29 +0800 Subject: [PATCH 4/6] feat(core): add ability to clear stencil buffer --- packages/core/src/enums/CameraClearFlags.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/enums/CameraClearFlags.ts b/packages/core/src/enums/CameraClearFlags.ts index 715f8859fa..79697425ff 100644 --- a/packages/core/src/enums/CameraClearFlags.ts +++ b/packages/core/src/enums/CameraClearFlags.ts @@ -4,20 +4,20 @@ export enum CameraClearFlags { /* Do nothing. */ None = 0, - /* Clear color only. */ + /* Clear color with scene background. */ Color = 1, /* Clear depth only. */ Depth = 2, /* Clear depth only. */ Stencil = 4, - /* Clear color and depth from background. */ + /* Clear color with scene background and depth. */ ColorDepth = 3, - /* Clear color and stencil from background. */ + /* Clear color with scene background and stencil. */ ColorStencil = 5, - /* Clear depth and stencil from background. */ + /* Clear depth and stencil. */ DepthStencil = 6, - /** Clear stencil, depth and color from background. */ + /* Clear color with scene background, depth, and stencil. */ All = 7 } From 69c11584f38bcc90d87c6956b7c745e7e1b36ed7 Mon Sep 17 00:00:00 2001 From: cptbtptpbcptdtptp Date: Wed, 29 Jun 2022 14:41:40 +0800 Subject: [PATCH 5/6] feat(core): add ability to clear stencil buffer --- packages/core/src/input/pointer/PointerManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/input/pointer/PointerManager.ts b/packages/core/src/input/pointer/PointerManager.ts index e602b14aed..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.Color) { + } else if (camera.clearFlags & CameraClearFlags.Color) { return null; } } From f00f022502d009d84a5444d7961bff392aad5d35 Mon Sep 17 00:00:00 2001 From: cptbtptpbcptdtptp Date: Wed, 29 Jun 2022 14:45:17 +0800 Subject: [PATCH 6/6] feat(core): add ability to clear stencil buffer --- packages/core/src/enums/CameraClearFlags.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/core/src/enums/CameraClearFlags.ts b/packages/core/src/enums/CameraClearFlags.ts index 79697425ff..7646cfbe19 100644 --- a/packages/core/src/enums/CameraClearFlags.ts +++ b/packages/core/src/enums/CameraClearFlags.ts @@ -3,21 +3,21 @@ */ export enum CameraClearFlags { /* Do nothing. */ - None = 0, + None = 0x0, /* Clear color with scene background. */ - Color = 1, + Color = 0x1, /* Clear depth only. */ - Depth = 2, + Depth = 0x2, /* Clear depth only. */ - Stencil = 4, + Stencil = 0x4, /* Clear color with scene background and depth. */ - ColorDepth = 3, + ColorDepth = 0x3, /* Clear color with scene background and stencil. */ - ColorStencil = 5, + ColorStencil = 0x5, /* Clear depth and stencil. */ - DepthStencil = 6, + DepthStencil = 0x6, /* Clear color with scene background, depth, and stencil. */ - All = 7 + All = 0x7 }