From c85763d28d0e813ef5bbf31a1d8718ecc8ea9777 Mon Sep 17 00:00:00 2001 From: Codeboy-cn Date: Fri, 26 Jan 2024 19:54:44 +0800 Subject: [PATCH 1/5] chore: remove sample_candleflame maskMap --- samples/particle/Sample_CandleFlame.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/particle/Sample_CandleFlame.ts b/samples/particle/Sample_CandleFlame.ts index 8ba4ecdd..32a61312 100644 --- a/samples/particle/Sample_CandleFlame.ts +++ b/samples/particle/Sample_CandleFlame.ts @@ -104,8 +104,7 @@ export class Sample_CandleFlame { mat.baseMap = Engine3D.res.whiteTexture; mat.normalMap = Engine3D.res.normalTexture; mat.aoMap = Engine3D.res.whiteTexture; - mat.maskMap = Engine3D.res.createTexture(32, 32, 255.0, 255.0, 0.0, 1); - mat.emissiveMap = Engine3D.res.blackTexture; + mat.emissiveMap = Engine3D.res.whiteTexture; mat.roughness = 0.5; mat.metallic = 0.2; From 5251b0809da75f355e8ed0b8c46b93f6f3a580ad Mon Sep 17 00:00:00 2001 From: Codeboy Date: Thu, 18 Jul 2024 22:36:27 +0800 Subject: [PATCH 2/5] fix pick --- samples/compute/Sample_Fluid.ts | 2 +- samples/compute/Sample_FluidOptimize.ts | 16 ++++++++-------- samples/compute/fluid/FluidRenderShader.ts | 2 +- samples/compute/fluid/FluidRenderShaderOpt.ts | 1 + src/components/gui/GUIPick.ts | 15 +++++++++++---- src/components/gui/uiComponents/UIPanel.ts | 1 - 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/samples/compute/Sample_Fluid.ts b/samples/compute/Sample_Fluid.ts index bd095d15..0ad271ef 100644 --- a/samples/compute/Sample_Fluid.ts +++ b/samples/compute/Sample_Fluid.ts @@ -52,7 +52,7 @@ export class Demo_Fluid { obj.addComponent(ColliderComponent); let pickFire = scene.view.pickFire; pickFire.addEventListener( - PointerEvent3D.PICK_MOVE, + PointerEvent3D.PICK_MOVE, function (e: PointerEvent3D) { let point = e.data.worldPos; if (point.y >= 0 && (this.mLastPoint.x != point.x && this.mLastPoint.y != point.y && this.mLastPoint.z != point.z)) { diff --git a/samples/compute/Sample_FluidOptimize.ts b/samples/compute/Sample_FluidOptimize.ts index b39afbbc..016995e4 100644 --- a/samples/compute/Sample_FluidOptimize.ts +++ b/samples/compute/Sample_FluidOptimize.ts @@ -51,18 +51,18 @@ export class Demo_FluidOptimize { obj.addComponent(ColliderComponent); let pickFire = scene.view.pickFire; pickFire.addEventListener( - PointerEvent3D.PICK_MOVE, + PointerEvent3D.PICK_MOVE, function (e: PointerEvent3D) { let point = e.data.worldPos; if (point.y >= 0 && (this.mLastPoint.x != point.x && this.mLastPoint.y != point.y && this.mLastPoint.z != point.z)) { - try{ - point.subtract(this.mLastPoint, this.mVelocity); - this.mLastPoint.copy(point); - let r = scene.view.camera; - let ray = r.screenPointToRay(Engine3D.inputSystem.mouseX, Engine3D.inputSystem.mouseY); - emulation.updateInputInfo(scene.view.camera.transform.localPosition, ray.direction, this.mVelocity); + try { + point.subtract(this.mLastPoint, this.mVelocity); + this.mLastPoint.copy(point); + let r = scene.view.camera; + let ray = r.screenPointToRay(Engine3D.inputSystem.mouseX, Engine3D.inputSystem.mouseY); + emulation.updateInputInfo(scene.view.camera.transform.localPosition, ray.direction, this.mVelocity); } - catch(e){ + catch (e) { console.error(e); } diff --git a/samples/compute/fluid/FluidRenderShader.ts b/samples/compute/fluid/FluidRenderShader.ts index f4bd9d21..3ffb27ea 100644 --- a/samples/compute/fluid/FluidRenderShader.ts +++ b/samples/compute/fluid/FluidRenderShader.ts @@ -57,7 +57,7 @@ export let FluidRenderShader = /* wgsl */ ` //ORI_VertexOut.fragCoord = normalize(vertex.position.xy) + vec2(0.5, 0.5); ORI_VertexOut.varying_Color = particleColor[vertex.index]; ORI_VertexOut.varying_WNormal = worldNormal ; - + ORI_VertexOut.index = f32(particleGlobalData.instance_index) ; return ORI_VertexOut; } diff --git a/samples/compute/fluid/FluidRenderShaderOpt.ts b/samples/compute/fluid/FluidRenderShaderOpt.ts index 121a8865..68bec127 100644 --- a/samples/compute/fluid/FluidRenderShaderOpt.ts +++ b/samples/compute/fluid/FluidRenderShaderOpt.ts @@ -69,6 +69,7 @@ export let FluidRenderShaderOpt = /* wgsl */ ` ORI_VertexOut.varying_WPos = worldPos; ORI_VertexOut.varying_WPos.w = f32(particleGlobalData.instance_index); + ORI_VertexOut.index = f32(particleGlobalData.instance_index) ; var clipPosition = globalUniform.projMat * viewPosition ; diff --git a/src/components/gui/GUIPick.ts b/src/components/gui/GUIPick.ts index 1e55ddcd..a12e9d62 100644 --- a/src/components/gui/GUIPick.ts +++ b/src/components/gui/GUIPick.ts @@ -4,7 +4,6 @@ import { MouseCode } from '../../event/MouseCode'; import { webGPUContext } from '../../gfx/graphics/webGpu/Context3D'; import { Ray } from '../../math/Ray'; import { Vector2 } from '../../math/Vector2'; -import { Vector3 } from '../../math/Vector3'; import { Time } from '../../util/Time'; import { IUIInteractive, UIInteractiveStyle } from './uiComponents/IUIInteractive'; import { UITransform } from './uiComponents/UITransform'; @@ -68,11 +67,15 @@ export class GUIPick { if (target != this._lastOverTarget) { if (this._lastOverTarget && this._lastOverTarget.enable) { this._lastOverTarget.mouseStyle = UIInteractiveStyle.NORMAL; + Object.assign(this._outEvent, e); this._outEvent.data = this._lastOverTarget; + this._outEvent.type = PointerEvent3D.PICK_OUT_GUI; this._lastOverTarget.object3D.dispatchEvent(this._outEvent); } if (target) { target.mouseStyle = UIInteractiveStyle.OVER; + Object.assign(this._overEvent, e); + this._overEvent.type = PointerEvent3D.PICK_OVER_GUI; this._overEvent.data = target; target.object3D.dispatchEvent(this._overEvent); } @@ -97,8 +100,10 @@ export class GUIPick { let target = ret ? ret.collider : null; if (target) { target.mouseStyle = UIInteractiveStyle.DOWN; - this._overEvent.data = target; - target.object3D.dispatchEvent(this._overEvent); + Object.assign(this._downEvent, e); + this._downEvent.type = PointerEvent3D.PICK_DOWN_GUI; + this._downEvent.data = target; + target.object3D.dispatchEvent(this._downEvent); } this._lastDownTarget = target; } @@ -120,7 +125,9 @@ export class GUIPick { if (Time.time - this._lastDownTime <= this._clickTimeSpan) { this._calcDistanceVec2.set(e.mouseX, e.mouseY); if (this._calcDistanceVec2.distance(this._lastDownPosition) <= this._clickDistanceSpan) { - this._clickEvent.data = { pick: target, pickInfo: ret, mouseCode: this._mouseCode }; + Object.assign(this._clickEvent, e); + this._clickEvent.data = ret; + this._clickEvent.type = PointerEvent3D.PICK_CLICK_GUI; target.object3D.dispatchEvent(this._clickEvent); } } diff --git a/src/components/gui/uiComponents/UIPanel.ts b/src/components/gui/uiComponents/UIPanel.ts index 5881529c..44a7d613 100644 --- a/src/components/gui/uiComponents/UIPanel.ts +++ b/src/components/gui/uiComponents/UIPanel.ts @@ -96,7 +96,6 @@ export class UIPanel extends UIImage { public set billboard(type: BillboardType) { if (this.space == GUISpace.View) { type = BillboardType.None; - } else { console.warn('Cannot enable billboard in view space'); } if (type == BillboardType.BillboardXYZ || type == BillboardType.BillboardY) { From 77a0f04691895029e02cd7b98b6d1865ad08cd47 Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Fri, 19 Jul 2024 03:58:12 +0800 Subject: [PATCH 3/5] fix(pick): fix gui pick over/out --- src/components/gui/GUIPick.ts | 61 ++++++++++++------- .../gui/uiComponents/IUIInteractive.ts | 4 +- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/components/gui/GUIPick.ts b/src/components/gui/GUIPick.ts index a12e9d62..2619b70a 100644 --- a/src/components/gui/GUIPick.ts +++ b/src/components/gui/GUIPick.ts @@ -62,24 +62,37 @@ export class GUIPick { this._mouseCode = e.mouseCode; this.collectEntities(); let ret = this.pick(this._colliderOut); - ret && e.stopImmediatePropagation(); - let target = ret ? ret.collider : null; - if (target != this._lastOverTarget) { - if (this._lastOverTarget && this._lastOverTarget.enable) { + if(ret){ + e.stopImmediatePropagation(); + let _target = ret.collider; + if(_target != this._lastOverTarget){ + _target.mouseStyle = UIInteractiveStyle.OVER; + Object.assign(this._overEvent, e); + this._overEvent.type = PointerEvent3D.PICK_OVER_GUI; + this._overEvent.target = _target.object3D; + this._overEvent.data = ret; + _target.object3D.dispatchEvent(this._overEvent); + + if (this._lastOverTarget) { + this._lastOverTarget.mouseStyle = UIInteractiveStyle.NORMAL; + Object.assign(this._outEvent, e); + this._outEvent.type = PointerEvent3D.PICK_OUT_GUI; + this._outEvent.target = _target.object3D; + this._outEvent.data = ret; + this._lastOverTarget.object3D.dispatchEvent(this._outEvent); + } + } + this._lastOverTarget = _target; + }else{ + if (this._lastOverTarget) { this._lastOverTarget.mouseStyle = UIInteractiveStyle.NORMAL; Object.assign(this._outEvent, e); - this._outEvent.data = this._lastOverTarget; this._outEvent.type = PointerEvent3D.PICK_OUT_GUI; + this._outEvent.target = this._lastOverTarget.object3D; + this._outEvent.data = ret; this._lastOverTarget.object3D.dispatchEvent(this._outEvent); + this._lastOverTarget = null } - if (target) { - target.mouseStyle = UIInteractiveStyle.OVER; - Object.assign(this._overEvent, e); - this._overEvent.type = PointerEvent3D.PICK_OVER_GUI; - this._overEvent.data = target; - target.object3D.dispatchEvent(this._overEvent); - } - this._lastOverTarget = target; } } @@ -97,15 +110,16 @@ export class GUIPick { this.collectEntities(); let ret = this.pick(this._colliderOut); ret && e.stopImmediatePropagation(); - let target = ret ? ret.collider : null; - if (target) { - target.mouseStyle = UIInteractiveStyle.DOWN; + let collider = ret ? ret.collider : null; + if (collider) { + collider.mouseStyle = UIInteractiveStyle.DOWN; Object.assign(this._downEvent, e); this._downEvent.type = PointerEvent3D.PICK_DOWN_GUI; - this._downEvent.data = target; - target.object3D.dispatchEvent(this._downEvent); + this._downEvent.target = collider.object3D; + this._downEvent.data = ret; + collider.object3D.dispatchEvent(this._downEvent); } - this._lastDownTarget = target; + this._lastDownTarget = collider; } private onTouchUp(e: PointerEvent3D) { @@ -116,19 +130,20 @@ export class GUIPick { let ret = this.pick(this._colliderOut); ret && e.stopImmediatePropagation(); - let target = ret ? ret.collider : null; + let collider = ret ? ret.collider : null; if (this._lastDownTarget && this._lastDownTarget.enable) { this._lastDownTarget.mouseStyle = UIInteractiveStyle.NORMAL; } - if (target && target == this._lastDownTarget) { + if (collider && collider == this._lastDownTarget) { if (Time.time - this._lastDownTime <= this._clickTimeSpan) { this._calcDistanceVec2.set(e.mouseX, e.mouseY); if (this._calcDistanceVec2.distance(this._lastDownPosition) <= this._clickDistanceSpan) { Object.assign(this._clickEvent, e); - this._clickEvent.data = ret; this._clickEvent.type = PointerEvent3D.PICK_CLICK_GUI; - target.object3D.dispatchEvent(this._clickEvent); + this._clickEvent.target = collider.object3D; + this._clickEvent.data = ret; + collider.object3D.dispatchEvent(this._clickEvent); } } } diff --git a/src/components/gui/uiComponents/IUIInteractive.ts b/src/components/gui/uiComponents/IUIInteractive.ts index 7aeb785a..acc10cab 100644 --- a/src/components/gui/uiComponents/IUIInteractive.ts +++ b/src/components/gui/uiComponents/IUIInteractive.ts @@ -1,4 +1,4 @@ -import { CEventDispatcher } from "../../../event/CEventDispatcher"; +import { Object3D } from "../../../core/entities/Object3D"; import { Ray } from "../../../math/Ray"; import { Vector2 } from "../../../math/Vector2"; @@ -13,7 +13,7 @@ export interface IUIInteractive { interactive: boolean; enable: boolean; visible: boolean; - object3D?: CEventDispatcher; + object3D?: Object3D; get interactiveVisible(): boolean; From e11cc146e2c86cd7c827b21dd4e8c67ab3647a0d Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Fri, 19 Jul 2024 04:10:55 +0800 Subject: [PATCH 4/5] fix: pickpick sample --- samples/pick/Sample_PixelPick.ts | 3 +-- src/io/PickFire.ts | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/samples/pick/Sample_PixelPick.ts b/samples/pick/Sample_PixelPick.ts index 40cbfb71..34277827 100644 --- a/samples/pick/Sample_PixelPick.ts +++ b/samples/pick/Sample_PixelPick.ts @@ -84,8 +84,7 @@ class Sample_PixelPick { } private getPickObject(e: PointerEvent3D): Object3D { - let pick = e.data.pick; - return pick ? pick.object3D : null; + return e.target || null; } private onMouseUp(e: PointerEvent3D) { diff --git a/src/io/PickFire.ts b/src/io/PickFire.ts index 151ce3f5..d2a80a1b 100644 --- a/src/io/PickFire.ts +++ b/src/io/PickFire.ts @@ -55,7 +55,6 @@ export class PickFire extends CEventDispatcher { */ private init(): void { this.ray = new Ray(); - this.mouseEnableMap = new Map(); this._pickEvent = new PointerEvent3D(PointerEvent3D.PICK_CLICK); @@ -260,7 +259,6 @@ export class PickFire extends CEventDispatcher { } } - } } } From 6e32bae7ea425511e5a155507c6239770d70ed64 Mon Sep 17 00:00:00 2001 From: Codeboy-cn Date: Tue, 23 Jul 2024 12:17:14 +0800 Subject: [PATCH 5/5] fix GUI sample --- public | 2 +- samples/gui/Sample_POI.ts | 27 ++++- src/components/gui/core/GUIMaterial.ts | 42 ++++--- src/components/gui/core/GUIShader.ts | 10 +- src/components/gui/uiComponents/UIPanel.ts | 4 + src/components/renderer/RenderNode.ts | 2 + .../descriptor/WebGPUDescriptorCreator.ts | 9 +- src/gfx/renderJob/frame/GBufferFrame.ts | 26 +++-- src/gfx/renderJob/jobs/ForwardRenderJob.ts | 11 +- src/gfx/renderJob/jobs/RendererJob.ts | 13 ++- .../renderJob/passRenderer/RenderContext.ts | 6 + .../passRenderer/color/ColorPassRenderer.ts | 8 +- .../passRenderer/color/GUIPassRenderer.ts | 109 ++++++++++++++++++ .../passRenderer/post/PostRenderer.ts | 16 +-- .../renderJob/passRenderer/state/PassType.ts | 2 +- src/index.ts | 1 + 16 files changed, 233 insertions(+), 55 deletions(-) create mode 100644 src/gfx/renderJob/passRenderer/color/GUIPassRenderer.ts diff --git a/public b/public index eeeaca67..5a6f7231 160000 --- a/public +++ b/public @@ -1 +1 @@ -Subproject commit eeeaca67f9ada0a09cc9d6fb93d3fe449bf4ff69 +Subproject commit 5a6f72318f7eac3cacde980adc3a3a108c2b0035 diff --git a/samples/gui/Sample_POI.ts b/samples/gui/Sample_POI.ts index 9ab45392..57c3d4f6 100644 --- a/samples/gui/Sample_POI.ts +++ b/samples/gui/Sample_POI.ts @@ -1,11 +1,16 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; import { createExampleScene, createSceneParam } from "@samples/utils/ExampleScene"; -import { Scene3D, PropertyAnimation, Engine3D, Object3D, Object3DUtil, PropertyAnimClip, WrapMode, WorldPanel, BillboardType, TextAnchor, UIImage, UIShadow, UITextField, Vector3, Color, Time } from "@orillusion/core"; +import { + Scene3D, PropertyAnimation, Engine3D, Object3D, Object3DUtil, PropertyAnimClip, + WrapMode, WorldPanel, BillboardType, TextAnchor, UIImage, UIShadow, UITextField, + Vector3, Color, Time, PostProcessingComponent, BloomPost, UIPanel +} from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; class Sample_POI { scene: Scene3D; panel: WorldPanel; + panel2: UIPanel; position: Vector3; async run() { @@ -18,19 +23,26 @@ class Sample_POI { await Engine3D.init({ renderLoop: () => { this.loop(); } }); let param = createSceneParam(); + param.light.intensity = 5; param.camera.distance = 30; let exampleScene = createExampleScene(param); GUIHelp.init(); this.scene = exampleScene.scene; - // exampleScene.camera.enableCSM = true; Engine3D.startRenderView(exampleScene.view); + let postCom = this.scene.addComponent(PostProcessingComponent); + let bloom = postCom.addPost(BloomPost); + + bloom.luminanceThreshole = 1; + bloom.bloomIntensity = 0.8; await this.initScene(); this.initDuckPOI(); this.initScenePOI(); + this.panel2.renderer.isRecievePostEffectUI = true; + GUIHelp.add(this.panel2.renderer, 'isRecievePostEffectUI'); } private modelContainer: Object3D; @@ -73,7 +85,7 @@ class Sample_POI { return animation; } - private initDuckPOI() { + private initDuckPOI(): UIPanel { let canvas = this.scene.view.enableUICanvas(); //panel this.panel = new Object3D().addComponent(WorldPanel); @@ -99,14 +111,16 @@ class Sample_POI { text.fontSize = 4; text.color = new Color(0, 0, 0, 1); text.alignment = TextAnchor.MiddleCenter; - GUIUtil.renderUIPanel(this.panel, true); + GUIUtil.renderUIPanel(this.panel, false); + return this.panel; } private sceneText: UITextField; - private initScenePOI() { + private initScenePOI(): UIPanel { let canvas = this.scene.view.enableUICanvas(); //panel let panel = new Object3D().addComponent(WorldPanel); + this.panel2 = panel; panel.cullMode = "none"; //add to canvas canvas.addChild(panel.object3D); @@ -123,11 +137,12 @@ class Sample_POI { text.uiTransform.resize(80, 16); text.text = this.title; text.fontSize = 10; - text.color = new Color(0.5, 1.0, 0.5, 1.0); + text.color = new Color(0.5, 1.5, 0.5, 1.0); text.alignment = TextAnchor.MiddleLeft; panelRoot.addComponent(UIShadow).shadowOffset.multiplyScaler(0.2); this.sceneText = text; + return panel; } private charCount = 0; diff --git a/src/components/gui/core/GUIMaterial.ts b/src/components/gui/core/GUIMaterial.ts index 7f6f3ad0..21c35592 100644 --- a/src/components/gui/core/GUIMaterial.ts +++ b/src/components/gui/core/GUIMaterial.ts @@ -29,32 +29,38 @@ export class GUIMaterial extends Material { let newShader = new Shader(); + // colorPass.transparent = true; + // colorPass.receiveEnv = false; + + this.addColorPass(newShader, PassType.COLOR, space); + this.addColorPass(newShader, PassType.UI, space); + this.shader = newShader; + } + + private addColorPass(shader: Shader, passType: PassType, space: GUISpace) { let shaderKey: string = space == GUISpace.View ? 'GUI_shader_view' : 'GUI_shader_world'; - let colorPass = new RenderShaderPass(shaderKey, shaderKey); - colorPass.passType = PassType.COLOR; - colorPass.setShaderEntry(`VertMain`, `FragMain`); + let shaderPass = new RenderShaderPass(shaderKey, shaderKey); + shaderPass.passType = passType; + shaderPass.setShaderEntry(`VertMain`, `FragMain`); - colorPass.setUniformVector4('scissorRect', new Vector4()); - colorPass.setUniformVector2('screenSize', this._screenSize); - colorPass.setUniformFloat('scissorCornerRadius', 0.0); - colorPass.setUniformFloat('scissorFadeOutSize', 0.0); + shaderPass.setUniformVector4('scissorRect', new Vector4()); + shaderPass.setUniformVector2('screenSize', this._screenSize); + shaderPass.setUniformFloat('scissorCornerRadius', 0.0); + shaderPass.setUniformFloat('scissorFadeOutSize', 0.0); - colorPass.setUniformFloat('pixelRatio', 1); - colorPass.setUniformVector3('v3', Vector3.ZERO); + shaderPass.setUniformFloat('pixelRatio', 1); + shaderPass.setUniformVector3('v3', Vector3.ZERO); - let shaderState = colorPass.shaderState; + let shaderState = shaderPass.shaderState; // shaderState.useZ = false; shaderState.depthWriteEnabled = false; - colorPass.blendMode = BlendMode.ALPHA; - colorPass.depthCompare = space == GUISpace.View ? GPUCompareFunction.always : GPUCompareFunction.less_equal; - colorPass.cullMode = GPUCullMode.back; - newShader.addRenderPass(colorPass); - // colorPass.transparent = true; - // colorPass.receiveEnv = false; - - this.shader = newShader; + shaderPass.blendMode = BlendMode.NORMAL; + shaderPass.depthCompare = space == GUISpace.View ? GPUCompareFunction.always : GPUCompareFunction.less_equal; + shaderPass.cullMode = GPUCullMode.back; + shader.addRenderPass(shaderPass); } + public setPanelRatio(pixelRatio: number) { this.shader.setUniformFloat('pixelRatio', pixelRatio); } diff --git a/src/components/gui/core/GUIShader.ts b/src/components/gui/core/GUIShader.ts index a65d755b..156d32b3 100644 --- a/src/components/gui/core/GUIShader.ts +++ b/src/components/gui/core/GUIShader.ts @@ -150,14 +150,18 @@ export class GUIShader { }else if(texId == 6){ ${this.sampleTexture(6)} } - color *= vColor4; - color.a *= scissorAlpha; + var rgb = color.rgb; + var alpha = color.a; + + rgb *= vColor4.rgb; + alpha *= vColor4.a; + alpha *= scissorAlpha; if(color.a < EPSILON) { discard; } - fragmentOutput.color = color; + fragmentOutput.color = vec4(rgb, alpha); return fragmentOutput ; }`; diff --git a/src/components/gui/uiComponents/UIPanel.ts b/src/components/gui/uiComponents/UIPanel.ts index 44a7d613..48fa05b0 100644 --- a/src/components/gui/uiComponents/UIPanel.ts +++ b/src/components/gui/uiComponents/UIPanel.ts @@ -93,6 +93,10 @@ export class UIPanel extends UIImage { return this._maxCount; } + public get renderer() { + return this._uiRenderer; + } + public set billboard(type: BillboardType) { if (this.space == GUISpace.View) { type = BillboardType.None; diff --git a/src/components/renderer/RenderNode.ts b/src/components/renderer/RenderNode.ts index 7985d991..5df939fa 100644 --- a/src/components/renderer/RenderNode.ts +++ b/src/components/renderer/RenderNode.ts @@ -54,6 +54,7 @@ export class RenderNode extends ComponentBase { protected _passInit: Map = new Map(); public isRenderOrderChange?: boolean; public needSortOnCameraZ?: boolean; + public isRecievePostEffectUI?: boolean; protected _octreeBinder: { octree: Octree, entity: OctreeEntity }; /** @@ -102,6 +103,7 @@ export class RenderNode extends ComponentBase { this.castShadow = from.castShadow; this.castGI = from.castGI; this.rendererMask = from.rendererMask; + this.isRecievePostEffectUI = from.isRecievePostEffectUI; return this; } diff --git a/src/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts b/src/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts index bdac0b25..34f66e80 100644 --- a/src/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts +++ b/src/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts @@ -4,6 +4,7 @@ import { GPUTextureFormat } from '../WebGPUConst'; import { webGPUContext } from '../Context3D'; import { RendererPassState } from '../../../renderJob/passRenderer/state/RendererPassState'; import { CResizeEvent } from '../../../../event/CResizeEvent'; +import { GBufferFrame } from '../../../renderJob/frame/GBufferFrame'; /** * @internal * @author sirxu @@ -30,8 +31,14 @@ export class WebGPUDescriptorCreator { if (rtFrame && rtFrame.renderTargets.length > 0) { rps.renderTargets = rtFrame.renderTargets; rps.rtTextureDescriptors = rtFrame.rtDescriptors; - rps.renderPassDescriptor = WebGPUDescriptorCreator.getRenderPassDescriptor(rps); + if (rps.renderPassDescriptor.depthStencilAttachment) { + rps.renderPassDescriptor.depthStencilAttachment.depthLoadOp = rtFrame.depthLoadOp; + } + if (loadOp == 'load' && rtFrame?.renderTargets[0] && rtFrame.renderTargets[0].name.startsWith(GBufferFrame.gui_GBuffer)) { + rps.renderPassDescriptor.colorAttachments[0].loadOp = 'load' + } + rps.depthLoadOp = rtFrame.depthLoadOp; rps.renderBundleEncoderDescriptor = WebGPUDescriptorCreator.getRenderBundleDescriptor(rps); rps.renderTargetTextures = []; for (let i = 0; i < rtFrame.renderTargets.length; i++) { diff --git a/src/gfx/renderJob/frame/GBufferFrame.ts b/src/gfx/renderJob/frame/GBufferFrame.ts index f32be552..bc8f1fa8 100644 --- a/src/gfx/renderJob/frame/GBufferFrame.ts +++ b/src/gfx/renderJob/frame/GBufferFrame.ts @@ -10,6 +10,7 @@ import { RTResourceMap } from "./RTResourceMap"; export class GBufferFrame extends RTFrame { public static colorPass_GBuffer: string = "ColorPassGBuffer"; public static reflections_GBuffer: string = "reflections_GBuffer"; + public static gui_GBuffer: string = "gui_GBuffer"; public static gBufferMap: Map = new Map(); // public static bufferTexture: boolean = false; @@ -20,7 +21,7 @@ export class GBufferFrame extends RTFrame { super([], []); } - createGBuffer(key: string, rtWidth: number, rtHeight: number, autoResize: boolean = true, outColor: boolean = true) { + createGBuffer(key: string, rtWidth: number, rtHeight: number, autoResize: boolean = true, outColor: boolean = true, depthTexture?: RenderTexture) { let attachments = this.renderTargets; let reDescriptors = this.rtDescriptors; if (outColor) { @@ -34,11 +35,12 @@ export class GBufferFrame extends RTFrame { this._compressGBufferTex = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.rgba32float, false, undefined, 1, 0, true, true); attachments.push(this._compressGBufferTex); - this.depthTexture = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.depth24plus, false, undefined, 1, 0, true, true); - this.depthTexture.name = key + `_depthTexture`; - - let depthDec = new RTDescriptor(); - depthDec.loadOp = `load`; + if (depthTexture) { + this.depthTexture = depthTexture; + } else { + this.depthTexture = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.depth24plus, false, undefined, 1, 0, true, true); + this.depthTexture.name = key + `_depthTexture`; + } let compressGBufferRTDes: RTDescriptor; compressGBufferRTDes = new RTDescriptor(); @@ -65,7 +67,7 @@ export class GBufferFrame extends RTFrame { /** * @internal */ - public static getGBufferFrame(key: string, fixedWidth: number = 0, fixedHeight: number = 0, outColor: boolean = true): GBufferFrame { + public static getGBufferFrame(key: string, fixedWidth: number = 0, fixedHeight: number = 0, outColor: boolean = true, depthTexture?: RenderTexture): GBufferFrame { let gBuffer: GBufferFrame; if (!GBufferFrame.gBufferMap.has(key)) { gBuffer = new GBufferFrame(); @@ -76,7 +78,8 @@ export class GBufferFrame extends RTFrame { fixedWidth == 0 ? size[0] : fixedWidth, fixedHeight == 0 ? size[1] : fixedHeight, fixedWidth != 0 && fixedHeight != 0, - outColor + outColor, + depthTexture ); GBufferFrame.gBufferMap.set(key, gBuffer); } else { @@ -85,6 +88,13 @@ export class GBufferFrame extends RTFrame { return gBuffer; } + + public static getGUIBufferFrame() { + let colorRTFrame = this.getGBufferFrame(this.colorPass_GBuffer); + let rtFrame = GBufferFrame.getGBufferFrame(GBufferFrame.gui_GBuffer, 0, 0, true, colorRTFrame.depthTexture); + return rtFrame; + } + public clone() { let gBufferFrame = new GBufferFrame(); this.clone2Frame(gBufferFrame); diff --git a/src/gfx/renderJob/jobs/ForwardRenderJob.ts b/src/gfx/renderJob/jobs/ForwardRenderJob.ts index c1b77590..d4021960 100644 --- a/src/gfx/renderJob/jobs/ForwardRenderJob.ts +++ b/src/gfx/renderJob/jobs/ForwardRenderJob.ts @@ -9,6 +9,7 @@ import { webGPUContext } from '../../graphics/webGpu/Context3D'; import { RTResourceConfig } from '../config/RTResourceConfig'; import { RTResourceMap } from '../frame/RTResourceMap'; import { GPUTextureFormat } from '../../graphics/webGpu/WebGPUConst'; +import { GUIPassRenderer } from '../passRenderer/color/GUIPassRenderer'; /** * Forward+ * Every time a forward rendering is performed, @@ -25,10 +26,9 @@ export class ForwardRenderJob extends RendererJob { public start(): void { super.start(); - - let rtFrame = GBufferFrame.getGBufferFrame("ColorPassGBuffer"); { let colorPassRenderer = new ColorPassRenderer(); + let rtFrame = GBufferFrame.getGBufferFrame(GBufferFrame.colorPass_GBuffer); if (Engine3D.setting.render.zPrePass) { rtFrame.zPreTexture = this.depthPassRenderer.rendererPassState.depthTexture; @@ -50,6 +50,13 @@ export class ForwardRenderJob extends RendererJob { this.rendererMap.addRenderer(colorPassRenderer); } + { + let guiFrame = GBufferFrame.getGUIBufferFrame(); + let guiPassRenderer = new GUIPassRenderer(); + guiPassRenderer.setRenderStates(guiFrame); + this.rendererMap.addRenderer(guiPassRenderer); + } + if (Engine3D.setting.render.debug) { this.debug(); } diff --git a/src/gfx/renderJob/jobs/RendererJob.ts b/src/gfx/renderJob/jobs/RendererJob.ts index d45fb2ab..762b7d47 100644 --- a/src/gfx/renderJob/jobs/RendererJob.ts +++ b/src/gfx/renderJob/jobs/RendererJob.ts @@ -231,6 +231,7 @@ export class RendererJob { this.ddgiProbeRenderer.render(view, this.occlusionSystem); } + let passList = this.rendererMap.getAllPassRenderer(); for (let i = 0; i < passList.length; i++) { const renderer = passList[i]; @@ -238,10 +239,16 @@ export class RendererJob { renderer.render(view, this.occlusionSystem, this.clusterLightingRender.clusterLightingBuffer, false); } - if (this.postRenderer && this.postRenderer.postList.size > 0) { - this.postRenderer.render(view); - } + this.postRenderer.render(view); + + //GUI + let guiRenderer = this.rendererMap.getRenderer(PassType.UI); + guiRenderer.compute(view, this.occlusionSystem); + guiRenderer.render(view, this.occlusionSystem, this.clusterLightingRender.clusterLightingBuffer, false); + //output + let lastTexture = GBufferFrame.getGUIBufferFrame().getColorTexture(); + this.postRenderer.presentContent(view, lastTexture); } public debug() { diff --git a/src/gfx/renderJob/passRenderer/RenderContext.ts b/src/gfx/renderJob/passRenderer/RenderContext.ts index 4d7c698c..560d4388 100644 --- a/src/gfx/renderJob/passRenderer/RenderContext.ts +++ b/src/gfx/renderJob/passRenderer/RenderContext.ts @@ -58,6 +58,12 @@ export class RenderContext { this.beginNewEncoder(); } + public specialtRenderPass() { + this.beginContinueRendererPassState('load', 'load'); + this.begineNewCommand(); + this.beginNewEncoder(); + } + public endRenderPass() { this.endEncoder(); this.endCommand(); diff --git a/src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts b/src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts index 12090064..a3cf2fed 100644 --- a/src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts +++ b/src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts @@ -1,17 +1,16 @@ -import { GlobalBindGroup } from "../../../.."; import { Engine3D } from "../../../../Engine3D"; import { RenderNode } from "../../../../components/renderer/RenderNode"; import { View3D } from "../../../../core/View3D"; import { ProfilerUtil } from "../../../../util/ProfilerUtil"; +import { GlobalBindGroup } from "../../../graphics/webGpu/core/bindGroups/GlobalBindGroup"; import { GPUContext } from "../../GPUContext"; import { EntityCollect } from "../../collect/EntityCollect"; -import { RTResourceConfig } from "../../config/RTResourceConfig"; -import { RTResourceMap } from "../../frame/RTResourceMap"; import { OcclusionSystem } from "../../occlusion/OcclusionSystem"; import { RenderContext } from "../RenderContext"; import { RendererBase } from "../RendererBase"; import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer"; import { PassType } from "../state/PassType"; +import { RendererMask } from "../state/RendererMask"; /** * @internal @@ -133,7 +132,8 @@ export class ColorPassRenderer extends RendererBase { continue; if (!renderNode.enable) continue; - + if (renderNode.hasMask(RendererMask.UI) && !renderNode.isRecievePostEffectUI) + continue; if (!renderNode.preInit(this._rendererType)) { renderNode.nodeUpdate(view, this._rendererType, this.rendererPassState, clusterLightingBuffer); } diff --git a/src/gfx/renderJob/passRenderer/color/GUIPassRenderer.ts b/src/gfx/renderJob/passRenderer/color/GUIPassRenderer.ts new file mode 100644 index 00000000..c9b768e5 --- /dev/null +++ b/src/gfx/renderJob/passRenderer/color/GUIPassRenderer.ts @@ -0,0 +1,109 @@ +import { Engine3D } from "../../../../Engine3D"; +import { RenderNode } from "../../../../components/renderer/RenderNode"; +import { View3D } from "../../../../core/View3D"; +import { GlobalBindGroup } from "../../../graphics/webGpu/core/bindGroups/GlobalBindGroup"; +import { GPUContext } from "../../GPUContext"; +import { EntityCollect } from "../../collect/EntityCollect"; +import { GBufferFrame } from "../../frame/GBufferFrame"; +import { RTFrame } from "../../frame/RTFrame"; +import { OcclusionSystem } from "../../occlusion/OcclusionSystem"; +import { RenderContext } from "../RenderContext"; +import { RendererBase } from "../RendererBase"; +import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer"; +import { PassType } from "../state/PassType"; +import { RendererMask } from "../state/RendererMask"; + +/** + * @internal + * Base Color Renderer + * @author sirxu + * @group Post + */ +export class GUIPassRenderer extends RendererBase { + constructor() { + super(); + this.passType = PassType.UI; + } + + public compute(view: View3D, occlusionSystem: OcclusionSystem): void { + let command = GPUContext.beginCommandEncoder(); + let src = GPUContext.lastRenderPassState.getLastRenderTexture(); + let dest = GBufferFrame.getGUIBufferFrame().getColorTexture(); + GPUContext.copyTexture(command, src, dest); + GPUContext.endCommandEncoder(command); + } + + public render(view: View3D, occlusionSystem: OcclusionSystem, clusterLightingBuffer?: ClusterLightingBuffer, maskTr: boolean = false) { + this.renderContext.clean(); + + + let scene = view.scene; + let camera = view.camera; + + GlobalBindGroup.updateCameraGroup(camera); + + this.rendererPassState.camera3D = camera; + + let collectInfo = EntityCollect.instance.getRenderNodes(scene, camera); + + { + this.renderContext.specialtRenderPass(); + + let renderPassEncoder = this.renderContext.encoder; + + + if (collectInfo.opaqueList) { + GPUContext.bindCamera(renderPassEncoder, camera); + this.drawNodes(view, this.renderContext, collectInfo.opaqueList, occlusionSystem, clusterLightingBuffer); + } + } + + { + + let renderPassEncoder = this.renderContext.encoder; + + + if (!maskTr && collectInfo.transparentList) { + GPUContext.bindCamera(renderPassEncoder, camera); + this.drawNodes(view, this.renderContext, collectInfo.transparentList, occlusionSystem, clusterLightingBuffer); + } + this.renderContext.endRenderPass(); + } + + } + + public drawNodes(view: View3D, renderContext: RenderContext, nodes: RenderNode[], occlusionSystem: OcclusionSystem, clusterLightingBuffer: ClusterLightingBuffer) { + let viewRenderList = EntityCollect.instance.getRenderShaderCollect(view); + if (viewRenderList) { + for (const renderList of viewRenderList) { + let nodeMap = renderList[1]; + for (const iterator of nodeMap) { + let node = iterator[1]; + if (node.preInit(this._rendererType)) { + node.nodeUpdate(view, this._rendererType, this.rendererPassState, clusterLightingBuffer); + break; + } + } + } + + for (let i = Engine3D.setting.render.drawOpMin; i < Math.min(nodes.length, Engine3D.setting.render.drawOpMax); ++i) { + let renderNode = nodes[i]; + if (!renderNode.transform.enable) + continue; + if (!renderNode.enable) + continue; + if (!renderNode.hasMask(RendererMask.UI) || renderNode.isRecievePostEffectUI) + continue; + if (!renderNode.preInit(this._rendererType)) { + renderNode.nodeUpdate(view, this._rendererType, this.rendererPassState, clusterLightingBuffer); + } + renderNode.renderPass(view, this.passType, this.renderContext); + } + } + } + + + protected occlusionRenderNodeTest(i: number, id: number, occlusionSystem: OcclusionSystem): boolean { + return occlusionSystem.zDepthRenderNodeTest(id) > 0; + } +} diff --git a/src/gfx/renderJob/passRenderer/post/PostRenderer.ts b/src/gfx/renderJob/passRenderer/post/PostRenderer.ts index 4f3352e7..0be0a34a 100644 --- a/src/gfx/renderJob/passRenderer/post/PostRenderer.ts +++ b/src/gfx/renderJob/passRenderer/post/PostRenderer.ts @@ -3,7 +3,9 @@ import { ShaderLib } from "../../../../assets/shader/ShaderLib"; import { FullQuad_vert_wgsl } from "../../../../assets/shader/quad/Quad_shader"; import { View3D } from "../../../../core/View3D"; import { ViewQuad } from "../../../../core/ViewQuad"; +import { Texture } from "../../../graphics/webGpu/core/texture/Texture"; import { GPUContext } from "../../GPUContext"; +import { GBufferFrame } from "../../frame/GBufferFrame"; import { RTFrame } from "../../frame/RTFrame"; import { PostBase } from "../../post/PostBase"; import { RendererBase } from "../RendererBase"; @@ -67,15 +69,13 @@ export class PostRenderer extends RendererBase { v.render(view, command); } }); + GPUContext.endCommandEncoder(command); + } - let lastTexture = GPUContext.lastRenderPassState.getLastRenderTexture(); - this.finalQuadView.renderToViewQuad(view, this.finalQuadView, command, lastTexture); - { - if (this.debugViewQuads.length) { - let debugIndex = Engine3D.setting.render.debugQuad; - if (debugIndex >= 0) this.debugViewQuads[debugIndex].renderToViewQuad(view, this.debugViewQuads[debugIndex], command, this.debugTextures[debugIndex]); - } - } + public presentContent(view: View3D, texture: Texture) { + let command = GPUContext.beginCommandEncoder(); + this.finalQuadView.renderToViewQuad(view, this.finalQuadView, command, texture); GPUContext.endCommandEncoder(command); } + } diff --git a/src/gfx/renderJob/passRenderer/state/PassType.ts b/src/gfx/renderJob/passRenderer/state/PassType.ts index 18a1200c..8fab3a8e 100644 --- a/src/gfx/renderJob/passRenderer/state/PassType.ts +++ b/src/gfx/renderJob/passRenderer/state/PassType.ts @@ -6,11 +6,11 @@ export enum PassType { REFLECTION = 1 << 1, POSITION = 1 << 2, GRAPHIC = 1 << 3, - GI = 1 << 4, Cluster = 1 << 5, SHADOW = 1 << 6, POINT_SHADOW = 1 << 7, POST = 1 << 8, DEPTH = 1 << 9, + UI = 1 << 10, } diff --git a/src/index.ts b/src/index.ts index 28acd9a2..03684f4d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -351,6 +351,7 @@ export * from "./gfx/renderJob/passRenderer/cluster/ClusterConfig" export * from "./gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer" export * from "./gfx/renderJob/passRenderer/cluster/ClusterLightingRender" export * from "./gfx/renderJob/passRenderer/color/ColorPassRenderer" +export * from "./gfx/renderJob/passRenderer/color/GUIPassRenderer" export * from "./gfx/renderJob/passRenderer/cubeRenderer/ReflectionRenderer" export * from "./gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass" export * from "./gfx/renderJob/passRenderer/ddgi/DDGIIrradianceGPUBufferReader"