From 2883c18feac6261ce3b34b047f449ad938464b48 Mon Sep 17 00:00:00 2001 From: OldGentleMan Date: Tue, 14 Nov 2023 21:29:26 +0800 Subject: [PATCH 1/7] fix: fix engine bug (#329) * fix: fix gltf sample * fix: fix chromaKey material * fix: fix grass sample * fix: fix resize * fix: fix canvas resize change gpu attachments texture * fix: fix post sample resize bug * fix: fix csm shadow. * chore: add sample * fix: Cancel automatic resizing of rendertexture in GI * feat: add graphic ribbon * fix: Wrong offset for bloom. * perf: reduce texture sample times. * feat: fix: texture Count Exceeded the maximum limit of 7 * chore: get param from setting. * feat: add new graphic face * fix index.ts * update physics car sample * fix: Auto sort transparent renderers. (#318) --------- Co-authored-by: ShuangLiu Co-authored-by: hellmor Co-authored-by: Codeboy-cn --- .../shader/GrassVertexAttributeShader.ts | 17 +- public | 2 +- samples/ext/Sample_Grass.ts | 23 +- samples/graphic/Sample_GraphicMeshWave.ts | 2 +- samples/graphic/Sample_GraphicMesh_0.ts | 2 +- samples/graphic/Sample_GraphicMesh_1.ts | 2 +- samples/graphic/Sample_GraphicMesh_2.ts | 2 +- samples/graphic/Sample_GraphicMesh_3.ts | 2 +- samples/gui/Sample_UIMultipleTextures.ts | 53 +++ samples/index.ts | 2 +- samples/loader/Sample_LoadGLB.ts | 66 ++-- samples/pick/Sample_PixelPick.ts | 8 +- samples/post/Sample_DepthOfView.ts | 112 ++++++ samples/post/Sample_FXAA.ts | 125 +++++++ samples/post/Sample_GodRay.ts | 8 +- samples/post/Sample_Outline.ts | 119 ++++++ samples/post/Sample_SSR.ts | 128 +++++++ samples/utils/GUIUtil.ts | 23 +- src/Engine3D.ts | 30 +- src/assets/shader/compute/BloomEffect_cs.ts | 29 +- .../shader/compute/DDGILighting_CSShader.ts | 42 ++- src/assets/shader/compute/DepthOfView_cs.ts | 6 +- .../shader/compute/OutLineBlendColor_cs.ts | 13 +- .../shader/compute/SSR_BlendColor_cs.ts | 11 +- .../shader/core/common/GlobalUniform.ts | 3 +- .../core/struct/VertexAttributeIndexShader.ts | 2 + .../shader/graphic/GraphicFaceComput2.ts | 247 +++++++++++++ .../shader/graphic/GraphicFaceCompute.ts | 342 ++++++++++++++++++ .../shader/graphic/GraphicFaceCompute3.ts | 259 +++++++++++++ .../shader/graphic/GraphicTrailCompute.ts | 165 +++++++++ src/assets/shader/lighting/BxDF_frag.ts | 4 + src/assets/shader/math/MathShader.ts | 1 + src/assets/shader/quad/Quad_shader.ts | 15 +- src/components/SkeletonAnimationComponent.ts | 2 +- src/components/anim/AnimatorComponent.ts | 2 +- src/components/gui/core/GUIGeometry.ts | 47 ++- src/components/gui/core/GUIGeometryRebuild.ts | 72 ++-- src/components/gui/core/GUIMaterial.ts | 9 +- src/components/gui/core/GUIRenderer.ts | 6 +- src/components/gui/core/GUIShader.ts | 6 +- src/components/gui/uiComponents/UIPanel.ts | 42 ++- src/components/gui/uiComponents/WorldPanel.ts | 5 +- src/components/lights/DirectLight.ts | 2 +- src/components/lights/Light.ts | 2 +- src/components/lights/PointLight.ts | 18 +- src/components/lights/SpotLight.ts | 48 +-- .../post/PostProcessingComponent.ts | 6 +- src/components/renderer/MeshFilter.ts | 2 +- src/components/renderer/MeshRenderer.ts | 2 +- src/components/renderer/RenderNode.ts | 29 +- .../renderer/SkinnedMeshRenderer.ts | 2 +- .../renderer/SkinnedMeshRenderer2.ts | 2 +- src/core/ViewQuad.ts | 17 + src/core/entities/Entity.ts | 8 +- src/core/geometry/GeometryBase.ts | 3 +- src/core/geometry/GeometryVertexBuffer.ts | 1 - .../generate/convert/TextureCubeStdCreator.ts | 4 +- src/gfx/graphics/webGpu/Context3D.ts | 18 +- .../core/bindGroups/GlobalUniformGroup.ts | 6 +- .../webGpu/core/buffer/GPUBufferBase.ts | 78 ++-- .../webGpu/core/buffer/IndicesGPUBuffer.ts | 4 +- .../webGpu/core/buffer/VertexGPUBuffer.ts | 3 + .../graphics/webGpu/core/texture/Texture.ts | 6 +- .../graphics/webGpu/shader/ComputeShader.ts | 10 +- src/gfx/renderJob/frame/GBufferFrame.ts | 6 +- src/gfx/renderJob/frame/ProbeGBufferFrame.ts | 18 +- src/gfx/renderJob/frame/RTFrame.ts | 11 +- src/gfx/renderJob/frame/RTResourceMap.ts | 23 +- src/gfx/renderJob/jobs/RendererJob.ts | 1 - .../renderJob/passRenderer/RendererBase.ts | 8 +- .../ddgi/DDGIIrradianceComputePass.ts | 8 +- .../ddgi/DDGIIrradianceGPUBufferReader.ts | 8 +- .../passRenderer/ddgi/DDGILightingPass.ts | 6 +- .../passRenderer/ddgi/DDGIMultiBouncePass.ts | 8 +- .../passRenderer/ddgi/DDGIProbeRenderer.ts | 20 +- .../graphic/new/Float32ArrayUtil.ts | 11 + .../graphic/new/Graphic3DFaceRenderer.ts | 172 +++++++++ .../passRenderer/graphic/new/Graphic3DMesh.ts | 27 ++ .../graphic/new/Graphic3DMeshRenderer.ts | 30 +- .../graphic/new/Graphic3DRibbonRenderer.ts | 173 +++++++++ .../shadow/PointLightShadowRenderer.ts | 5 +- .../shadow/ShadowMapPassRenderer.ts | 5 +- .../passRenderer/state/RendererPassState.ts | 6 +- src/gfx/renderJob/post/BloomPost.ts | 81 ++++- src/gfx/renderJob/post/DepthOfFieldPost.ts | 34 +- src/gfx/renderJob/post/GTAOPost.ts | 29 +- src/gfx/renderJob/post/GlobalFog.ts | 1 + src/gfx/renderJob/post/GodRayPost.ts | 86 +++-- src/gfx/renderJob/post/OutlinePost.ts | 107 ++++-- src/gfx/renderJob/post/PostBase.ts | 13 +- src/gfx/renderJob/post/SSRPost.ts | 32 ++ src/gfx/renderJob/post/TAAPost.ts | 27 +- src/index.ts | 12 +- .../parser/prefab/mats/MaterialUtilities.ts | 3 +- src/loader/parser/prefab/prefabData/APatch.ts | 2 +- src/setting/RenderSetting.ts | 2 + src/setting/post/GodRaySetting.ts | 12 + src/shape/TrailGeometry.ts | 93 +++++ src/shape/TriGeometry.ts | 62 ++++ src/textures/BitmapTexture2DArray.ts | 6 +- src/textures/BitmapTextureCube.ts | 3 +- src/textures/Depth2DTextureArray.ts | 6 +- src/textures/DepthCubeArrayTexture.ts | 6 +- src/textures/DepthCubeTexture.ts | 6 +- .../{ShadowTexture.ts => RenderTexture.ts} | 50 ++- src/textures/VirtualTexture.ts | 15 +- src/util/SerializeDecoration.ts | 6 +- src/util/struct/Struct.ts | 11 +- 108 files changed, 3027 insertions(+), 551 deletions(-) create mode 100644 samples/gui/Sample_UIMultipleTextures.ts create mode 100644 samples/post/Sample_DepthOfView.ts create mode 100644 samples/post/Sample_FXAA.ts create mode 100644 samples/post/Sample_Outline.ts create mode 100644 samples/post/Sample_SSR.ts create mode 100644 src/assets/shader/graphic/GraphicFaceComput2.ts create mode 100644 src/assets/shader/graphic/GraphicFaceCompute.ts create mode 100644 src/assets/shader/graphic/GraphicFaceCompute3.ts create mode 100644 src/assets/shader/graphic/GraphicTrailCompute.ts create mode 100644 src/gfx/renderJob/passRenderer/graphic/new/Float32ArrayUtil.ts create mode 100644 src/gfx/renderJob/passRenderer/graphic/new/Graphic3DFaceRenderer.ts create mode 100644 src/gfx/renderJob/passRenderer/graphic/new/Graphic3DRibbonRenderer.ts create mode 100644 src/setting/post/GodRaySetting.ts create mode 100644 src/shape/TrailGeometry.ts create mode 100644 src/shape/TriGeometry.ts rename src/textures/{ShadowTexture.ts => RenderTexture.ts} (86%) diff --git a/packages/effect/grass/shader/GrassVertexAttributeShader.ts b/packages/effect/grass/shader/GrassVertexAttributeShader.ts index 61269e7e..d78f5208 100644 --- a/packages/effect/grass/shader/GrassVertexAttributeShader.ts +++ b/packages/effect/grass/shader/GrassVertexAttributeShader.ts @@ -13,15 +13,16 @@ export let GrassVertexAttributeShader: string = /*wgsl*/ ` } struct VertexOutput { - @location(0) varying_UV0: vec2, - @location(1) varying_UV1: vec2, - @location(2) varying_ViewPos: vec4, - @location(3) varying_Clip: vec4, - @location(4) varying_WPos: vec4, - @location(5) varying_WNormal: vec3, - @location(6) varying_Color: vec4, + @location(0) index: f32, + @location(1) varying_UV0: vec2, + @location(2) varying_UV1: vec2, + @location(3) varying_ViewPos: vec4, + @location(4) varying_Clip: vec4, + @location(5) varying_WPos: vec4, + @location(6) varying_WNormal: vec3, + @location(7) varying_Color: vec4, #if USE_SHADOWMAPING - @location(7) varying_ShadowPos: vec4, + @location(8) varying_ShadowPos: vec4, #endif @builtin(position) member: vec4 }; diff --git a/public b/public index 5f32b408..82b77d26 160000 --- a/public +++ b/public @@ -1 +1 @@ -Subproject commit 5f32b408d1314243ece38c4fd47c871206cd7996 +Subproject commit 82b77d26e6b6e2cd43b470faf55d1b5f99d30c58 diff --git a/samples/ext/Sample_Grass.ts b/samples/ext/Sample_Grass.ts index b85e6d3f..a2a2e594 100644 --- a/samples/ext/Sample_Grass.ts +++ b/samples/ext/Sample_Grass.ts @@ -31,16 +31,16 @@ export class Sample_Grass { Engine3D.startRenderView(this.view); - this.post = this.view.scene.addComponent(PostProcessingComponent); - let fxaa = this.post.addPost(FXAAPost); - let fog = this.post.addPost(GlobalFog); - fog.fogColor = new Color(136 / 255, 215 / 255, 236 / 255, 1); - fog.start = 0; - fog.overrideSkyFactor = 0.0764; - fog.ins = 1; - fog.falloff = 0.626; - fog.scatteringExponent = 3; - fog.dirHeightLine = 10; + // this.post = this.view.scene.addComponent(PostProcessingComponent); + // let fxaa = this.post.addPost(FXAAPost); + // let fog = this.post.addPost(GlobalFog); + // fog.fogColor = new Color(136 / 255, 215 / 255, 236 / 255, 1); + // fog.start = 0; + // fog.overrideSkyFactor = 0.0764; + // fog.ins = 1; + // fog.falloff = 0.626; + // fog.scatteringExponent = 3; + // fog.dirHeightLine = 10; // post.addPost(TAAPost); this.createScene(this.view.scene); @@ -148,9 +148,6 @@ export class Sample_Grass { // GUIHelp.addFolder("shadow"); // GUIHelp.add(Engine3D.setting.shadow, "shadowBound", 0.0, 3000, 0.0001); // GUIHelp.endFolder(); - - let globalFog = this.post.getPost(GlobalFog); - // GUIUtil.renderFog(globalFog); } } diff --git a/samples/graphic/Sample_GraphicMeshWave.ts b/samples/graphic/Sample_GraphicMeshWave.ts index d0bc573f..7ddc167c 100644 --- a/samples/graphic/Sample_GraphicMeshWave.ts +++ b/samples/graphic/Sample_GraphicMeshWave.ts @@ -1,5 +1,5 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, PrefabParser } from "@orillusion/core"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, PrefabParser } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; import { Stats } from "@orillusion/stats"; diff --git a/samples/graphic/Sample_GraphicMesh_0.ts b/samples/graphic/Sample_GraphicMesh_0.ts index c836e4d8..f3de297f 100644 --- a/samples/graphic/Sample_GraphicMesh_0.ts +++ b/samples/graphic/Sample_GraphicMesh_0.ts @@ -1,5 +1,5 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode } from "@orillusion/core"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; import { Stats } from "@orillusion/stats"; diff --git a/samples/graphic/Sample_GraphicMesh_1.ts b/samples/graphic/Sample_GraphicMesh_1.ts index 8c24588e..8493975c 100644 --- a/samples/graphic/Sample_GraphicMesh_1.ts +++ b/samples/graphic/Sample_GraphicMesh_1.ts @@ -1,5 +1,5 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, Color } from "@orillusion/core"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, Color } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; import { Stats } from "@orillusion/stats"; diff --git a/samples/graphic/Sample_GraphicMesh_2.ts b/samples/graphic/Sample_GraphicMesh_2.ts index a6c7945e..ca9498e0 100644 --- a/samples/graphic/Sample_GraphicMesh_2.ts +++ b/samples/graphic/Sample_GraphicMesh_2.ts @@ -1,5 +1,5 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode } from "@orillusion/core"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; import { Stats } from "@orillusion/stats"; diff --git a/samples/graphic/Sample_GraphicMesh_3.ts b/samples/graphic/Sample_GraphicMesh_3.ts index 4890c6b7..26284fc2 100644 --- a/samples/graphic/Sample_GraphicMesh_3.ts +++ b/samples/graphic/Sample_GraphicMesh_3.ts @@ -1,5 +1,5 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, PrefabParser } from "@orillusion/core"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, MeshRenderer, UnLitTexArrayMaterial, BitmapTexture2DArray, Vector3, Graphic3DMesh, Matrix4, Time, PrefabParser } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; import { Stats } from "@orillusion/stats"; diff --git a/samples/gui/Sample_UIMultipleTextures.ts b/samples/gui/Sample_UIMultipleTextures.ts new file mode 100644 index 00000000..e7c4afd2 --- /dev/null +++ b/samples/gui/Sample_UIMultipleTextures.ts @@ -0,0 +1,53 @@ +import { Engine3D, Scene3D, Object3D, Camera3D, View3D, UIImage, HoverCameraController, AtmosphericComponent, BitmapTexture2D, makeAloneSprite, WorldPanel, GPUCullMode, UIPanel, Color } from '@orillusion/core' + +class Sample_UIMultipleTextures { + async run() { + // initializa engine + await Engine3D.init() + // create new scene as root node + let scene3D: Scene3D = new Scene3D() + scene3D.addComponent(AtmosphericComponent) + // create camera + let cameraObj: Object3D = new Object3D() + let camera = cameraObj.addComponent(Camera3D) + // adjust camera view + camera.perspective(60, Engine3D.aspect, 1, 5000.0) + // set camera controller + let controller = cameraObj.addComponent(HoverCameraController) + controller.setCamera(15, 10, 80) + // add camera node + scene3D.addChild(cameraObj) + let view = new View3D() + view.scene = scene3D + view.camera = camera + Engine3D.startRenderView(view) + // create panel root + let panelRoot: Object3D = new Object3D() + let panel: UIPanel = panelRoot.addComponent(WorldPanel) + panel.cullMode = GPUCullMode.none; + panelRoot.localScale.set(0.1, 0.1, 0.1) + let canvas = view.enableUICanvas() + canvas.addChild(panelRoot) + + for (let i = 0; i < 10; i++) { + let bitmapTexture2D = new BitmapTexture2D() + bitmapTexture2D.flipY = true + await bitmapTexture2D.load('textures/digit/digit_' + i + '.png') + + // create image node + let imageQuad = new Object3D() + panelRoot.addChild(imageQuad) + // create image component + let image: UIImage = imageQuad.addComponent(UIImage) + // set image size + image.uiTransform.resize(10, 10) + image.uiTransform.setXY((i - 5) * 8, 0); + image.color = Color.random(); + // set image source + image.sprite = makeAloneSprite('webgpu' + i, bitmapTexture2D) + } + + } +} + +new Sample_UIMultipleTextures().run() diff --git a/samples/index.ts b/samples/index.ts index 7558858f..01af358a 100644 --- a/samples/index.ts +++ b/samples/index.ts @@ -67,4 +67,4 @@ ` document.body.appendChild(iframe) } -} +} \ No newline at end of file diff --git a/samples/loader/Sample_LoadGLB.ts b/samples/loader/Sample_LoadGLB.ts index d24ac932..e68ee1c8 100644 --- a/samples/loader/Sample_LoadGLB.ts +++ b/samples/loader/Sample_LoadGLB.ts @@ -6,6 +6,7 @@ import { GUIUtil } from "@samples/utils/GUIUtil"; // Sample to load glb file export class Sample_LoadGLB { scene: Scene3D; + model: Object3D; async run() { GUIHelp.init(); @@ -49,71 +50,60 @@ export class Sample_LoadGLB { /******** load glb file *******/ - //cull mode - let list = {}; - list[`HIE-Hand-Armor`] = JSON.stringify( - { + //model list + let list = { + "HIE-Hand-Armor": { url: `gltfs/glb/HIE-Hand-Armor.glb`, scale: 1, offset: [0, 0, 0], rotation: [0, 0, 0] - } - ) - list[`PebsiCan`] = JSON.stringify( - { + }, + "PebsiCan": { url: `gltfs/glb/PebsiCan.glb`, scale: 1, offset: [0, 3, 0], rotation: [0, 0, 0] - } - ) - list[`Liv-SpecOpsWolf`] = JSON.stringify( - { + }, + "Liv-SpecOpsWolf": { url: `gltfs/glb/Liv-SpecOpsWolf.glb`, scale: 20, offset: [0, 0, 0], rotation: [0, 0, 0] - } - ) - list[`FlamingoPool`] = JSON.stringify( - { + }, + "FlamingoPool": { url: `gltfs/glb/FlamingoPool.glb`, scale: 0.5, offset: [0, 0, 0], rotation: [180, 0, 0] - } - ) - list[`PotionBottle`] = JSON.stringify( - { + }, + "PotionBottle": { url: `gltfs/glb/PotionBottle.glb`, scale: 0.1, offset: [0, 0, 0], rotation: [0, 0, 0] - } - ) - list[`wukong`] = JSON.stringify( - { + }, + "wukong": { url: `gltfs/wukong/wukong.gltf`, scale: 10, offset: [0, 0, 0], rotation: [0, 0, 0] } - ) - - let model: Object3D; - let { url, scale, offset, rotation } = JSON.parse(list[`HIE-Hand-Armor`]); - this.loadGLB(model, url, offset, scale, rotation); - GUIHelp.add({ Model: `HIE-Hand-Armor` }, 'Model', list).onChange(async (v) => { - let { url, scale, offset, rotation } = JSON.parse(v); - this.loadGLB(model, url, offset, scale, rotation); + }; + + + GUIHelp.add({ Model: `HIE-Hand-Armor` }, 'Model', Object.keys(list)).onChange(async (v) => { + let { url, scale, offset, rotation } = list[v]; + this.loadGLB(url, offset, scale, rotation); }); + let { url, scale, offset, rotation } = list[`HIE-Hand-Armor`]; + this.loadGLB(url, offset, scale, rotation); } - private async loadGLB(model: Object3D, url: string, offset: number[], scale: number, rotation: number[]) { - if (model) { - this.scene.removeChild(model); + private async loadGLB(url: string, offset: number[], scale: number, rotation: number[]) { + if (this.model) { + this.scene.removeChild(this.model); } - model = (await Engine3D.res.loadGltf(url, { onProgress: (e) => this.onLoadProgress(e), onComplete: (e) => this.onComplete(e) })) as Object3D; + let model = this.model = (await Engine3D.res.loadGltf(url, { onProgress: (e) => this.onLoadProgress(e), onComplete: (e) => this.onComplete(e) })) as Object3D; this.scene.addChild(model); model.x = offset[0]; model.y = offset[1]; @@ -129,11 +119,11 @@ export class Sample_LoadGLB { } onLoadProgress(e) { - console.log(e); + console.log('[loading]', e); } onComplete(e) { - console.log(e); + console.log('[compelete]', e); } } diff --git a/samples/pick/Sample_PixelPick.ts b/samples/pick/Sample_PixelPick.ts index 5c23a384..40cbfb71 100644 --- a/samples/pick/Sample_PixelPick.ts +++ b/samples/pick/Sample_PixelPick.ts @@ -92,7 +92,7 @@ class Sample_PixelPick { let obj = this.getPickObject(e); if (obj) { let msc = obj.getComponent(MaterialStateComponent); - msc.changeColor(new Color(2, 0, 0, 1), 120); + msc.changeColor(new Color(1.2, 0, 0, 1), 120); } } @@ -100,7 +100,7 @@ class Sample_PixelPick { let obj = this.getPickObject(e); if (obj) { let msc = obj.getComponent(MaterialStateComponent); - msc.changeColor(new Color(2, 2, 0, 1), 120); + msc.changeColor(new Color(1, 1.2, 0, 1), 120); } } @@ -108,7 +108,7 @@ class Sample_PixelPick { let obj = this.getPickObject(e); if (obj) { let msc = obj.getComponent(MaterialStateComponent); - msc.changeColor(new Color(2, 0, 0, 1), 120); + msc.changeColor(new Color(1.2, 0, 0.5, 1), 120); } } @@ -116,7 +116,7 @@ class Sample_PixelPick { let obj = this.getPickObject(e); if (obj) { let msc = obj.getComponent(MaterialStateComponent); - msc.changeColor(new Color(1, 0.64, 0.8, 2.5), 100); + msc.changeColor(new Color(1, 0.64, 0.8, 1.5), 100); } } diff --git a/samples/post/Sample_DepthOfView.ts b/samples/post/Sample_DepthOfView.ts new file mode 100644 index 00000000..d68e072c --- /dev/null +++ b/samples/post/Sample_DepthOfView.ts @@ -0,0 +1,112 @@ +import { DepthOfFieldPost, DirectLight, Engine3D, PostProcessingComponent, View3D, LitMaterial, HoverCameraController, KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, SSR_IS_Kernel, CameraUtil, webGPUContext, AtmosphericComponent } from '@orillusion/core' +import * as dat from '@orillusion/debug/dat.gui.module' + +class Sample_DepthOfView { + lightObj: Object3D + scene: Scene3D + constructor() { } + + async run() { + Engine3D.setting.shadow.enable = true + Engine3D.setting.shadow.shadowBound = 100 + await Engine3D.init({ + canvasConfig: { + devicePixelRatio: 1 + } + }) + + this.scene = new Scene3D() + this.scene.addComponent(AtmosphericComponent).sunY = 0.6 + + let camera = CameraUtil.createCamera3DObject(this.scene) + camera.perspective(60, webGPUContext.aspect, 1, 5000.0) + let ctrl = camera.object3D.addComponent(HoverCameraController) + ctrl.setCamera(100, -15, 150) + + await this.initScene(this.scene) + + let view = new View3D() + view.scene = this.scene + view.camera = camera + Engine3D.startRenderView(view) + + let postProcessing = this.scene.addComponent(PostProcessingComponent) + let DOFPost = postProcessing.addPost(DepthOfFieldPost) + DOFPost.near = 0 + DOFPost.far = 150 + DOFPost.pixelOffset = 2 + + let GUIHelp = new dat.GUI() + GUIHelp.addFolder('Depth of Field') + GUIHelp.add(DOFPost, 'near', 0, 100, 1) + GUIHelp.add(DOFPost, 'far', 150, 300, 1) + + console.log("run"); + + } + + async initScene(scene: Scene3D) { + /******** light *******/ + { + this.lightObj = new Object3D() + this.lightObj.rotationX = 15 + this.lightObj.rotationY = 110 + this.lightObj.rotationZ = 0 + let lc = this.lightObj.addComponent(DirectLight) + lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355) + lc.castShadow = true + lc.intensity = 10 + scene.addChild(this.lightObj) + } + + // load a test gltf model + let minimalObj = await Engine3D.res.loadGltf('/PBR/ToyCar/ToyCar.gltf') + minimalObj.scaleX = minimalObj.scaleY = minimalObj.scaleZ = 800 + scene.addChild(minimalObj) + + this.createPlane(scene) + return true + } + + private createPlane(scene: Scene3D) { + let mat = new LitMaterial() + { + let debugGeo = new PlaneGeometry(2000, 2000) + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = mat + mr.geometry = debugGeo + scene.addChild(obj) + } + + { + let sphereGeometry = new SphereGeometry(10, 50, 50) + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = mat + mr.geometry = sphereGeometry + obj.x = 30 + obj.y = 10 + scene.addChild(obj) + } + + { + let seeds = SSR_IS_Kernel.createSeeds() + let sphereGeometry = new SphereGeometry(2, 50, 50) + for (let i = 0; i < seeds.length; i++) { + let pt = seeds[i] + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = mat + mr.geometry = sphereGeometry + + obj.y = pt.z + obj.x = pt.x + obj.z = pt.y + scene.addChild(obj) + } + } + } +} + +new Sample_DepthOfView().run() diff --git a/samples/post/Sample_FXAA.ts b/samples/post/Sample_FXAA.ts new file mode 100644 index 00000000..70043ed1 --- /dev/null +++ b/samples/post/Sample_FXAA.ts @@ -0,0 +1,125 @@ +import { + View3D, DirectLight, Engine3D, + PostProcessingComponent, LitMaterial, HoverCameraController, + KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, + CameraUtil, webGPUContext, BoxGeometry, TAAPost, AtmosphericComponent, GTAOPost, Color, BloomPost, FXAAPost +} from '@orillusion/core'; + +class Sample_Bloom { + lightObj: Object3D; + scene: Scene3D; + + async run() { + Engine3D.setting.shadow.shadowSize = 2048 + Engine3D.setting.shadow.shadowBound = 500; + + await Engine3D.init(); + + this.scene = new Scene3D(); + let sky = this.scene.addComponent(AtmosphericComponent); + sky.sunY = 0.6; + + let mainCamera = CameraUtil.createCamera3DObject(this.scene, 'camera'); + mainCamera.perspective(60, webGPUContext.aspect, 1, 5000.0); + let ctrl = mainCamera.object3D.addComponent(HoverCameraController); + ctrl.setCamera(0, -15, 500); + await this.initScene(); + sky.relativeTransform = this.lightObj.transform; + + + let view = new View3D(); + view.scene = this.scene; + view.camera = mainCamera; + Engine3D.startRenderView(view); + // 1. 必须在 startRenderView 后添加 post 才可以,否则错误 + let postProcessing = this.scene.addComponent(PostProcessingComponent); + let post = postProcessing.addPost(FXAAPost); + // 2. 有post 的情况下,render 后立即触发 canvas resize,但无法触发画面reisze,必须得等e.g 200ms+ + // document.body.querySelector('canvas').setAttribute('style', 'width:100px') + } + + async initScene() { + { + this.lightObj = new Object3D(); + this.lightObj.rotationX = 45; + this.lightObj.rotationY = 110; + this.lightObj.rotationZ = 0; + let lc = this.lightObj.addComponent(DirectLight); + lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355); + lc.castShadow = true; + lc.intensity = 10; + this.scene.addChild(this.lightObj); + } + + { + let mat = new LitMaterial(); + mat.roughness = 1.0; + mat.metallic = 0.1; + + let floor = new Object3D(); + let mr = floor.addComponent(MeshRenderer); + mr.geometry = new PlaneGeometry(400, 400); + mr.material = mat; + this.scene.addChild(floor); + + { + let wall = new Object3D(); + let mr = wall.addComponent(MeshRenderer); + mr.geometry = new BoxGeometry(5, 260, 320); + mr.material = mat; + wall.x = -320 * 0.5; + this.scene.addChild(wall); + } + + { + let wall = new Object3D(); + let mr = wall.addComponent(MeshRenderer); + mr.geometry = new BoxGeometry(5, 260, 320); + mr.material = mat; + wall.x = 320 * 0.5; + this.scene.addChild(wall); + } + + { + let wall = new Object3D(); + let mr = wall.addComponent(MeshRenderer); + mr.geometry = new BoxGeometry(320, 260, 5); + mr.material = mat; + wall.z = -320 * 0.5; + this.scene.addChild(wall); + } + + { + { + let litMat = new LitMaterial(); + litMat.emissiveColor = new Color(0.0, 0.0, 1.0); + litMat.emissiveIntensity = 1.8; + let sp = new Object3D(); + let mr = sp.addComponent(MeshRenderer); + mr.geometry = new SphereGeometry(15, 30, 30); + mr.material = litMat; + sp.x = 68; + sp.y = 15; + sp.z = -15; + this.scene.addChild(sp); + } + + { + let litMat = new LitMaterial(); + litMat.emissiveColor = new Color(1.0, 1.0, 0.0); + litMat.emissiveIntensity = 1.2; + let sp = new Object3D(); + let mr = sp.addComponent(MeshRenderer); + mr.geometry = new SphereGeometry(15, 30, 30); + mr.material = litMat; + sp.x = 1; + sp.y = 15; + sp.z = -8; + this.scene.addChild(sp); + } + } + } + } +} + +new Sample_Bloom().run(); diff --git a/samples/post/Sample_GodRay.ts b/samples/post/Sample_GodRay.ts index fc920bec..f8bdebbb 100644 --- a/samples/post/Sample_GodRay.ts +++ b/samples/post/Sample_GodRay.ts @@ -36,10 +36,11 @@ class Sample_GodRay { Engine3D.startRenderView(view); let postProcessing = this.scene.addComponent(PostProcessingComponent); - postProcessing.addPost(GodRayPost); + let godRay = postProcessing.addPost(GodRayPost); postProcessing.addPost(BloomPost); GUIUtil.renderAtmosphericSky(sky, false); + GUIUtil.renderGodRay(godRay); } async initScene() { { @@ -52,12 +53,13 @@ class Sample_GodRay { lc.castShadow = true; lc.intensity = 20; this.scene.addChild(this.lightObj); - GUIUtil.renderDirLight(lc); + GUIUtil.renderDirLight(lc, false); } { let mat = new LitMaterial(); - + mat.roughness = 0.5; + mat.metallic = 0.2; let floor = new Object3D(); let mr = floor.addComponent(MeshRenderer); mr.geometry = new PlaneGeometry(2000, 2000); diff --git a/samples/post/Sample_Outline.ts b/samples/post/Sample_Outline.ts new file mode 100644 index 00000000..78917c56 --- /dev/null +++ b/samples/post/Sample_Outline.ts @@ -0,0 +1,119 @@ +import { DirectLight, Engine3D, View3D, LitMaterial, HoverCameraController, KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, PostProcessingComponent, CameraUtil, webGPUContext, OutlinePost, outlinePostManager, AtmosphericComponent, Color, FXAAPost } from '@orillusion/core' +import * as dat from '@orillusion/debug/dat.gui.module' + +class Sample_Outline { + lightObj: Object3D + scene: Scene3D + + constructor() { } + + async run() { + Engine3D.setting.shadow.enable = false + await Engine3D.init({ + canvasConfig: { + devicePixelRatio: 1 + } + }) + + this.scene = new Scene3D() + this.scene.addComponent(AtmosphericComponent).sunY = 0.6 + + let mainCamera = CameraUtil.createCamera3DObject(this.scene, 'camera') + mainCamera.perspective(60, webGPUContext.aspect, 1, 2000.0) + let ctrl = mainCamera.object3D.addComponent(HoverCameraController) + ctrl.setCamera(180, -45, 15) + + await this.initScene(this.scene) + + let view = new View3D() + view.scene = this.scene + view.camera = mainCamera + Engine3D.startRenderView(view) + + let postProcessing = this.scene.addComponent(PostProcessingComponent) + // let outlinePost = postProcessing.addPost(FXAAPost) + let outlinePost = postProcessing.addPost(OutlinePost) + + const GUIHelp = new dat.GUI() + GUIHelp.addFolder('Outline') + GUIHelp.add(outlinePost, 'outlinePixel', 0, 5) + GUIHelp.add(outlinePost, 'fadeOutlinePixel', 0, 5) + GUIHelp.add( + { + Change: () => { + this.selectBall() + } + }, + 'Change' + ) + this.selectBall() + } + + private selectBall(): void { + outlinePostManager.setOutlineList([[this.nextSphere()], [this.nextSphere()], [this.nextSphere()]], [new Color(1, 0.2, 0, 1), new Color(0.2, 1, 0), new Color(0.2, 0, 1)]) + } + + async initScene(scene: Scene3D) { + /******** light *******/ + { + this.lightObj = new Object3D() + this.lightObj.x = 0 + this.lightObj.y = 30 + this.lightObj.z = -40 + this.lightObj.rotationX = 45 + this.lightObj.rotationY = 0 + this.lightObj.rotationZ = 45 + let lc = this.lightObj.addComponent(DirectLight) + lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355) + lc.intensity = 10 + scene.addChild(this.lightObj) + } + this.createPlane(scene) + + return true + } + + private sphereList: Object3D[] = [] + private sphereIndex = 0 + + private nextSphere(): Object3D { + this.sphereIndex++ + if (this.sphereIndex >= this.sphereList.length) { + this.sphereIndex = 1 + } + + return this.sphereList[this.sphereIndex] + } + + private createPlane(scene: Scene3D) { + let mat = new LitMaterial() + mat.roughness = 0.5; + mat.metallic = 0.5; + { + let debugGeo = new PlaneGeometry(1000, 1000) + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = mat + mr.geometry = debugGeo + scene.addChild(obj) + } + + let sphereGeometry = new SphereGeometry(1, 50, 50) + for (let i = 0; i < 10; i++) { + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = mat + mr.geometry = sphereGeometry + obj.x = 2 + obj.y = 2 + + let angle = (2 * Math.PI * i) / 10 + obj.x = Math.sin(angle) * 2 + obj.z = Math.cos(angle) * 2 + scene.addChild(obj) + this.sphereList.push(obj) + } + } +} + +new Sample_Outline().run() diff --git a/samples/post/Sample_SSR.ts b/samples/post/Sample_SSR.ts new file mode 100644 index 00000000..0d08b9e7 --- /dev/null +++ b/samples/post/Sample_SSR.ts @@ -0,0 +1,128 @@ +import { DirectLight, Engine3D, View3D, LitMaterial, HoverCameraController, KelvinUtil, MeshRenderer, Object3D, PlaneGeometry, Scene3D, SphereGeometry, SSRPost, Time, CameraUtil, webGPUContext, PostProcessingComponent, BloomPost, AtmosphericComponent } from '@orillusion/core' +import * as dat from '@orillusion/debug/dat.gui.module' + +class Sample_SSR { + lightObj: Object3D + scene: Scene3D + mats: any[] + + constructor() { } + + async run() { + Engine3D.setting.shadow.enable = true + await Engine3D.init({ + canvasConfig: { + devicePixelRatio: 1 + }, + renderLoop: () => this.loop() + }) + + this.scene = new Scene3D() + this.scene.addComponent(AtmosphericComponent).sunY = 0.6 + + let mainCamera = CameraUtil.createCamera3DObject(this.scene, 'camera') + mainCamera.perspective(60, webGPUContext.aspect, 1, 2000.0) + let ctrl = mainCamera.object3D.addComponent(HoverCameraController) + ctrl.setCamera(180, -5, 60) + await this.initScene(this.scene) + + let view = new View3D() + view.scene = this.scene + view.camera = mainCamera + Engine3D.startRenderView(view) + + let postProcessing = this.scene.addComponent(PostProcessingComponent) + postProcessing.addPost(SSRPost) + postProcessing.addPost(BloomPost) + } + + async initScene(scene: Scene3D) { + /******** light *******/ + { + this.lightObj = new Object3D() + this.lightObj.rotationX = 15 + this.lightObj.rotationY = 110 + this.lightObj.rotationZ = 0 + let lc = this.lightObj.addComponent(DirectLight) + lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355) + lc.castShadow = true + lc.intensity = 27 + scene.addChild(this.lightObj) + } + + // load test model + let minimalObj = await Engine3D.res.loadGltf('/PBR/ToyCar/ToyCar.gltf') + minimalObj.scaleX = minimalObj.scaleY = minimalObj.scaleZ = 1000 + scene.addChild(minimalObj) + + await this.createPlane(scene) + return true + } + + private sphere: Object3D + + private async createPlane(scene: Scene3D) { + let mat = new LitMaterial() + mat.roughness = 0.2 + mat.metallic = 0.5 + + { + let floorMaterial = new LitMaterial() + floorMaterial.roughness = 0.5 + floorMaterial.metallic = 0.5 + + let planeGeometry = new PlaneGeometry(200, 200) + let floor: Object3D = new Object3D() + let mr = floor.addComponent(MeshRenderer) + mr.material = floorMaterial + mr.geometry = planeGeometry + scene.addChild(floor) + + const GUIHelp = new dat.GUI() + GUIHelp.add(floorMaterial, 'roughness', 0, 1, 0.01) + GUIHelp.add(floorMaterial, 'metallic', 0, 1, 0.01) + } + + { + let sphereGeometry = new SphereGeometry(10, 50, 50) + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = mat + mr.geometry = sphereGeometry + obj.x = 30 + obj.y = 10 + scene.addChild(obj) + this.sphere = obj + } + + { + let sphereGeometry = new SphereGeometry(2, 50, 50) + for (let i = 0; i < 10; i += 2) { + for (let j = 0; j < 10; j += 2) { + let rmMaterial = new LitMaterial() + rmMaterial.roughness = j / 10 + rmMaterial.metallic = i / 10 + + let obj: Object3D = new Object3D() + let mr = obj.addComponent(MeshRenderer) + mr.material = rmMaterial + mr.geometry = sphereGeometry + + obj.y = j * 5 + 10 + obj.x = 50 + obj.z = i * 5 - 25 + scene.addChild(obj) + } + } + } + } + + private loop(): void { + if (this.sphere) { + this.sphere.x = Math.sin(Time.time * 0.0001) * 30 + this.sphere.z = Math.cos(Time.time * 0.0001) * 30 + } + } +} + +new Sample_SSR().run() diff --git a/samples/utils/GUIUtil.ts b/samples/utils/GUIUtil.ts index 64afaa3d..cb0b56c3 100644 --- a/samples/utils/GUIUtil.ts +++ b/samples/utils/GUIUtil.ts @@ -1,10 +1,12 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { AnimatorComponent, AtmosphericComponent, BillboardType, BlendMode, BloomPost, Color, DirectLight, Engine3D, GPUCullMode, GTAOPost, GlobalFog, GlobalIlluminationComponent, LitMaterial, Material, MorphTargetBlender, Object3D, PointLight, SkinnedMeshRenderer2, SpotLight, Transform, UIImage, UIPanel, UIShadow, View3D } from "@orillusion/core"; +import { AnimatorComponent, AtmosphericComponent, BillboardType, BlendMode, BloomPost, Color, DepthOfFieldPost, DirectLight, Engine3D, GPUCullMode, GTAOPost, GlobalFog, GlobalIlluminationComponent, GodRayPost, LitMaterial, Material, MorphTargetBlender, Object3D, PointLight, SkinnedMeshRenderer2, SpotLight, Transform, UIImage, UIPanel, UIShadow, View3D } from "@orillusion/core"; import { UVMoveComponent } from "@samples/material/script/UVMoveComponent"; export class GUIUtil { + + public static renderShadowSetting(open: boolean = true) { GUIHelp.addFolder('ShadowSetting'); let setting = Engine3D.setting.shadow; @@ -89,6 +91,17 @@ export class GUIUtil { GUIHelp.endFolder(); } + static renderGodRay(godRay: GodRayPost, open: boolean = true, name?: string) { + name ||= 'GodRay'; + GUIHelp.addFolder(name); + GUIHelp.add(godRay, 'blendColor'); + GUIHelp.add(godRay, 'rayMarchCount', 8, 20, 1); + GUIHelp.add(godRay, 'scatteringExponent', 1, 40, 1); + GUIHelp.add(godRay, 'intensity', 0.01, 5, 0.001); + open && GUIHelp.open(); + GUIHelp.endFolder(); + } + public static renderVector3(obj: Object3D, open: boolean = true, name?: string) { name ||= 'Vector3'; GUIHelp.addFolder(name); @@ -536,4 +549,12 @@ export class GUIUtil { GUIHelp.add(post, "multiBounce"); GUIHelp.endFolder(); } + + static renderDepthOfField(post: DepthOfFieldPost) { + GUIHelp.addFolder("DOFPost"); + GUIHelp.add(post, 'near', 0, 100, 1) + GUIHelp.add(post, 'far', 150, 300, 1) + GUIHelp.add(post, 'pixelOffset', 0.0, 15, 1) + GUIHelp.endFolder(); + } } \ No newline at end of file diff --git a/src/Engine3D.ts b/src/Engine3D.ts index 609c9878..d04f92e6 100644 --- a/src/Engine3D.ts +++ b/src/Engine3D.ts @@ -25,7 +25,6 @@ import { WasmMatrix } from '@orillusion/wasm-matrix/WasmMatrix'; import { Matrix4 } from './math/Matrix4'; import { FXAAPost } from './gfx/renderJob/post/FXAAPost'; import { PostProcessingComponent } from './components/post/PostProcessingComponent'; -import { Texture } from './gfx/graphics/webGpu/core/texture/Texture'; /** * Orillusion 3D Engine @@ -169,6 +168,12 @@ export class Engine3D { scatteringExponent: 2.7, dirHeightLine: 10.0, }, + godRay: { + blendColor: true, + rayMarchCount: 16, + scatteringExponent: 5, + intensity: 0.5 + }, ssao: { enable: false, radius: 0.15, @@ -308,12 +313,15 @@ export class Engine3D { public static async init(descriptor: { canvasConfig?: CanvasConfig; beforeRender?: Function; renderLoop?: Function; lateRender?: Function, engineSetting?: EngineSetting } = {}) { console.log('Engine Version', version); - this.divB = document.createElement("div"); - this.divB.style.position = 'absolute' - this.divB.style.zIndex = '999' - this.divB.style.color = '#FFFFFF' - this.divB.style.top = '150px' - document.body.appendChild(this.divB); + // for dev debug + if (import.meta.env.DEV) { + this.divB = document.createElement("div"); + this.divB.style.position = 'absolute' + this.divB.style.zIndex = '999' + this.divB.style.color = '#FFFFFF' + this.divB.style.top = '150px' + document.body.appendChild(this.divB); + } this.setting = { ...this.setting, ...descriptor.engineSetting } @@ -355,11 +363,11 @@ export class Engine3D { this.renderJobs.set(view, renderJob); let presentationSize = webGPUContext.presentationSize; // RTResourceMap.createRTTexture(RTResourceConfig.colorBufferTex_NAME, presentationSize[0], presentationSize[1], GPUTextureFormat.rgba16float, false); - + if (this.setting.pick.mode == `pixel`) { let postProcessing = view.scene.getOrAddComponent(PostProcessingComponent); postProcessing.addPost(FXAAPost); - + } else { } @@ -431,9 +439,6 @@ export class Engine3D { * @internal */ private static render(time) { - webGPUContext.updateSize(); - Texture.destroyTexture(); - this._deltaTime = time - this._time; this._time = time; @@ -568,7 +573,6 @@ export class Engine3D { } if (this._lateRender) this._lateRender(); - } diff --git a/src/assets/shader/compute/BloomEffect_cs.ts b/src/assets/shader/compute/BloomEffect_cs.ts index 36b4e3d7..e5029fa0 100644 --- a/src/assets/shader/compute/BloomEffect_cs.ts +++ b/src/assets/shader/compute/BloomEffect_cs.ts @@ -12,6 +12,17 @@ struct BloomCfg{ } @group(0) @binding(0) var bloomCfg: BloomCfg; ` + +let CalcUV_01 = /*wgsl*/ ` + fn CalcUV_01(coord:vec2, texSize:vec2) -> vec2 + { + let u = (f32(coord.x) + 0.5) / f32(texSize.x); + let v = (f32(coord.y) + 0.5) / f32(texSize.y); + return vec2(u, v); + } + +` + //_______________calc weight let GaussWeight2D: string = /*wgsl*/ ` @@ -106,6 +117,7 @@ var fragCoord: vec2; ${GaussWeight2D} ${GaussBlur('GaussNxN', 'inTex', 'inTexSampler')} +${CalcUV_01} @compute @workgroup_size( 8 , 8 , 1 ) fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) @@ -116,7 +128,7 @@ fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_inv return; } var color = vec4(0.0, 0.0, 0.0, 1.0); - var uv = vec2(f32(fragCoord.x), f32(fragCoord.y)) / vec2(f32(texSize.x - 1), f32(texSize.y -1)); + var uv = CalcUV_01(fragCoord, texSize); let stride = vec2(1.0) / vec2(f32(texSize.x), f32(texSize.y)); // texel size of last level let rgb = GaussNxN(uv, i32(bloomCfg.downSampleBlurSize), stride, bloomCfg.downSampleBlurSigma); color = vec4(rgb, color.w); @@ -141,6 +153,7 @@ var fragCoord: vec2; ${GaussWeight2D} ${GaussBlur('GaussNxN_0', '_MainTex', '_MainTexSampler')} ${GaussBlur('GaussNxN_1', '_PrevMip', '_PrevMipSampler')} +${CalcUV_01} @compute @workgroup_size( 8 , 8 , 1 ) fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) @@ -151,14 +164,15 @@ fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_inv return; } var color = vec4(0.0, 0.0, 0.0, 1.0); - var uv = vec2(f32(fragCoord.x), f32(fragCoord.y)) / vec2(f32(texSize.x - 1), f32(texSize.y -1)); + var uv = CalcUV_01(fragCoord, texSize); + // half stride let prev_stride = vec2(0.5) / vec2(f32(texSize.x), f32(texSize.y)); let curr_stride = vec2(1.0) / vec2(f32(texSize.x), f32(texSize.y)); - let rgb1 = GaussNxN_0(uv, i32(bloomCfg.upSampleBlurSize), prev_stride, bloomCfg.upSampleBlurSigma); - let rgb2 = GaussNxN_1(uv, i32(bloomCfg.upSampleBlurSize), curr_stride, bloomCfg.upSampleBlurSigma); - color = vec4(rgb1+rgb2, color.w); + let rgb1 = GaussNxN_1(uv, i32(bloomCfg.upSampleBlurSize), prev_stride, bloomCfg.upSampleBlurSigma); + let rgb2 = GaussNxN_0(uv, i32(bloomCfg.upSampleBlurSize), curr_stride, bloomCfg.upSampleBlurSigma); + color = vec4(rgb1 + rgb2, color.w); textureStore(outTex, fragCoord, color); } ` @@ -167,6 +181,7 @@ fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_inv //__________________________blend export let post = /*wgsl*/ ` ${BloomCfg} +${CalcUV_01} @group(0) @binding(1) var _MainTex : texture_2d; @group(0) @binding(2) var _BloomTex : texture_2d; @@ -198,9 +213,7 @@ fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_inv return; } var color = textureLoad(_MainTex, fragCoord, 0); - let uv = vec2(f32(fragCoord.x), f32(fragCoord.y)) / vec2(f32(texSize.x - 1), f32(texSize.y - 1)); - - // var bloom = textureLoad(_BloomTex, fragCoord, 0).xyz; + var uv = CalcUV_01(fragCoord, texSize); var bloom = textureSampleLevel(_BloomTex, _BloomTexSampler, uv, 0.0).xyz * bloomCfg.bloomIntensity; // tone map diff --git a/src/assets/shader/compute/DDGILighting_CSShader.ts b/src/assets/shader/compute/DDGILighting_CSShader.ts index e650ee67..585e4b3e 100644 --- a/src/assets/shader/compute/DDGILighting_CSShader.ts +++ b/src/assets/shader/compute/DDGILighting_CSShader.ts @@ -82,24 +82,19 @@ var wNormal:vec3; const LUMEN = 10.764; -fn samplePosition(uv:vec2) -> vec4 +fn samplePosition(uv:vec2) -> vec4 { - var oc1:vec4 = textureSampleLevel(positionMap, positionMapSampler, vec2(0.0), 0.0); - var oc:vec4 = textureLoad(positionMap, uv, 0) ; - return oc; + return textureSampleLevel(positionMap, positionMapSampler,uv, 0.0); } -fn sampleNormal(uv:vec2) -> vec4 +fn sampleNormal(uv:vec2) -> vec4 { - var oc1:vec4 = textureSampleLevel(normalMap, normalMapSampler, vec2(0.0), 0.0); - var oc:vec4 = textureLoad(normalMap, uv, 0); - return oc; + return textureSampleLevel(normalMap, normalMapSampler, uv, 0.0); } -fn sampleColor(uv:vec2) -> vec4 +fn sampleColor(uv:vec2) -> vec4 { - var oc1:vec4 = textureSampleLevel(colorMap, colorMapSampler, vec2(0.0), 0.0); - var oc:vec4 = textureLoad(colorMap, uv, 0); + var oc:vec4 = textureSampleLevel(colorMap, colorMapSampler, uv, 0.0); ulitColor = vec3(oc.xyz); return oc; } @@ -245,14 +240,21 @@ fn spotLight( albedo:vec3,WP:vec3, N:vec3, V:vec3, light:Lig return color ; } -fn coordFun(fragCoord:vec2)-> vec4{ - var uv = vec2(i32(fragCoord.x), i32(fragCoord.y)) ; - var pos = samplePosition(uv); +fn CalcUV_01(coord:vec2, texSize:vec2) -> vec2 +{ + let u = (f32(coord.x) + 0.5) / f32(texSize.x); + let v = (f32(coord.y) + 0.5) / f32(texSize.y); + return vec2(u, v); +} + +fn coordFun(fragCoord:vec2)-> vec4{ + let uv_01 = CalcUV_01(fragCoord, texSize); + var pos = samplePosition(uv_01); - var normalMap = sampleNormal(uv); + var normalMap = sampleNormal(uv_01); var normal = normalize( normalMap.xyz * 2.0 - 1.0 ); - var color = sampleColor(uv); + var color = sampleColor(uv_01); var emissive = vec4(pos.a,normalMap.a,color.a,0.0) * 1.0 ; if(pos.w + 1.0 > 10000.0){ return vec4(color); @@ -305,14 +307,16 @@ fn coordFun(fragCoord:vec2)-> vec4{ // return fragPosition; // } +var texSize: vec2; + @compute @workgroup_size( 8 , 8 , 1 ) fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) { - var fragCoord = vec2( globalInvocation_id.x, globalInvocation_id.y); + var fragCoord = vec2(globalInvocation_id.xy); + texSize = textureDimensions(colorMap).xy; var color = coordFun(fragCoord); - // color = vec4(pow(color.rgb,vec3(1.0/2.4)),1.0); - textureStore(outputBuffer, vec2(fragCoord),color); + textureStore(outputBuffer, fragCoord, color); } ` \ No newline at end of file diff --git a/src/assets/shader/compute/DepthOfView_cs.ts b/src/assets/shader/compute/DepthOfView_cs.ts index 1b8dc97e..f3b9c499 100644 --- a/src/assets/shader/compute/DepthOfView_cs.ts +++ b/src/assets/shader/compute/DepthOfView_cs.ts @@ -6,10 +6,8 @@ export let DepthOfView_cs: string = /*wgsl*/ ` far: f32, pixelOffset: f32, } - - @group(0) @binding(0) var standUniform: GlobalUniform; + @group(0) @binding(1) var blurSetting: BlurSetting; - @group(0) @binding(2) var positionBufferTex : texture_2d; @group(0) @binding(3) var normalBufferTex : texture_2d; @group(0) @binding(4) var inTexSampler : sampler; @@ -30,7 +28,7 @@ export let DepthOfView_cs: string = /*wgsl*/ ` if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ return; } - cameraPosition = vec3(standUniform.cameraWorldMatrix[3].xyz); + cameraPosition = globalUniform.CameraPos.xyz ; let wPosition:vec3 = textureLoad(positionBufferTex, fragCoord , 0).xyz; var distance = length(wPosition - cameraPosition); var oc:vec4 = textureLoad(inTex, fragCoord, 0); diff --git a/src/assets/shader/compute/OutLineBlendColor_cs.ts b/src/assets/shader/compute/OutLineBlendColor_cs.ts index 117734e7..4661a55d 100644 --- a/src/assets/shader/compute/OutLineBlendColor_cs.ts +++ b/src/assets/shader/compute/OutLineBlendColor_cs.ts @@ -19,6 +19,14 @@ export let OutLineBlendColor_cs: string = /*wgsl*/ ` var texSize: vec2; var fragCoord: vec2; + + fn CalcUV_01(coord:vec2, texSize:vec2) -> vec2 + { + let u = (f32(coord.x) + 0.5) / f32(texSize.x); + let v = (f32(coord.y) + 0.5) / f32(texSize.y); + return vec2(u, v); + } + @compute @workgroup_size( 8 , 8 , 1 ) fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) { @@ -28,10 +36,7 @@ export let OutLineBlendColor_cs: string = /*wgsl*/ ` return; } - var uv01 = vec2(fragCoord) / (vec2(texSize) - 1.0); - var offset = vec2(texSize) / vec2(outlineSetting.lowTexWidth, outlineSetting.lowTexHeight); - offset = 0.5 * offset / (vec2(texSize) - 1.0); - uv01 += offset; + let uv01 = CalcUV_01(fragCoord, texSize); var outLineColor = textureSampleLevel(lowTex, lowTexSampler, uv01, 0.0); outLineColor.x *= outlineSetting.strength; diff --git a/src/assets/shader/compute/SSR_BlendColor_cs.ts b/src/assets/shader/compute/SSR_BlendColor_cs.ts index d66af8b2..cd1b6340 100644 --- a/src/assets/shader/compute/SSR_BlendColor_cs.ts +++ b/src/assets/shader/compute/SSR_BlendColor_cs.ts @@ -18,6 +18,14 @@ export let SSR_BlendColor_cs: string = /*wgsl*/ ` alpha:f32, fresnel:f32, } + + fn CalcUV_01(coord:vec2, texSize:vec2) -> vec2 + { + let u = (f32(coord.x) + 0.5) / f32(texSize.x); + let v = (f32(coord.y) + 0.5) / f32(texSize.y); + return vec2(u, v); + } + @compute @workgroup_size( 8 , 8 , 1 ) fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) @@ -33,8 +41,7 @@ export let SSR_BlendColor_cs: string = /*wgsl*/ ` let index = ssrCoord.x + ssrCoord.y * i32(ssrTexSize.x); let hitData = rayTraceBuffer[index]; var color = textureLoad(colorMap, fragCoord , 0); - var uv01 = vec2(f32(fragCoord.x), f32(fragCoord.y)); - uv01 = uv01 / vec2(colorTexSize - 1); + var uv01 = CalcUV_01(fragCoord, colorTexSize); var ssrColor = textureSampleLevel(ssrMap, ssrMapSampler, uv01, 0.0); var tc = mix(color, ssrColor, hitData.fresnel) ; diff --git a/src/assets/shader/core/common/GlobalUniform.ts b/src/assets/shader/core/common/GlobalUniform.ts index 89750c83..825ebdf8 100644 --- a/src/assets/shader/core/common/GlobalUniform.ts +++ b/src/assets/shader/core/common/GlobalUniform.ts @@ -10,6 +10,8 @@ export let GlobalUniform: string = /*wgsl*/ ` shadowMatrix: array, 8u>, csmShadowBias: vec4, csmMatrix: array,${CSM.Cascades}>, + + shadowLights:mat4x4, CameraPos: vec3, frame: f32, @@ -49,7 +51,6 @@ export let GlobalUniform: string = /*wgsl*/ ` empty2: i32, empty3: i32, - shadowLights:mat4x4 }; @group(0) @binding(0) diff --git a/src/assets/shader/core/struct/VertexAttributeIndexShader.ts b/src/assets/shader/core/struct/VertexAttributeIndexShader.ts index 475785bf..92cb7336 100644 --- a/src/assets/shader/core/struct/VertexAttributeIndexShader.ts +++ b/src/assets/shader/core/struct/VertexAttributeIndexShader.ts @@ -9,6 +9,8 @@ export let VertexAttributeIndexShader: string = /*wgsl*/ ` @location(2) uv: vec2, @location(3) TEXCOORD_1: vec2, @location(4) vIndex: f32, + @location(5) index2: f32, + } struct VertexOutput { diff --git a/src/assets/shader/graphic/GraphicFaceComput2.ts b/src/assets/shader/graphic/GraphicFaceComput2.ts new file mode 100644 index 00000000..31a9191e --- /dev/null +++ b/src/assets/shader/graphic/GraphicFaceComput2.ts @@ -0,0 +1,247 @@ +export let graphicFaceCompute2 = (segmentCode: number) => { + let code = /*wgsl*/` + #include "GlobalUniform" + struct VertexInfo{ + position:vec3f, + nx:f32, + ny:f32, + nz:f32, + uv_x:f32, + uv_y:f32, + uv2_x:f32, + uv2_y:f32, + index:f32, + index2:f32 + } + + struct GeometryInfo{ + index : u32 , + faceStart : u32 , + faceEnd : u32 , + faceCount : u32 , + } + + struct ShapeInfo{ + shapeIndex:f32, //face,poly,rectangle,line,cycle,,box,sphere + shapeType:f32, + width:f32, + height:f32, + pathCount:f32, + uSpeed:f32, + vSpeed:f32, + radiu:f32, + paths:array + } + + @group(0) @binding(1) var vertexBuffer : array; + // @group(0) @binding(2) var geometryInfoBuffer : array; + @group(0) @binding(2) var shapeBuffer : array; + // @group(0) @binding(3) var models : array>; + var shapeIndex:u32 ; + var segIndex:u32 ; + var segCount:u32 ; + var time:f32 ; + var shape:ShapeInfo ; + @compute @workgroup_size(256) + fn CsMain(@builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) global_invocation_id : vec3){ + shapeIndex = workgroup_id.x ; + segIndex = workgroup_id.y * 256u + global_invocation_id.x ; + shape = shapeBuffer[shapeIndex]; + segCount = u32(shape.pathCount -1.0); + // segIndex = 3u ; + if( segIndex < segCount ){ + time = globalUniform.time * 0.001; + let uv = vec2f(0.0,0.0); + // geometryInfoBuffer[0].index = 0; + switch (u32(shape.shapeType)) { + case 0u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + break; + } + case 1u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + // drawFace(1u,shape.paths[2].xyz,shape.paths[3].xyz,shape.paths[0].xyz,uv,uv,uv); + break; + } + case 2u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + // drawFace(1u,shape.paths[2].xyz,shape.paths[3].xyz,shape.paths[0].xyz,uv,uv,uv); + break; + } + case 3u:{ + // if(segIndex < u32(shape.pathCount)){ + drawLine(segIndex,shape,vec3f(0.0,1.0,0.0)); + // } + break; + } + default: + { + break; + } + } + } + } + + fn drawLine(segi:u32,shapeInfo:ShapeInfo,up:vec3f){ + if(segCount == 1u){ + drawPolyStartEnd(segi,shapeInfo,up); + }else{ + if(segi == 0u){ + let l0 = segi ; + let l1 = segi + 1u; + let l2 = segi + 2u; + genDir(l0,l1,l2,shapeInfo,up); + }else if(segi == (segCount -1u)){ + let l0 = segi - 1u; + let l1 = segi ; + let l2 = segi + 1u; + genDir2(l0,l1,l2,shapeInfo,up); + } + } + } + + fn genDir(l0:u32,l1:u32,l2:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let dc = normalize(d1 - d0) ; + + let sOe = dot(d0,dc); + let neg = dirNeg(sOe) ; + + let angle = acos(sOe) ; + let lc = shapeInfo.width / sin(angle) ; + + let right = cross( normalize(d0) , up ); + let first_l = -right * shapeInfo.width + p0; + let first_r = right * shapeInfo.width + p0; + + let end_l = lc * dc + p1 ; + // let end_l = -right * shapeInfo.width + p1; + let end_r = right * shapeInfo.width + p1; + // let end_r = lc * dc * 2.0 + p1; + + let uScale = 1.0 ; + let lVScale = length(end_l - first_l); + let rVScale = length(end_r - first_r); + + let u0 = vec2f(0.0,0.0) ;//* + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) ;//* + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale) ;//* + vec2f(0.0,1.0) /* vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale) ;//* + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(l0 * 2u + 0u,first_l,first_r,end_l,u0,u1,u3); + drawFace(l0 * 2u + 1u,first_r,end_r,end_l,u1,u2,u3); + } + + + fn genDir2(l0:u32,l1:u32,l2:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let dc = normalize(d1 - d0) ; + + let sOe = dot(d0,dc); + let neg = dirNeg(sOe) ; + + let angle = acos(sOe) ; + let lc = shapeInfo.width / sin(angle) ; + let offsetV = shapeInfo.width / tan(angle) * neg; + + let right = cross( normalize(d1) , up ); + let first_l = lc * dc + p1; + let first_r = right * shapeInfo.width + p1; + + let end_l = -right * shapeInfo.width + p2; + let end_r = right * shapeInfo.width + p2; + + let uScale = 1.0 ; + let lVScale = length(end_l - first_l) ; + let rVScale = length(end_r - first_r) ; + + let u0 = vec2f(0.0,0.0) ;//* + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0 - offsetV) ;//* + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale - offsetV) ;//* + vec2f(0.0,1.0) /* vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale) ;//* + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(l1 * 2u + 0u,first_l,first_r,end_l,u0,u1,u3); + drawFace(l1 * 2u + 1u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawPolyStartEnd(segi:u32,shapeInfo:ShapeInfo,up:vec3f){ + let firstSegi = segi ; + let endSegi = segi + 1u; + let nextSegi = segi + 2u; + + let p0 = shapeInfo.paths[firstSegi].xyz; + let p1 = shapeInfo.paths[endSegi].xyz; + // let p2 = shapeInfo.paths[nextSegi].xyz; + + let dir = p1 - p0 ; + let right = cross( normalize(dir) , up ); + let first_l = -right * shapeInfo.width + p0; + let first_r = right * shapeInfo.width + p0; + + let end_l = -right * shapeInfo.width + p1; + let end_r = right * shapeInfo.width + p1; + + let uScale = 1.0 ; + let vScale = length(dir); + + let u0 = vec2f(0.0,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,vScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,vScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(segi * 2u + 0u,first_l,first_r,end_l,u0,u1,u3); + drawFace(segi * 2u + 1u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawFace( fID:u32, v1:vec3f , v2:vec3f , v3:vec3f , u1:vec2f , u2:vec2f, u3:vec2f){ + let uv2 = vec2f(0.0,0.0); + let n = getNormal(v1,v2,v3); + writeVertexBuffer(fID*3u+0u,v1,n,u1,uv2); + writeVertexBuffer(fID*3u+1u,v2,n,u2,uv2); + writeVertexBuffer(fID*3u+2u,v3,n,u3,uv2); + } + + fn getNormal(v1:vec3f , v2:vec3f , v3:vec3f) -> vec3f{ + let p0 = v2 - v1 ; + let p1 = v3 - v2 ; + let n = cross(p0,p1); + return normalize(n); + } + + fn writeVertexBuffer( vID:u32 , pos:vec3f , normal:vec3f , uv:vec2f, uv2:vec2f ){ + vertexBuffer[vID].position = pos; + vertexBuffer[vID].nx = normal.x ; + vertexBuffer[vID].ny = normal.y ; + vertexBuffer[vID].nz = normal.z ; + vertexBuffer[vID].uv_x = uv.x ; + vertexBuffer[vID].uv_y = uv.y ; + vertexBuffer[vID].uv2_x = uv2.x ; + vertexBuffer[vID].uv2_y = uv2.y ; + vertexBuffer[vID].index = f32(0) ; + } + + fn dirNeg(cosO:f32) -> f32{ + var neg = 1.0 ; + if(cosO == 0.0){ + neg = 0.0 ; + }else if(cosO < 0.0){ + neg = -1.0 ; + } + return neg ; + } + + ` + return code; +} + + diff --git a/src/assets/shader/graphic/GraphicFaceCompute.ts b/src/assets/shader/graphic/GraphicFaceCompute.ts new file mode 100644 index 00000000..721bdc00 --- /dev/null +++ b/src/assets/shader/graphic/GraphicFaceCompute.ts @@ -0,0 +1,342 @@ +export let graphicFaceCompute = (segmentCode: number) => { + let code = /*wgsl*/` + #include "GlobalUniform" + struct VertexInfo{ + position:vec3f, + nx:f32, + ny:f32, + nz:f32, + uv_x:f32, + uv_y:f32, + uv2_x:f32, + uv2_y:f32, + index:f32, + index2:f32 + } + + struct GeometryInfo{ + index : u32 , + faceStart : u32 , + faceEnd : u32 , + faceCount : u32 , + } + + struct ShapeInfo{ + shapeIndex:f32, //face,poly,rectangle,line,cycle,,box,sphere + shapeType:f32, + width:f32, + height:f32, + pathCount:f32, + uSpeed:f32, + vSpeed:f32, + radiu:f32, + paths:array + } + + @group(0) @binding(1) var vertexBuffer : array; + // @group(0) @binding(2) var geometryInfoBuffer : array; + @group(0) @binding(2) var shapeBuffer : array; + // @group(0) @binding(3) var models : array>; + var shapeIndex:u32 ; + var segIndex:u32 ; + var segCount:u32 ; + var time:f32 ; + var shape:ShapeInfo ; + @compute @workgroup_size(256) + fn CsMain(@builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) global_invocation_id : vec3){ + shapeIndex = workgroup_id.x ; + segIndex = workgroup_id.y * 256u + global_invocation_id.x ; + shape = shapeBuffer[shapeIndex]; + segCount = u32(shape.pathCount -1.0); + // segIndex = 3u ; + if( segIndex < segCount ){ + time = globalUniform.time * 0.001; + let uv = vec2f(0.0,0.0); + // geometryInfoBuffer[0].index = 0; + switch (u32(shape.shapeType)) { + case 0u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + break; + } + case 1u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + // drawFace(1u,shape.paths[2].xyz,shape.paths[3].xyz,shape.paths[0].xyz,uv,uv,uv); + break; + } + case 2u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + // drawFace(1u,shape.paths[2].xyz,shape.paths[3].xyz,shape.paths[0].xyz,uv,uv,uv); + break; + } + case 3u:{ + // if(segIndex < u32(shape.pathCount)){ + drawLine(segIndex,shape,vec3f(0.0,1.0,0.0)); + // } + break; + } + default: + { + break; + } + } + } + } + + fn drawLine(segi:u32,shapeInfo:ShapeInfo,up:vec3f){ + if(segCount == 1u){ + drawPolyStartEnd(segi,shapeInfo,up); + }else{ + if(segi == (segCount -1u)){ + let l0 = segi - 1u; + let l1 = segi ; + let l2 = segi + 1u; + drawLineEnd(l0,l1,l2,shapeInfo,up); + }else if(segi == 0u){ + let l0 = segi ; + let l1 = segi + 1u; + let l2 = segi + 2u; + drawLineStart(l0,l1,l2,shapeInfo,up); + }else{ + let l0 = segi - 1u; + let l1 = segi ; + let l2 = segi + 1u; + let l3 = segi + 2u; + drawLineBody(l0,l1,l2,l3,shapeInfo,up); + } + } + } + + fn drawLineBody(l0:u32,l1:u32,l2:u32,l3:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + let p3 = shapeInfo.paths[l3].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let d2 = normalize(p3 - p2) ; + + let right0 = cross(d0 , d1) ; + let right1 = cross(d2 , d1) ; + + let dir0 = normalize(d1 - d0) ; + let dir1 = normalize(d2 - d1) ; + + // let lOr0 = dot(d0 , d3); + // let lOr1 = dot(d1 , d4); + + var angle0 = acos(dot(d0,dir0)) ; + var angle1 = acos(dot(d1,dir1)) ; + + if(angle0<0.0){ + angle0 *= -1.0 ; + } + if(angle1<0.0){ + angle1 *= -1.0 ; + } + + let lc0 = shapeInfo.width / sin(angle0) ; + let lc1 = shapeInfo.width / sin(angle1) ; + + var newP0 : vec3f ; + var newP1 : vec3f ; + var newP2 : vec3f ; + var newP3 : vec3f ; + var newP4 : vec3f ; + var newP5 : vec3f ; + + let d1Right = cross(d1,up); + let d2Right = cross(d2,up); + + newP0 = dir0 * lc0 + p1 ; + newP1 = -dir0 * lc0 + p1 ; + newP2 = dir1 * lc1 + p2 ; + newP3 = -dir1 * lc1 + p2 ; + + newP4 = -d2Right * shapeInfo.width + p2 ; + newP5 = -lc1 * dir1 + p2 ; + + let uScale = 1.0 ; + let lVScale = length(newP2 - newP0); + let rVScale = length(newP3 - newP1); + + let u0 = vec2f(0.0,0.0) - vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) - vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale)- vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale)- vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(l1 * 4u + 0u,newP0,newP1,newP2,u0,u1,u3); + // drawFace(l1 * 4u + 1u,newP0,newP2,newP3,u0,u1,u3); + + // drawFace(l1 * 4u + 2u,newP2,newP4,newP3,u1,u2,u3); + // drawFace(l1 * 4u + 3u,newP3,newP4,newP5,u1,u2,u3); + } + + fn drawLineStart(l0:u32,l1:u32,l2:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let dc = normalize(d1 - d0) ; + + let lOr = cross(d0 , d1).y; + let angle = acos(dot(d0,dc)) ; + let lc = shapeInfo.width / sin(angle) ; + + let nextRight = cross( normalize(d1) , up ); + let right = cross( normalize(d0) , up ); + let first_l = -right * shapeInfo.width + p0; + let first_r = right * shapeInfo.width + p0; + + var end_l:vec3f; + var end_r:vec3f; + var next:vec3f; + var outer:vec3f = p1 - lc * dc; + + if(lOr < 0.0){ + end_l = -right * shapeInfo.width + p1; + end_r = lc * dc + p1 ; + next = -nextRight * shapeInfo.width + p1 ; + }else{ + end_l = lc * dc + p1 ; + end_r = right * shapeInfo.width + p1 ; + next = nextRight * shapeInfo.width + p1 ; + } + + let uScale = 1.0 ; + let lVScale = length(end_l - first_l); + let rVScale = length(end_r - first_r); + + let u0 = vec2f(0.0,0.0) - vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) - vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale)- vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale)- vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(l0 * 4u + 0u,end_l,end_r,next,u0,u1,u3); + + if(lOr < 0.0){ + drawFace(l0 * 4u + 1u,outer,end_l,next,u0,u1,u3); + }else{ + drawFace(l0 * 4u + 1u,next,end_r,outer,u0,u1,u3); + } + + drawFace(l0 * 4u + 2u,first_l,first_r,end_l,u0,u1,u3); + drawFace(l0 * 4u + 3u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawLineEnd(l0:u32,l1:u32,l2:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let dc = normalize(d1 - d0) ; + + let lOr = cross(d0 , d1).y; + let angle = acos(dot(d0,dc)); + let lc = shapeInfo.width / sin(angle) ; + let offsetV = shapeInfo.width / tan(angle) * (-lOr) ; + + let right = cross( normalize(d1) , up ); + + var first_l:vec3f; + var first_r:vec3f; + if(lOr<0.0){ + first_l = -right * shapeInfo.width + p1; + first_r = lc * dc + p1; + }else{ + first_l = lc * dc + p1; + first_r = right * shapeInfo.width + p1; + } + + let end_l = -right * shapeInfo.width + p2; + let end_r = right * shapeInfo.width + p2; + + let uScale = 1.0 ; + let lVScale = length(end_l - first_l) ; + let rVScale = length(end_r - first_r) ; + + let u0 = vec2f(0.0,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0 - offsetV) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale - offsetV) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + // drawFace(l2 * 3u + 0u,p1,first_r,first_l,u0,u1,u3); + drawFace(l2 * 4u + 1u,first_l,first_r,end_l,u0,u1,u3); + drawFace(l2 * 4u + 2u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawPolyStartEnd(segi:u32,shapeInfo:ShapeInfo,up:vec3f){ + let firstSegi = segi ; + let endSegi = segi + 1u; + let nextSegi = segi + 2u; + + let p0 = shapeInfo.paths[firstSegi].xyz; + let p1 = shapeInfo.paths[endSegi].xyz; + // let p2 = shapeInfo.paths[nextSegi].xyz; + + let dir = p1 - p0 ; + let right = cross( normalize(dir) , up ); + let first_l = -right * shapeInfo.width + p0; + let first_r = right * shapeInfo.width + p0; + + let end_l = -right * shapeInfo.width + p1; + let end_r = right * shapeInfo.width + p1; + + let uScale = 1.0 ; + let vScale = length(dir); + + let u0 = vec2f(0.0,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,vScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,vScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(segi * 2u + 0u,first_l,first_r,end_l,u0,u1,u3); + drawFace(segi * 2u + 1u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawFace(fID:u32, v1:vec3f , v2:vec3f , v3:vec3f , u1:vec2f , u2:vec2f, u3:vec2f){ + let uv2 = vec2f(0.0,0.0); + let n = getNormal(v1,v2,v3); + writeVertexBuffer(fID*3u+0u,v1,n,u1,uv2); + writeVertexBuffer(fID*3u+1u,v2,n,u2,uv2); + writeVertexBuffer(fID*3u+2u,v3,n,u3,uv2); + } + + fn getNormal(v1:vec3f , v2:vec3f , v3:vec3f) -> vec3f{ + let p0 = v2 - v1 ; + let p1 = v3 - v2 ; + let n = cross(p0,p1); + return normalize(n); + } + + fn writeVertexBuffer( vID:u32 , pos:vec3f , normal:vec3f , uv:vec2f, uv2:vec2f ){ + vertexBuffer[vID].position = pos; + vertexBuffer[vID].nx = normal.x ; + vertexBuffer[vID].ny = normal.y ; + vertexBuffer[vID].nz = normal.z ; + vertexBuffer[vID].uv_x = uv.x ; + vertexBuffer[vID].uv_y = uv.y ; + vertexBuffer[vID].uv2_x = uv2.x ; + vertexBuffer[vID].uv2_y = uv2.y ; + vertexBuffer[vID].index = f32(0) ; + } + + fn dirNeg(cosO:f32) -> f32{ + var neg = 1.0 ; + if(cosO == 0.0){ + neg = 0.0 ; + }else if(cosO < 0.0){ + neg = -1.0 ; + } + return neg ; + } + + ` + return code; +} + + diff --git a/src/assets/shader/graphic/GraphicFaceCompute3.ts b/src/assets/shader/graphic/GraphicFaceCompute3.ts new file mode 100644 index 00000000..04de8d71 --- /dev/null +++ b/src/assets/shader/graphic/GraphicFaceCompute3.ts @@ -0,0 +1,259 @@ +export let GraphicFaceCompute3 = (segmentCode: number) => { + let code = /*wgsl*/` + #include "GlobalUniform" + struct VertexInfo{ + position:vec3f, + nx:f32, + ny:f32, + nz:f32, + uv_x:f32, + uv_y:f32, + uv2_x:f32, + uv2_y:f32, + index:f32, + index2:f32 + } + + struct GeometryInfo{ + index : u32 , + faceStart : u32 , + faceEnd : u32 , + faceCount : u32 , + } + + struct ShapeInfo{ + shapeIndex:f32, //face,poly,rectangle,line,cycle,,box,sphere + shapeType:f32, + width:f32, + height:f32, + pathCount:f32, + uSpeed:f32, + vSpeed:f32, + radiu:f32, + paths:array + } + + @group(0) @binding(1) var vertexBuffer : array; + // @group(0) @binding(2) var geometryInfoBuffer : array; + @group(0) @binding(2) var shapeBuffer : array; + // @group(0) @binding(3) var models : array>; + var shapeIndex:u32 ; + var segIndex:u32 ; + var segCount:u32 ; + var time:f32 ; + var shape:ShapeInfo ; + @compute @workgroup_size(256) + fn CsMain(@builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) global_invocation_id : vec3){ + shapeIndex = workgroup_id.x ; + segIndex = workgroup_id.y * 256u + global_invocation_id.x ; + shape = shapeBuffer[shapeIndex]; + segCount = u32(shape.pathCount -1.0); + // segIndex = 3u ; + if( segIndex < segCount ){ + time = globalUniform.time * 0.001; + let uv = vec2f(0.0,0.0); + // geometryInfoBuffer[0].index = 0; + switch (u32(shape.shapeType)) { + case 0u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + break; + } + case 1u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + // drawFace(1u,shape.paths[2].xyz,shape.paths[3].xyz,shape.paths[0].xyz,uv,uv,uv); + break; + } + case 2u:{ + // drawFace(0u,shape.paths[0].xyz,shape.paths[1].xyz,shape.paths[2].xyz,uv,uv,uv); + // drawFace(1u,shape.paths[2].xyz,shape.paths[3].xyz,shape.paths[0].xyz,uv,uv,uv); + break; + } + case 3u:{ + // if(segIndex < u32(shape.pathCount)){ + drawLine(segIndex,shape,vec3f(0.0,1.0,0.0)); + // } + break; + } + default: + { + break; + } + } + } + } + + fn drawLine(segi:u32,shapeInfo:ShapeInfo,up:vec3f){ + if(segCount == 1u){ + drawPolyStartEnd(segi,shapeInfo,up); + }else{ + if(segi == 0u){ + let l0 = segi ; + let l1 = segi + 1u; + let l2 = segi + 2u; + drawLineStart(l0,l1,l2,shapeInfo,up); + }else if(segi == (segCount -1u)){ + let l0 = segi - 1u; + let l1 = segi ; + let l2 = segi + 1u; + drawLineEnd(l0,l1,l2,shapeInfo,up); + } + } + } + + fn drawLineStart(l0:u32,l1:u32,l2:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let dc = normalize(d1 - d0) ; + + let lOr = dirNeg(p2.x - p0.x); + let angle = acos(dot(d0,dc)) ; + let lc = shapeInfo.width / sin(angle) ; + + let right = cross( normalize(d0) , up ); + let first_l = -right * shapeInfo.width + p0; + let first_r = right * shapeInfo.width + p0; + + var end_l:vec3f; + var end_r:vec3f; + + if(lOr<0.0){ + end_l = -right * shapeInfo.width + p1; + end_r = lc * dc + p1 ; + }else{ + end_l = lc * dc + p1 ; + end_r = right * shapeInfo.width + p1 ; + } + + let uScale = 1.0 ; + let lVScale = length(end_l - first_l); + let rVScale = length(end_r - first_r); + + let u0 = vec2f(0.0,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(l0 * 3u + 0u,end_l,end_r,p1,u0,u1,u3); + drawFace(l0 * 3u + 1u,first_l,first_r,end_l,u0,u1,u3); + drawFace(l0 * 3u + 2u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawLineEnd(l0:u32,l1:u32,l2:u32,shapeInfo:ShapeInfo,up:vec3f){ + let p0 = shapeInfo.paths[l0].xyz; + let p1 = shapeInfo.paths[l1].xyz; + let p2 = shapeInfo.paths[l2].xyz; + + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + let dc = normalize(d1 - d0) ; + + let lOr = dirNeg(p2.x - p0.x); + + let angle = acos(dot(d0,dc)); + let lc = shapeInfo.width / sin(angle) ; + let offsetV = shapeInfo.width / tan(angle) * (-lOr) ; + + let right = cross( normalize(d1) , up ); + + var first_l:vec3f; + var first_r:vec3f; + if(lOr<0.0){ + first_l = -right * shapeInfo.width + p1; + first_r = lc * dc + p1; + }else{ + first_l = lc * dc + p1; + first_r = right * shapeInfo.width + p1; + } + + let end_l = -right * shapeInfo.width + p2; + let end_r = right * shapeInfo.width + p2; + + let uScale = 1.0 ; + let lVScale = length(end_l - first_l) ; + let rVScale = length(end_r - first_r) ; + + let u0 = vec2f(0.0,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0 - offsetV) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,rVScale - offsetV) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,lVScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(l2 * 3u + 0u,p1,first_r,first_l,u0,u1,u3); + drawFace(l2 * 3u + 1u,first_l,first_r,end_l,u0,u1,u3); + drawFace(l2 * 3u + 2u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawPolyStartEnd(segi:u32,shapeInfo:ShapeInfo,up:vec3f){ + let firstSegi = segi ; + let endSegi = segi + 1u; + let nextSegi = segi + 2u; + + let p0 = shapeInfo.paths[firstSegi].xyz; + let p1 = shapeInfo.paths[endSegi].xyz; + // let p2 = shapeInfo.paths[nextSegi].xyz; + + let dir = p1 - p0 ; + let right = cross( normalize(dir) , up ); + let first_l = -right * shapeInfo.width + p0; + let first_r = right * shapeInfo.width + p0; + + let end_l = -right * shapeInfo.width + p1; + let end_r = right * shapeInfo.width + p1; + + let uScale = 1.0 ; + let vScale = length(dir); + + let u0 = vec2f(0.0,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + let u1 = vec2f(uScale,0.0) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u2 = vec2f(uScale,vScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time; + let u3 = vec2f(0.0,vScale) + vec2f(0.0,1.0) * vec2f(shapeInfo.uSpeed,shapeInfo.vSpeed) * time ; + + drawFace(segi * 2u + 0u,first_l,first_r,end_l,u0,u1,u3); + drawFace(segi * 2u + 1u,first_r,end_r,end_l,u1,u2,u3); + } + + fn drawFace(fID:u32, v1:vec3f , v2:vec3f , v3:vec3f , u1:vec2f , u2:vec2f, u3:vec2f){ + let uv2 = vec2f(0.0,0.0); + let n = getNormal(v1,v2,v3); + writeVertexBuffer(fID*3u+0u,v1,n,u1,uv2); + writeVertexBuffer(fID*3u+1u,v2,n,u2,uv2); + writeVertexBuffer(fID*3u+2u,v3,n,u3,uv2); + } + + fn getNormal(v1:vec3f , v2:vec3f , v3:vec3f) -> vec3f{ + let p0 = v2 - v1 ; + let p1 = v3 - v2 ; + let n = cross(p0,p1); + return normalize(n); + } + + fn writeVertexBuffer( vID:u32 , pos:vec3f , normal:vec3f , uv:vec2f, uv2:vec2f ){ + vertexBuffer[vID].position = pos; + vertexBuffer[vID].nx = normal.x ; + vertexBuffer[vID].ny = normal.y ; + vertexBuffer[vID].nz = normal.z ; + vertexBuffer[vID].uv_x = uv.x ; + vertexBuffer[vID].uv_y = uv.y ; + vertexBuffer[vID].uv2_x = uv2.x ; + vertexBuffer[vID].uv2_y = uv2.y ; + vertexBuffer[vID].index = f32(0) ; + } + + fn dirNeg(cosO:f32) -> f32{ + var neg = 1.0 ; + if(cosO == 0.0){ + neg = 0.0 ; + }else if(cosO < 0.0){ + neg = -1.0 ; + } + return neg ; + } + + ` + return code; +} + + diff --git a/src/assets/shader/graphic/GraphicTrailCompute.ts b/src/assets/shader/graphic/GraphicTrailCompute.ts new file mode 100644 index 00000000..4bb75805 --- /dev/null +++ b/src/assets/shader/graphic/GraphicTrailCompute.ts @@ -0,0 +1,165 @@ +export let graphicTrailCompute = (segmentCode: number) => { + let code = /*wgsl*/` + #include "GlobalUniform" + struct VertexInfo{ + position:vec3f, + // px:f32, + // py:f32, + // pz:f32, + nx:f32, + ny:f32, + nz:f32, + uv_x:f32, + uv_y:f32, + uv2_x:f32, + uv2_y:f32, + index:f32, + index2:f32 + } + + struct TrailInfo{ + index : f32 , + segment : f32 , + visible : f32 , + width: f32, + + uv: vec4f, + + uvSpeed: vec2f, + smoothLine: f32, + faceMode: f32, + up: vec4f, + ids:array + } + + @group(0) @binding(1) var vertexBuffer : array; + @group(0) @binding(2) var trailBuffer : array; + @group(0) @binding(3) var models : array>; + + var time:f32; + var viewDir:vec3f; + + @compute @workgroup_size(256) + fn CsMain(@builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) global_invocation_id : vec3){ + let rID = workgroup_id.x ; + let trailInfo = trailBuffer[rID]; + let vLen = u32(trailInfo.segment+1.0) ; + let vID = global_invocation_id.x ; + + // if(vID < vLen ){ + time = globalUniform.time * 0.001; + var right:vec3f ; + + switch (u32(trailInfo.faceMode)) { + case 0u:{ + right = getRightByMode(vID,vLen,viewDir,trailInfo) ; + break; + } + case 1u:{ + right = vec3f(0.0,0.0,1.0) ; + break; + } + case 2u:{ + right = getRightByMode(vID,vLen,trailInfo.up.xyz,trailInfo) ; + break; + } + default:{ + break; + } + } + writeTOBuffer(rID,vID,vLen,right,trailInfo); + // } + } + + + + fn writeTOBuffer(rID:u32, vID:u32 , vLen:u32, right:vec3f , trailInfo:TrailInfo ){ + let i0 = (vID + (vLen * rID)) * 2u ; + let li = i0 + 0u ; + let ri = i0 + 1u ; + + let worldPos = models[i32(trailInfo.ids[vID])][3].xyz ; + let leftPos = worldPos - right.xyz * trailInfo.width ; + let rightPos = worldPos + right.xyz * trailInfo.width ; + + vertexBuffer[li].position = leftPos ; + vertexBuffer[ri].position = rightPos ; + + let uvS = time * trailInfo.uvSpeed ; + + vertexBuffer[li].uv_x = (trailInfo.uv.x) + uvS.x ; + vertexBuffer[ri].uv_x = (trailInfo.uv.z + trailInfo.uv.x) + uvS.x ; + + // var ld = 0.0 ; + // var rd = 0.0 ; + // if(vID>0u){ + // let vid0 = getVID(vID,vLen,rID); + // let vid1 = getVID(vID-1u,vLen,rID); + + // ld = distance( vertexBuffer[li].position , vertexBuffer[vid1.x].position ) ; + // rd = distance( vertexBuffer[ri].position , vertexBuffer[vid1.y].position ) ; + + // vertexBuffer[li].uv_y = vertexBuffer[vid1.x].uv_y + 1.0 / ld * 100.0 ;//+ uvS.y ; + // vertexBuffer[ri].uv_y = vertexBuffer[vid1.y].uv_y + 1.0 / rd * 100.0 ;//+ uvS.y ; + // }else{ + let v = (1.0 - f32(vID) / trailInfo.segment) * trailInfo.uv.w + trailInfo.uv.y; + vertexBuffer[li].uv_y = v + uvS.y ; + vertexBuffer[ri].uv_y = v + uvS.y ; + // } + } + + fn getRight(p0:vec3f,p1:vec3f,p2:vec3f,up:vec3f) -> vec3f { + let d0 = normalize(p1 - p0) ; + let d1 = normalize(p2 - p1) ; + // var a = dot(d0,d1) ; + // var ep = 0.0 ; + // if(a<0.0){ + // a = -a ; + // ep = 1.0/sin(a*0.25) ; + // }else if(a == 0.0){ + // ep = 1.414 ; + // }else{ + // ep = 1.0 ; + // } + let forward = normalize((d0 + d1)+ vec3f(0.000001,0.000001,0.000001)) ; + return normalize(cross(forward,up)) ;//* ep ; + } + + fn getVID(vID:u32,vLen:u32,rID:u32) -> vec2 { + let i0 = (vID + (vLen * rID)) * 2u ; + let li = i0 + 0u ; + let ri = i0 + 1u ; + return vec2(li,ri); + } + + fn getRightByMode( vID:u32 , vLen:u32, up:vec3f, trailInfo:TrailInfo ) -> vec3f{ + var right:vec3f; + if(vID==0u){ + // first + let sp0 = models[i32(trailInfo.ids[ 0 ])][3].xyz ; + let sp1 = models[i32(trailInfo.ids[ 1 ])][3].xyz ; + let firstFront = normalize(sp1 - sp0) ; + viewDir = -normalize(globalUniform.CameraPos.xyz - sp0) ; + right = normalize(cross(firstFront,viewDir)); + }else if( vID < (vLen-1) ){ + // body + let bp0 = models[i32(trailInfo.ids[vID-1])][3].xyz ; + let bp1 = models[i32(trailInfo.ids[vID])][3].xyz ; + let bp2 = models[i32(trailInfo.ids[vID+1])][3].xyz ; + viewDir = -normalize(globalUniform.CameraPos.xyz - bp1) ; + right = getRight(bp0,bp1,bp2,viewDir) ; + }else{ + // last + let ep0 = models[i32(trailInfo.ids[u32(trailInfo.segment)-1u])][3].xyz ; + let ep1 = models[i32(trailInfo.ids[u32(trailInfo.segment)])][3].xyz ; + let endFront = normalize(ep1 - ep0) ; + viewDir = -normalize(globalUniform.CameraPos.xyz - ep1) ; + right = normalize(cross(endFront,viewDir)); + } + return normalize(right) ; + } + ` + return code; +} + + diff --git a/src/assets/shader/lighting/BxDF_frag.ts b/src/assets/shader/lighting/BxDF_frag.ts index 5544a3b7..274b0a74 100644 --- a/src/assets/shader/lighting/BxDF_frag.ts +++ b/src/assets/shader/lighting/BxDF_frag.ts @@ -76,14 +76,18 @@ export let BxDF_frag: string = /*wgsl*/ ` switch (light.lightType) { case PointLightType: { specColor += pointLighting( fragData.Albedo.rgb,ORI_VertexVarying.vWorldPos.xyz,fragData.N,fragData.V,fragData.Roughness,fragData.Metallic,light) ; + break; } case DirectLightType: { specColor += directLighting( fragData.Albedo.rgb ,fragData.N,fragData.V,fragData.Roughness ,fragData.Metallic, light , globalUniform.shadowBias) ; + break; } case SpotLightType: { specColor += spotLighting( fragData.Albedo.rgb,ORI_VertexVarying.vWorldPos.xyz,fragData.N,fragData.V,fragData.Roughness,fragData.Metallic , light ) ; + break; } default: { + break; } } } diff --git a/src/assets/shader/math/MathShader.ts b/src/assets/shader/math/MathShader.ts index 20d3e8b4..4b8cbd4a 100644 --- a/src/assets/shader/math/MathShader.ts +++ b/src/assets/shader/math/MathShader.ts @@ -310,4 +310,5 @@ fn dir_to_faceId(pt:vec3) -> i32 { let yAxis = normalize(cross(zAxis, xAxis)); return mat3x3(xAxis, yAxis, zAxis); } + `; diff --git a/src/assets/shader/quad/Quad_shader.ts b/src/assets/shader/quad/Quad_shader.ts index 92c4af37..59327de2 100644 --- a/src/assets/shader/quad/Quad_shader.ts +++ b/src/assets/shader/quad/Quad_shader.ts @@ -50,17 +50,12 @@ export let Quad_vert_wgsl: string = /*wgsl*/ ` @vertex fn main(@builtin(instance_index) index : u32,@location(0) position: vec3, @location(1) TEXCOORD_1: vec2) -> VertexOutput { - let id = u32(index) ; - let worldMatrix = models.matrix[id]; - - let windowSize = vec2(globalUniform.windowWidth,globalUniform.windowHeight) ; - + // let id = u32(index) ; + // let worldMatrix = models.matrix[id]; + // let windowSize = vec2(globalUniform.windowWidth,globalUniform.windowHeight) ; // let pos = worldMatrix[3].xy ; - - let size = vec2(worldMatrix[0].x,worldMatrix[1].y) / windowSize ; - - let uv = vec2(((TEXCOORD_1.xy * 2.0) - vec2(1.0))) ;// / windowSize * size - offset ; - + // let size = vec2(worldMatrix[0].x,worldMatrix[1].y) / windowSize ; + let uv = vec2(((TEXCOORD_1.xy * 2.0) - vec2(1.0))) ;// / windowSize * size - offset ; return VertexOutput(TEXCOORD_1, vec4(uv, 0.0, 1.0)); } ` diff --git a/src/components/SkeletonAnimationComponent.ts b/src/components/SkeletonAnimationComponent.ts index d30e6b5f..3d8d63b0 100644 --- a/src/components/SkeletonAnimationComponent.ts +++ b/src/components/SkeletonAnimationComponent.ts @@ -12,7 +12,7 @@ import { SkeletonPose } from "./anim/skeletonAnim/SkeletonPose"; * skeleton animation * @group Animation */ -@RegisterComponent +@RegisterComponent(SkeletonAnimationComponent, 'SkeletonAnimationComponent') export class SkeletonAnimationComponent extends ComponentBase { /** * Whether it is playing diff --git a/src/components/anim/AnimatorComponent.ts b/src/components/anim/AnimatorComponent.ts index d03ae871..ce6f563b 100644 --- a/src/components/anim/AnimatorComponent.ts +++ b/src/components/anim/AnimatorComponent.ts @@ -4,7 +4,7 @@ import { PropertyAnimationClip } from "../../math/AnimationCurveClip"; import { RegisterComponent } from "../../util/SerializeDecoration"; import { ComponentBase } from "../ComponentBase"; -@RegisterComponent +@RegisterComponent(AnimatorComponent, 'AnimatorComponent') export class AnimatorComponent extends ComponentBase { public jointMatrixIndexTableBuffer: StorageGPUBuffer; public playBlendShapeLoop: boolean = false; diff --git a/src/components/gui/core/GUIGeometry.ts b/src/components/gui/core/GUIGeometry.ts index f8bec48a..09680922 100644 --- a/src/components/gui/core/GUIGeometry.ts +++ b/src/components/gui/core/GUIGeometry.ts @@ -47,6 +47,36 @@ export class GUIGeometry extends GeometryBase { this.maxQuadCount = max; } + updateSubGeometry(index: number, start: number, count: number) { + let geom = this.subGeometries[index]; + if (geom) { + let desc = geom.lodLevels[0]; + desc.indexStart = start; + desc.indexCount = count; + desc.index = index; + } else { + geom = this.addSubGeometry({ + indexStart: start, + indexCount: count, + vertexStart: 0, + vertexCount: 0, + firstStart: 0, + index: index, + topology: 0, + }); + } + return geom; + } + + resetSubGeometries() { + for (let item of this.subGeometries) { + let desc = item.lodLevels[0]; + desc.indexStart = 0; + desc.indexCount = 0; + desc.index = 0; + } + } + /** * the bounds will be set to infinity * @returns GUIGeometry @@ -59,7 +89,7 @@ export class GUIGeometry extends GeometryBase { return this; } - public get vPositionBuffer(): StorageGPUBuffer { + public getPositionBuffer(): StorageGPUBuffer { if (this._onPositionChange) { this._posAttribute.buffer.apply(); this._onPositionChange = false; @@ -67,7 +97,7 @@ export class GUIGeometry extends GeometryBase { return this._posAttribute.buffer; } - public get vSpriteBuffer(): StorageGPUBuffer { + public getSpriteBuffer(): StorageGPUBuffer { if (this._onSpriteChange) { this._spriteAttribute.buffer.apply(); this._onSpriteChange = false; @@ -75,7 +105,7 @@ export class GUIGeometry extends GeometryBase { return this._spriteAttribute.buffer; } - public get vColorBuffer(): StorageGPUBuffer { + public getColorBuffer(): StorageGPUBuffer { if (this._onColorChange) { this._colorAttribute.buffer.apply(); this._onColorChange = false; @@ -120,15 +150,8 @@ export class GUIGeometry extends GeometryBase { this.setAttribute(VertexAttributeName.uv, this._attributeUV); this.setAttribute(VertexAttributeName.vIndex, this._attributeVIndex); - this.addSubGeometry({ - indexStart: 0, - indexCount: this._faceIndexes.length, - vertexStart: 0, - vertexCount: 0, - firstStart: 0, - index: 0, - topology: 0, - }); + this.updateSubGeometry(0, 0, this._faceIndexes.length); + return this; } diff --git a/src/components/gui/core/GUIGeometryRebuild.ts b/src/components/gui/core/GUIGeometryRebuild.ts index 8407b2c2..32d7cb80 100644 --- a/src/components/gui/core/GUIGeometryRebuild.ts +++ b/src/components/gui/core/GUIGeometryRebuild.ts @@ -1,9 +1,12 @@ -import { GUIQuadAttrEnum, Object3D, UIPanel } from "../../.."; import { Texture } from "../../../gfx/graphics/webGpu/core/texture/Texture"; import { UITransform } from "../uiComponents/UITransform"; import { UIRenderAble } from "../uiComponents/UIRenderAble"; import { GUIQuad } from "./GUIQuad"; import { GUITexture } from "./GUITexture"; +import { UIPanel } from "../uiComponents/UIPanel"; +import { GUIQuadAttrEnum } from "./GUIDefine"; +import { Object3D } from "../../../core/entities/Object3D"; +import { GUIMaterial } from "./GUIMaterial"; /** * This class is responsible for performing the Geometry reconstruction work of the GUI @@ -22,33 +25,57 @@ export class GUIGeometryRebuild { * @returns Return the build result (the maximum number of textures supported by GUIMaterials for a single UIPanel is limited and cannot exceed the limit) */ public build(transforms: UITransform[], panel: UIPanel, forceUpdate: boolean): boolean { + let geometry = panel['_geometry']; + geometry.resetSubGeometries(); + let quadIndex = -1; - let texIndex = -1; + let texIndex = 0; + + let indexStart = 0; + let indexCount = 0; + let geometryIndex = 0; - this._textureMap.clear(); - this._textureList.length = 0; + let textureList = this._textureList; + let textureMap = this._textureMap; - let collectQuads = []; + function flushPanel() { + if (indexCount > 0) { + panel.updateDrawCallSegment(geometryIndex, indexStart, indexCount); + let material: GUIMaterial = panel['_uiRenderer']['materials'][geometryIndex] as any; + material.setTextures(textureList); + textureMap.clear(); + textureList.length = 0; + geometryIndex++; + indexStart += indexCount; + indexCount = 0; + texIndex = 0; + } + } + + textureMap.clear(); + textureList.length = 0; + + let collectQuads: GUIQuad[] = []; let zMax: number = panel.quadMaxCount - 1; - let needBreak: boolean; + for (let transform of transforms) { let needUpdateQuads = transform.needUpdateQuads; collectQuads.length = 0; const quads = this.collectQuads(transform.object3D, collectQuads); for (let quad of quads) { - quad.z = ++quadIndex; let textureSource = quad.sprite.guiTexture; - if (!this._textureMap.has(textureSource.staticId)) { - ++texIndex; - this._textureMap.set(textureSource.staticId, textureSource); + + if (!textureMap.has(textureSource.staticId)) { + if (texIndex == 7) flushPanel(); + + textureMap.set(textureSource.staticId, textureSource); textureSource.dynamicId = texIndex; - this._textureList[texIndex] = textureSource.texture; - if (texIndex > 7) { - console.warn('texture Count Exceeded the maximum limit of 7'); - break; - } + textureList[texIndex] = textureSource.texture; + texIndex += 1; } + quad.z = ++quadIndex; + indexCount += 6; if (quad.cacheTextureId != textureSource.dynamicId) { quad.dirtyAttributes = GUIQuadAttrEnum.MAX; quad.cacheTextureId = textureSource.dynamicId; @@ -62,21 +89,16 @@ export class GUIGeometryRebuild { quad.applyTransform(transform); } if (quad.dirtyAttributes) { - quad.writeToGeometry(panel['_geometry'], transform); + quad.writeToGeometry(geometry, transform); } if (quadIndex == zMax) { - needBreak = true; - break; + flushPanel(); + return true; } } - if (needBreak) { - break; - } } - - panel['_uiMaterial'].setTextures(this._textureList); - panel['_limitVertexCount'] = (quadIndex + 1) * 4; - return !needBreak; + flushPanel(); + return false; } private collectQuads(object3D: Object3D, list?: GUIQuad[]): GUIQuad[] { diff --git a/src/components/gui/core/GUIMaterial.ts b/src/components/gui/core/GUIMaterial.ts index ecf81945..24870765 100644 --- a/src/components/gui/core/GUIMaterial.ts +++ b/src/components/gui/core/GUIMaterial.ts @@ -37,8 +37,8 @@ export class GUIMaterial extends Material { colorPass.setUniformVector4('scissorRect', new Vector4()); colorPass.setUniformFloat('scissorCornerRadius', 0.0); colorPass.setUniformFloat('scissorFadeOutSize', 0.0); - colorPass.setUniformFloat('limitVertex', 0); colorPass.setUniformFloat('pixelRatio', 1); + colorPass.setUniformFloat('empty', 0); let shaderState = colorPass.shaderState; // shaderState.useZ = false; @@ -53,13 +53,6 @@ export class GUIMaterial extends Material { this.shader = newShader; } - /** - * Write effective vertex count (vertex index < vertexCount) - */ - public setLimitVertex(vertexCount: number) { - this.shader.setUniformFloat('limitVertex', vertexCount); - } - public setGUISolution(value: Vector2, pixelRatio: number) { this.shader.setUniformVector2('guiSolution', value); this.shader.setUniformFloat('pixelRatio', pixelRatio); diff --git a/src/components/gui/core/GUIRenderer.ts b/src/components/gui/core/GUIRenderer.ts index b53c5ca0..f6889570 100644 --- a/src/components/gui/core/GUIRenderer.ts +++ b/src/components/gui/core/GUIRenderer.ts @@ -52,9 +52,9 @@ export class GUIRenderer extends MeshRenderer { for (let i = 0; i < this.materials.length; i++) { const material = this.materials[i]; let passes = material.getPass(rendererType); - let vPosition = this._guiGeometry.vPositionBuffer; - let vSprite = this._guiGeometry.vSpriteBuffer; - let vColor = this._guiGeometry.vColorBuffer; + let vPosition = this._guiGeometry.getPositionBuffer(); + let vSprite = this._guiGeometry.getSpriteBuffer(); + let vColor = this._guiGeometry.getColorBuffer(); if (passes) { for (let j = 0; j < passes.length; j++) { const renderShader = passes[j]; diff --git a/src/components/gui/core/GUIShader.ts b/src/components/gui/core/GUIShader.ts index aa44dd20..3d80d3d4 100644 --- a/src/components/gui/core/GUIShader.ts +++ b/src/components/gui/core/GUIShader.ts @@ -181,8 +181,8 @@ export class GUIShader { scissorCornerRadius:f32, scissorFadeOutSize:f32, - limitVertex:f32, pixelRatio:f32, + empty:f32, } struct VertexOutput { @@ -247,7 +247,7 @@ export class GUIShader { var vSpriteData = vSpriteBuffer[quadIndex]; var op = vec2(0.0001); - let isValidVertex = vSpriteData.vVisible > 0.5 && vertexIndex < materialUniform.limitVertex; + let isValidVertex = vSpriteData.vVisible > 0.5; if(isValidVertex){ op = 2.0 * vertexPosition * materialUniform.pixelRatio / materialUniform.screenSize; } @@ -281,7 +281,7 @@ export class GUIShader { var op = vec4(0.0001); var vSpriteData = vSpriteBuffer[quadIndex]; - let isValidVertex = vSpriteData.vVisible > 0.5 && vertexIndex < materialUniform.limitVertex; + let isValidVertex = vSpriteData.vVisible > 0.5; if(isValidVertex){ op = globalUniform.projMat * globalUniform.viewMat * modelMatrix * localPos ; } diff --git a/src/components/gui/uiComponents/UIPanel.ts b/src/components/gui/uiComponents/UIPanel.ts index 0b8b062e..8f8f78c1 100644 --- a/src/components/gui/uiComponents/UIPanel.ts +++ b/src/components/gui/uiComponents/UIPanel.ts @@ -29,9 +29,7 @@ export class UIPanel extends UIImage { public scissorFadeOutSize: number = 0; protected _uiRenderer: GUIRenderer; - protected _uiMaterial: GUIMaterial; protected _geometry: GUIGeometry; - protected _limitVertexCount: number = 0; protected _maxCount: number = 128; public readonly isUIPanel = true; @@ -61,11 +59,25 @@ export class UIPanel extends UIImage { this.visible = false; } + public updateDrawCallSegment(index: number, indexStart: number, indexCount: number) { + this._geometry.updateSubGeometry(index, indexStart, indexCount); + let firstMaterial = this._uiRenderer.material; + let newMaterial: GUIMaterial = this._uiRenderer.materials[index] as GUIMaterial; + if (!newMaterial) { + newMaterial = new GUIMaterial(this.space); + let newMaterials = this._uiRenderer.materials.slice(); + newMaterials.push(newMaterial); + this._uiRenderer.materials = newMaterials; + newMaterial.cullMode = firstMaterial.cullMode; + newMaterial.depthCompare = firstMaterial.depthCompare; + } + } + private create(space: GUISpace) { this._maxCount = this.space == GUISpace.World ? GUIConfig.quadMaxCountForWorld : GUIConfig.quadMaxCountForView; this._uiRenderer = this.object3D.addComponent(GUIRenderer); this._geometry = this._uiRenderer.geometry = new GUIGeometry(this._maxCount).create(); - this._uiMaterial = this._uiRenderer.material = new GUIMaterial(space); + this._uiRenderer.material = new GUIMaterial(space); this._uiRenderer.renderOrder = GUIConfig.SortOrderStartWorld; this._rebuild = new GUIGeometryRebuild(); @@ -100,7 +112,9 @@ export class UIPanel extends UIImage { public set cullMode(value: GPUCullMode) { if (this.space == GUISpace.World) { - this._uiRenderer.material.cullMode = value; + for (let item of this._uiRenderer.materials) { + item.cullMode = value; + } } else { console.warn('Cannot change cullMode in view space'); } @@ -139,17 +153,19 @@ export class UIPanel extends UIImage { panel._uiRenderer.needSortOnCameraZ = panel.needSortOnCameraZ; //update material - let material = panel._uiMaterial; - material.setGUISolution(GUIConfig.solution, GUIConfig.pixelRatio); - material.setScreenSize(webGPUContext.canvas.clientWidth, webGPUContext.canvas.clientHeight); - material.setLimitVertex(panel._limitVertexCount); - material.setScissorEnable(panel.scissorEnable); - if (panel.scissorEnable) { - let maskQuad = panel.mainQuads[0]; - material.setScissorRect(maskQuad.left, maskQuad.bottom, maskQuad.right, maskQuad.top); - material.setScissorCorner(panel.scissorCornerRadius, panel.scissorFadeOutSize); + for (let item of panel['_uiRenderer'].materials) { + let material = item as GUIMaterial; + material.setGUISolution(GUIConfig.solution, GUIConfig.pixelRatio); + material.setScreenSize(webGPUContext.canvas.clientWidth, webGPUContext.canvas.clientHeight); + material.setScissorEnable(panel.scissorEnable); + if (panel.scissorEnable) { + let maskQuad = panel.mainQuads[0]; + material.setScissorRect(maskQuad.left, maskQuad.bottom, maskQuad.right, maskQuad.top); + material.setScissorCorner(panel.scissorCornerRadius, panel.scissorFadeOutSize); + } } + //clear flag panel.needUpdateGeometry = false; } diff --git a/src/components/gui/uiComponents/WorldPanel.ts b/src/components/gui/uiComponents/WorldPanel.ts index 82e58a8c..4c540127 100644 --- a/src/components/gui/uiComponents/WorldPanel.ts +++ b/src/components/gui/uiComponents/WorldPanel.ts @@ -35,7 +35,10 @@ export class WorldPanel extends UIPanel { if (this._depthTest != value) { this._depthTest = value; let compare = this.depthTest ? GPUCompareFunction.less_equal : GPUCompareFunction.always; - this._uiRenderer.material.depthCompare = compare; + for (let item of this._uiRenderer.materials) { + item.depthCompare = compare; + } + } } diff --git a/src/components/lights/DirectLight.ts b/src/components/lights/DirectLight.ts index 848cb8e2..fa17563e 100644 --- a/src/components/lights/DirectLight.ts +++ b/src/components/lights/DirectLight.ts @@ -9,7 +9,7 @@ import { LightType } from './LightData'; *The light of this light source is parallel, for example, sunlight. This light source can generate shadows. * @group Lights */ -@RegisterComponent +@RegisterComponent(DirectLight, 'DirectLight') export class DirectLight extends LightBase { public shadowCamera: Camera3D; diff --git a/src/components/lights/Light.ts b/src/components/lights/Light.ts index f1d1c1e4..98c37489 100644 --- a/src/components/lights/Light.ts +++ b/src/components/lights/Light.ts @@ -11,7 +11,7 @@ import { LightType } from './LightData'; *A common example is to simulate the light emitted by a light bulb, where a point light source cannot create shadows. * @group Lights */ -@RegisterComponent +@RegisterComponent(Light, 'Light') export class Light extends LightBase { constructor() { diff --git a/src/components/lights/PointLight.ts b/src/components/lights/PointLight.ts index 5e3cfe81..51a97899 100644 --- a/src/components/lights/PointLight.ts +++ b/src/components/lights/PointLight.ts @@ -10,7 +10,7 @@ import { LightType } from './LightData'; *A common example is to simulate the light emitted by a light bulb, where a point light source cannot create shadows. * @group Lights */ -@RegisterComponent +@RegisterComponent(PointLight, 'PointLight') export class PointLight extends LightBase { constructor() { @@ -108,14 +108,14 @@ export class PointLight extends LightBase { } public onGraphic(view?: View3D): void { - let custom = view.graphic3D.createCustomShape( - `PointLight_${this.object3D.instanceID}`, - this.transform, - ); - custom.buildAxis(); - custom.buildCircle(Vector3.ZERO, this.range, 32, Vector3.X_AXIS); - custom.buildCircle(Vector3.ZERO, this.range, 32, Vector3.Y_AXIS); - custom.buildCircle(Vector3.ZERO, this.range, 32, Vector3.Z_AXIS); + // let custom = view.graphic3D.createCustomShape( + // `PointLight_${this.object3D.instanceID}`, + // this.transform, + // ); + // custom.buildAxis(); + // custom.buildCircle(Vector3.ZERO, this.range, 32, Vector3.X_AXIS); + // custom.buildCircle(Vector3.ZERO, this.range, 32, Vector3.Y_AXIS); + // custom.buildCircle(Vector3.ZERO, this.range, 32, Vector3.Z_AXIS); } /** diff --git a/src/components/lights/SpotLight.ts b/src/components/lights/SpotLight.ts index a8060dc2..fb63c999 100644 --- a/src/components/lights/SpotLight.ts +++ b/src/components/lights/SpotLight.ts @@ -13,7 +13,7 @@ import { LightType } from './LightData'; * Similar to a desk lamp, chandelier, or flashlight, this light source can produce shadows. * @group Lights */ -@RegisterComponent +@RegisterComponent(SpotLight, 'SpotLight') export class SpotLight extends LightBase { constructor() { super(); @@ -124,29 +124,29 @@ export class SpotLight extends LightBase { } public onGraphic(view: View3D) { - let custom = view.graphic3D.createCustomShape( - `SpotLight_${this.object3D.instanceID}`, - this.transform, - ); - - const range = this.range; - const outerAngle = this.outerAngle / 2.0; - custom.buildAxis(); - - let angle = (90 - outerAngle) * DEGREES_TO_RADIANS; - let v0 = range * Math.cos(angle); - let v1 = range * Math.sin(angle); - custom.buildLines([Vector3.ZERO, new Vector3(0, v0, v1)]); - custom.buildLines([Vector3.ZERO, new Vector3(v0, 0, v1)]); - - angle = (90 + outerAngle) * DEGREES_TO_RADIANS; - v0 = range * Math.cos(angle); - v1 = range * Math.sin(angle); - custom.buildLines([Vector3.ZERO, new Vector3(0, v0, v1)]); - custom.buildLines([Vector3.ZERO, new Vector3(v0, 0, v1)]); - custom.buildArcLine(Vector3.ZERO, range, 90 - outerAngle, 90 + outerAngle, 16, Vector3.X_AXIS); - custom.buildArcLine(Vector3.ZERO, range, 90 - outerAngle, 90 + outerAngle, 16, Vector3.Y_AXIS); - custom.buildCircle(new Vector3(0, 0, range * Math.sin(angle)), range * Math.cos(angle), 32, Vector3.Z_AXIS); + // let custom = view.graphic3D.createCustomShape( + // `SpotLight_${this.object3D.instanceID}`, + // this.transform, + // ); + + // const range = this.range; + // const outerAngle = this.outerAngle / 2.0; + // custom.buildAxis(); + + // let angle = (90 - outerAngle) * DEGREES_TO_RADIANS; + // let v0 = range * Math.cos(angle); + // let v1 = range * Math.sin(angle); + // custom.buildLines([Vector3.ZERO, new Vector3(0, v0, v1)]); + // custom.buildLines([Vector3.ZERO, new Vector3(v0, 0, v1)]); + + // angle = (90 + outerAngle) * DEGREES_TO_RADIANS; + // v0 = range * Math.cos(angle); + // v1 = range * Math.sin(angle); + // custom.buildLines([Vector3.ZERO, new Vector3(0, v0, v1)]); + // custom.buildLines([Vector3.ZERO, new Vector3(v0, 0, v1)]); + // custom.buildArcLine(Vector3.ZERO, range, 90 - outerAngle, 90 + outerAngle, 16, Vector3.X_AXIS); + // custom.buildArcLine(Vector3.ZERO, range, 90 - outerAngle, 90 + outerAngle, 16, Vector3.Y_AXIS); + // custom.buildCircle(new Vector3(0, 0, range * Math.sin(angle)), range * Math.cos(angle), 32, Vector3.Z_AXIS); } /** diff --git a/src/components/post/PostProcessingComponent.ts b/src/components/post/PostProcessingComponent.ts index adc63477..36bd33e9 100644 --- a/src/components/post/PostProcessingComponent.ts +++ b/src/components/post/PostProcessingComponent.ts @@ -29,7 +29,6 @@ export class PostProcessingComponent extends ComponentBase { } private activePost() { - webGPUContext.canResize = false; let view = this.transform.view3D; let job = Engine3D.getRenderJob(view); this._postList.forEach((v) => { @@ -38,7 +37,6 @@ export class PostProcessingComponent extends ComponentBase { } private unActivePost() { - webGPUContext.canResize = true; let view = this.transform.view3D; let job = Engine3D.getRenderJob(view); this._postList.forEach((v) => { @@ -48,12 +46,12 @@ export class PostProcessingComponent extends ComponentBase { public addPost(c: Ctor): T { if (this._postList.has(c.name)) return; - if (!this._postList.has("FXAAPost")) { + if (!this._postList.has(FXAAPost.name)) { let post = new FXAAPost(); this._postList.set(post.constructor.name, post); if (this._enable) this.activePost(); - if (c.name == "FXAAPost") { + if (c.name === FXAAPost.name) { return post as T; } } diff --git a/src/components/renderer/MeshFilter.ts b/src/components/renderer/MeshFilter.ts index 56e067af..4e60213e 100644 --- a/src/components/renderer/MeshFilter.ts +++ b/src/components/renderer/MeshFilter.ts @@ -7,7 +7,7 @@ import { MeshRenderer } from './MeshRenderer'; * The mesh renderer component is a component used to render the mesh * @group Components */ -@RegisterComponent +@RegisterComponent(MeshFilter, 'MeshFilter') export class MeshFilter extends MeshRenderer { constructor() { super(); diff --git a/src/components/renderer/MeshRenderer.ts b/src/components/renderer/MeshRenderer.ts index b028fe6f..62519b13 100644 --- a/src/components/renderer/MeshRenderer.ts +++ b/src/components/renderer/MeshRenderer.ts @@ -14,7 +14,7 @@ import { Color, Material, mergeFunctions } from '../..'; * The mesh renderer component is a component used to render the mesh * @group Components */ -@RegisterComponent +@RegisterComponent(MeshRenderer, 'MeshRenderer') export class MeshRenderer extends RenderNode { /** * Enabling this option allows the grid to display any shadows cast on the grid. diff --git a/src/components/renderer/RenderNode.ts b/src/components/renderer/RenderNode.ts index 8e7b519f..d2fb4519 100644 --- a/src/components/renderer/RenderNode.ts +++ b/src/components/renderer/RenderNode.ts @@ -396,17 +396,14 @@ export class RenderNode extends ComponentBase { GPUContext.bindGeometryBuffer(renderContext.encoder, renderNode._geometry); } GPUContext.bindPipeline(renderContext.encoder, renderShader); - let subGeometries = renderNode._geometry.subGeometries; - for (let k = 0; k < subGeometries.length; k++) { - const subGeometry = subGeometries[k]; - let lodInfos = subGeometry.lodLevels; - let lodInfo = lodInfos[renderNode.lodLevel]; - - if (renderNode.instanceCount > 0) { - GPUContext.drawIndexed(renderContext.encoder, lodInfo.indexCount, renderNode.instanceCount, lodInfo.indexStart, 0, 0); - } else { - GPUContext.drawIndexed(renderContext.encoder, lodInfo.indexCount, 1, lodInfo.indexStart, 0, worldMatrix.index); - } + let subGeometry = renderNode._geometry.subGeometries[i]; + let lodInfos = subGeometry.lodLevels; + let lodInfo = lodInfos[renderNode.lodLevel]; + + if (renderNode.instanceCount > 0) { + GPUContext.drawIndexed(renderContext.encoder, lodInfo.indexCount, renderNode.instanceCount, lodInfo.indexStart, 0, 0); + } else { + GPUContext.drawIndexed(renderContext.encoder, lodInfo.indexCount, 1, lodInfo.indexStart, 0, worldMatrix.index); } } } @@ -452,12 +449,10 @@ export class RenderNode extends ComponentBase { if (matPass.pipeline) { GPUContext.bindPipeline(encoder, matPass); let subGeometries = node._geometry.subGeometries; - for (let k = 0; k < subGeometries.length; k++) { - const subGeometry = subGeometries[k]; - let lodInfos = subGeometry.lodLevels; - let lodInfo = lodInfos[node.lodLevel]; - GPUContext.drawIndexed(encoder, lodInfo.indexCount, 1, lodInfo.indexStart, 0, worldMatrix.index); - } + const subGeometry = subGeometries[i]; + let lodInfos = subGeometry.lodLevels; + let lodInfo = lodInfos[node.lodLevel]; + GPUContext.drawIndexed(encoder, lodInfo.indexCount, 1, lodInfo.indexStart, 0, worldMatrix.index); } } } diff --git a/src/components/renderer/SkinnedMeshRenderer.ts b/src/components/renderer/SkinnedMeshRenderer.ts index 704fc397..0ded5c18 100644 --- a/src/components/renderer/SkinnedMeshRenderer.ts +++ b/src/components/renderer/SkinnedMeshRenderer.ts @@ -16,7 +16,7 @@ import { GeometryBase, Matrix4, RegisterComponent } from "../.."; * meshes with mixed shapes, and meshes running cloth simulations. * @group Components */ -@RegisterComponent +@RegisterComponent(SkinnedMeshRenderer, 'SkinnedMeshRenderer') export class SkinnedMeshRenderer extends MeshRenderer { public skinJointsName: Array; protected mInverseBindMatrixData: Array; diff --git a/src/components/renderer/SkinnedMeshRenderer2.ts b/src/components/renderer/SkinnedMeshRenderer2.ts index 469fcbde..dba19a12 100644 --- a/src/components/renderer/SkinnedMeshRenderer2.ts +++ b/src/components/renderer/SkinnedMeshRenderer2.ts @@ -15,7 +15,7 @@ import { AnimatorComponent, GeometryBase, LitMaterial, Matrix4, RegisterComponen * meshes with mixed shapes, and meshes running cloth simulations. * @group Components */ -@RegisterComponent +@RegisterComponent(SkinnedMeshRenderer2, 'SkinnedMeshRenderer2') export class SkinnedMeshRenderer2 extends MeshRenderer { public skinJointsName: Array; protected mInverseBindMatrixData: Array; diff --git a/src/core/ViewQuad.ts b/src/core/ViewQuad.ts index 0f4db71b..f271852c 100644 --- a/src/core/ViewQuad.ts +++ b/src/core/ViewQuad.ts @@ -12,6 +12,7 @@ import { PassType } from '../gfx/renderJob/passRenderer/state/RendererType'; import { View3D } from './View3D'; import { Material } from '../materials/Material'; import { QuadShader } from '../loader/parser/prefab/mats/shader/QuadShader'; +import { CResizeEvent } from '../event/CResizeEvent'; /** * @internal * @group Entity @@ -61,6 +62,22 @@ export class ViewQuad extends Object3D { usage: GPUTextureUsage.RENDER_ATTACHMENT, }) } + + webGPUContext.addEventListener(CResizeEvent.RESIZE, (e) => { + this.rendererPassState = WebGPUDescriptorCreator.createRendererPassState(rtFrame, `load`); + if (multisample > 0) { + this.rendererPassState.multisample = this.quadShader.getDefaultColorShader().shaderState.multisample; + this.rendererPassState.multiTexture = webGPUContext.device.createTexture({ + size: { + width: webGPUContext.presentationSize[0], + height: webGPUContext.presentationSize[1], + }, + sampleCount: multisample, + format: renderTexture.length > 0 ? renderTexture[0].format : webGPUContext.presentationFormat, + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }) + } + }, this); } /** diff --git a/src/core/entities/Entity.ts b/src/core/entities/Entity.ts index ff6df208..3c17bae1 100644 --- a/src/core/entities/Entity.ts +++ b/src/core/entities/Entity.ts @@ -126,10 +126,10 @@ export class Entity extends CEventDispatcher { */ public addChild(child: Entity): Entity { if (child == null) { - return new console.error('child is null!'); + throw new Error('child is null!'); } if (child === this) { - return new console.error('child is self!'); + throw new Error('child is self!'); } let index = this.entityChildren.indexOf(child); @@ -149,8 +149,8 @@ export class Entity extends CEventDispatcher { * @param child Removed objects */ public removeChild(child: Entity) { - if (child === null) return new console.error('remove child is null!'); - if (child === this) return new console.error('add child is self!'); + if (child === null) return; // throw new Error('remove child is null!'); + if (child === this) throw new Error('add child is self!'); let index = this.entityChildren.indexOf(child); if (index != -1) { this.entityChildren.splice(index, 1); diff --git a/src/core/geometry/GeometryBase.ts b/src/core/geometry/GeometryBase.ts index 54962f05..fc07e05c 100644 --- a/src/core/geometry/GeometryBase.ts +++ b/src/core/geometry/GeometryBase.ts @@ -139,10 +139,11 @@ export class GeometryBase { * add subGeometry from lod level * @param lodLevels @see LODDescriptor */ - public addSubGeometry(...lodLevels: LODDescriptor[]) { + public addSubGeometry(...lodLevels: LODDescriptor[]): SubGeometry { let sub = new SubGeometry(); sub.lodLevels = lodLevels; this.subGeometries.push(sub); + return sub; } /** diff --git a/src/core/geometry/GeometryVertexBuffer.ts b/src/core/geometry/GeometryVertexBuffer.ts index 23bef450..bb2add73 100644 --- a/src/core/geometry/GeometryVertexBuffer.ts +++ b/src/core/geometry/GeometryVertexBuffer.ts @@ -73,7 +73,6 @@ export class GeometryVertexBuffer { } this.vertexCount = len; - this._vertexBufferLayouts[attributeInfo.location] = { name: attributeInfo.name, arrayStride: attributeInfo.size * 4, diff --git a/src/gfx/generate/convert/TextureCubeStdCreator.ts b/src/gfx/generate/convert/TextureCubeStdCreator.ts index cbad6d1e..a37d7e98 100644 --- a/src/gfx/generate/convert/TextureCubeStdCreator.ts +++ b/src/gfx/generate/convert/TextureCubeStdCreator.ts @@ -1,7 +1,7 @@ import { Texture } from '../../graphics/webGpu/core/texture/Texture'; import { webGPUContext } from '../../graphics/webGpu/Context3D'; -import { VirtualTexture } from '../../../textures/VirtualTexture'; import { GPUContext } from '../../renderJob/GPUContext'; +import { RenderTexture } from '../../../textures/RenderTexture'; /** * @internal @@ -70,7 +70,7 @@ fn samplePixel(face:i32, uv01:vec2) -> vec4 { private static blurSettingBuffer: GPUBuffer = null; private static pipeline: GPUComputePipeline; - static createFace(index: number, size: number, inTex: Texture, outTex: VirtualTexture): void { + static createFace(index: number, size: number, inTex: Texture, outTex: RenderTexture): void { const device = webGPUContext.device; if (this.pipeline == null) { this.pipeline = device.createComputePipeline({ diff --git a/src/gfx/graphics/webGpu/Context3D.ts b/src/gfx/graphics/webGpu/Context3D.ts index 8b0865df..51193c7b 100644 --- a/src/gfx/graphics/webGpu/Context3D.ts +++ b/src/gfx/graphics/webGpu/Context3D.ts @@ -1,6 +1,8 @@ +import { CEvent, Texture } from '../../..'; import { CEventDispatcher } from '../../../event/CEventDispatcher'; import { CResizeEvent } from '../../../event/CResizeEvent'; import { CanvasConfig } from './CanvasConfig'; + /** * @internal */ @@ -17,7 +19,7 @@ class Context3D extends CEventDispatcher { public canvasConfig: CanvasConfig; public super: number = 1.0; private _pixelRatio: number = 1.0; - canResize: boolean = true; + private _resizeEvent: CEvent; // initSize: number[]; public get pixelRatio() { return this._pixelRatio; @@ -108,6 +110,13 @@ class Context3D extends CEventDispatcher { alphaMode: 'premultiplied', colorSpace: `srgb`, }); + + this._resizeEvent = new CResizeEvent(CResizeEvent.RESIZE, { width: this.windowWidth, height: this.windowHeight }) + const resizeObserver = new ResizeObserver(() => { + this.updateSize() + Texture.destroyTexture() + }); + resizeObserver.observe(this.canvas); this.updateSize(); return true; } @@ -116,14 +125,15 @@ class Context3D extends CEventDispatcher { let w = Math.floor(this.canvas.clientWidth * this.pixelRatio * this.super); let h = Math.floor(this.canvas.clientHeight * this.pixelRatio * this.super); if (w != this.windowWidth || h != this.windowHeight) { - // if (this.canvas.width != this.windowWidth || this.canvas.height != this.windowHeight) { this.canvas.width = this.windowWidth = w; this.canvas.height = this.windowHeight = h; this.presentationSize[0] = this.windowWidth; this.presentationSize[1] = this.windowHeight; this.aspect = this.windowWidth / this.windowHeight; - if (this.canResize) - this.dispatchEvent(new CResizeEvent(CResizeEvent.RESIZE, { width: this.windowWidth, height: this.windowHeight })); + + this._resizeEvent.data.width = this.windowWidth; + this._resizeEvent.data.height = this.windowHeight; + this.dispatchEvent(this._resizeEvent); } } } diff --git a/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts b/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts index 34b5d342..9904236a 100644 --- a/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts +++ b/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts @@ -111,6 +111,8 @@ export class GlobalUniformGroup { } this.uniformGPUBuffer.setFloat32Array(`csmShadowBias`, this.csmShadowBias); this.uniformGPUBuffer.setFloat32Array(`csmMatrix`, this.csmMatrixRaw); + this.uniformGPUBuffer.setFloat32Array(`shadowLights`, this.shadowLights); + this.uniformGPUBuffer.setVector3(`CameraPos`, camera.transform.worldPosition); this.uniformGPUBuffer.setFloat(`frame`, Time.frame); this.uniformGPUBuffer.setFloat(`time`, Time.frame); @@ -141,7 +143,6 @@ export class GlobalUniformGroup { this.uniformGPUBuffer.setInt32(`nDirShadowEnd`, this.dirShadowEnd); this.uniformGPUBuffer.setInt32(`nPointShadowStart`, this.pointShadowStart); this.uniformGPUBuffer.setInt32(`nPointShadowEnd`, this.pointShadowEnd); - this.uniformGPUBuffer.setFloat32Array(`shadowLights`, this.shadowLights); this.uniformGPUBuffer.apply(); } @@ -157,6 +158,8 @@ export class GlobalUniformGroup { this.uniformGPUBuffer.setFloat32Array(`shadowCamera`, this.shadowMatrixRaw); this.uniformGPUBuffer.setFloat32Array(`csmShadowBias`, this.csmShadowBias); this.uniformGPUBuffer.setFloat32Array(`csmMatrix`, this.csmMatrixRaw); + this.uniformGPUBuffer.setFloat32Array(`shadowLights`, this.shadowLights); + this.uniformGPUBuffer.setVector3(`CameraPos`, camera.transform.worldPosition); this.uniformGPUBuffer.setFloat(`frame`, Time.frame); @@ -191,7 +194,6 @@ export class GlobalUniformGroup { this.uniformGPUBuffer.setInt32(`nDirShadowEnd`, this.dirShadowEnd); this.uniformGPUBuffer.setInt32(`nPointShadowStart`, this.pointShadowStart); this.uniformGPUBuffer.setInt32(`nPointShadowEnd`, this.pointShadowEnd); - this.uniformGPUBuffer.setFloat32Array(`shadowLights`, this.shadowLights); this.uniformGPUBuffer.apply(); } diff --git a/src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts b/src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts index bb6a6d7c..2ab41af2 100644 --- a/src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts +++ b/src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts @@ -33,9 +33,9 @@ export class GPUBufferBase { constructor() { this.mapAsyncReady = []; - this.memory = new MemoryDO(); - this.memoryNodes = new Map(); - this._dataView = new Float32Array(this.memory.shareDataBuffer); + // this.memory = new MemoryDO(); + // this.memoryNodes = new Map(); + // this._dataView = new Float32Array(this.memory.shareDataBuffer); } public debug() { @@ -249,40 +249,43 @@ export class GPUBufferBase { for (let i = 0; i < ref.length; i++) { const att = ref[i]; let value = obj[att.name]; + this.writeValue(node, att, value); + } + } - switch (att.type) { - case `Boolean`: - node.writeFloat(value); - break; + private writeValue(node: MemoryInfo, att: { name: string, type: string }, value: any) { + switch (att.type) { + case `Boolean`: + node.writeFloat(value); + break; - case `Number`: - node.writeFloat(value); - break; + case `Number`: + node.writeFloat(value); + break; - case `Float32Array`: - node.writeFloat32Array(value); - break; + case `Float32Array`: + node.writeFloat32Array(value); + break; - case `Vector2`: - node.writeVector2(value); - break; + case `Vector2`: + node.writeVector2(value); + break; - case `Vector3`: - node.writeVector3(value); - break; + case `Vector3`: + node.writeVector3(value); + break; - case `Vector4`: - node.writeVector4(value); - break; + case `Vector4`: + node.writeVector4(value); + break; - case `Color`: - node.writeRGBColor(value); - break; + case `Color`: + node.writeRGBColor(value); + break; - case `Array`: - node.writeArray(value); - break; - } + case `Array`: + node.writeArray(value); + break; } } @@ -380,11 +383,14 @@ export class GPUBufferBase { protected createBuffer(usage: GPUBufferUsageFlags, size: number, data?: ArrayBufferData, debugLabel?: string) { let device = webGPUContext.device; - this.byteSize = size * 4; - this.usage = usage; + if (this.buffer) { this.destroy(); } + + this.byteSize = size * 4; + this.usage = usage; + this.buffer = device.createBuffer({ label: debugLabel, size: this.byteSize, @@ -392,6 +398,9 @@ export class GPUBufferBase { mappedAtCreation: false, }); + this.memory = new MemoryDO(); + this.memoryNodes = new Map(); + this._dataView = new Float32Array(this.memory.shareDataBuffer); this.memory.allocation(this.byteSize); if (data) { let m = this.memory.allocation_node(data.length * 4); @@ -400,6 +409,10 @@ export class GPUBufferBase { } } + public resizeBuffer(size: number, data?: ArrayBufferData) { + this.createBuffer(this.usage, size, data); + } + protected createNewBuffer(usage: GPUBufferUsageFlags, size: number): GPUBuffer { let device = webGPUContext.device; let tByteSize = size * 4; @@ -428,6 +441,9 @@ export class GPUBufferBase { mappedAtCreation: false, }); + this.memory = new MemoryDO(); + this.memoryNodes = new Map(); + this._dataView = new Float32Array(this.memory.shareDataBuffer); this.memory.allocation(totalLength); for (let i = 0; i < count; i++) { let name = i; diff --git a/src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts index ab6f0ea0..296a17f7 100644 --- a/src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts @@ -1,3 +1,4 @@ +import { MemoryDO } from '../../../../../core/pool/memory/MemoryDO'; import { MemoryInfo } from '../../../../../core/pool/memory/MemoryInfo'; import { webGPUContext } from '../../Context3D'; import { ArrayBufferData } from './ArrayBufferData'; @@ -32,7 +33,8 @@ export class IndicesGPUBuffer extends GPUBufferBase { mappedAtCreation: false, }); - + this.memory = new MemoryDO(); + this.memoryNodes = new Map(); this.memory.allocation(this.byteSize); if (data) { this.indicesNode = this.memory.allocation_node(data.length * 4); diff --git a/src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts index c09605e4..4dcd9028 100644 --- a/src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts @@ -1,3 +1,4 @@ +import { MemoryDO } from '../../../../../core/pool/memory/MemoryDO'; import { MemoryInfo } from '../../../../../core/pool/memory/MemoryInfo'; import { webGPUContext } from '../../Context3D'; import { GPUBufferBase } from './GPUBufferBase'; @@ -31,6 +32,8 @@ export class VertexGPUBuffer extends GPUBufferBase { mappedAtCreation: false, }); + this.memory = new MemoryDO(); + this.memoryNodes = new Map(); this.memory.allocation(this.byteSize); this.node = this.memory.allocation_node(this.byteSize); // this.outFloat32Array = new Float32Array(size); diff --git a/src/gfx/graphics/webGpu/core/texture/Texture.ts b/src/gfx/graphics/webGpu/core/texture/Texture.ts index 13534184..55f5350c 100644 --- a/src/gfx/graphics/webGpu/core/texture/Texture.ts +++ b/src/gfx/graphics/webGpu/core/texture/Texture.ts @@ -32,7 +32,7 @@ export class Texture implements GPUSamplerDescriptor { /** * GPUTextureView */ - public view: GPUTextureView; // Assigned later + public view: GPUTextureView | GPUExternalTexture; // Assigned later /** * GPUSampler @@ -545,7 +545,9 @@ export class Texture implements GPUSamplerDescriptor { private static _texs: GPUTexture[] = []; public static delayDestroyTexture(tex: GPUTexture) { - this._texs.push(tex); + if (!this._texs.includes(tex)) { + this._texs.push(tex); + } } public static destroyTexture() { diff --git a/src/gfx/graphics/webGpu/shader/ComputeShader.ts b/src/gfx/graphics/webGpu/shader/ComputeShader.ts index 88b57776..80cfb4fd 100644 --- a/src/gfx/graphics/webGpu/shader/ComputeShader.ts +++ b/src/gfx/graphics/webGpu/shader/ComputeShader.ts @@ -3,7 +3,7 @@ import { webGPUContext } from '../Context3D'; import { ShaderPassBase } from './ShaderPassBase'; import { ShaderReflection, ShaderReflectionVarInfo } from './value/ShaderReflectionInfo'; import { Preprocessor } from './util/Preprocessor'; -import { Reference, Struct } from '../../../..'; +import { CResizeEvent, Reference, Struct } from '../../../..'; import { StorageGPUBuffer } from '../core/buffer/StorageGPUBuffer'; import { StructStorageGPUBuffer } from '../core/buffer/StructStorageGPUBuffer'; import { UniformGPUBuffer } from '../core/buffer/UniformGPUBuffer'; @@ -229,6 +229,14 @@ export class ComputeShader extends ShaderPassBase { this._groupsShaderReflectionVarInfos[i] = srvs; this.genGroups(i, this._groupsShaderReflectionVarInfos); } + + webGPUContext.addEventListener(CResizeEvent.RESIZE, (e) => { + for (let i = 0; i < shaderReflection.groups.length; ++i) { + let srvs = shaderReflection.groups[i]; + this._groupsShaderReflectionVarInfos[i] = srvs; + this.genGroups(i, this._groupsShaderReflectionVarInfos, true); + } + }, this); } protected preCompileShader(shader: string) { diff --git a/src/gfx/renderJob/frame/GBufferFrame.ts b/src/gfx/renderJob/frame/GBufferFrame.ts index c6976b3e..d09fbd86 100644 --- a/src/gfx/renderJob/frame/GBufferFrame.ts +++ b/src/gfx/renderJob/frame/GBufferFrame.ts @@ -1,5 +1,5 @@ -import { Engine3D } from "../../.."; -import { VirtualTexture } from "../../../textures/VirtualTexture"; + +import { RenderTexture } from "../../../textures/RenderTexture"; import { webGPUContext } from "../../graphics/webGpu/Context3D"; import { GPUTextureFormat } from "../../graphics/webGpu/WebGPUConst"; import { RTDescriptor } from "../../graphics/webGpu/descriptor/RTDescriptor"; @@ -32,7 +32,7 @@ export class GBufferFrame extends RTFrame { let colorRTDes = new RTDescriptor(); colorRTDes.loadOp = `clear`; - let depthTexture = new VirtualTexture(rtWidth, rtHeight, GPUTextureFormat.depth24plus, false); + let depthTexture = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.depth24plus, false); depthTexture.name = `depthTexture`; let depthDec = new RTDescriptor(); depthDec.loadOp = `load`; diff --git a/src/gfx/renderJob/frame/ProbeGBufferFrame.ts b/src/gfx/renderJob/frame/ProbeGBufferFrame.ts index 9fa95d81..50f122cc 100644 --- a/src/gfx/renderJob/frame/ProbeGBufferFrame.ts +++ b/src/gfx/renderJob/frame/ProbeGBufferFrame.ts @@ -1,36 +1,34 @@ -import { VirtualTexture } from "../../../textures/VirtualTexture"; +import { RenderTexture } from "../../.."; import { GPUTextureFormat } from "../../graphics/webGpu/WebGPUConst"; import { RTDescriptor } from "../../graphics/webGpu/descriptor/RTDescriptor"; -import { RTResourceConfig } from "../config/RTResourceConfig"; import { RTFrame } from "./RTFrame"; -import { RTResourceMap } from "./RTResourceMap"; export class ProbeGBufferFrame extends RTFrame { - constructor(rtWidth: number, rtHeight: number) { + constructor(rtWidth: number, rtHeight: number, autoResize: boolean = true) { super([], []); - this.crateGBuffer(rtWidth, rtHeight); + this.crateGBuffer(rtWidth, rtHeight, autoResize); } - crateGBuffer(rtWidth: number, rtHeight: number) { + crateGBuffer(rtWidth: number, rtHeight: number, autoResize: boolean) { let attachments = this.renderTargets; let rtDescriptors = this.rtDescriptors; - let positionMap = new VirtualTexture(rtWidth, rtHeight, GPUTextureFormat.rgba16float, false); + let positionMap = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.rgba16float, false, undefined, 1, 0, true, autoResize); positionMap.name = `positionMap`; let posDec = new RTDescriptor(); posDec.loadOp = `load`; - let normalMap = new VirtualTexture(rtWidth, rtHeight, GPUTextureFormat.rgba16float, false); + let normalMap = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.rgba16float, false, undefined, 1, 0, true, autoResize); normalMap.name = `normalMap`; let normalDec = new RTDescriptor(); normalDec.loadOp = `load`; - let colorMap = new VirtualTexture(rtWidth, rtHeight, GPUTextureFormat.rgba16float, false); + let colorMap = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.rgba16float, false, undefined, 1, 0, true, autoResize); colorMap.name = `colorMap`; let colorDec = new RTDescriptor(); colorDec.loadOp = `load`; - let depthTexture = new VirtualTexture(rtWidth, rtHeight, GPUTextureFormat.depth24plus, false); + let depthTexture = new RenderTexture(rtWidth, rtHeight, GPUTextureFormat.depth24plus, false, undefined, 1, 0, true, autoResize); depthTexture.name = `depthTexture`; let depthDec = new RTDescriptor(); depthDec.loadOp = `load`; diff --git a/src/gfx/renderJob/frame/RTFrame.ts b/src/gfx/renderJob/frame/RTFrame.ts index a06bd644..9d9f20ba 100644 --- a/src/gfx/renderJob/frame/RTFrame.ts +++ b/src/gfx/renderJob/frame/RTFrame.ts @@ -1,22 +1,21 @@ -import { VirtualTexture } from "../../../textures/VirtualTexture"; -import { Texture } from "../../graphics/webGpu/core/texture/Texture"; +import { RenderTexture } from "../../../textures/RenderTexture"; import { RTDescriptor } from "../../graphics/webGpu/descriptor/RTDescriptor"; export class RTFrame { public label: string; public customSize: boolean = false; - public renderTargets: VirtualTexture[]; + public renderTargets: RenderTexture[]; public rtDescriptors: RTDescriptor[]; - public zPreTexture: VirtualTexture; - public depthTexture: VirtualTexture; + public zPreTexture: RenderTexture; + public depthTexture: RenderTexture; public depthViewIndex: number = 0; public depthCleanValue: number = 1; public depthLoadOp: GPULoadOp = `clear`; public isOutTarget: boolean = true; - constructor(attachments: VirtualTexture[], rtDescriptors: RTDescriptor[], depthTexture?: VirtualTexture, zPreTexture?: VirtualTexture, isOutTarget: boolean = true) { + constructor(attachments: RenderTexture[], rtDescriptors: RTDescriptor[], depthTexture?: RenderTexture, zPreTexture?: RenderTexture, isOutTarget: boolean = true) { this.renderTargets = attachments; this.rtDescriptors = rtDescriptors; this.depthTexture = depthTexture; diff --git a/src/gfx/renderJob/frame/RTResourceMap.ts b/src/gfx/renderJob/frame/RTResourceMap.ts index dbcaed69..8b560a3d 100644 --- a/src/gfx/renderJob/frame/RTResourceMap.ts +++ b/src/gfx/renderJob/frame/RTResourceMap.ts @@ -1,35 +1,30 @@ import { ViewQuad } from '../../../core/ViewQuad'; - -import { VirtualTexture } from '../../../textures/VirtualTexture'; -import { UniformNode } from '../../graphics/webGpu/core/uniforms/UniformNode'; import { RTDescriptor } from '../../graphics/webGpu/descriptor/RTDescriptor'; -import { GPUTextureFormat } from '../../graphics/webGpu/WebGPUConst'; -import { webGPUContext } from '../../graphics/webGpu/Context3D'; import { GPUContext } from '../GPUContext'; -import { GBufferFrame } from './GBufferFrame'; import { RTFrame } from './RTFrame'; import { RTResourceConfig } from '../config/RTResourceConfig'; +import { RenderTexture } from '../../../textures/RenderTexture'; /** * @internal * @group Post */ export class RTResourceMap { - public static rtTextureMap: Map; + public static rtTextureMap: Map; public static rtViewQuad: Map; public static init() { - this.rtTextureMap = new Map(); + this.rtTextureMap = new Map(); this.rtViewQuad = new Map(); } public static createRTTexture(name: string, rtWidth: number, rtHeight: number, format: GPUTextureFormat, useMipmap: boolean = false, sampleCount: number = 0) { - let rt: VirtualTexture = this.rtTextureMap.get(name); + let rt: RenderTexture = this.rtTextureMap.get(name); if (!rt) { if (name == RTResourceConfig.colorBufferTex_NAME) { - rt = new VirtualTexture(rtWidth, rtHeight, format, useMipmap, undefined, 1, sampleCount, false); + rt = new RenderTexture(rtWidth, rtHeight, format, useMipmap, undefined, 1, sampleCount, false); } else { - rt = new VirtualTexture(rtWidth, rtHeight, format, useMipmap, undefined, 1, sampleCount, true); + rt = new RenderTexture(rtWidth, rtHeight, format, useMipmap, undefined, 1, sampleCount, true); } rt.name = name; RTResourceMap.rtTextureMap.set(name, rt); @@ -38,16 +33,16 @@ export class RTResourceMap { } public static createRTTextureArray(name: string, rtWidth: number, rtHeight: number, format: GPUTextureFormat, length: number = 1, useMipmap: boolean = false, sampleCount: number = 0) { - let rt: VirtualTexture = this.rtTextureMap.get(name); + let rt: RenderTexture = this.rtTextureMap.get(name); if (!rt) { - rt = new VirtualTexture(rtWidth, rtHeight, format, useMipmap, undefined, length, sampleCount); + rt = new RenderTexture(rtWidth, rtHeight, format, useMipmap, undefined, length, sampleCount); rt.name = name; RTResourceMap.rtTextureMap.set(name, rt); } return rt; } - public static createViewQuad(name: string, shaderVS: string, shaderFS: string, outRtTexture: VirtualTexture, multisample: number = 0) { + public static createViewQuad(name: string, shaderVS: string, shaderFS: string, outRtTexture: RenderTexture, multisample: number = 0) { let rtFrame = new RTFrame([ outRtTexture ], diff --git a/src/gfx/renderJob/jobs/RendererJob.ts b/src/gfx/renderJob/jobs/RendererJob.ts index ec8f2fdd..c477566a 100644 --- a/src/gfx/renderJob/jobs/RendererJob.ts +++ b/src/gfx/renderJob/jobs/RendererJob.ts @@ -17,7 +17,6 @@ import { PostBase } from '../post/PostBase'; import { RendererBase } from '../passRenderer/RendererBase'; import { Ctor } from '../../../util/Global'; import { DDGIProbeRenderer } from '../passRenderer/ddgi/DDGIProbeRenderer'; -import { Texture } from '../../graphics/webGpu/core/texture/Texture'; /** * render jobs diff --git a/src/gfx/renderJob/passRenderer/RendererBase.ts b/src/gfx/renderJob/passRenderer/RendererBase.ts index ae43b94a..71d53154 100644 --- a/src/gfx/renderJob/passRenderer/RendererBase.ts +++ b/src/gfx/renderJob/passRenderer/RendererBase.ts @@ -4,7 +4,6 @@ import { Scene3D } from "../../../core/Scene3D"; import { View3D } from "../../../core/View3D"; import { ViewQuad } from "../../../core/ViewQuad"; import { CEventDispatcher } from "../../../event/CEventDispatcher"; -import { VirtualTexture } from "../../../textures/VirtualTexture"; import { GPUTextureFormat } from "../../graphics/webGpu/WebGPUConst"; import { Texture } from "../../graphics/webGpu/core/texture/Texture"; import { WebGPUDescriptorCreator } from "../../graphics/webGpu/descriptor/WebGPUDescriptorCreator"; @@ -16,11 +15,8 @@ import { OcclusionSystem } from "../occlusion/OcclusionSystem"; import { RendererPassState } from "./state/RendererPassState"; import { PassType } from "./state/RendererType"; import { RenderContext } from "./RenderContext"; -import { ClusterLightingRender } from "./cluster/ClusterLightingRender"; import { ClusterLightingBuffer } from "./cluster/ClusterLightingBuffer"; -import { RTResourceMap } from "../frame/RTResourceMap"; -import { RTResourceConfig } from "../config/RTResourceConfig"; -import { webGPUContext } from "../../graphics/webGpu/Context3D"; +import { RenderTexture } from "../../.."; /** @@ -69,7 +65,7 @@ export class RendererBase extends CEventDispatcher { } - public setIrradiance(probeIrradianceMap: VirtualTexture, probeDepthMap: VirtualTexture) { + public setIrradiance(probeIrradianceMap: RenderTexture, probeDepthMap: RenderTexture) { this.rendererPassState.irradianceBuffer = [probeIrradianceMap, probeDepthMap]; } diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts index a69acf5c..1881d27d 100644 --- a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts +++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts @@ -1,7 +1,7 @@ import { DDGIIrradiance_shader } from '../../../../assets/shader/compute/DDGIIrradiance_Cs'; import { View3D } from '../../../../core/View3D'; import { Engine3D } from '../../../../Engine3D'; -import { VirtualTexture } from '../../../../textures/VirtualTexture'; +import { RenderTexture } from '../../../../textures/RenderTexture'; import { GlobalBindGroup } from '../../../graphics/webGpu/core/bindGroups/GlobalBindGroup'; import { StorageGPUBuffer } from '../../../graphics/webGpu/core/buffer/StorageGPUBuffer'; import { ComputeShader } from '../../../graphics/webGpu/shader/ComputeShader'; @@ -17,8 +17,8 @@ import { DDGIIrradianceVolume } from './DDGIIrradianceVolume'; export class DDGIIrradianceComputePass { private irradianceBuffer: StorageGPUBuffer; private depthBuffer: StorageGPUBuffer; - private probeIrradianceMap: VirtualTexture; - private probeDepthMap: VirtualTexture; + private probeIrradianceMap: RenderTexture; + private probeDepthMap: RenderTexture; private volume: DDGIIrradianceVolume; private computeShader: ComputeShader; private depthRaysBuffer: StorageGPUBuffer; @@ -48,7 +48,7 @@ export class DDGIIrradianceComputePass { this.computeShader.setStorageBuffer("models", GlobalBindGroup.modelMatrixBindGroup.matrixBufferDst); } - public setTextures(inputs: VirtualTexture[], probeIrradianceMap: VirtualTexture, probeDepthMap: VirtualTexture) { + public setTextures(inputs: RenderTexture[], probeIrradianceMap: RenderTexture, probeDepthMap: RenderTexture) { this.probeIrradianceMap = probeIrradianceMap; this.probeDepthMap = probeDepthMap; diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceGPUBufferReader.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceGPUBufferReader.ts index e302d538..b5cf0908 100644 --- a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceGPUBufferReader.ts +++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceGPUBufferReader.ts @@ -1,7 +1,7 @@ import { Engine3D } from "../../../../Engine3D"; import { CEvent } from "../../../../event/CEvent"; import { CEventDispatcher } from "../../../../event/CEventDispatcher"; -import { VirtualTexture } from "../../../../textures/VirtualTexture"; +import { RenderTexture } from "../../../../textures/RenderTexture"; import { webGPUContext } from "../../../graphics/webGpu/Context3D"; import { GPUContext } from "../../GPUContext"; import { DDGIProbeRenderer, GIRenderCompleteEvent, GIRenderStartEvent } from "./DDGIProbeRenderer"; @@ -12,13 +12,13 @@ export class DDGIIrradianceGPUBufferReader extends CEventDispatcher { private probeRenderer: DDGIProbeRenderer; private opColorBuffer: GPUBuffer; private opDepthBuffer: GPUBuffer; - private srcColorMap: VirtualTexture; - private srcDepthMap: VirtualTexture; + private srcColorMap: RenderTexture; + private srcDepthMap: RenderTexture; public opDepthArray: Float32Array; public opColorArray: Float32Array; - public initReader(probeRender: DDGIProbeRenderer, colorMap: VirtualTexture, depthMap: VirtualTexture) { + public initReader(probeRender: DDGIProbeRenderer, colorMap: RenderTexture, depthMap: RenderTexture) { this.probeRenderer = probeRender; this.srcColorMap = colorMap; this.srcDepthMap = depthMap; diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGILightingPass.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGILightingPass.ts index eb22bf49..bb9f06ce 100644 --- a/src/gfx/renderJob/passRenderer/ddgi/DDGILightingPass.ts +++ b/src/gfx/renderJob/passRenderer/ddgi/DDGILightingPass.ts @@ -1,7 +1,7 @@ import { DDGILighting_shader } from '../../../../assets/shader/compute/DDGILighting_CSShader'; import { View3D } from '../../../../core/View3D'; import { Engine3D } from '../../../../Engine3D'; -import { VirtualTexture } from '../../../../textures/VirtualTexture'; +import { RenderTexture } from '../../../../textures/RenderTexture'; import { GlobalBindGroup } from '../../../graphics/webGpu/core/bindGroups/GlobalBindGroup'; import { Texture } from '../../../graphics/webGpu/core/texture/Texture'; import { ComputeShader } from '../../../graphics/webGpu/shader/ComputeShader'; @@ -20,10 +20,10 @@ export class DDGILightingPass { private shadowMap: Texture; private pointShadowMap: Texture; - public lightingTexture: VirtualTexture; + public lightingTexture: RenderTexture; constructor() { let giSetting = Engine3D.setting.gi; - this.lightingTexture = new VirtualTexture(giSetting.probeSourceTextureSize, giSetting.probeSourceTextureSize, GPUTextureFormat.rgba16float, false, GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING); + this.lightingTexture = new RenderTexture(giSetting.probeSourceTextureSize, giSetting.probeSourceTextureSize, GPUTextureFormat.rgba16float, false, GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING); } private create(view: View3D) { diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts index f117be71..46246116 100644 --- a/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts +++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts @@ -1,7 +1,7 @@ import { MultiBouncePass_cs } from '../../../../assets/shader/compute/MultiBouncePass_cs'; import { View3D } from '../../../../core/View3D'; import { Engine3D } from '../../../../Engine3D'; -import { VirtualTexture } from '../../../../textures/VirtualTexture'; +import { RenderTexture } from '../../../../textures/RenderTexture'; import { ComputeShader } from '../../../graphics/webGpu/shader/ComputeShader'; import { GPUTextureFormat } from '../../../graphics/webGpu/WebGPUConst'; import { GPUContext } from '../../GPUContext'; @@ -13,7 +13,7 @@ import { DDGIIrradianceVolume } from './DDGIIrradianceVolume'; * @group Post */ export class DDGIMultiBouncePass { - public blendTexture: VirtualTexture; + public blendTexture: RenderTexture; private volume: DDGIIrradianceVolume; private computerShader: ComputeShader; @@ -24,14 +24,14 @@ export class DDGIMultiBouncePass { private initPipeline() { let giSetting = Engine3D.setting.gi; - this.blendTexture = new VirtualTexture(giSetting.probeSourceTextureSize, giSetting.probeSourceTextureSize, GPUTextureFormat.rgba16float, false, GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING); + this.blendTexture = new RenderTexture(giSetting.probeSourceTextureSize, giSetting.probeSourceTextureSize, GPUTextureFormat.rgba16float, false, GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING); this.computerShader = new ComputeShader(MultiBouncePass_cs); this.computerShader.setStorageTexture("outputBuffer", this.blendTexture); this.computerShader.setUniformBuffer("uniformData", this.volume.irradianceVolumeBuffer); } - public setInputs(inputs: VirtualTexture[]) { + public setInputs(inputs: RenderTexture[]) { let worldNormalMap = inputs[0]; let colorMap = inputs[1]; let lightingMap = inputs[2]; diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIProbeRenderer.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIProbeRenderer.ts index 201abaad..7dae7b77 100644 --- a/src/gfx/renderJob/passRenderer/ddgi/DDGIProbeRenderer.ts +++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIProbeRenderer.ts @@ -2,7 +2,7 @@ import { Camera3D } from '../../../../core/Camera3D'; import { CubeCamera } from '../../../../core/CubeCamera'; import { Engine3D } from '../../../../Engine3D'; import { CEvent } from '../../../../event/CEvent'; -import { VirtualTexture } from '../../../../textures/VirtualTexture'; +import { RenderTexture } from '../../../../textures/RenderTexture'; import { EntityCollect } from '../../collect/EntityCollect'; import { GPUContext } from '../../GPUContext'; import { ProbeGBufferFrame } from '../../frame/ProbeGBufferFrame'; @@ -43,17 +43,17 @@ export class DDGIProbeRenderer extends RendererBase { private probeRenderResult: ProbeRenderResult; private renderStatus: GlobalIrradianceStatus = 'none'; - public positionMap: VirtualTexture; - public normalMap: VirtualTexture; - public colorMap: VirtualTexture; + public positionMap: RenderTexture; + public normalMap: RenderTexture; + public colorMap: RenderTexture; public probeNext: number = 128; public sizeW: number; public sizeH: number; public lightingPass: DDGILightingPass; public bouncePass: DDGIMultiBouncePass; public irradianceComputePass: DDGIIrradianceComputePass; - public irradianceDepthMap: VirtualTexture; - public irradianceColorMap: VirtualTexture; + public irradianceDepthMap: RenderTexture; + public irradianceColorMap: RenderTexture; /** * @@ -78,7 +78,7 @@ export class DDGIProbeRenderer extends RendererBase { this.probeRenderResult = new ProbeRenderResult(); - let probeGBufferFrame = new ProbeGBufferFrame(this.sizeW, this.sizeH); + let probeGBufferFrame = new ProbeGBufferFrame(this.sizeW, this.sizeH, false); this.positionMap = probeGBufferFrame.renderTargets[0]; this.normalMap = probeGBufferFrame.renderTargets[1]; this.colorMap = probeGBufferFrame.renderTargets[2]; @@ -341,9 +341,9 @@ export class DDGIProbeRenderer extends RendererBase { private initIrradianceMap(volume: DDGIIrradianceVolume): void { let setting = volume.setting; let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST; - this.irradianceDepthMap = new VirtualTexture(setting.octRTMaxSize, setting.octRTMaxSize, GPUTextureFormat.rgba16float, false, usage); + this.irradianceDepthMap = new RenderTexture(setting.octRTMaxSize, setting.octRTMaxSize, GPUTextureFormat.rgba16float, false, usage); this.irradianceDepthMap.name = 'irradianceDepthMap'; - this.irradianceColorMap = new VirtualTexture(setting.octRTMaxSize, setting.octRTMaxSize, GPUTextureFormat.rgba16float, false, usage); + this.irradianceColorMap = new RenderTexture(setting.octRTMaxSize, setting.octRTMaxSize, GPUTextureFormat.rgba16float, false, usage); this.irradianceColorMap.name = 'irradianceColorMap'; } @@ -351,7 +351,7 @@ export class DDGIProbeRenderer extends RendererBase { * @internal * @group DDGI */ - private writeToTexture(texture: VirtualTexture, array: Float32Array, width: number, height: number) { + private writeToTexture(texture: RenderTexture, array: Float32Array, width: number, height: number) { console.log(texture.name); const buffer = webGPUContext.device.createBuffer({ size: array.byteLength, diff --git a/src/gfx/renderJob/passRenderer/graphic/new/Float32ArrayUtil.ts b/src/gfx/renderJob/passRenderer/graphic/new/Float32ArrayUtil.ts new file mode 100644 index 00000000..88d59170 --- /dev/null +++ b/src/gfx/renderJob/passRenderer/graphic/new/Float32ArrayUtil.ts @@ -0,0 +1,11 @@ +import { Vector4 } from "../../../../.."; + +export class Float32ArrayUtil { + + public static wirteVec4(array: Float32Array, index: number, value: Vector4) { + array[index * 4 + 0] = value.x; + array[index * 4 + 1] = value.y; + array[index * 4 + 2] = value.z; + array[index * 4 + 3] = value.w; + } +} \ No newline at end of file diff --git a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DFaceRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DFaceRenderer.ts new file mode 100644 index 00000000..ba29519f --- /dev/null +++ b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DFaceRenderer.ts @@ -0,0 +1,172 @@ +import { graphicFaceCompute } from "../../../../../assets/shader/graphic/GraphicFaceCompute"; +import { graphicTrailCompute } from "../../../../../assets/shader/graphic/GraphicTrailCompute"; +import { MeshRenderer } from "../../../../../components/renderer/MeshRenderer"; +import { View3D } from "../../../../../core/View3D"; +import { Object3D } from "../../../../../core/entities/Object3D"; +import { UnLitTexArrayMaterial } from "../../../../../materials/UnLitTexArrayMaterial"; +import { Color } from "../../../../../math/Color"; +import { Vector3 } from "../../../../../math/Vector3"; +import { Vector4 } from "../../../../../math/Vector4"; +import { TriGeometry } from "../../../../../shape/TriGeometry"; +import { BitmapTexture2DArray } from "../../../../../textures/BitmapTexture2DArray"; +import { GeometryUtil } from "../../../../../util/GeometryUtil"; +import { Struct } from "../../../../../util/struct/Struct"; +import { GlobalBindGroup } from "../../../../graphics/webGpu/core/bindGroups/GlobalBindGroup"; +import { StorageGPUBuffer } from "../../../../graphics/webGpu/core/buffer/StorageGPUBuffer"; +import { StructStorageGPUBuffer } from "../../../../graphics/webGpu/core/buffer/StructStorageGPUBuffer"; +import { ComputeShader } from "../../../../graphics/webGpu/shader/ComputeShader"; +import { GPUContext } from "../../../GPUContext"; +import { Float32ArrayUtil } from "./Float32ArrayUtil"; + +export class GeometryInfo extends Struct { + public index: number = 0; + public faceStart: number = 0; + public faceEnd: number = 0; + public faceCount: number = 0; +} + +export class ShapeInfo extends Struct { + public shapeIndex: number = 0;; //face,poly,line,cycle,rectangle,box,sphere + public shapeType: number = 0; + public width: number = 0; + public height: number = 0; + public pathCount: number = 0; + public uSpeed: number = 0; + public vSpeed: number = 0; + public radiu: number = 0; + public paths: Float32Array = new Float32Array(Graphic3DFaceRenderer.maxPathPointCount * 4); +} + +export class Graphic3DFaceRenderer extends MeshRenderer { + public static maxFaceCount: number = 50000; + public static maxGeometryCount: number = 1; + public static maxShapeCount: number = 1; + public static maxPathPointCount: number = 50; + public texture: BitmapTexture2DArray; + public transformBuffer: StorageGPUBuffer; + + private _onChange: boolean = false; + private _computeGeoShader: ComputeShader; + + public geometryInfoBuffer: StructStorageGPUBuffer; + public shapeBuffer: StructStorageGPUBuffer; + + object3Ds: any[]; + shapes: ShapeInfo[]; + public init(): void { + super.init(); + } + + public create(tex: BitmapTexture2DArray, num: number) { + this._computeGeoShader = new ComputeShader(graphicFaceCompute(Graphic3DFaceRenderer.maxPathPointCount)); + this.geometryInfoBuffer = new StructStorageGPUBuffer(GeometryInfo, Graphic3DFaceRenderer.maxGeometryCount); + this.shapeBuffer = new StructStorageGPUBuffer(ShapeInfo, Graphic3DFaceRenderer.maxShapeCount); + + let geo = new TriGeometry(Graphic3DFaceRenderer.maxFaceCount) + let mat = new UnLitTexArrayMaterial(); + mat.baseMap = tex; + this.material = mat; + + this.transformBuffer = new StorageGPUBuffer(num * (4 * 4), 0); + this.material.setStorageBuffer("graphicBuffer", this.transformBuffer); + + this.object3Ds = []; + for (let i = 0; i < num; i++) { + const element = new Object3D(); + this.object3Ds.push(element); + this.object3D.addChild(element); + this.transformBuffer.setFloat("matrix_" + i, element.transform.worldMatrix.index); + this.transformBuffer.setFloat("texId_" + i, 1); + this.transformBuffer.setFloat("texId2_" + i, 1); + this.transformBuffer.setFloat("texId3_" + i, 1); + this.transformBuffer.setColor("baseColor_" + i, new Color()); + this.transformBuffer.setColor("emissiveColor_" + i, new Color(0, 0, 0, 0)); + this.transformBuffer.setVector4("uvRect_" + i, new Vector4(0, 0, 1, 1)); + } + + this.transformBuffer.apply(); + this.geometry = geo; + } + + public startShape(texture: BitmapTexture2DArray) { + this.create(texture, Graphic3DFaceRenderer.maxGeometryCount); + + let geos = []; + for (let i = 0; i < Graphic3DFaceRenderer.maxGeometryCount; i++) { + const geometryInfo = new GeometryInfo(); + geos.push(geometryInfo); + } + this.shapeBuffer.setStructArray(GeometryInfo, geos); + this.geometryInfoBuffer.apply(); + + this.shapes = []; + for (let i = 0; i < Graphic3DFaceRenderer.maxShapeCount; i++) { + const shapeInfo = new ShapeInfo(); + this.shapes.push(shapeInfo); + } + this.shapeBuffer.setStructArray(ShapeInfo, this.shapes); + this.shapeBuffer.apply(); + + this.start = () => { + this._computeGeoShader.setStorageBuffer("vertexBuffer", this.geometry.vertexBuffer.vertexGPUBuffer); + this._computeGeoShader.setStructStorageBuffer("geometryInfoBuffer", this.geometryInfoBuffer); + this._computeGeoShader.setStructStorageBuffer("shapeBuffer", this.shapeBuffer); + // this._computeGeoShader.setStorageBuffer("models", GlobalBindGroup.modelMatrixBindGroup.matrixBufferDst); + this._computeGeoShader.setStorageBuffer("globalUniform", GlobalBindGroup.getCameraGroup(this.transform.scene3D.view.camera).uniformGPUBuffer); + } + + this.onCompute = (view: View3D, command: GPUCommandEncoder) => this.computeTrail(view, command); + } + + public updateShape(index: number, shape: ShapeInfo) { + this.shapeBuffer.setStruct(ShapeInfo, index, shape); + this.shapeBuffer.apply(); + } + + public setTextureID(i: number, id: number) { + this.transformBuffer.setFloat("texId_" + i, id); + this._onChange = true; + } + + // public setTexture2ID(i: number, id: number) { + // this.transformBuffer.setFloat("texId_" + i, id); + // this._onChange = true; + // } + + // public setTexture3ID(i: number, id: number) { + // this.transformBuffer.setFloat("texId_" + i, id); + // this._onChange = true; + // } + + public setBaseColor(i: number, color: Color) { + this.transformBuffer.setColor("baseColor_" + i, color); + this._onChange = true; + } + + public setEmissiveColor(i: number, color: Color) { + this.transformBuffer.setColor("emissiveColor_" + i, color); + this._onChange = true; + } + + public setUVRect(i: number, v: Vector4) { + this.transformBuffer.setVector4("uvRect_" + i, v); + this._onChange = true; + } + + public onUpdate(view?: View3D) { + if (this._onChange) { + this._onChange = false; + this.transformBuffer.apply(); + } + } + + private computeTrail(view: View3D, command: GPUCommandEncoder) { + // this._computeShader.workerSizeX = this.ribbonCount; + this._computeGeoShader.workerSizeX = 1;// Math.floor(this.ribbonSegment / Graphic3DRibbonRenderer.maxRibbonSegment); + this._computeGeoShader.workerSizeY = 4;// Math.floor(this.ribbonSegment / Graphic3DRibbonRenderer.maxRibbonSegment); + // this._computeShader.workerSizeY = 1;// Math.floor(this.ribbonSegment / Graphic3DRibbonRenderer.maxRibbonSegment); + // this._computeShader.workerSizeX = 1; + GPUContext.computeCommand(command, [this._computeGeoShader]); + } + +} \ No newline at end of file diff --git a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMesh.ts b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMesh.ts index 5f35d318..8b0f082a 100644 --- a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMesh.ts +++ b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMesh.ts @@ -3,10 +3,15 @@ import { Object3D } from "../../../../../core/entities/Object3D"; import { GeometryBase } from "../../../../../core/geometry/GeometryBase"; import { BitmapTexture2DArray } from "../../../../../textures/BitmapTexture2DArray"; import { Graphic3DMeshRenderer } from "./Graphic3DMeshRenderer"; +import { Graphic3DRibbonRenderer } from "./Graphic3DRibbonRenderer"; +import { Graphic3DFaceRenderer } from "./Graphic3DFaceRenderer"; export class Graphic3DMesh { public static meshMap: Map = new Map(); public static meshDrawGroup: Map = new Map(); + public static ribbonMap: Map = new Map(); + public static faceMap: Map = new Map(); + public static draw(scene: Scene3D, geo: GeometryBase, texture: BitmapTexture2DArray, count: number): Graphic3DMeshRenderer { if (!this.meshMap.has(geo)) { let object = new Object3D(); @@ -17,4 +22,26 @@ export class Graphic3DMesh { return renderNode; } } + + public static drawRibbon(id: string, scene: Scene3D, texture: BitmapTexture2DArray, trailSegment: number, count: number): Graphic3DRibbonRenderer { + if (!this.ribbonMap.has(id)) { + let object = new Object3D(); + let renderNode = object.addComponent(Graphic3DRibbonRenderer); + renderNode.startRibbon(texture, trailSegment, count); + this.ribbonMap.set(id, renderNode); + scene.addChild(object); + return renderNode; + } + } + + public static drawShape(id: string, scene: Scene3D, texture: BitmapTexture2DArray): Graphic3DFaceRenderer { + if (!this.ribbonMap.has(id)) { + let object = new Object3D(); + let renderNode = object.addComponent(Graphic3DFaceRenderer); + renderNode.startShape(texture); + this.faceMap.set(id, renderNode); + scene.addChild(object); + return renderNode; + } + } } \ No newline at end of file diff --git a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts index b3e56f62..b30946b1 100644 --- a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts +++ b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts @@ -1,12 +1,21 @@ -import { Color, Vector4 } from "../../../../.."; +import { Vector2, mergeFunctions } from "../../../../.."; +import { graphicTrailCompute } from "../../../../../assets/shader/graphic/GraphicTrailCompute"; import { MeshRenderer } from "../../../../../components/renderer/MeshRenderer"; import { View3D } from "../../../../../core/View3D"; import { Object3D } from "../../../../../core/entities/Object3D"; import { GeometryBase } from "../../../../../core/geometry/GeometryBase"; +import { UnLitMaterial } from "../../../../../materials/UnLitMaterial"; import { UnLitTexArrayMaterial } from "../../../../../materials/UnLitTexArrayMaterial"; +import { Color } from "../../../../../math/Color"; +import { Vector4 } from "../../../../../math/Vector4"; +import { BoxGeometry } from "../../../../../shape/BoxGeometry"; +import { TrailGeometry } from "../../../../../shape/TrailGeometry"; import { BitmapTexture2DArray } from "../../../../../textures/BitmapTexture2DArray"; import { GeometryUtil } from "../../../../../util/GeometryUtil"; +import { GlobalBindGroup } from "../../../../graphics/webGpu/core/bindGroups/GlobalBindGroup"; import { StorageGPUBuffer } from "../../../../graphics/webGpu/core/buffer/StorageGPUBuffer"; +import { ComputeShader } from "../../../../graphics/webGpu/shader/ComputeShader"; +import { GPUContext } from "../../../GPUContext"; export class Graphic3DMeshRenderer extends MeshRenderer { public transformBuffer: StorageGPUBuffer; @@ -15,6 +24,8 @@ export class Graphic3DMeshRenderer extends MeshRenderer { public object3Ds: Object3D[]; private _onChange: boolean = false; + private _computeShader: ComputeShader; + public init(): void { super.init(); } @@ -24,8 +35,7 @@ export class Graphic3DMeshRenderer extends MeshRenderer { mat.baseMap = tex; this.material = mat; - this.transformBuffer = new StorageGPUBuffer( num * (4 * 4) , 0); - // this.transformBuffer = new StorageGPUBuffer( num * 2 , 0); + this.transformBuffer = new StorageGPUBuffer(num * (4 * 4), 0); this.material.setStorageBuffer("graphicBuffer", this.transformBuffer); this.object3Ds = []; @@ -38,15 +48,19 @@ export class Graphic3DMeshRenderer extends MeshRenderer { this.transformBuffer.setFloat("texId_" + i, 1); this.transformBuffer.setFloat("texId2_" + i, 1); this.transformBuffer.setFloat("texId3_" + i, 1); - this.transformBuffer.setColor("baseColor_" + i, new Color() ); - this.transformBuffer.setColor("emissiveColor_" + i, new Color(0,0,0,0)); - this.transformBuffer.setVector4("uvRect_" + i, new Vector4(0,0,1,1) ); + this.transformBuffer.setColor("baseColor_" + i, new Color()); + this.transformBuffer.setColor("emissiveColor_" + i, new Color(0, 0, 0, 0)); + this.transformBuffer.setVector4("uvRect_" + i, new Vector4(0, 0, 1, 1)); } this.transformBuffer.apply(); this.geometry = GeometryUtil.mergeNumber(source, num); } + public startSpark() { + + } + public setTextureID(i: number, id: number) { this.transformBuffer.setFloat("texId_" + i, id); this._onChange = true; @@ -84,4 +98,8 @@ export class Graphic3DMeshRenderer extends MeshRenderer { } } + private computeTrail(view: View3D, command: GPUCommandEncoder) { + GPUContext.computeCommand(command, [this._computeShader]); + } + } \ No newline at end of file diff --git a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DRibbonRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DRibbonRenderer.ts new file mode 100644 index 00000000..137bd279 --- /dev/null +++ b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DRibbonRenderer.ts @@ -0,0 +1,173 @@ +import { NonSerialize, StructStorageGPUBuffer, Vector3 } from "../../../../.."; +import { graphicTrailCompute } from "../../../../../assets/shader/graphic/GraphicTrailCompute"; +import { MeshRenderer } from "../../../../../components/renderer/MeshRenderer"; +import { View3D } from "../../../../../core/View3D"; +import { Object3D } from "../../../../../core/entities/Object3D"; +import { GeometryBase } from "../../../../../core/geometry/GeometryBase"; +import { UnLitTexArrayMaterial } from "../../../../../materials/UnLitTexArrayMaterial"; +import { Color } from "../../../../../math/Color"; +import { Vector2 } from "../../../../../math/Vector2"; +import { Vector4 } from "../../../../../math/Vector4"; +import { TrailGeometry } from "../../../../../shape/TrailGeometry"; +import { BitmapTexture2DArray } from "../../../../../textures/BitmapTexture2DArray"; +import { GeometryUtil } from "../../../../../util/GeometryUtil"; +import { Struct } from "../../../../../util/struct/Struct"; +import { GlobalBindGroup } from "../../../../graphics/webGpu/core/bindGroups/GlobalBindGroup"; +import { StorageGPUBuffer } from "../../../../graphics/webGpu/core/buffer/StorageGPUBuffer"; +import { ComputeShader } from "../../../../graphics/webGpu/shader/ComputeShader"; +import { GPUContext } from "../../../GPUContext"; + +export enum FaceMode { + FaceToCamera, + FaceToPath, + FaceToUp +} + +export class RibbonStruct extends Struct { + public index: number = 1; + public segment: number = 5; + public visible: number = 1; + public width: number = 0.25; + public uv: Vector4 = new Vector4(0, 0, 1, 30); + public uvSpeed: Vector2 = new Vector2(0, 2.1); + public smooth: number = 0; + public faceMode: number = FaceMode.FaceToCamera; + public up: Vector4 = new Vector4(0, 1, 0); + public ids: Float32Array = new Float32Array(Graphic3DRibbonRenderer.maxRibbonSegment); + + @NonSerialize + public ribbonPoint: Object3D[] = []; +} + +export class Graphic3DRibbonRenderer extends MeshRenderer { + public static maxRibbonSegment: number = 256; + public transformBuffer: StorageGPUBuffer; + public sourceGeometry: GeometryBase; + public texture: BitmapTexture2DArray; + public object3Ds: Object3D[]; + // public ribbon3Ds: Object3D[][]; + public ribbons: RibbonStruct[]; + public ribbonCount: number = 10; + + private _onChange: boolean = false; + private _computeShader: ComputeShader; + private _ribbonBuffer: StructStorageGPUBuffer; + ribbonSegment: number; + public init(): void { + super.init(); + } + + public create(ribbonSegment: number, tex: BitmapTexture2DArray, num: number) { + this.ribbons = []; + this.ribbonSegment = ribbonSegment; + for (let i = 0; i < num; i++) { + this.ribbons[i] = new RibbonStruct(); + this.ribbons[i].index = i; + this.ribbons[i].segment = ribbonSegment; + this.ribbons[i].width = 0.5; + this.ribbons[i].faceMode = FaceMode.FaceToCamera; + } + + let geo = new TrailGeometry(ribbonSegment) + let mat = new UnLitTexArrayMaterial(); + mat.baseMap = tex; + this.material = mat; + + this.transformBuffer = new StorageGPUBuffer(num * (4 * 4), 0); + this.material.setStorageBuffer("graphicBuffer", this.transformBuffer); + + this.object3Ds = []; + for (let i = 0; i < num; i++) { + const element = new Object3D(); + this.object3Ds.push(element); + this.object3D.addChild(element); + + this.transformBuffer.setFloat("matrix_" + i, element.transform.worldMatrix.index); + this.transformBuffer.setFloat("texId_" + i, 1); + this.transformBuffer.setFloat("texId2_" + i, 1); + this.transformBuffer.setFloat("texId3_" + i, 1); + this.transformBuffer.setColor("baseColor_" + i, new Color()); + this.transformBuffer.setColor("emissiveColor_" + i, new Color(0, 0, 0, 0)); + this.transformBuffer.setVector4("uvRect_" + i, new Vector4(0, 0, 1, 1)); + } + + this.transformBuffer.apply(); + this.geometry = GeometryUtil.mergeNumber(geo, num); + } + + public startRibbon(texture: BitmapTexture2DArray, ribonSegment: number, count: number) { + this.ribbonCount = count; + + this.create(ribonSegment, texture, count); + + this._computeShader = new ComputeShader(graphicTrailCompute(Graphic3DRibbonRenderer.maxRibbonSegment)); + this._ribbonBuffer = new StructStorageGPUBuffer(RibbonStruct, count); + + for (let i = 0; i < count; i++) { + this.ribbons[i].ribbonPoint = []; + for (let j = 0; j < Graphic3DRibbonRenderer.maxRibbonSegment; j++) { + const element = new Object3D(); + this.object3D.addChild(element); + this.ribbons[i].ribbonPoint[j] = element; + this.ribbons[i].ids[j] = element.transform.worldMatrix.index; + } + } + + this._ribbonBuffer.setStructArray(RibbonStruct, this.ribbons); + this._ribbonBuffer.apply(); + + this.start = () => { + this._computeShader.setStorageBuffer("vertexBuffer", this.geometry.vertexBuffer.vertexGPUBuffer); + this._computeShader.setStorageBuffer("trailBuffer", this._ribbonBuffer); + this._computeShader.setStorageBuffer("models", GlobalBindGroup.modelMatrixBindGroup.matrixBufferDst); + this._computeShader.setStorageBuffer("globalUniform", GlobalBindGroup.getCameraGroup(this.transform.scene3D.view.camera).uniformGPUBuffer); + } + + this.onCompute = (view: View3D, command: GPUCommandEncoder) => this.computeTrail(view, command); + } + + public setTextureID(i: number, id: number) { + this.transformBuffer.setFloat("texId_" + i, id); + this._onChange = true; + } + + // public setTexture2ID(i: number, id: number) { + // this.transformBuffer.setFloat("texId_" + i, id); + // this._onChange = true; + // } + + // public setTexture3ID(i: number, id: number) { + // this.transformBuffer.setFloat("texId_" + i, id); + // this._onChange = true; + // } + + public setBaseColor(i: number, color: Color) { + this.transformBuffer.setColor("baseColor_" + i, color); + this._onChange = true; + } + + public setEmissiveColor(i: number, color: Color) { + this.transformBuffer.setColor("emissiveColor_" + i, color); + this._onChange = true; + } + + public setUVRect(i: number, v: Vector4) { + this.transformBuffer.setVector4("uvRect_" + i, v); + this._onChange = true; + } + + public onUpdate(view?: View3D) { + if (this._onChange) { + this._onChange = false; + this.transformBuffer.apply(); + } + } + + private computeTrail(view: View3D, command: GPUCommandEncoder) { + this._computeShader.workerSizeX = this.ribbonCount; + this._computeShader.workerSizeY = 1;// Math.floor(this.ribbonSegment / Graphic3DRibbonRenderer.maxRibbonSegment); + // this._computeShader.workerSizeX = 1; + GPUContext.computeCommand(command, [this._computeShader]); + } + +} \ No newline at end of file diff --git a/src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts b/src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts index 8815cbaf..dd595303 100644 --- a/src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts +++ b/src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts @@ -21,7 +21,6 @@ import { WebGPUDescriptorCreator } from '../../../graphics/webGpu/descriptor/Web import { RendererPassState } from '../state/RendererPassState'; import { PassType } from '../state/RendererType'; import { ILight } from '../../../../components/lights/ILight'; -import { ShadowTexture } from '../../../../textures/ShadowTexture'; import { Reference } from '../../../../util/Reference'; type CubeShadowMapInfo = { @@ -61,11 +60,11 @@ export class PointLightShadowRenderer extends RendererBase { } else { let camera = new PointShadowCubeCamera(view.camera.near, view.camera.far, 90, true); camera.label = lightBase.name; - let depths: ShadowTexture[] = []; + let depths: VirtualTexture[] = []; let rendererPassStates: RendererPassState[] = []; for (let i = 0; i < 6; i++) { - let depthTexture = new ShadowTexture(this.shadowSize, this.shadowSize, this.cubeArrayTexture.format, false); + let depthTexture = new VirtualTexture(this.shadowSize, this.shadowSize, this.cubeArrayTexture.format, false); let rtFrame = new RTFrame([this.colorTexture], [new RTDescriptor()]); depthTexture.name = `shadowDepthTexture_` + lightBase.name + i + "_face"; rtFrame.depthTexture = depthTexture; diff --git a/src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts b/src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts index 9f2ed6bb..2a6278ca 100644 --- a/src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts +++ b/src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts @@ -5,7 +5,6 @@ import { Camera3D } from "../../../../core/Camera3D"; import { View3D } from "../../../../core/View3D"; import { Vector3 } from "../../../../math/Vector3"; import { Depth2DTextureArray } from "../../../../textures/Depth2DTextureArray"; -import { VirtualTexture } from "../../../../textures/VirtualTexture"; import { Time } from "../../../../util/Time"; import { GPUTextureFormat } from "../../../graphics/webGpu/WebGPUConst"; import { WebGPUDescriptorCreator } from "../../../graphics/webGpu/descriptor/WebGPUDescriptorCreator"; @@ -21,7 +20,7 @@ import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer"; import { Reference } from "../../../../util/Reference"; import { Texture } from "../../../graphics/webGpu/core/texture/Texture"; import { CSM } from "../../../../core/csm/CSM"; -import { ShadowTexture } from "../../../../textures/ShadowTexture"; +import { VirtualTexture } from "../../../../textures/VirtualTexture"; /** * @internal @@ -46,7 +45,7 @@ export class ShadowMapPassRenderer extends RendererBase { for (let i = 0; i < 8; i++) { let rtFrame = new RTFrame([], []); - const tex = new ShadowTexture(size, size, GPUTextureFormat.depth32float, false); + const tex = new VirtualTexture(size, size, GPUTextureFormat.depth32float, false); tex.name = `shadowDepthTexture_${i}`; rtFrame.depthTexture = tex; rtFrame.label = "shadowRender"; diff --git a/src/gfx/renderJob/passRenderer/state/RendererPassState.ts b/src/gfx/renderJob/passRenderer/state/RendererPassState.ts index 0a584154..7b9a97e1 100644 --- a/src/gfx/renderJob/passRenderer/state/RendererPassState.ts +++ b/src/gfx/renderJob/passRenderer/state/RendererPassState.ts @@ -1,7 +1,7 @@ import { Engine3D } from "../../../../Engine3D"; import { Camera3D } from "../../../../core/Camera3D"; -import { VirtualTexture } from "../../../../textures/VirtualTexture"; +import { RenderTexture } from "../../../../textures/RenderTexture"; import { Texture } from "../../../graphics/webGpu/core/texture/Texture"; import { RTDescriptor } from "../../../graphics/webGpu/descriptor/RTDescriptor"; import { RTFrame } from "../../frame/RTFrame"; @@ -13,8 +13,8 @@ export class RendererPassState { public label: string = ""; public customSize: boolean = false; - public zPreTexture: VirtualTexture = null; - public depthTexture: VirtualTexture = null; + public zPreTexture: RenderTexture = null; + public depthTexture: RenderTexture = null; public renderTargetTextures: GPUColorTargetState[]; public outColor: number = -1; public renderTargets: Texture[]; diff --git a/src/gfx/renderJob/post/BloomPost.ts b/src/gfx/renderJob/post/BloomPost.ts index e68aecb9..e015c9cf 100644 --- a/src/gfx/renderJob/post/BloomPost.ts +++ b/src/gfx/renderJob/post/BloomPost.ts @@ -1,4 +1,3 @@ -import { VirtualTexture } from '../../../textures/VirtualTexture'; import { UniformGPUBuffer } from '../../graphics/webGpu/core/buffer/UniformGPUBuffer'; import { WebGPUDescriptorCreator } from '../../graphics/webGpu/descriptor/WebGPUDescriptorCreator'; import { ComputeShader } from '../../graphics/webGpu/shader/ComputeShader'; @@ -12,6 +11,7 @@ import { View3D } from '../../../core/View3D'; import { RTDescriptor } from '../../graphics/webGpu/descriptor/RTDescriptor'; import { RTFrame } from '../frame/RTFrame'; import { downSample, post, threshold, upSample } from '../../../assets/shader/compute/BloomEffect_cs'; +import { VirtualTexture } from '../../../textures/VirtualTexture'; /** * Bloom Effects @@ -80,10 +80,10 @@ export class BloomPost extends PostBase { Engine3D.setting.render.postProcessing.bloom.downSampleBlurSize = value; } - public get downSampleBlurSigma(): number { return Engine3D.setting.render.postProcessing.bloom.downSampleBlurSigma; } + public set downSampleBlurSigma(value: number) { Engine3D.setting.render.postProcessing.bloom.downSampleBlurSigma = value; } @@ -91,6 +91,7 @@ export class BloomPost extends PostBase { public get upSampleBlurSize(): number { return Engine3D.setting.render.postProcessing.bloom.upSampleBlurSize; } + public set upSampleBlurSize(value: number) { Engine3D.setting.render.postProcessing.bloom.upSampleBlurSize = value; } @@ -98,6 +99,7 @@ export class BloomPost extends PostBase { public get upSampleBlurSigma(): number { return Engine3D.setting.render.postProcessing.bloom.upSampleBlurSigma; } + public set upSampleBlurSigma(value: number) { Engine3D.setting.render.postProcessing.bloom.upSampleBlurSigma = value; } @@ -105,6 +107,7 @@ export class BloomPost extends PostBase { public get luminanceThreshole(): number { return Engine3D.setting.render.postProcessing.bloom.luminanceThreshole; } + public set luminanceThreshole(value: number) { Engine3D.setting.render.postProcessing.bloom.luminanceThreshole = value; } @@ -112,6 +115,7 @@ export class BloomPost extends PostBase { public get bloomIntensity(): number { return Engine3D.setting.render.postProcessing.bloom.bloomIntensity; } + public set bloomIntensity(value: number) { Engine3D.setting.render.postProcessing.bloom.bloomIntensity = value; } @@ -129,7 +133,7 @@ export class BloomPost extends PostBase { private createDownSampleComputes() { let setting = Engine3D.setting.render.postProcessing.bloom; - const N = setting.downSampleStep; // 下采样次数 + const N = setting.downSampleStep; this.downSampleComputes = []; for (let i = 0; i < N; i++) { @@ -142,16 +146,14 @@ export class BloomPost extends PostBase { compute.workerSizeX = Math.ceil(dstTexture.width / 8); compute.workerSizeY = Math.ceil(dstTexture.height / 8); compute.workerSizeZ = 1; - this.downSampleComputes.push(compute); - // Graphics.Blit(RT_BloomDown[i - 1], RT_BloomDown[i], new Material(Shader.Find("Shaders/downSample"))); } } private createUpSampleComputes() { let setting = Engine3D.setting.render.postProcessing.bloom; - const N = setting.downSampleStep; // 下采样次数 + const N = setting.downSampleStep; this.upSampleComputes = []; { let compute = new ComputeShader(upSample); @@ -187,7 +189,7 @@ export class BloomPost extends PostBase { private createPostCompute() { let setting = Engine3D.setting.render.postProcessing.bloom; - const N = setting.downSampleStep; // 融合结果 + const N = setting.downSampleStep; this.postCompute = new ComputeShader(post); @@ -201,7 +203,6 @@ export class BloomPost extends PostBase { this.postCompute.workerSizeZ = 1; } - private createResource() { let setting = Engine3D.setting.render.postProcessing.bloom; @@ -213,12 +214,11 @@ export class BloomPost extends PostBase { this.RT_threshold = new VirtualTexture(screenWidth, screenHeight, GPUTextureFormat.rgba16float, false, GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC | GPUTextureUsage.TEXTURE_BINDING); - const N = setting.downSampleStep; // 下采样次数 + const N = setting.downSampleStep; { let downSize = 2; this.RT_BloomDown = []; - // 创建下纹理 for (let i = 0; i < N; i++) { let w = Math.ceil(screenWidth / downSize); let h = Math.ceil(screenHeight / downSize); @@ -228,7 +228,6 @@ export class BloomPost extends PostBase { } { - // 创建上采样纹理 this.RT_BloomUp = []; for (let i = 0; i < N - 1; i++) { let w = this.RT_BloomDown[N - 2 - i].width; @@ -240,9 +239,6 @@ export class BloomPost extends PostBase { let bloomDesc = new RTDescriptor(); bloomDesc.loadOp = `load`; - // this.rtFrame = new RTFrame([this.RT_threshold], [bloomDesc]); - // this.rtFrame = new RTFrame([this.RT_BloomDown[4]], [bloomDesc]); - // this.rtFrame = new RTFrame([this.RT_BloomUp[5]], [bloomDesc]); this.rtFrame = new RTFrame([this.RT_threshold], [bloomDesc]); } @@ -277,4 +273,61 @@ export class BloomPost extends PostBase { GPUContext.lastRenderPassState = this.rendererPassState; } + public onResize() { + let cfg = Engine3D.setting.render.postProcessing.bloom; + + let presentationSize = webGPUContext.presentationSize; + let screenWidth = presentationSize[0]; + let screenHeight = presentationSize[1]; + this.RT_threshold.resize(screenWidth, screenHeight); + const N = cfg.downSampleStep; + let downSize = 2; + // + for (let i = 0; i < N; i++) { + let w = Math.ceil(screenWidth / downSize); + let h = Math.ceil(screenHeight / downSize); + this.RT_BloomDown[i].resize(w, h); + downSize *= 2; + } + + for (let i = 0; i < N - 1; i++) { + let w = this.RT_BloomDown[N - 2 - i].width; + let h = this.RT_BloomDown[N - 2 - i].height; + this.RT_BloomUp[i].resize(w, h); + } + + this.thresholdCompute.workerSizeX = Math.ceil(this.RT_threshold.width / 8); + this.thresholdCompute.workerSizeY = Math.ceil(this.RT_threshold.height / 8); + this.thresholdCompute.workerSizeZ = 1; + + for (let i = 0; i < N; i++) { + let compute = this.downSampleComputes[i]; + let dstTexture = this.RT_BloomDown[i]; + compute.workerSizeX = Math.ceil(dstTexture.width / 8); + compute.workerSizeY = Math.ceil(dstTexture.height / 8); + compute.workerSizeZ = 1; + } + + { + let dstTexture = this.RT_BloomUp[0]; + let compute = this.upSampleComputes[0]; + compute.workerSizeX = Math.ceil(dstTexture.width / 8); + compute.workerSizeY = Math.ceil(dstTexture.height / 8); + compute.workerSizeZ = 1; + } + + { + for (let i = 1; i < N - 1; i++) { + let dstTexture = this.RT_BloomUp[i]; + let compute = this.upSampleComputes[i]; + compute.workerSizeX = Math.ceil(dstTexture.width / 8); + compute.workerSizeY = Math.ceil(dstTexture.height / 8); + compute.workerSizeZ = 1; + } + } + + this.postCompute.workerSizeX = Math.ceil(this.RT_threshold.width / 8); + this.postCompute.workerSizeY = Math.ceil(this.RT_threshold.height / 8); + this.postCompute.workerSizeZ = 1; + } } diff --git a/src/gfx/renderJob/post/DepthOfFieldPost.ts b/src/gfx/renderJob/post/DepthOfFieldPost.ts index fc92a435..67dc413b 100644 --- a/src/gfx/renderJob/post/DepthOfFieldPost.ts +++ b/src/gfx/renderJob/post/DepthOfFieldPost.ts @@ -78,10 +78,6 @@ export class DepthOfFieldPost extends PostBase { Engine3D.setting.render.postProcessing.depthOfView.enable = false; } - private createGUI() { - - } - public get pixelOffset() { let setting = Engine3D.setting.render.postProcessing.depthOfView; return setting.pixelOffset; @@ -129,8 +125,8 @@ export class DepthOfFieldPost extends PostBase { blurCompute.setUniformBuffer('blurSetting', blurSetting); let rtFrame = GBufferFrame.getGBufferFrame("ColorPassGBuffer"); - blurCompute.setSamplerTexture(RTResourceConfig.positionBufferTex_NAME, rtFrame.renderTargets[1]); - blurCompute.setSamplerTexture(RTResourceConfig.normalBufferTex_NAME, rtFrame.renderTargets[2]); + blurCompute.setSamplerTexture(RTResourceConfig.positionBufferTex_NAME, rtFrame.getPositionMap()); + blurCompute.setSamplerTexture(RTResourceConfig.normalBufferTex_NAME, rtFrame.getNormalMap()); let input = i % 2 == 0 ? this.blurTexture1 : this.blurTexture2; let output = i % 2 == 1 ? this.blurTexture1 : this.blurTexture2; @@ -177,21 +173,17 @@ export class DepthOfFieldPost extends PostBase { if (!this.blurComputes) { this.createResource(); this.createBlurCompute(); - this.createGUI(); - let standUniform = GlobalBindGroup.getCameraGroup(view.camera); for (let i = 0; i < this.blurComputes.length; i++) { const blurCompute = this.blurComputes[i]; - blurCompute.setUniformBuffer('standUniform', standUniform.uniformGPUBuffer); + blurCompute.setUniformBuffer('globalUniform', standUniform.uniformGPUBuffer); } this.rendererPassState = WebGPUDescriptorCreator.createRendererPassState(this.rtFrame, null); } - this.autoSetColorTexture('inTex', this.blurComputes[0]); let cfg = Engine3D.setting.render.postProcessing.depthOfView; cfg.far = Math.max(cfg.near, cfg.far) + 0.0001; - for (let i = 0; i < cfg.iterationCount; i++) { let blurCompute = this.blurComputes[i]; let blurSetting = this.blurSettings[i]; @@ -201,9 +193,25 @@ export class DepthOfFieldPost extends PostBase { blurSetting.apply(); blurCompute.setStorageBuffer('blurSetting', blurSetting); } - GPUContext.computeCommand(command, this.blurComputes); - GPUContext.lastRenderPassState = this.rendererPassState; } + + public onResize(): void { + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + let cfg = Engine3D.setting.render.postProcessing.depthOfView; + cfg.far = Math.max(cfg.near, cfg.far) + 0.0001; + + this.blurTexture1.resize(w, h); + this.blurTexture2.resize(w, h); + + for (let i = 0; i < cfg.iterationCount; i++) { + let compute = this.blurComputes[i]; + compute.workerSizeX = Math.ceil(this.blurTexture1.width / 8); + compute.workerSizeY = Math.ceil(this.blurTexture1.height / 8); + compute.workerSizeZ = 1; + } + } } diff --git a/src/gfx/renderJob/post/GTAOPost.ts b/src/gfx/renderJob/post/GTAOPost.ts index 049cb45e..cf4c6409 100644 --- a/src/gfx/renderJob/post/GTAOPost.ts +++ b/src/gfx/renderJob/post/GTAOPost.ts @@ -17,6 +17,7 @@ import { RTDescriptor } from '../../graphics/webGpu/descriptor/RTDescriptor'; import { GBufferFrame } from '../frame/GBufferFrame'; import { RTFrame } from '../frame/RTFrame'; import { GTAO_cs } from '../../../assets/shader/compute/GTAO_cs'; +import { CResizeEvent } from '../../../event/CResizeEvent'; /** * Ground base Ambient Occlusion @@ -68,14 +69,12 @@ export class GTAOPost extends PostBase { */ onAttach(view: View3D,) { Engine3D.setting.render.postProcessing.gtao.enable = true; - this.createGUI(); } /** * @internal */Render onDetach(view: View3D,) { Engine3D.setting.render.postProcessing.gtao.enable = false; - this.removeGUI(); } public get maxDistance() { @@ -153,14 +152,6 @@ export class GTAOPost extends PostBase { setting.usePosFloat32 = value; } - private createGUI() { - - } - - private removeGUI() { - } - - private createCompute() { let setting = Engine3D.setting.render.postProcessing.gtao; @@ -180,16 +171,12 @@ export class GTAOPost extends PostBase { this.gtaoCompute.setStorageBuffer('aoBuffer', this.aoBuffer); let rtFrame = GBufferFrame.getGBufferFrame("ColorPassGBuffer"); //setting.usePosFloat32 ? RTResourceMap.getTexture(RTResourceConfig.positionBufferTex_NAME): - let posTexture = rtFrame.renderTargets[1]; + let posTexture = rtFrame.getPositionMap(); this.gtaoCompute.setSamplerTexture(`posTex`, posTexture); this.gtaoCompute.setSamplerTexture(`normalTex`, rtFrame.renderTargets[2]); this.autoSetColorTexture('inTex', this.gtaoCompute); this.gtaoCompute.setStorageTexture(`outTex`, this.gtaoTexture); - this.gtaoCompute.workerSizeX = Math.ceil(this.gtaoTexture.width / 8); - this.gtaoCompute.workerSizeY = Math.ceil(this.gtaoTexture.height / 8); - this.gtaoCompute.workerSizeZ = 1; - this.gtaoSetting = gtaoSetting; } @@ -235,6 +222,7 @@ export class GTAOPost extends PostBase { if (!this.gtaoCompute) { this.createResource(); this.createCompute(); + this.onResize(); this.rendererPassState = WebGPUDescriptorCreator.createRendererPassState(this.rtFrame, null); this.rendererPassState.label = "GTAO"; @@ -265,4 +253,15 @@ export class GTAOPost extends PostBase { GPUContext.computeCommand(command, [this.gtaoCompute]); GPUContext.lastRenderPassState = this.rendererPassState; } + + public onResize() { + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + this.gtaoTexture.resize(w, h); + + this.gtaoCompute.workerSizeX = Math.ceil(this.gtaoTexture.width / 8); + this.gtaoCompute.workerSizeY = Math.ceil(this.gtaoTexture.height / 8); + this.gtaoCompute.workerSizeZ = 1; + } } \ No newline at end of file diff --git a/src/gfx/renderJob/post/GlobalFog.ts b/src/gfx/renderJob/post/GlobalFog.ts index 7c8c163b..16a9fe3a 100644 --- a/src/gfx/renderJob/post/GlobalFog.ts +++ b/src/gfx/renderJob/post/GlobalFog.ts @@ -215,6 +215,7 @@ export class GlobalFog extends PostBase { } return texture; } + /** * @internal */ diff --git a/src/gfx/renderJob/post/GodRayPost.ts b/src/gfx/renderJob/post/GodRayPost.ts index e59cadab..38a5e314 100644 --- a/src/gfx/renderJob/post/GodRayPost.ts +++ b/src/gfx/renderJob/post/GodRayPost.ts @@ -15,7 +15,7 @@ import { RTDescriptor } from '../../graphics/webGpu/descriptor/RTDescriptor'; import { GBufferFrame } from '../frame/GBufferFrame'; import { RTFrame } from '../frame/RTFrame'; import { GodRay_cs } from '../../../assets/shader/compute/GodRay_cs'; -import { GUIHelp } from '@orillusion/debug/GUIHelp'; +import { clamp } from '../../../math/MathUtil'; export class GodRayPost extends PostBase { @@ -50,21 +50,44 @@ export class GodRayPost extends PostBase { * @internal */ onAttach(view: View3D,) { - // Engine3D.setting.render.postProcessing.gtao.enable = true; + Engine3D.setting.render.postProcessing.godRay.enable = true; this.createGUI(); } /** * @internal */Render onDetach(view: View3D,) { - // Engine3D.setting.render.postProcessing.gtao.enable = false; + Engine3D.setting.render.postProcessing.godRay.enable = false; this.removeGUI(); } - public blendColor: boolean = true; - public rayMarchCount: number = 16; - public scatteringExponent: number = 5; - public intensity: number = 0.5; + public get blendColor(): boolean { + return Engine3D.setting.render.postProcessing.godRay.blendColor; + } + public set blendColor(value: boolean) { + Engine3D.setting.render.postProcessing.godRay.blendColor = value; + } + public get rayMarchCount(): number { + return Engine3D.setting.render.postProcessing.godRay.rayMarchCount; + } + public set rayMarchCount(value: number) { + value = clamp(value, 8, 20); + Engine3D.setting.render.postProcessing.godRay.rayMarchCount = value; + } + public get scatteringExponent(): number { + return Engine3D.setting.render.postProcessing.godRay.scatteringExponent; + } + public set scatteringExponent(value: number) { + value = clamp(value, 1, 40); + Engine3D.setting.render.postProcessing.godRay.scatteringExponent = value; + } + public get intensity(): number { + return Engine3D.setting.render.postProcessing.godRay.intensity; + } + public set intensity(value: number) { + value = clamp(value, 0.01, 5); + Engine3D.setting.render.postProcessing.godRay.intensity = value; + } private createGUI() { @@ -75,7 +98,7 @@ export class GodRayPost extends PostBase { private createCompute(view: View3D) { - let setting = Engine3D.setting.render.postProcessing.gtao; + let setting = Engine3D.setting.render.postProcessing.godRay; this.godRayCompute = new ComputeShader(GodRay_cs); @@ -95,11 +118,9 @@ export class GodRayPost extends PostBase { let shadowRenderer = Engine3D.getRenderJob(view).shadowMapPassRenderer; this.godRayCompute.setSamplerTexture(`shadowMap`, shadowRenderer.depth2DArrayTexture); - this.godRayCompute.workerSizeX = Math.ceil(this.godRayTexture.width / 8); - this.godRayCompute.workerSizeY = Math.ceil(this.godRayTexture.height / 8); - this.godRayCompute.workerSizeZ = 1; - this.godRaySetting = godRaySetting; + + this.onResize(); } private createResource() { @@ -114,6 +135,20 @@ export class GodRayPost extends PostBase { this.rtFrame = new RTFrame([this.godRayTexture], [gtaoDec]); } + public onResize() { + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + + this.godRayTexture.resize(w, h); + this.historyGodRayData.resizeBuffer(4 * this.godRayTexture.width * this.godRayTexture.height); + this.godRayCompute.setStorageBuffer('historyGodRayData', this.historyGodRayData); + + this.godRayCompute.workerSizeX = Math.ceil(this.godRayTexture.width / 8); + this.godRayCompute.workerSizeY = Math.ceil(this.godRayTexture.height / 8); + this.godRayCompute.workerSizeZ = 1; + } + /** * @internal */ @@ -131,28 +166,21 @@ export class GodRayPost extends PostBase { let globalUniform = GlobalBindGroup.getCameraGroup(view.camera); this.godRayCompute.setUniformBuffer('globalUniform', globalUniform.uniformGPUBuffer); - - GUIHelp.addFolder("GodRay"); - GUIHelp.add(this, "blendColor", 0.0, 1.0, 0.1); - GUIHelp.add(this, 'scatteringExponent', 1, 10.0, 0.1); - GUIHelp.add(this, 'rayMarchCount', 10, 30.0, 1.0); - GUIHelp.add(this, 'intensity', 0.01, 2.0, 0.01); - - GUIHelp.endFolder(); } - this.godRaySetting.setFloat('intensity', this.intensity); - this.godRaySetting.setFloat('rayMarchCount', this.rayMarchCount); + let setting = Engine3D.setting.render.postProcessing.godRay; - let camera = view.camera; - this.godRaySetting.setFloat('viewPortWidth', camera.viewPort.width); - this.godRaySetting.setFloat('viewPortHeight', camera.viewPort.height); - - this.godRaySetting.setFloat('blendColor', this.blendColor ? 1 : 0); - this.godRaySetting.setFloat('scatteringExponent', this.scatteringExponent); + this.godRaySetting.setFloat('intensity', setting.intensity); + this.godRaySetting.setFloat('rayMarchCount', setting.rayMarchCount); + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + this.godRaySetting.setFloat('viewPortWidth', w); + this.godRaySetting.setFloat('viewPortHeight', h); + this.godRaySetting.setFloat('blendColor', setting.blendColor ? 1 : 0); + this.godRaySetting.setFloat('scatteringExponent', setting.scatteringExponent); this.godRaySetting.apply(); - GPUContext.computeCommand(command, [this.godRayCompute]); GPUContext.lastRenderPassState = this.rendererPassState; } diff --git a/src/gfx/renderJob/post/OutlinePost.ts b/src/gfx/renderJob/post/OutlinePost.ts index a3b54abe..84d58c5b 100644 --- a/src/gfx/renderJob/post/OutlinePost.ts +++ b/src/gfx/renderJob/post/OutlinePost.ts @@ -25,14 +25,12 @@ import { OutlinePostSlot, outlinePostData } from '../../../io/OutlinePostData'; * post effect out line * OutlinePostManager, * ``` - * //setting - * let cfg = {@link Engine3D.setting.render.postProcessing.outline}; - * let view = new View3D(); - view.scene = this.scene; - view.camera = mainCamera; - - * - * Engine3D.startRender(renderJob); + * setting + * let cfg = {@link Engine3D.setting.render.postProcessing.outline}; + * let view = new View3D(); + * view.scene = this.scene; + * view.camera = mainCamera; + * Engine3D.startRender(renderJob); *``` * @group Post Effects */ @@ -40,40 +38,63 @@ export class OutlinePost extends PostBase { /** * @internal */ - outlineTex: VirtualTexture; - - lowTex: VirtualTexture; - + private outlineTex: VirtualTexture; + /** + * @internal + */ + private lowTex: VirtualTexture; /** * @internal */ - rendererPassState: RendererPassState; + private rendererPassState: RendererPassState; /** * @internal */ - calcWeightCompute: ComputeShader; - outlineCompute: ComputeShader; - blendCompute: ComputeShader; + private calcWeightCompute: ComputeShader; /** * @internal */ - outlineSetting: StorageGPUBuffer; - + private outlineCompute: ComputeShader; + /** + * @internal + */ + private blendCompute: ComputeShader; /** * @internal */ - slotsBuffer: StorageGPUBuffer; - slotsArray: Float32Array; - - - entitiesArray: Float32Array; - entitiesBuffer: StorageGPUBuffer; - - weightBuffer: StorageGPUBuffer; - lowTexSize: Vector2; - - oldOutlineColor: StorageGPUBuffer; - rtFrame: RTFrame; + private outlineSetting: StorageGPUBuffer; + /** + * @internal + */ + private slotsBuffer: StorageGPUBuffer; + /** + * @internal + */ + private slotsArray: Float32Array; + /** + * @internal + */ + private entitiesArray: Float32Array; + /** + * @internal + */ + private entitiesBuffer: StorageGPUBuffer; + /** + * @internal + */ + private weightBuffer: StorageGPUBuffer; + /** + * @internal + */ + private lowTexSize: Vector2; + /** + * @internal + */ + private oldOutlineColor: StorageGPUBuffer; + /** + * @internal + */ + private rtFrame: RTFrame; constructor() { super(); @@ -268,4 +289,30 @@ export class OutlinePost extends PostBase { GPUContext.computeCommand(command, this.computeList); GPUContext.lastRenderPassState = this.rendererPassState; } + + public onResize(): void { + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + let textureScale = Engine3D.setting.render.postProcessing.outline.textureScale; + this.lowTexSize = new Vector2(Math.ceil(w * textureScale), Math.ceil(h * textureScale)); + + this.lowTex.resize(this.lowTexSize.x, this.lowTexSize.y); + this.outlineTex.resize(w, h); + + this.weightBuffer.resizeBuffer(this.lowTexSize.x * this.lowTexSize.y * 4); + this.oldOutlineColor.resizeBuffer(this.lowTexSize.x * this.lowTexSize.y * 4); + + this.calcWeightCompute.workerSizeX = Math.ceil(this.lowTex.width / 8); + this.calcWeightCompute.workerSizeY = Math.ceil(this.lowTex.height / 8); + this.calcWeightCompute.workerSizeZ = 1; + + this.outlineCompute.workerSizeX = Math.ceil(this.lowTex.width / 8); + this.outlineCompute.workerSizeY = Math.ceil(this.lowTex.height / 8); + this.outlineCompute.workerSizeZ = 1; + + this.blendCompute.workerSizeX = Math.ceil(this.outlineTex.width / 8); + this.blendCompute.workerSizeY = Math.ceil(this.outlineTex.height / 8); + this.blendCompute.workerSizeZ = 1; + } } diff --git a/src/gfx/renderJob/post/PostBase.ts b/src/gfx/renderJob/post/PostBase.ts index 7c1b9cba..660cde78 100644 --- a/src/gfx/renderJob/post/PostBase.ts +++ b/src/gfx/renderJob/post/PostBase.ts @@ -9,6 +9,8 @@ import { RTResourceConfig } from '../config/RTResourceConfig'; import { PostRenderer } from '../passRenderer/post/PostRenderer'; import { View3D } from '../../../core/View3D'; import { Reference } from '../../../util/Reference'; +import { CResizeEvent } from '../../../event/CResizeEvent'; +import { webGPUContext } from '../../graphics/webGpu/Context3D'; /** * @internal * Base class for post-processing effects @@ -23,6 +25,8 @@ export class PostBase { constructor() { this.rtViewQuad = new Map(); this.virtualTexture = new Map(); + + webGPUContext.addEventListener(CResizeEvent.RESIZE, this.onResize, this); } protected createRTTexture(name: string, rtWidth: number, rtHeight: number, format: GPUTextureFormat, useMipmap: boolean = false, sampleCount: number = 0) { @@ -57,15 +61,18 @@ export class PostBase { /** * @internal */ - public compute(view: View3D,) { } + public compute(view: View3D) { } /** * @internal */ - public onAttach(view: View3D,) { } + public onAttach(view: View3D) { } /** * @internal */ - public onDetach(view: View3D,) { } + public onDetach(view: View3D) { } + public onResize() { + + } /** * @internal */ diff --git a/src/gfx/renderJob/post/SSRPost.ts b/src/gfx/renderJob/post/SSRPost.ts index 2746ccdb..e3e77256 100644 --- a/src/gfx/renderJob/post/SSRPost.ts +++ b/src/gfx/renderJob/post/SSRPost.ts @@ -289,6 +289,38 @@ export class SSRPost extends PostBase { GPUContext.computeCommand(command, computes); GPUContext.lastRenderPassState = this.rendererPassState; } + + public onResize(): void { + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + let ssrWidth = Math.ceil(w * Engine3D.setting.render.postProcessing.ssr.pixelRatio); + let ssrHeight = Math.ceil(h * Engine3D.setting.render.postProcessing.ssr.pixelRatio); + + this.finalTexture.resize(w, h); + this.isRetTexture.resize(ssrWidth, ssrHeight); + + this.rayTraceData.resizeBuffer(ssrWidth * ssrHeight * 8); + this.ssrColorData.resizeBuffer(ssrWidth * ssrHeight * 4); + this.historyPosition.resizeBuffer(ssrWidth * ssrHeight * 4); + + this.ssrUniformBuffer.setFloat('ssrBufferSizeX', this.isRetTexture.width); + this.ssrUniformBuffer.setFloat('ssrBufferSizeY', this.isRetTexture.height); + this.ssrUniformBuffer.setFloat('colorMapSizeX', this.finalTexture.width); + this.ssrUniformBuffer.setFloat('colorMapSizeY', this.finalTexture.height); + + this.SSR_RayTraceCompute.workerSizeX = Math.ceil(this.isRetTexture.width / 8); + this.SSR_RayTraceCompute.workerSizeY = Math.ceil(this.isRetTexture.height / 8); + this.SSR_RayTraceCompute.workerSizeZ = 1; + + this.SSR_IS_Compute.workerSizeX = Math.ceil(this.isRetTexture.width / 8); + this.SSR_IS_Compute.workerSizeY = Math.ceil(this.isRetTexture.height / 8); + this.SSR_IS_Compute.workerSizeZ = 1; + + this.SSR_Blend_Compute.workerSizeX = Math.ceil(this.finalTexture.width / 8); + this.SSR_Blend_Compute.workerSizeY = Math.ceil(this.finalTexture.height / 8); + this.SSR_Blend_Compute.workerSizeZ = 1; + } } /** diff --git a/src/gfx/renderJob/post/TAAPost.ts b/src/gfx/renderJob/post/TAAPost.ts index e395351b..ad4d16f3 100644 --- a/src/gfx/renderJob/post/TAAPost.ts +++ b/src/gfx/renderJob/post/TAAPost.ts @@ -19,6 +19,7 @@ import { View3D } from '../../../core/View3D'; import { TAA_cs } from '../../../assets/shader/compute/TAA_cs'; import { TAACopyTex_cs } from '../../../assets/shader/compute/TAACopyTex_cs'; import { TAASharpTex_cs } from '../../../assets/shader/compute/TAASharpTex_cs'; +import { CResizeEvent } from '../../../event/CResizeEvent'; /** * Temporal AA @@ -249,12 +250,32 @@ export class TAAPost extends PostBase { this.taaSetting.apply(); GPUContext.computeCommand(command, [this.copyTexCompute, this.taaCompute, this.sharpCompute]); - GPUContext.lastRenderPassState = this.rendererPassState; - this.preProjMatrix.copyFrom(view.camera.projectionMatrix); this.preViewMatrix.copyFrom(view.camera.viewMatrix); + } + + public onResize(): void { + let presentationSize = webGPUContext.presentationSize; + let w = presentationSize[0]; + let h = presentationSize[1]; + + this.preColorBuffer.resizeBuffer(w * h * 4); + + this.taaTexture.resize(w, h); + this.outTexture.resize(w, h); + this.preColorTex.resize(w, h); - // view.camera.getViewMatrix(this.preViewMatrix); + this.taaCompute.workerSizeX = Math.ceil(this.taaTexture.width / 8); + this.taaCompute.workerSizeY = Math.ceil(this.taaTexture.height / 8); + this.taaCompute.workerSizeZ = 1; + + this.copyTexCompute.workerSizeX = Math.ceil(this.taaTexture.width / 8); + this.copyTexCompute.workerSizeY = Math.ceil(this.taaTexture.height / 8); + this.copyTexCompute.workerSizeZ = 1; + + this.sharpCompute.workerSizeX = Math.ceil(this.outTexture.width / 8); + this.sharpCompute.workerSizeY = Math.ceil(this.outTexture.height / 8); + this.sharpCompute.workerSizeZ = 1; } } diff --git a/src/index.ts b/src/index.ts index 70fff56e..dddf5952 100644 --- a/src/index.ts +++ b/src/index.ts @@ -57,6 +57,10 @@ export * from "./assets/shader/glsl/Sky_glsl" export * from "./assets/shader/glsl/post/LUT_glsl" export * from "./assets/shader/graphic/Graphic3DShader_fs" export * from "./assets/shader/graphic/Graphic3DShader_vs" +export * from "./assets/shader/graphic/GraphicFaceComput2" +export * from "./assets/shader/graphic/GraphicFaceCompute" +export * from "./assets/shader/graphic/GraphicFaceCompute3" +export * from "./assets/shader/graphic/GraphicTrailCompute" export * from "./assets/shader/lighting/BRDF_frag" export * from "./assets/shader/lighting/BsDF_frag" export * from "./assets/shader/lighting/BxDF_frag" @@ -339,8 +343,11 @@ export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DLineBatchRenderer" export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DRender" export * from "./gfx/renderJob/passRenderer/graphic/GraphicConfig" export * from "./gfx/renderJob/passRenderer/graphic/Graphics3DShape" +export * from "./gfx/renderJob/passRenderer/graphic/new/Float32ArrayUtil" +export * from "./gfx/renderJob/passRenderer/graphic/new/Graphic3DFaceRenderer" export * from "./gfx/renderJob/passRenderer/graphic/new/Graphic3DMesh" export * from "./gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer" +export * from "./gfx/renderJob/passRenderer/graphic/new/Graphic3DRibbonRenderer" export * from "./gfx/renderJob/passRenderer/post/PostRenderer" export * from "./gfx/renderJob/passRenderer/preDepth/PreDepthPassRenderer" export * from "./gfx/renderJob/passRenderer/preDepth/ZCullingCompute" @@ -524,6 +531,7 @@ export * from "./setting/post/BloomSetting" export * from "./setting/post/DepthOfViewSetting" export * from "./setting/post/GTAOSetting" export * from "./setting/post/GlobalFogSetting" +export * from "./setting/post/GodRaySetting" export * from "./setting/post/OutlineSetting" export * from "./setting/post/SSRSetting" export * from "./setting/post/TAASetting" @@ -533,6 +541,8 @@ export * from "./shape/PlaneGeometry" export * from "./shape/SphereGeometry" export * from "./shape/StripeGeometry" export * from "./shape/TorusGeometry" +export * from "./shape/TrailGeometry" +export * from "./shape/TriGeometry" export * from "./textures/AtmosphericScatteringSky" export * from "./textures/BitmapTexture2D" export * from "./textures/BitmapTexture2DArray" @@ -545,7 +555,7 @@ export * from "./textures/Float32ArrayTexture" export * from "./textures/HDRTexture" export * from "./textures/HDRTextureCube" export * from "./textures/LDRTextureCube" -export * from "./textures/ShadowTexture" +export * from "./textures/RenderTexture" export * from "./textures/SolidColorSky" export * from "./textures/TextureCubeFaceData" export * from "./textures/Uint16Texture" diff --git a/src/loader/parser/prefab/mats/MaterialUtilities.ts b/src/loader/parser/prefab/mats/MaterialUtilities.ts index ecea5dcd..b178e50a 100644 --- a/src/loader/parser/prefab/mats/MaterialUtilities.ts +++ b/src/loader/parser/prefab/mats/MaterialUtilities.ts @@ -22,8 +22,7 @@ export class MaterialUtilities { material.shader = new shader(); return material; } else { - throw new console.error("not found shader, shader name is " + name); - + throw new Error("not found shader, shader name is " + name); } } diff --git a/src/loader/parser/prefab/prefabData/APatch.ts b/src/loader/parser/prefab/prefabData/APatch.ts index 3c91b196..f55bee6f 100644 --- a/src/loader/parser/prefab/prefabData/APatch.ts +++ b/src/loader/parser/prefab/prefabData/APatch.ts @@ -4,7 +4,7 @@ import { Color } from "../../../../math/Color"; import { Vector2 } from "../../../../math/Vector2"; import { RegisterComponent } from "../../../../util/SerializeDecoration"; -@RegisterComponent +@RegisterComponent(APatch, 'APatch') export class APatch extends ComponentBase { public size: Vector2; public blockSize: number; diff --git a/src/setting/RenderSetting.ts b/src/setting/RenderSetting.ts index f050347a..d86f95a7 100644 --- a/src/setting/RenderSetting.ts +++ b/src/setting/RenderSetting.ts @@ -5,6 +5,7 @@ import { OutlineSetting } from "./post/OutlineSetting"; import { SSRSetting } from "./post/SSRSetting"; import { TAASetting } from "./post/TAASetting"; import { BloomSetting } from "./post/BloomSetting"; +import { GodRaySetting } from "./post/GodRaySetting"; export type RenderSetting = { debug: boolean; @@ -43,6 +44,7 @@ export type RenderSetting = { gtao?: GTAOSetting; outline?: OutlineSetting; globalFog?: GlobalFogSetting; + godRay?: GodRaySetting; fxaa?: { enable: boolean; }; diff --git a/src/setting/post/GodRaySetting.ts b/src/setting/post/GodRaySetting.ts new file mode 100644 index 00000000..4b23bcd4 --- /dev/null +++ b/src/setting/post/GodRaySetting.ts @@ -0,0 +1,12 @@ + +/** + * GodRay + * @group Setting + */ +export type GodRaySetting = { + enable?: boolean, + blendColor: boolean, + rayMarchCount: number, + scatteringExponent: number, + intensity: number +}; \ No newline at end of file diff --git a/src/shape/TrailGeometry.ts b/src/shape/TrailGeometry.ts new file mode 100644 index 00000000..eab501bc --- /dev/null +++ b/src/shape/TrailGeometry.ts @@ -0,0 +1,93 @@ +import { BoundingBox } from "../core/bound/BoundingBox"; +import { GeometryBase } from "../core/geometry/GeometryBase"; +import { VertexAttributeName } from "../core/geometry/VertexAttributeName"; +import { Vector3 } from "../math/Vector3"; + +/** + * Plane geometry + * @group Geometry + */ +export class TrailGeometry extends GeometryBase { + + /** + * Number of trail segments of a plane + */ + public segment: number; + private row: number = 0; + /** + * + * @constructor + */ + constructor(segment: number) { + super(); + this.segment = segment; + this.buildGeometry(); + } + + private buildGeometry(): void { + this.row = this.segment + 1; + let indices_arr = new Uint32Array(this.segment * 6); + let position_arr = new Float32Array(this.row * 3 * 2); + let normal_arr = new Float32Array(this.row * 3 * 2); + let uv_arr = new Float32Array(this.row * 2 * 2); + + for (let i = 0; i < this.row; i++) { + position_arr[i * 3 * 2 + 0] = 0; + position_arr[i * 3 * 2 + 1] = 0; + position_arr[i * 3 * 2 + 2] = 0; + + position_arr[i * 3 * 2 + 3] = 0; + position_arr[i * 3 * 2 + 4] = 0; + position_arr[i * 3 * 2 + 5] = 0; + + normal_arr[i * 3 * 2 + 0] = 0; + normal_arr[i * 3 * 2 + 1] = 0; + normal_arr[i * 3 * 2 + 2] = 1; + + normal_arr[i * 3 * 2 + 3] = 0; + normal_arr[i * 3 * 2 + 4] = 0; + normal_arr[i * 3 * 2 + 5] = 1; + + uv_arr[i * 2 * 2 + 0] = 0; + uv_arr[i * 2 * 2 + 1] = i / this.segment; + + uv_arr[i * 2 * 2 + 2] = 1; + uv_arr[i * 2 * 2 + 3] = i / this.segment; + + let c = i * 2; + let f0 = c; + let f1 = c + 1; + let f2 = c + 2; + let f3 = c + 3; + + indices_arr[i * 6 + 0] = f0; + indices_arr[i * 6 + 1] = f1; + indices_arr[i * 6 + 2] = f2; + + indices_arr[i * 6 + 3] = f1; + indices_arr[i * 6 + 4] = f3; + indices_arr[i * 6 + 5] = f2; + } + + // c = i * 2 + //c -> (c + 1) -> (c + 2) + //(c + 2) -> (c + 1) -> (c + 3) + + this.setIndices(indices_arr); + this.setAttribute(VertexAttributeName.position, position_arr); + this.setAttribute(VertexAttributeName.normal, normal_arr); + this.setAttribute(VertexAttributeName.uv, uv_arr); + this.setAttribute(VertexAttributeName.TEXCOORD_1, uv_arr); + + this.addSubGeometry({ + indexStart: 0, + indexCount: indices_arr.length, + vertexStart: 0, + vertexCount: 0, + firstStart: 0, + index: 0, + topology: 0 + }); + } + +} diff --git a/src/shape/TriGeometry.ts b/src/shape/TriGeometry.ts new file mode 100644 index 00000000..e8b5af55 --- /dev/null +++ b/src/shape/TriGeometry.ts @@ -0,0 +1,62 @@ +import { GeometryBase } from "../core/geometry/GeometryBase"; +import { VertexAttributeName } from "../core/geometry/VertexAttributeName"; + +/** + * Plane geometry + * @group Geometry + */ +export class TriGeometry extends GeometryBase { + + + private faceCount: number = 0; + /** + * + * @constructor + */ + constructor(count: number) { + super(); + this.faceCount = count; + this.buildGeometry(); + } + + private buildGeometry(): void { + let indices_arr = new Uint32Array(this.faceCount * 3); + let position_arr = new Float32Array(this.faceCount * 3 * 3); + let normal_arr = new Float32Array(this.faceCount * 3 * 3); + let uv_arr = new Float32Array(this.faceCount * 3 * 2); + let meshIndexList = new Float32Array(this.faceCount * 3 * 1); + + // for (let index = 0; index < this.faceCount * 3; index++) { + // position_arr[index * 3 + 0] = Math.random() * 100; + // position_arr[index * 3 + 1] = Math.random() * 100; + // position_arr[index * 3 + 2] = Math.random() * 100; + // } + + for (let index = 0; index < this.faceCount; index++) { + let i1 = index * 3 + 0; + let i2 = index * 3 + 1; + let i3 = index * 3 + 2; + indices_arr[i1] = i1; + indices_arr[i2] = i2; + indices_arr[i3] = i3; + } + + this.setIndices(indices_arr); + this.setAttribute(VertexAttributeName.position, position_arr); + this.setAttribute(VertexAttributeName.normal, normal_arr); + this.setAttribute(VertexAttributeName.uv, uv_arr); + this.setAttribute(VertexAttributeName.TEXCOORD_1, uv_arr); + this.setAttribute(VertexAttributeName.vIndex, meshIndexList); + + this.addSubGeometry({ + indexStart: 0, + indexCount: indices_arr.length, + vertexStart: 0, + vertexCount: 0, + firstStart: 0, + index: 0, + topology: 0 + }); + } + +} diff --git a/src/textures/BitmapTexture2DArray.ts b/src/textures/BitmapTexture2DArray.ts index f6897ae9..3d949698 100644 --- a/src/textures/BitmapTexture2DArray.ts +++ b/src/textures/BitmapTexture2DArray.ts @@ -117,14 +117,16 @@ export class BitmapTexture2DArray extends Texture implements ITexture { dimension: '2d', usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING, } - this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + // this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + this.gpuTexture = this.getGPUTexture(); } internalCreateView() { this.viewDescriptor = { dimension: `2d-array`, }; - this.view = this.gpuTexture.createView(this.viewDescriptor); + // this.view = this.gpuTexture.createView(this.viewDescriptor); + this.view = this.getGPUView(); } internalCreateSampler() { diff --git a/src/textures/BitmapTextureCube.ts b/src/textures/BitmapTextureCube.ts index c4558d19..d6b254d3 100644 --- a/src/textures/BitmapTextureCube.ts +++ b/src/textures/BitmapTextureCube.ts @@ -41,7 +41,8 @@ export class BitmapTextureCube extends TextureCube { this.textureDescriptor.size = { width: this.width, height: this.height, depthOrArrayLayers: 6 }; this.textureDescriptor.dimension = '2d'; - this.gpuTexture = device.createTexture(this.textureDescriptor); + // this.gpuTexture = device.createTexture(this.textureDescriptor); + this.gpuTexture = this.getGPUTexture(); let faceTextures: GPUTexture[] = []; let lastFaceTextures: GPUTexture[] = faceTextures; diff --git a/src/textures/Depth2DTextureArray.ts b/src/textures/Depth2DTextureArray.ts index 4b858844..bccd351d 100644 --- a/src/textures/Depth2DTextureArray.ts +++ b/src/textures/Depth2DTextureArray.ts @@ -41,14 +41,16 @@ export class Depth2DTextureArray extends Texture implements ITexture { dimension: '2d', usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING, } - this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + // this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + this.gpuTexture = this.getGPUTexture(); } internalCreateView() { this.viewDescriptor = { dimension: `2d-array`, }; - this.view = this.gpuTexture.createView(this.viewDescriptor); + this.view = this.getGPUView(); + // this.view = this.gpuTexture.createView(this.viewDescriptor); } internalCreateSampler() { diff --git a/src/textures/DepthCubeArrayTexture.ts b/src/textures/DepthCubeArrayTexture.ts index b0bb57fe..d1f50a63 100644 --- a/src/textures/DepthCubeArrayTexture.ts +++ b/src/textures/DepthCubeArrayTexture.ts @@ -38,14 +38,16 @@ export class DepthCubeArrayTexture extends Texture implements ITexture { dimension: '2d', usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING, } - this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + // this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + this.gpuTexture = this.getGPUTexture(); } internalCreateView() { this.viewDescriptor = { dimension: `cube-array`, }; - this.view = this.gpuTexture.createView(this.viewDescriptor); + this.view = this.getGPUView(); + // this.view = this.gpuTexture.createView(this.viewDescriptor); } internalCreateSampler() { diff --git a/src/textures/DepthCubeTexture.ts b/src/textures/DepthCubeTexture.ts index dd19734d..08814fb6 100644 --- a/src/textures/DepthCubeTexture.ts +++ b/src/textures/DepthCubeTexture.ts @@ -56,14 +56,16 @@ export class DepthCubeTexture extends Texture implements ITexture { dimension: '2d', usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING, } - this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + // this.gpuTexture = webGPUContext.device.createTexture(this.textureDescriptor); + this.gpuTexture = this.getGPUTexture(); } public internalCreateView() { this.viewDescriptor = { dimension: `cube`, }; - this.view = this.gpuTexture.createView(this.viewDescriptor); + this.view = this.getGPUView(); + // this.view = this.gpuTexture.createView(this.viewDescriptor); } public internalCreateSampler() { diff --git a/src/textures/ShadowTexture.ts b/src/textures/RenderTexture.ts similarity index 86% rename from src/textures/ShadowTexture.ts rename to src/textures/RenderTexture.ts index 2c46720c..26277ec6 100644 --- a/src/textures/ShadowTexture.ts +++ b/src/textures/RenderTexture.ts @@ -10,19 +10,12 @@ import { CResizeEvent } from '..'; * Render what we want to render onto a texture instead of rendering it onto the screen as we usually do * @group Texture */ -export class ShadowTexture extends Texture { +export class RenderTexture extends Texture { public resolveTarget: GPUTextureView; - sampleCount: number; - // storeOp: string = 'store'; - // loadOp: GPULoadOp = `load`; - // clearValue: GPUColor = [0, 0, 0, 0]; - - public clone() { - let texture = new ShadowTexture(this.width, this.height, this.format, this.useMipmap, this.usage, this.numberLayer, this.sampleCount); - texture.name = "clone_" + texture.name; - return texture; - } + sampleCount: number; + autoResize?: boolean; + clear?: boolean; /** * create virtual texture * @param width width of texture @@ -31,15 +24,21 @@ export class ShadowTexture extends Texture { * @param useMipmap whether or not gen mipmap * @returns */ - constructor(width: number, height: number, format: GPUTextureFormat = GPUTextureFormat.rgba8unorm, useMipMap: boolean = false, usage?: GPUFlagsConstant, numberLayer: number = 1, sampleCount: number = 0, clear: boolean = true) { + constructor(width: number, height: number, + format: GPUTextureFormat = GPUTextureFormat.rgba8unorm, + useMipMap: boolean = false, usage?: GPUFlagsConstant, + numberLayer: number = 1, sampleCount: number = 0, + clear: boolean = true, autoResize: boolean = true) { + super(width, height, numberLayer); - let device = webGPUContext.device; this.name = UUID(); + this.autoResize = autoResize; this.useMipmap = useMipMap; this.sampleCount = sampleCount; this.format = format; this.numberLayer = numberLayer; + this.clear = clear; if (usage != undefined) { this.usage = usage; @@ -47,20 +46,23 @@ export class ShadowTexture extends Texture { this.usage = usage | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST; } - // if (this.usage & GPUTextureUsage.RENDER_ATTACHMENT || this.format == GPUTextureFormat.depth24plus || this.format == GPUTextureFormat.depth32float) { - // webGPUContext.addEventListener(CResizeEvent.RESIZE, (e) => { - // let { width, height } = e.data; - // this.resize(width, height); - // }, this); - // } this.resize(width, height); + + if (autoResize) { + webGPUContext.addEventListener(CResizeEvent.RESIZE, (e) => { + let { width, height } = e.data; + this.resize(width, height); + this._textureChange = true; + }, this); + } + } public resize(width, height) { let device = webGPUContext.device; if (this.gpuTexture) { + Texture.delayDestroyTexture(this.gpuTexture); this.gpuTexture = null; - // Texture.delayDestroyTexture(this.gpuTexture); this.view = null; } @@ -117,6 +119,8 @@ export class ShadowTexture extends Texture { // this.visibility = GPUShaderStage.FRAGMENT; this.gpuSampler = device.createSampler(this); } + + this._textureChange = true; } /** @@ -157,6 +161,12 @@ export class ShadowTexture extends Texture { GPUContext.endCommandEncoder(commandEncoder); } + public clone() { + let texture = new RenderTexture(this.width, this.height, this.format, this.useMipmap, this.usage, this.numberLayer, this.sampleCount, this.clear, this.autoResize); + texture.name = "clone_" + texture.name; + return texture; + } + public readTextureToImage() { let device = webGPUContext.device; let w = webGPUContext.windowWidth; diff --git a/src/textures/VirtualTexture.ts b/src/textures/VirtualTexture.ts index 43b28807..de342f78 100644 --- a/src/textures/VirtualTexture.ts +++ b/src/textures/VirtualTexture.ts @@ -3,7 +3,6 @@ import { GPUAddressMode, GPUTextureFormat } from '../gfx/graphics/webGpu/WebGPUC import { webGPUContext } from '../gfx/graphics/webGpu/Context3D'; import { GPUContext } from '../gfx/renderJob/GPUContext'; import { UUID } from '../util/Global'; -import { CResizeEvent } from '..'; /** * @internal * Render target texture @@ -47,12 +46,6 @@ export class VirtualTexture extends Texture { this.usage = usage | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST; } - if (this.usage & GPUTextureUsage.RENDER_ATTACHMENT || this.format == GPUTextureFormat.depth24plus || this.format == GPUTextureFormat.depth32float) { - webGPUContext.addEventListener(CResizeEvent.RESIZE, (e) => { - let { width, height } = e.data; - this.resize(width, height); - }, this); - } this.resize(width, height); } @@ -66,13 +59,8 @@ export class VirtualTexture extends Texture { this.width = width; this.height = height; - this.createTextureDescriptor(width, height, 1, this.format, this.usage, this.numberLayer, this.sampleCount); - // this.loadOp = clear ? `clear` : `load` - // this.loadOp = `clear` - this.useMipmap = false; - this.visibility = GPUShaderStage.COMPUTE | GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT; if (this.format == GPUTextureFormat.rgba32float) { @@ -114,9 +102,10 @@ export class VirtualTexture extends Texture { this.addressModeU = GPUAddressMode.clamp_to_edge; this.addressModeV = GPUAddressMode.clamp_to_edge; - // this.visibility = GPUShaderStage.FRAGMENT; this.gpuSampler = device.createSampler(this); } + + this._textureChange = true; } /** diff --git a/src/util/SerializeDecoration.ts b/src/util/SerializeDecoration.ts index 398b8b0d..a457a36e 100644 --- a/src/util/SerializeDecoration.ts +++ b/src/util/SerializeDecoration.ts @@ -11,7 +11,7 @@ export function NonSerialize(cls, key): any { dic[key] = true; } -export function IsNonSerialize(instance: T, key: keyof T): boolean { +export function IsNonSerialize(instance: T, key: string): boolean { let noSerializeDic; while (instance) { instance = instance['__proto__']; @@ -84,7 +84,7 @@ export function RegisterComponent(cls, key, p1?, p2?, p3?): any { if (!dic) { dic = window['__Component__'] = {}; } - dic[cls.name] = cls; + dic[key] = cls; } export function GetComponentClass(name: string) { @@ -100,7 +100,7 @@ export function RegisterShader(cls, key, p1?, p2?, p3?): any { if (!dic) { dic = window['__shader__'] = {}; } - dic[cls.name] = cls; + dic[key] = cls; } export function GetShader(name: string) { diff --git a/src/util/struct/Struct.ts b/src/util/struct/Struct.ts index 6edb1a58..3060c586 100644 --- a/src/util/struct/Struct.ts +++ b/src/util/struct/Struct.ts @@ -6,13 +6,16 @@ * @group Util */ import { Ctor } from "../Global"; +import { EditorInspector, IsNonSerialize, NonSerialize } from "../SerializeDecoration"; export class Struct { + @NonSerialize private __refection: { name: string; type: string; }[]; + @NonSerialize private __size: number = 0; /** @@ -24,7 +27,7 @@ export class Struct { let self = this; this.__refection = []; for (const key in self) { - if (!key.includes(`__`)) { + if (!IsNonSerialize(this, key)) { const element = self[key]; let att = { name: key, @@ -61,13 +64,13 @@ export class Struct { return 1 * 4; case `Float32Array`: - return value.byteLength * 4; + return value.byteLength; case `Vector2`: return 2 * 4; case `Vector3`: - return 4 * 4; + return 3 * 4; case `Vector4`: return 4 * 4; @@ -110,7 +113,7 @@ export class Struct { let struct = this.Get(c); if (struct.__size == 0) { for (const key in struct) { - if (key.indexOf(`__`) == -1) { + if (!IsNonSerialize(struct, key)) { const element = struct[key]; struct.__size += Struct.getValueSize(element); } From 0957d1af022d818daaf3e8ca51409f98d4484fee Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Tue, 14 Nov 2023 21:38:13 +0800 Subject: [PATCH 2/7] bump v0.7.1 --- CHANGELOG.md | 23 +++++++++++++++++++++++ package.json | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd661031..4d11c0f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +## [0.7.1](https://github.com/Orillusion/orillusion/compare/v0.7.0...v0.7.1) (2023-11-14) + + +### Bug Fixes + +* Auto sort transparent renderers. ([#318](https://github.com/Orillusion/orillusion/issues/318)) ([5becdc4](https://github.com/Orillusion/orillusion/commit/5becdc48739e4ce7745d15a60c46612f991ae5f2)) +* fix: load gltf sample +* fix: fix grass sample +* fix: fix media-extention material +* fix: fix post sample resize bug +* fix: fix csm shadow +* fix: Cancel automatic resizing of rendertexture in GI +* fix: Wrong offset for bloom +* fix: reduce texture sample times +* fix: texture Count Exceeded the maximum limit of 7 + +### Features +* **engine:** enable gpu attachments texture auto resize +* **graphic:** add new graphic samples +* **sample:** update physics car sample ([#327](https://github.com/Orillusion/orillusion/issues/327)) ([e09b243](https://github.com/Orillusion/orillusion/commit/e09b24386bb517d1277e00dcaa4105999d2dd856)) + + + # [0.7.0](https://github.com/Orillusion/orillusion/compare/v0.6.9...v0.7.0) (2023-11-01) diff --git a/package.json b/package.json index db371c08..4e591b2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orillusion/core", - "version": "0.7.0", + "version": "0.7.1", "author": "Orillusion", "description": "Orillusion WebGPU Engine", "main": "./dist/orillusion.umd.js", @@ -31,7 +31,7 @@ "dev": "vite", "build": "tsc --p tsconfig.build.json && vite build && npm run build:types && npm run minify", "build:test": "tsc --p tsconfig.build.json && vite build", - "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json && mv dist/src dist/types", + "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json && rm -rf dist/packages && mv dist/src dist/types", "minify": "./node_modules/vite/node_modules/.bin/esbuild dist/orillusion.es.max.js --minify --outfile=dist/orillusion.es.js && ./node_modules/vite/node_modules/.bin/esbuild dist/orillusion.umd.max.js --minify --outfile=dist/orillusion.umd.js", "test": "electron test/ci/main.js", "test:ci": "xvfb-maybe -- electron --enable-unsafe-webgpu --enable-features=Vulkan --use-vulkan=swiftshader --use-webgpu-adapter=swiftshader --no-sandbox test/ci/main.js", From 481aa35f19fae3a41449397534d82991ef91886d Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Wed, 15 Nov 2023 15:56:43 +0800 Subject: [PATCH 3/7] chore: update packages version --- packages/effect/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/effect/package.json b/packages/effect/package.json index 1bf36ae6..56698654 100644 --- a/packages/effect/package.json +++ b/packages/effect/package.json @@ -1,6 +1,6 @@ { "name": "@orillusion/effect", - "version": "0.1.1", + "version": "0.1.2", "author": "Orillusion", "description": "Orillusion Effects Plugin", "main": "./dist/effect.umd.js", From ff469840ef157c77ac5c17b6e6cff2f8cdcfffae Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Thu, 16 Nov 2023 00:23:36 +0800 Subject: [PATCH 4/7] chore: fix sample graphicline --- samples/graphic/Sample_GraphicLine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/graphic/Sample_GraphicLine.ts b/samples/graphic/Sample_GraphicLine.ts index 436abe52..384d2958 100644 --- a/samples/graphic/Sample_GraphicLine.ts +++ b/samples/graphic/Sample_GraphicLine.ts @@ -1,11 +1,11 @@ import { createExampleScene, createSceneParam } from "@samples/utils/ExampleScene"; -import { Object3D, Scene3D, Engine3D, GlobalIlluminationComponent, Object3DUtil, GTAOPost, PostProcessingComponent, TAAPost, Vector3, Color, AnimationCurve, Keyframe } from "@orillusion/core"; +import { Scene3D, Engine3D, Vector3, Color, AnimationCurve, Keyframe, View3D } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; import { GUIHelp } from "@orillusion/debug/GUIHelp"; class Sample_GraphicLine { scene: Scene3D; - view: import("c:/work/git/orillusion-nian/src/index").View3D; + view: View3D; async run() { Engine3D.setting.material.materialChannelDebug = true; From b7bf87362e6d9ad2d755ff22f462c71f2b2f18f1 Mon Sep 17 00:00:00 2001 From: moyuer1992 Date: Thu, 16 Nov 2023 16:25:19 +0800 Subject: [PATCH 5/7] feat(sample): add draw mesh line sample (#331) --------- Co-authored-by: ShuangLiu --- samples/graphic/Sample_MeshLines.ts | 172 ++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 samples/graphic/Sample_MeshLines.ts diff --git a/samples/graphic/Sample_MeshLines.ts b/samples/graphic/Sample_MeshLines.ts new file mode 100644 index 00000000..1b988693 --- /dev/null +++ b/samples/graphic/Sample_MeshLines.ts @@ -0,0 +1,172 @@ +import { Engine3D, Scene3D, CameraUtil, HoverCameraController, Object3D, MeshRenderer, View3D, PlaneGeometry, UnLitMaterial, Color, Vector3, PointerEvent3D, Camera3D, SphereGeometry, CylinderGeometry, MathUtil, BlendMode, GPUCullMode } from '@orillusion/core'; +import * as dat from "@orillusion/debug/dat.gui.module"; +import { Stats } from '@orillusion/stats'; + +class Sample_MeshLines { + private onDraw: boolean = false + private scene: Scene3D + private camera: Camera3D + private lastTime: number + private path: Object3D[] = [] + private hoverCameraController: HoverCameraController; + private lastX: number = -1 + private lastY: number = -1 + private pointGeometry: SphereGeometry + private lineGeometry: CylinderGeometry + private material: UnLitMaterial + + public lineWidth: number = 0.1 + public drawInterval: number = 30 + public precision: number = 32 + public depth: number = 0 + public lineColor: Color = new Color(1, 0, 0) + + async run() { + // init engine + await Engine3D.init(); + // create new Scene + let scene = new Scene3D(); + scene.addComponent(Stats) + this.scene = scene; + + // init camera3D + let mainCamera = CameraUtil.createCamera3D(null, scene); + mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); + + // add a basic camera controller + this.hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController); + this.hoverCameraController.setCamera(0, 0, 20) + + this.camera = mainCamera + + this.pointGeometry = new SphereGeometry(0.5, 32, 32) + this.lineGeometry = new CylinderGeometry(0.5, 0.5, 1, 32, 32) + this.material = new UnLitMaterial() + this.material.baseColor = this.lineColor + + // add basic plane + let plane = new Object3D(); + let mr = plane.addComponent(MeshRenderer); + mr.geometry = new PlaneGeometry(20, 20, 1, 1, Vector3.Z_AXIS); + let mat = new UnLitMaterial() + mat.baseColor = new Color(1, 1, 1, 0.4) + mat.transparent = true + mat.cullMode = GPUCullMode.none + mat.blendMode = BlendMode.NORMAL + mr.material = mat; + scene.addChild(plane); + + // create a view with target scene and camera + let view = new View3D(); + view.scene = scene; + view.camera = mainCamera; + + // start render + Engine3D.startRenderView(view); + + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_DOWN, this.onMouseDown, this, null, 999); + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_MOVE, this.onMouseMove, this); + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_UP, this.onMouseUp, this); + + // debug GUI + let gui = new dat.GUI(); + let f = gui.addFolder('Orillusion'); + f.add(this, 'lineWidth', 0.1, 2, 0.1); + f.add(this, 'precision', 4, 64, 1).onChange((precision) => { + this.lineGeometry = new CylinderGeometry(0.5, 0.5, 1, precision, precision) + this.pointGeometry = new SphereGeometry(0.5, precision, precision) + }); + f.add(this, 'depth', -1, 1, 0.01); + f.add(this, 'drawInterval', 15, 100, 1); + f.addColor({lineColor: Object.values(this.lineColor).map((v,i)=> i === 3 ? v : v*255)}, 'lineColor').onChange(v=>{ + this.lineColor = new Color(v[0]/255, v[1]/255, v[2]/255, v[3]) + this.material = new UnLitMaterial() + this.material.baseColor = this.lineColor + }); + f.add({'resetView': () => this.hoverCameraController.setCamera(0, 0, 20)}, 'resetView') + f.add({'clearCanvas': () => { + this.path.map((point) => { + this.scene.removeChild(point) + }) + this.path.length = 0 + }}, 'clearCanvas') + f.open() + + // add tips + gui.add({tips: 'Press to rotate camera'}, 'tips').name('Left Mouse') + gui.add({tips: 'Press to draw lines'}, 'tips').name('Right Mouse') + } + + onMouseDown(e: PointerEvent3D) { + if(e.mouseCode === 2) { + e.stopImmediatePropagation() + this.lastTime = Date.now() + this.onDraw = true; + this.drawPoint(e.mouseX, e.mouseY); + this.lastX = e.mouseX; + this.lastY = e.mouseY; + } + } + + onMouseMove(e: PointerEvent3D) { + if (!this.onDraw) return; + e.stopImmediatePropagation() + const now = Date.now(); + if (now - this.lastTime > this.drawInterval) { + this.drawLine(e.mouseX, e.mouseY); + this.drawPoint(e.mouseX, e.mouseY); + this.lastTime = now; + this.lastX = e.mouseX + this.lastY = e.mouseY + } + } + + onMouseUp(e: PointerEvent3D) { + this.onDraw = false; + this.lastX = -1; + this.lastY = -1; + } + + drawPoint(x: number, y: number) { + let point = new Object3D(); + let mr = point.addComponent(MeshRenderer); + mr.geometry = this.pointGeometry; + mr.material = this.material; + point.scaleX = point.scaleY = point.scaleZ = this.lineWidth + this.camera.worldToScreenPoint(this.hoverCameraController.target, Vector3.HELP_0) + const pos = this.camera.screenPointToWorld(x, y, Vector3.HELP_0.z + this.depth / 100); + point.x = pos.x; + point.y = pos.y; + point.z = pos.z; + this.path.push(point); + this.scene.addChild(point); + } + + drawLine(x: number, y: number) { + this.camera.worldToScreenPoint(this.hoverCameraController.target, Vector3.HELP_0) + const start = this.camera.screenPointToWorld(this.lastX, this.lastY, Vector3.HELP_0.z + this.depth / 100); + const end = this.camera.screenPointToWorld(x, y, Vector3.HELP_0.z); + const distance = Math.sqrt(end.distanceToSquared(start)) + let line = new Object3D(); + let mr = line.addComponent(MeshRenderer); + mr.geometry = this.lineGeometry; + mr.material = this.material; + line.scaleX = line.scaleZ = this.lineWidth; + line.scaleY = distance; + line.x = start.x + (end.x - start.x) / 2; + line.y = start.y + (end.y - start.y) / 2; + line.z = start.z + (end.z - start.z) / 2; + + // normalize the direction vector + const dir = Vector3.HELP_1.set(end.x - start.x, end.y - start.y, end.z - start.z).normalize() + const rot = MathUtil.fromToRotation(Vector3.Y_AXIS, dir) + // make sure the rotation is valid + if (!Number.isNaN(rot.x) && !Number.isNaN(rot.y) && !Number.isNaN(rot.z)) { + line.transform.localRotQuat = rot; + } + this.path.push(line); + this.scene.addChild(line); + } +} + +new Sample_MeshLines().run() From 3a0293a5c530678d71a63b15bbeb7caa69d3a9d6 Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Fri, 17 Nov 2023 18:19:51 +0800 Subject: [PATCH 6/7] chore: fix destroy sample --- samples/base/Sample_Destroy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/base/Sample_Destroy.ts b/samples/base/Sample_Destroy.ts index 3a8d6947..d7ab4d37 100644 --- a/samples/base/Sample_Destroy.ts +++ b/samples/base/Sample_Destroy.ts @@ -65,8 +65,9 @@ class Sample_Destroy { GUIHelp.addButton("del", () => { for (let i = 0; i < list.length; i++) { const obj = list[i]; - obj.destroy(); + obj.destroy(true); } + list.length = 0; }); GUIHelp.open() } From 2fc6f27d91ebdee871168cad2a723d76411cdfd3 Mon Sep 17 00:00:00 2001 From: ShuangLiu Date: Sat, 18 Nov 2023 15:49:09 +0800 Subject: [PATCH 7/7] perf(build): use esnext as build target prevent performance lose in old js target --- vite.config.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/vite.config.js b/vite.config.js index 403e39bc..75884c5e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -56,16 +56,17 @@ export default defineConfig(option => ({ server.watcher.on('unlink', autoIndex) } }, { - name: 'cors', - configureServer: server => { - // server.middlewares.use((_req, res, next) => { - // res.setHeader("Cross-Origin-Resource-Policy", "cross-origin") - // res.setHeader("Cross-Origin-Opener-Policy", "same-origin") - // res.setHeader("Cross-Origin-Embedder-Policy", "require-corp") - // }) - } + // name: 'cors', + // configureServer: server => { + // server.middlewares.use((_req, res, next) => { + // res.setHeader("Cross-Origin-Resource-Policy", "cross-origin") + // res.setHeader("Cross-Origin-Opener-Policy", "same-origin") + // res.setHeader("Cross-Origin-Embedder-Policy", "require-corp") + // }) + // } }], build: { + target: 'esnext', lib: { entry: resolve(__dirname, './src/index.ts'), name: 'Orillusion',