From a1eeb043072354d1aa60fefc88242379d10fe8f4 Mon Sep 17 00:00:00 2001
From: sirxu <397939361@qq.com>
Date: Fri, 22 Sep 2023 21:19:26 +0800
Subject: [PATCH 01/51] feat: add new prefab data load and parser
add new prefab data load and parser
add prefab component
---
samples/game/Sample_Game.ts | 178 ++++++++++++++
samples/index.ts | 157 ++++++------
samples/prefab/Sample_Prefab.ts | 80 ++++++
samples/utils/GUIUtil.ts | 16 +-
src/Engine3D.ts | 16 ++
src/assets/Res.ts | 86 ++++++-
src/assets/shader/core/base/Common_frag.ts | 7 -
.../shader/core/common/GlobalUniform.ts | 14 +-
.../shader/core/pass/CastShadow_pass.ts | 147 +++++++----
.../shader/core/struct/VertexAttributes.ts | 118 ++++++---
src/assets/shader/lighting/BRDF_frag.ts | 29 ++-
src/assets/shader/lighting/BxDF_frag.ts | 36 +--
src/assets/shader/lighting/Irradiance_frag.ts | 7 +-
.../shader/lighting/LightingFunction_frag.ts | 2 +-
src/assets/shader/materials/ColorLitShader.ts | 2 +-
src/assets/shader/materials/LitShader.ts | 2 +-
src/assets/shader/materials/PBRLItShader.ts | 133 ++++++----
src/assets/shader/materials/PavementShader.ts | 4 +-
.../materials/program/NormalMap_frag.ts | 10 +-
.../materials/program/ShadowMapping_frag.ts | 31 +--
.../uniforms/PhysicMaterialUniform_frag.ts | 1 +
src/assets/shader/math/FastMathShader.ts | 10 +-
src/assets/shader/utils/ColorUtil.ts | 8 +
src/components/SkeletonAnimationComponent.ts | 2 +
src/components/anim/AnimatorComponent.ts | 153 ++++++++++++
.../anim/morphAnim/MorphTargetBlender.ts | 8 +
src/components/anim/skeletonAnim/Joint.ts | 7 +-
.../anim/skeletonAnim/SkeletonPose.ts | 188 +++++++-------
src/components/lights/DirectLight.ts | 2 +
src/components/lights/Light.ts | 141 +++++++++++
src/components/lights/LightBase.ts | 19 ++
src/components/lights/PointLight.ts | 3 +-
src/components/lights/SpotLight.ts | 2 +
src/components/renderer/MeshFilter.ts | 25 ++
src/components/renderer/MeshRenderer.ts | 5 +-
src/components/renderer/RenderNode.ts | 5 +-
.../renderer/SkinnedMeshRenderer.ts | 202 ++++++++-------
.../renderer/SkinnedMeshRenderer2.ts | 149 ++++++++++++
src/core/View3D.ts | 2 +-
src/core/geometry/GeometryBase.ts | 16 +-
src/core/geometry/GeometryVertexBuffer.ts | 77 +++++-
src/core/geometry/GeometryVertexType.ts | 1 +
src/core/geometry/VertexAttributeName.ts | 8 +
.../core/bindGroups/GlobalUniformGroup.ts | 28 ++-
.../graphics/webGpu/core/texture/Texture.ts | 21 +-
.../core/texture/TextureMipmapGenerator.ts | 14 +-
.../graphics/webGpu/shader/RenderShader.ts | 28 ++-
.../renderJob/collect/RenderShaderCollect.ts | 5 -
.../renderJob/collect/ShadowLightsCollect.ts | 55 ++---
src/gfx/renderJob/jobs/RendererJob.ts | 2 +-
.../ddgi/DDGIIrradianceComputePass.ts | 2 +-
.../passRenderer/ddgi/DDGIIrradianceVolume.ts | 5 +-
.../passRenderer/ddgi/DDGIMultiBouncePass.ts | 2 +-
src/index.ts | 29 ++-
src/loader/FileLoader.ts | 16 +-
src/loader/parser/AtlasParser.ts | 3 +-
src/loader/parser/B3DMParser.ts | 3 +-
src/loader/parser/FontParser.ts | 3 +-
src/loader/parser/I3DMParser.ts | 4 +-
src/loader/parser/OBJParser.ts | 3 +-
src/loader/parser/ParserBase.ts | 3 +-
src/loader/parser/ParserFormat.ts | 5 +
src/loader/parser/gltf/GLBParser.ts | 3 +-
src/loader/parser/gltf/GLTFParser.ts | 3 +-
.../parser/gltf/GLTFSubParserConverter.ts | 16 +-
.../parser/gltf/GLTFSubParserSkeleton.ts | 73 +++---
.../parser/prefab/PrefabAvatarParser.ts | 56 +++++
.../parser/prefab/PrefabMaterialParser.ts | 171 +++++++++++++
src/loader/parser/prefab/PrefabMeshParser.ts | 140 +++++++++++
src/loader/parser/prefab/PrefabParser.ts | 95 ++++++++
src/loader/parser/prefab/PrefabStringUtil.ts | 63 +++++
.../parser/prefab/PrefabTextureParser.ts | 50 ++++
src/loader/parser/prefab/prefabData/KVData.ts | 20 ++
.../prefab/prefabData/PrefabAvatarData.ts | 23 ++
.../prefab/prefabData/PrefabBoneData.ts | 32 +++
.../prefab/prefabData/PrefabMeshData.ts | 20 ++
.../parser/prefab/prefabData/PrefabNode.ts | 67 +++++
.../prefab/prefabData/PrefabTextureData.ts | 16 ++
.../parser/prefab/prefabData/ValueParser.ts | 111 +++++++++
.../parser/prefab/prefabData/ValueType.ts | 33 +++
src/materials/LitMaterial.ts | 2 +
src/materials/PhysicMaterial.ts | 41 +++-
src/math/AnimationCurve.ts | 67 +----
src/math/AnimationCurveClip.ts | 58 +++++
src/math/AnimationCurveT.ts | 148 +++++++++++
src/math/ParticleSystemCurves.ts | 3 +-
src/math/Quaternion.ts | 6 +
src/math/Vector3.ts | 7 +
src/math/enum/FrameCache.ts | 10 +
src/math/enum/Keyframe.ts | 41 ++++
src/math/enum/T/KeyframeT.ts | 136 +++++++++++
src/math/enum/T/ValueOp.ts | 39 +++
src/math/enum/WrapTimeMode.ts | 11 +
src/textures/BitmapTexture2D.ts | 34 ++-
src/util/BytesArray.ts | 229 ++++++++++++++++++
src/util/BytesStream.ts | 12 -
src/util/Global.ts | 3 +
src/util/SerializeDecoration.ts | 8 +
src/util/StorageUtil.ts | 19 ++
vite.config.js | 2 +-
100 files changed, 3497 insertions(+), 711 deletions(-)
create mode 100644 samples/game/Sample_Game.ts
create mode 100644 samples/prefab/Sample_Prefab.ts
create mode 100644 src/components/anim/AnimatorComponent.ts
create mode 100644 src/components/lights/Light.ts
create mode 100644 src/components/renderer/MeshFilter.ts
create mode 100644 src/components/renderer/SkinnedMeshRenderer2.ts
create mode 100644 src/loader/parser/ParserFormat.ts
create mode 100644 src/loader/parser/prefab/PrefabAvatarParser.ts
create mode 100644 src/loader/parser/prefab/PrefabMaterialParser.ts
create mode 100644 src/loader/parser/prefab/PrefabMeshParser.ts
create mode 100644 src/loader/parser/prefab/PrefabParser.ts
create mode 100644 src/loader/parser/prefab/PrefabStringUtil.ts
create mode 100644 src/loader/parser/prefab/PrefabTextureParser.ts
create mode 100644 src/loader/parser/prefab/prefabData/KVData.ts
create mode 100644 src/loader/parser/prefab/prefabData/PrefabAvatarData.ts
create mode 100644 src/loader/parser/prefab/prefabData/PrefabBoneData.ts
create mode 100644 src/loader/parser/prefab/prefabData/PrefabMeshData.ts
create mode 100644 src/loader/parser/prefab/prefabData/PrefabNode.ts
create mode 100644 src/loader/parser/prefab/prefabData/PrefabTextureData.ts
create mode 100644 src/loader/parser/prefab/prefabData/ValueParser.ts
create mode 100644 src/loader/parser/prefab/prefabData/ValueType.ts
create mode 100644 src/math/AnimationCurveClip.ts
create mode 100644 src/math/AnimationCurveT.ts
create mode 100644 src/math/enum/FrameCache.ts
create mode 100644 src/math/enum/Keyframe.ts
create mode 100644 src/math/enum/T/KeyframeT.ts
create mode 100644 src/math/enum/T/ValueOp.ts
create mode 100644 src/math/enum/WrapTimeMode.ts
create mode 100644 src/util/BytesArray.ts
delete mode 100644 src/util/BytesStream.ts
create mode 100644 src/util/StorageUtil.ts
diff --git a/samples/game/Sample_Game.ts b/samples/game/Sample_Game.ts
new file mode 100644
index 00000000..6add24b2
--- /dev/null
+++ b/samples/game/Sample_Game.ts
@@ -0,0 +1,178 @@
+import { GUIHelp } from "@orillusion/debug/GUIHelp";
+import { Scene3D, HoverCameraController, Engine3D, AtmosphericComponent, Object3D, Camera3D, Vector3, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, CameraUtil, SphereGeometry, Color, Object3DUtil, BlendMode, Vector4, PostProcessingComponent, GTAOPost, SkinnedMeshRenderer, MorphTargetBlender, StorageUtil, Interpolator, HDRBloomPost } from "@orillusion/core";
+import { GUIUtil } from "@samples/utils/GUIUtil";
+import { GUIController } from "@orillusion/debug/dat.gui.module";
+
+//sample of direction light
+class Sample_Game {
+ scene: Scene3D;
+ async run() {
+ Engine3D.setting.shadow.enable = true;
+ // Engine3D.setting.render.zPrePass = true;
+ Engine3D.setting.shadow.autoUpdate = true;
+ Engine3D.setting.shadow.shadowSize = 4096;
+ Engine3D.setting.render.debug = false;
+ Engine3D.setting.render.useLogDepth = false;
+ // Engine3D.setting.occlusionQuery.octree = { width: 1000, height: 1000, depth: 1000, x: 0, y: 0, z: 0 }
+ await Engine3D.init({});
+
+ GUIHelp.init();
+
+ this.scene = new Scene3D();
+ let sky = this.scene.addComponent(AtmosphericComponent);
+
+ // init camera3D
+ let mainCamera = CameraUtil.createCamera3D(null, this.scene);
+ // mainCamera.enableCSM = true;
+ mainCamera.perspective(60, Engine3D.aspect, 2, 5000.0);
+ //set camera data
+ mainCamera.object3D.z = -15;
+ mainCamera.object3D.addComponent(HoverCameraController).setCamera(-15, -35, 1000);
+
+ sky.relativeTransform = this.initLight();
+ await this.initScene();
+
+ let view = new View3D();
+ view.scene = this.scene;
+ view.camera = mainCamera;
+
+
+
+ Engine3D.startRenderView(view);
+ GUIUtil.renderDebug();
+
+ let post = this.scene.addComponent(PostProcessingComponent);
+ post.addPost(GTAOPost);
+ let bloom = post.addPost(HDRBloomPost);
+ GUIUtil.renderBloom(bloom);
+ }
+
+ // create direction light
+ private initLight() {
+ // add a direction light
+ let lightObj3D = new Object3D();
+ lightObj3D.rotationX = 46;
+ lightObj3D.rotationY = 174.56;
+ lightObj3D.rotationZ = 0;
+ let sunLight = lightObj3D.addComponent(DirectLight);
+ sunLight.intensity = 58;
+ sunLight.lightColor = KelvinUtil.color_temperature_to_rgb(6553);
+ sunLight.castShadow = true;
+
+ GUIUtil.renderDirLight(sunLight);
+ this.scene.addChild(lightObj3D);
+ return sunLight.transform;
+ }
+
+ async initScene() {
+ let tex = await Engine3D.res.loadTexture("textures/grid.jpg");
+ {
+ let mat = new LitMaterial();
+ // mat.baseMap = Engine3D.res.grayTexture;
+ mat.uvTransform_1 = new Vector4(0, 0, 100, 100);
+ let floor = new Object3D();
+ let mr = floor.addComponent(MeshRenderer);
+ mr.geometry = new BoxGeometry(10000, 1, 10000);
+ mr.material = mat;
+ mat.baseMap = tex;
+ this.scene.addChild(floor);
+ }
+
+ //ThirdPersonIdle
+ // let model = await Engine3D.res.loadGltf("character/SK_RYU_CASUAL_02.glb");
+ // let model = await Engine3D.res.loadGltf("metaHuman/metahuman.gltf");
+ // let model = await Engine3D.res.loadGltf("metaHuman/SK_RYU_HEAD.gltf");
+ let model = await Engine3D.res.loadGltf("metaHuman/testMaterial.gltf");
+
+ let data = StorageUtil.load("xunian");
+ data[`faceList`] ||= {};
+
+ // let model = await Engine3D.res.loadGltf("character/ThirdPersonIdle.glb");
+ {
+ // model.scaleX = 100 * 100 * 2;
+ // model.scaleY = 100 * 100 * 2;
+ // model.scaleZ = 100 * 100 * 2;
+
+ // model.scaleX = 100;
+ // model.scaleY = 100;
+ // model.scaleZ = 100;
+ this.scene.addChild(model);
+
+ GUIHelp.addFolder('morph controller');
+ // register MorphTargetBlender component
+ let influenceData = {};
+ let blendShapeComponent = model.addComponent(MorphTargetBlender);
+ let targetRenderers = blendShapeComponent.cloneMorphRenderers();
+
+ let dataList = {};
+ for (const key in data[`faceList`]) {
+ dataList[key] = key;
+ }
+ let select = { face: "" }
+ GUIHelp.add(select, 'face', dataList).onChange(
+ (v) => {
+ let faceData = data[`faceList`][select.face];
+ for (let key in targetRenderers) {
+ let start = influenceData[key];
+ let target = {};
+ target[key] = faceData[key];
+ Interpolator.to(influenceData, target, Math.random() * 200 + 100).onProgress = (p) => {
+ let list = blendShapeComponent.getMorphRenderersByKey(key);
+ for (let renderer of list) {
+ renderer.setMorphInfluence(key, influenceData[key]);
+ }
+ };
+ }
+ }
+ );
+
+ let input = GUIHelp.add({ inputFace: "faceName" }, "inputFace") as GUIController
+ GUIHelp.addButton("saveFace", () => {
+ let faceData = {};
+ for (let key in targetRenderers) {
+ faceData[key] = influenceData[key];
+ }
+ data[`faceList`][input.getValue()] = faceData;
+ StorageUtil.save("xunian", data);
+ });
+
+ // bind influenceData to gui
+ for (let key in targetRenderers) {
+ influenceData[key] = 0.0;
+ GUIHelp.add(influenceData, key, 0, 1, 0.01).onChange((v) => {
+ influenceData[key] = v;
+ let list = blendShapeComponent.getMorphRenderersByKey(key);
+ for (let renderer of list) {
+ renderer.setMorphInfluence(key, v);
+ }
+ });
+ }
+
+ GUIHelp.open();
+ GUIHelp.endFolder();
+
+ let mrs = model.getComponentsInChild(SkinnedMeshRenderer);
+ for (let i = 0; i < mrs.length; i++) {
+ const mr = mrs[i];
+ let mat = mr.material;
+ // if (mat.name.toLocaleLowerCase().indexOf("hair") != -1)
+ // GUIUtil.renderMaterial(mat, false, mat.name);
+
+
+ // GUIHelp.addButton("run", () => {
+ // mr.skeletonAnimation.play("run", 0.25);
+ // });
+
+ // GUIHelp.addButton("kick", () => {
+ // mr.skeletonAnimation.play("kick", 0.25);
+ // });
+
+ // GUIHelp.addButton("dance", () => {
+ // mr.skeletonAnimation.play("dance", 0.25);
+ // });
+ }
+ }
+ }
+}
+
+new Sample_Game().run();
diff --git a/samples/index.ts b/samples/index.ts
index d05c6510..ac08ba62 100644
--- a/samples/index.ts
+++ b/samples/index.ts
@@ -1,86 +1,89 @@
-/******** Load all samples in /src/sample/ ********/
-{
- // find all demos in /sample
- const modules = import.meta.glob(['./*/*.ts', '!./*/_*.ts'])
- // create menu
- let title = '', list = ``
- for (const path in modules) {
- if (!path.includes('Sample_')) continue
- const arr = path.split('/')
- const _title = arr[1]
- const _demo = arr[2].replace(/Sample_|\.ts/g, '')
- if (_title != title) {
- list += `
${_title}
`
- title = _title
- }
- list += `${_demo}`
- }
- const menu = document.createElement('div')
- menu.className = 'menu'
- menu.innerHTML = list
- document.body.appendChild(menu)
+// /******** Load all samples in /src/sample/ ********/
+// {
+// // find all demos in /sample
+// const modules = import.meta.glob(['./*/*.ts', '!./*/_*.ts'])
+// // create menu
+// let title = '', list = ``
+// for (const path in modules) {
+// if (!path.includes('Sample_')) continue
+// const arr = path.split('/')
+// const _title = arr[1]
+// const _demo = arr[2].replace(/Sample_|\.ts/g, '')
+// if (_title != title) {
+// list += `${_title}
`
+// title = _title
+// }
+// list += `${_demo}`
+// }
+// const menu = document.createElement('div')
+// menu.className = 'menu'
+// menu.innerHTML = list
+// document.body.appendChild(menu)
- // change sessionStorage.target on click, and reload iframe
- menu.addEventListener('click', (e: Event) => {
- const button = e.target as HTMLElement
- if (!button.id)
- return
- // remove prev iframe to clear memory
- document.querySelector('iframe')?.remove()
- const target = button.id
- if (target && modules[target]) {
- addIframe()
- document.querySelector('.active')?.classList.remove('active')
- button.classList.add('active')
- sessionStorage.top = menu.scrollTop
- sessionStorage.target = target
- }
- })
- // load target on refresh
- if (sessionStorage.target) {
- const target = sessionStorage.target
- const a = document.querySelector(`[id="${target}"]`)
- if (a) {
- addIframe()
- a.classList.add('active')
- menu.scrollTop = sessionStorage.top
- }
- } else {
- document.querySelector('a')?.click()
- }
+// // change sessionStorage.target on click, and reload iframe
+// menu.addEventListener('click', (e: Event) => {
+// const button = e.target as HTMLElement
+// if (!button.id)
+// return
+// // remove prev iframe to clear memory
+// document.querySelector('iframe')?.remove()
+// const target = button.id
+// if (target && modules[target]) {
+// addIframe()
+// document.querySelector('.active')?.classList.remove('active')
+// button.classList.add('active')
+// sessionStorage.top = menu.scrollTop
+// sessionStorage.target = target
+// }
+// })
- // create an iframe inside page to load sample
- function addIframe() {
- const iframe = document.createElement('iframe') as HTMLIFrameElement
- iframe.srcdoc = `
-
- `
- document.body.appendChild(iframe)
- }
-}
+// // load target on refresh
+// if (sessionStorage.target) {
+// const target = sessionStorage.target
+// const a = document.querySelector(`[id="${target}"]`)
+// if (a) {
+// addIframe()
+// a.classList.add('active')
+// menu.scrollTop = sessionStorage.top
+// }
+// } else {
+// document.querySelector('a')?.click()
+// }
-// new Sample_PointLight().run();
-// new Sample_LoadGLB4().run();
+// // create an iframe inside page to load sample
+// function addIframe() {
+// const iframe = document.createElement('iframe') as HTMLIFrameElement
+// iframe.srcdoc = `
+//
+// `
+// document.body.appendChild(iframe)
+// }
+// }
-// import { Sample_Grass } from "./ext/Sample_Grass";
-// console.log("a");
-// new Sample_Grass().run();
+// // new Sample_PointLight().run();
+// // new Sample_LoadGLB4().run();
-// new Sample_drawCallShareGeometry().run();
+// // import { Sample_Grass } from "./ext/Sample_Grass";
+// // console.log("a");
+// // new Sample_Grass().run();
-// import { Sample_InitEngine } from "./base/Sample_InitEngine";
-// import { Sample_PointLight } from "./lights/Sample_PointLight";
-// new Sample_InitEngine().run();
-// // new Sample_PointLight().run();
+// // new Sample_drawCallShareGeometry().run();
+
+// // import { Sample_InitEngine } from "./base/Sample_InitEngine";
+// // import { Sample_PointLight } from "./lights/Sample_PointLight";
+// // new Sample_InitEngine().run();
+// // // new Sample_PointLight().run();
+import { Sample_Prefab } from "./prefab/Sample_Prefab";
+new Sample_Prefab().run();
diff --git a/samples/prefab/Sample_Prefab.ts b/samples/prefab/Sample_Prefab.ts
new file mode 100644
index 00000000..8bff4039
--- /dev/null
+++ b/samples/prefab/Sample_Prefab.ts
@@ -0,0 +1,80 @@
+import { GUIHelp } from "@orillusion/debug/GUIHelp";
+import { GUIUtil } from "@samples/utils/GUIUtil";
+import { Engine3D, Object3D, Scene3D, CameraUtil, HoverCameraController, View3D, AtmosphericComponent, DirectLight, KelvinUtil, PrefabMeshParser, LitMaterial, MeshRenderer, PostProcessingComponent, GTAOPost, HDRBloomPost, SSRPost, PrefabParser } from "../../src";
+
+
+export class Sample_Prefab {
+ lightObj3D: Object3D;
+ scene: Scene3D;
+
+ async run() {
+ //config settings
+ Engine3D.setting.render.debug = true;
+ Engine3D.setting.shadow.shadowBound = 20;
+ Engine3D.setting.shadow.shadowSize = 4096;
+ Engine3D.setting.shadow.type = "SOFT";
+ Engine3D.setting.render.postProcessing.bloom = {
+ enable: true,
+ blurX: 4,
+ blurY: 4,
+ luminosityThreshold: 0.8,
+ strength: 0.86,
+ exposure: 1,
+ radius: 4,
+ debug: false
+ };
+
+ await Engine3D.init({ canvasConfig: { alpha: true, zIndex: 11 } });
+
+ GUIHelp.init(999);
+
+ this.scene = new Scene3D();
+ let camera = CameraUtil.createCamera3DObject(this.scene);
+ // camera.enableCSM = true;
+ camera.perspective(60, Engine3D.aspect, 0.1, 5000.0);
+
+ camera.object3D.addComponent(HoverCameraController).setCamera(-25, -5, 30);
+
+ let view = new View3D();
+ view.scene = this.scene;
+ view.camera = camera;
+
+ Engine3D.startRenderView(view);
+ await this.initScene();
+
+ let post = this.scene.addComponent(PostProcessingComponent);
+ post.addPost(GTAOPost);
+ // let bloom = post.addPost(HDRBloomPost);
+ // GUIUtil.renderBloom(bloom);
+ // post.addPost(SSRPost);
+
+ // GUIUtil.renderDebug();
+ }
+
+ async initScene() {
+ /******** sky *******/
+ let sky: AtmosphericComponent;
+ {
+ sky = this.scene.addComponent(AtmosphericComponent);
+ }
+ /******** light *******/
+ {
+ this.lightObj3D = new Object3D();
+ this.lightObj3D.rotationX = 124;
+ this.lightObj3D.rotationY = 327;
+ this.lightObj3D.rotationZ = 10;
+ let directLight = this.lightObj3D.addComponent(DirectLight);
+ directLight.lightColor = KelvinUtil.color_temperature_to_rgb(5355);
+ directLight.castShadow = true;
+ directLight.intensity = 65;
+ GUIUtil.renderDirLight(directLight);
+ this.scene.addChild(this.lightObj3D);
+ sky.relativeTransform = this.lightObj3D.transform;
+ }
+
+ {
+ let node = await Engine3D.res.load("prefab/as.bin", PrefabParser);
+ this.scene.addChild(node);
+ }
+ }
+}
diff --git a/samples/utils/GUIUtil.ts b/samples/utils/GUIUtil.ts
index ca4b4060..55f28600 100644
--- a/samples/utils/GUIUtil.ts
+++ b/samples/utils/GUIUtil.ts
@@ -1,5 +1,5 @@
import { GUIHelp } from "@orillusion/debug/GUIHelp";
-import { AtmosphericComponent, BillboardType, BlendMode, Color, DirectLight, Engine3D, GPUCullMode, GlobalFog, GlobalIlluminationComponent, HDRBloomPost, LitMaterial, Material, PointLight, SpotLight, Transform, UIImage, UIPanel, UIShadow, View3D } from "@orillusion/core";
+import { AtmosphericComponent, BillboardType, BlendMode, Color, DirectLight, Engine3D, GPUCullMode, GlobalFog, GlobalIlluminationComponent, HDRBloomPost, LitMaterial, Material, Object3D, PointLight, SpotLight, Transform, UIImage, UIPanel, UIShadow, View3D } from "@orillusion/core";
import { UVMoveComponent } from "@samples/material/script/UVMoveComponent";
export class GUIUtil {
@@ -91,6 +91,20 @@ export class GUIUtil {
GUIHelp.endFolder();
}
+ public static renderVector3(obj: Object3D, open: boolean = true, name?: string) {
+ name ||= 'Vector3';
+ GUIHelp.addFolder(name);
+ GUIHelp.add(obj, 'x', -10.0, 10.0, 0.01);
+ GUIHelp.add(obj, 'y', -10.0, 10.0, 0.01);
+ GUIHelp.add(obj, 'z', -10.0, 10.0, 0.01);
+
+ GUIHelp.add(obj.transform, 'rotationX', 0.0, 360.0, 0.01);
+ GUIHelp.add(obj.transform, 'rotationY', 0.0, 360.0, 0.01);
+ GUIHelp.add(obj.transform, 'rotationZ', 0.0, 360.0, 0.01);
+ open && GUIHelp.open();
+ GUIHelp.endFolder();
+ }
+
//render direct light gui panel
public static renderDirLight(light: DirectLight, open: boolean = true, name?: string) {
name ||= 'DirectLight';
diff --git a/src/Engine3D.ts b/src/Engine3D.ts
index 9b39d96a..bd352969 100644
--- a/src/Engine3D.ts
+++ b/src/Engine3D.ts
@@ -327,6 +327,8 @@ export class Engine3D {
this.res = new Res();
+ this.res.initDefault();
+
this._beforeRender = descriptor.beforeRender;
this._renderLoop = descriptor.renderLoop;
this._lateRender = descriptor.lateRender;
@@ -489,6 +491,20 @@ export class Engine3D {
}
}
+ if (this.setting.render.debug) {
+ for (const iterator of ComponentCollect.graphicComponent) {
+ let k = iterator[0];
+ let v = iterator[1];
+ for (const iterator2 of v) {
+ let f = iterator2[0];
+ let c = iterator2[1];
+ if (f.enable) {
+ c(k);
+ };
+ }
+ }
+ }
+
if (this._renderLoop) {
this._renderLoop();
}
diff --git a/src/assets/Res.ts b/src/assets/Res.ts
index 05a1e06e..a849a47c 100644
--- a/src/assets/Res.ts
+++ b/src/assets/Res.ts
@@ -23,20 +23,26 @@ import { FontParser, FontInfo } from '../loader/parser/FontParser';
import { fonts } from './Fonts';
import { AtlasParser } from '../loader/parser/AtlasParser';
import { Reference } from '../util/Reference';
-import { Material } from '..';
+import { Material } from '../materials/Material';
+import { Ctor, Parser } from '../util/Global';
+import { ParserBase } from '../loader/parser/ParserBase';
+import { GeometryBase } from '../core/geometry/GeometryBase';
+import { LitMaterial } from '../materials/LitMaterial';
/**
* Resource management classes for textures, materials, models, and preset bodies.
* @group Assets
*/
export class Res {
+
private _texturePool: Map;
private _materialPool: Map;
private _prefabPool: Map;
// private _prefabLoaderPool: Map;
private _gltfPool: Map;
+ private _geometryPool: Map;
private _atlasList: Map;
-
+ private _obj: Map;
/**
* @constructor
@@ -45,17 +51,36 @@ export class Res {
this._texturePool = new Map();
this._materialPool = new Map();
this._prefabPool = new Map();
+ this._geometryPool = new Map();
// this._prefabLoaderPool = new Map;
this._gltfPool = new Map;
this._atlasList = new Map();
-
- this.initDefault();
+ this._obj = new Map();
+ // this.initDefault();
}
public getGltf(url: string): GLTF_Info {
return this._gltfPool.get(url);
}
+ /**
+ * add a obj with reference of url
+ * @param url file path
+ * @param texture source obj
+ */
+ public addObj(url: string, obj: any) {
+ this._obj.set(url, obj);
+ }
+
+ /**
+ * get obj by url
+ * @param url file path
+ * @returns
+ */
+ public getObj(url: string): any {
+ return this._obj.get(url);
+ }
+
/**
* add a texture with reference of url
* @param url file path
@@ -74,6 +99,14 @@ export class Res {
return this._texturePool.get(url);
}
+ public addGeometry(url: string, geo: GeometryBase) {
+ this._geometryPool.set(url, geo);
+ }
+
+ public getGeometry(url: string): GeometryBase {
+ return this._geometryPool.get(url);
+ }
+
/**
* add a material with reference of name
* @param name material name
@@ -129,6 +162,13 @@ export class Res {
return null;
}
+ public async load(url: string, c: Parser, loaderFunctions?: LoaderFunctions) {
+ let loader = new FileLoader();
+ let parser = await loader.load(url, c, loaderFunctions);
+ let ret = parser.data;
+ return ret;
+ }
+
/**
* load a gltf file
* @param url the url of file
@@ -231,6 +271,39 @@ export class Res {
return texture;
}
+ private async loadTextureCount(urls: string[], count: number) {
+ return new Promise(
+ async (suc, fail) => {
+ let total = 0;
+ let loadTexture = [];
+ if (count == 0) {
+ suc(loadTexture);
+ }
+ for (let j = 0; j < count; j++) {
+ const url = urls.shift();
+ this.loadTexture(url).then((t) => {
+ loadTexture.push(t);
+ total++;
+ if (total == count) {
+ suc(loadTexture);
+ }
+ });
+ }
+ }
+ );
+ }
+
+ public async loadBitmapTextures(urls: string[], count: number = 5, loaderFunctions?: LoaderFunctions, flipY?: boolean) {
+ let loadTexture: BitmapTexture2D[] = [];
+ let loadCount = Math.floor(urls.length / count) + 1;
+ let last = Math.floor(urls.length % count)
+ for (let i = 0; i < loadCount; i++) {
+ let list = await this.loadTextureCount(urls, i == loadCount - 1 ? last : count);
+ loadTexture.push(...list);
+ }
+ return loadTexture;
+ }
+
/**
* load a hdr texture
* @param url texture url
@@ -373,6 +446,7 @@ export class Res {
public defaultGUITexture: GUITexture;
public defaultGUISprite: GUISprite;
+ public defaltMaterial: LitMaterial;
/**
* create a texture
@@ -424,7 +498,7 @@ export class Res {
/**
* Initialize a common texture object. Provide a universal solid color texture object.
*/
- private initDefault() {
+ public initDefault() {
this.normalTexture = this.createTexture(32, 32, 255 * 0.5, 255 * 0.5, 255.0, 255.0, 'default-normalTexture');
this.maskTexture = this.createTexture(32, 32, 255, 255 * 0.5, 0.0, 255.0, 'default-maskTexture');
this.whiteTexture = this.createTexture(32, 32, 255, 255, 255, 255, 'default-whiteTexture');
@@ -458,5 +532,7 @@ export class Res {
this.defaultGUITexture = new GUITexture(this.whiteTexture);
this.defaultGUISprite = new GUISprite(this.defaultGUITexture);
this.defaultGUISprite.trimSize.set(4, 4)
+
+ this.defaltMaterial = new LitMaterial();
}
}
diff --git a/src/assets/shader/core/base/Common_frag.ts b/src/assets/shader/core/base/Common_frag.ts
index 58ca186d..fad8d608 100644
--- a/src/assets/shader/core/base/Common_frag.ts
+++ b/src/assets/shader/core/base/Common_frag.ts
@@ -26,9 +26,6 @@ export let Common_frag: string = /*wgsl*/ `
debugFragmentOut();
#endif
- // var d1 = logDepth( ORI_VertexVarying.fragCoord.w , globalUniform.far);
- // ORI_FragmentOutput.out_depth = d1 ;
-
#if USE_OUTDEPTH
#if USE_LOGDEPTH
ORI_FragmentOutput.out_depth = log2Depth(ORI_VertexVarying.fragCoord.z,globalUniform.near,globalUniform.far) ;
@@ -37,10 +34,6 @@ export let Common_frag: string = /*wgsl*/ `
#endif
#endif
- // var d1 = log2(ORI_VertexVarying.fragCoord.w + 1.0) * 2.0 / (log(f + 1.0) / 0.6931471805599453) * 0.5 ;
- // 2.0 / (Math.log(camera.far + 1.0) / Math.LN2)
- // ORI_FragmentOutput.out_depth = d1 ;
-
return ORI_FragmentOutput ;
}
diff --git a/src/assets/shader/core/common/GlobalUniform.ts b/src/assets/shader/core/common/GlobalUniform.ts
index 954e679e..89750c83 100644
--- a/src/assets/shader/core/common/GlobalUniform.ts
+++ b/src/assets/shader/core/common/GlobalUniform.ts
@@ -40,10 +40,16 @@ export let GlobalUniform: string = /*wgsl*/ `
enableCSM:f32,
csmMargin:f32,
- notUsed1:f32,
- notUsed2:f32,
- notUsed3:f32
-
+ nDirShadowStart: i32,
+ nDirShadowEnd: i32,
+ nPointShadowStart: i32,
+
+ nPointShadowEnd: i32,
+ empty1: i32,
+ empty2: i32,
+ empty3: i32,
+
+ shadowLights:mat4x4
};
@group(0) @binding(0)
diff --git a/src/assets/shader/core/pass/CastShadow_pass.ts b/src/assets/shader/core/pass/CastShadow_pass.ts
index cd43c7bb..2948f253 100644
--- a/src/assets/shader/core/pass/CastShadow_pass.ts
+++ b/src/assets/shader/core/pass/CastShadow_pass.ts
@@ -26,27 +26,53 @@ struct VertexAttributes{
@location(2) uv: vec2,
@location(3) TEXCOORD_1: vec2,
- #if USE_TANGENT
- @location(4) TANGENT: vec4,
- #if USE_SKELETON
- @location(5) joints0: vec4,
- @location(6) weights0: vec4,
- #if USE_JOINT_VEC8
- @location(7) joints1: vec4,
- @location(8) weights1: vec4,
- #endif
- #elseif USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetAttr(5)}
- #endif
- #elseif USE_SKELETON
- @location(4) joints0: vec4,
- @location(5) weights0: vec4,
- #if USE_JOINT_VEC8
- @location(6) joints1: vec4,
- @location(7) weights1: vec4,
- #endif
- #elseif USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetAttr(4)}
+
+ #if USE_METAHUMAN
+ #if USE_TANGENT
+ @location(4) TANGENT: vec4,
+ @location(5) joints0: vec4,
+ @location(6) weights0: vec4,
+ @location(7) joints1: vec4,
+ @location(8) weights1: vec4,
+ ${MorphTarget_shader.getMorphTargetAttr(9)}
+ #else
+ @location(4) joints0: vec4,
+ @location(5) weights0: vec4,
+ @location(6) joints1: vec4,
+ @location(7) weights1: vec4,
+ ${MorphTarget_shader.getMorphTargetAttr(8)}
+ #endif
+ #else
+ #if USE_TANGENT
+ @location(4) TANGENT: vec4,
+ #endif
+
+ #if USE_SKELETON
+ #if USE_TANGENT
+ @location(5) joints0: vec4,
+ @location(6) weights0: vec4,
+ #if USE_JOINT_VEC8
+ @location(7) joints1: vec4,
+ @location(8) weights1: vec4,
+ #endif
+ #else
+ @location(4) joints0: vec4,
+ @location(5) weights0: vec4,
+ #if USE_JOINT_VEC8
+ @location(6) joints1: vec4,
+ @location(7) weights1: vec4,
+ #endif
+ #endif
+ #endif
+
+ #if USE_MORPHTARGETS
+ #if USE_TANGENT
+ ${MorphTarget_shader.getMorphTargetAttr(5)}
+ #else
+ ${MorphTarget_shader.getMorphTargetAttr(4)}
+ #endif
+ #endif
+
#endif
}
@@ -105,28 +131,54 @@ struct VertexAttributes{
@location(2) uv: vec2,
@location(3) TEXCOORD_1: vec2,
- #if USE_TANGENT
- @location(4) TANGENT: vec4,
- #if USE_SKELETON
- @location(5) joints0: vec4,
- @location(6) weights0: vec4,
- #if USE_JOINT_VEC8
- @location(7) joints1: vec4,
- @location(8) weights1: vec4,
- #endif
- #elseif USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetAttr(5)}
- #endif
- #elseif USE_SKELETON
- @location(4) joints0: vec4,
- @location(5) weights0: vec4,
- #if USE_JOINT_VEC8
- @location(6) joints1: vec4,
- @location(7) weights1: vec4,
- #endif
- #elseif USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetAttr(4)}
- #endif
+
+ #if USE_METAHUMAN
+ #if USE_TANGENT
+ @location(4) TANGENT: vec4,
+ @location(5) joints0: vec4,
+ @location(6) weights0: vec4,
+ @location(7) joints1: vec4,
+ @location(8) weights1: vec4,
+ ${MorphTarget_shader.getMorphTargetAttr(9)}
+ #else
+ @location(4) joints0: vec4,
+ @location(5) weights0: vec4,
+ @location(6) joints1: vec4,
+ @location(7) weights1: vec4,
+ ${MorphTarget_shader.getMorphTargetAttr(8)}
+ #endif
+ #else
+ #if USE_TANGENT
+ @location(4) TANGENT: vec4,
+ #endif
+
+ #if USE_SKELETON
+ #if USE_TANGENT
+ @location(5) joints0: vec4,
+ @location(6) weights0: vec4,
+ #if USE_JOINT_VEC8
+ @location(7) joints1: vec4,
+ @location(8) weights1: vec4,
+ #endif
+ #else
+ @location(4) joints0: vec4,
+ @location(5) weights0: vec4,
+ #if USE_JOINT_VEC8
+ @location(6) joints1: vec4,
+ @location(7) weights1: vec4,
+ #endif
+ #endif
+ #endif
+
+ #if USE_MORPHTARGETS
+ #if USE_TANGENT
+ ${MorphTarget_shader.getMorphTargetAttr(5)}
+ #else
+ ${MorphTarget_shader.getMorphTargetAttr(4)}
+ #endif
+ #endif
+
+ #endif
}
@vertex
@@ -135,6 +187,15 @@ fn main(vertex:VertexAttributes) -> VertexOutput {
let shadowMatrix: mat4x4 = globalUniform.projMat * globalUniform.viewMat ;
var vertexPosition = vertex.position.xyz;
+ #if USE_METAHUMAN
+ ${MorphTarget_shader.getMorphTargetCalcVertex()}
+ #if USE_JOINT_VEC8
+ worldMatrix *= getSkeletonWorldMatrix_8(vertex.joints0, vertex.weights0, vertex.joints1, vertex.weights1);
+ #else
+ worldMatrix *= getSkeletonWorldMatrix_4(vertex.joints0, vertex.weights0);
+ #endif
+ #endif
+
#if USE_MORPHTARGETS
${MorphTarget_shader.getMorphTargetCalcVertex()}
#endif
diff --git a/src/assets/shader/core/struct/VertexAttributes.ts b/src/assets/shader/core/struct/VertexAttributes.ts
index 5ed5f5da..9f9942d3 100644
--- a/src/assets/shader/core/struct/VertexAttributes.ts
+++ b/src/assets/shader/core/struct/VertexAttributes.ts
@@ -2,43 +2,74 @@ import { SkeletonAnimation_shader } from "../../anim/SkeletonAnimation_shader";
import { MorphTarget_shader } from "../../../../components/anim/morphAnim/MorphTarget_shader";
export let VertexAttributes: string = /*wgsl*/ `
- #if USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetShaderBinding(3, 0)}
- #endif
- #if USE_SKELETON
- ${SkeletonAnimation_shader.groupBindingAndFunctions(3, 0)}
+ #if USE_METAHUMAN
+ ${MorphTarget_shader.getMorphTargetShaderBinding(3, 0)}
+ ${SkeletonAnimation_shader.groupBindingAndFunctions(3, 2)}
+ #else
+ #if USE_MORPHTARGETS
+ ${MorphTarget_shader.getMorphTargetShaderBinding(3, 0)}
+ #endif
+
+ #if USE_SKELETON
+ ${SkeletonAnimation_shader.groupBindingAndFunctions(3, 0)}
+ #endif
#endif
struct VertexAttributes{
- @builtin(instance_index) index : u32,
- @location(0) position: vec3,
- @location(1) normal: vec3,
- @location(2) uv: vec2,
- @location(3) TEXCOORD_1: vec2,
+ @builtin(instance_index) index : u32,
+ @location(0) position: vec3,
+ @location(1) normal: vec3,
+ @location(2) uv: vec2,
+ @location(3) TEXCOORD_1: vec2,
+
+ #if USE_METAHUMAN
+ #if USE_TANGENT
+ @location(4) TANGENT: vec4,
+ @location(5) joints0: vec4,
+ @location(6) weights0: vec4,
+ @location(7) joints1: vec4,
+ @location(8) weights1: vec4,
+ ${MorphTarget_shader.getMorphTargetAttr(9)}
+ #else
+ @location(4) joints0: vec4,
+ @location(5) weights0: vec4,
+ @location(6) joints1: vec4,
+ @location(7) weights1: vec4,
+ ${MorphTarget_shader.getMorphTargetAttr(8)}
+ #endif
+ #else
+ #if USE_TANGENT
+ @location(4) TANGENT: vec4,
+ #endif
+
+ #if USE_SKELETON
+ #if USE_TANGENT
+ @location(5) joints0: vec4,
+ @location(6) weights0: vec4,
+ #if USE_JOINT_VEC8
+ @location(7) joints1: vec4,
+ @location(8) weights1: vec4,
+ #endif
+ #else
+ @location(4) joints0: vec4,
+ @location(5) weights0: vec4,
+ #if USE_JOINT_VEC8
+ @location(6) joints1: vec4,
+ @location(7) weights1: vec4,
+ #endif
+ #endif
+ #endif
+
+ #if USE_MORPHTARGETS
+ #if USE_TANGENT
+ ${MorphTarget_shader.getMorphTargetAttr(5)}
+ #else
+ ${MorphTarget_shader.getMorphTargetAttr(4)}
+ #endif
+ #endif
- #if USE_TANGENT
- @location(4) TANGENT: vec4,
- #if USE_SKELETON
- @location(5) joints0: vec4,
- @location(6) weights0: vec4,
- #if USE_JOINT_VEC8
- @location(7) joints1: vec4,
- @location(8) weights1: vec4,
- #endif
- #elseif USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetAttr(5)}
- #endif
- #elseif USE_SKELETON
- @location(4) joints0: vec4,
- @location(5) weights0: vec4,
- #if USE_JOINT_VEC8
- @location(6) joints1: vec4,
- @location(7) weights1: vec4,
#endif
- #elseif USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetAttr(4)}
- #endif
}
struct VertexOutput {
@@ -67,11 +98,8 @@ export let VertexAttributes: string = /*wgsl*/ `
var vertexPosition = vertex.position;
var vertexNormal = vertex.normal;
- #if USE_MORPHTARGETS
- ${MorphTarget_shader.getMorphTargetCalcVertex()}
- #endif
-
- #if USE_SKELETON
+ #if USE_METAHUMAN
+ // ${MorphTarget_shader.getMorphTargetCalcVertex()}
#if USE_JOINT_VEC8
let skeletonNormal = getSkeletonWorldMatrix_8(vertex.joints0, vertex.weights0, vertex.joints1, vertex.weights1);
ORI_MATRIX_M *= skeletonNormal ;
@@ -79,6 +107,20 @@ export let VertexAttributes: string = /*wgsl*/ `
let skeletonNormal = getSkeletonWorldMatrix_4(vertex.joints0, vertex.weights0);
ORI_MATRIX_M *= skeletonNormal ;
#endif
+ #else
+ #if USE_MORPHTARGETS
+ ${MorphTarget_shader.getMorphTargetCalcVertex()}
+ #endif
+
+ #if USE_SKELETON
+ #if USE_JOINT_VEC8
+ let skeletonNormal = getSkeletonWorldMatrix_8(vertex.joints0, vertex.weights0, vertex.joints1, vertex.weights1);
+ ORI_MATRIX_M *= skeletonNormal ;
+ #else
+ let skeletonNormal = getSkeletonWorldMatrix_4(vertex.joints0, vertex.weights0);
+ ORI_MATRIX_M *= skeletonNormal ;
+ #endif
+ #endif
#endif
#if USE_TANGENT
@@ -94,7 +136,9 @@ export let VertexAttributes: string = /*wgsl*/ `
ORI_CameraWorldDir = normalize(ORI_CAMERAMATRIX[3].xyz - worldPos.xyz) ;
ORI_VertexOut.varying_UV0 = vertex.uv.xy ;
- ORI_VertexOut.varying_UV1 = vertex.TEXCOORD_1.xy;
+
+ ORI_VertexOut.varying_UV1 = vertex.TEXCOORD_1.xy;
+
ORI_VertexOut.varying_ViewPos = viewPosition ;
ORI_VertexOut.varying_Clip = clipPosition ;
ORI_VertexOut.varying_WPos = worldPos ;
diff --git a/src/assets/shader/lighting/BRDF_frag.ts b/src/assets/shader/lighting/BRDF_frag.ts
index 99f04012..08627fa4 100644
--- a/src/assets/shader/lighting/BRDF_frag.ts
+++ b/src/assets/shader/lighting/BRDF_frag.ts
@@ -219,24 +219,34 @@ export let BRDF_frag: string = /*wgsl*/ `
fn simpleBRDF( albedo:vec3, N:vec3, V:vec3,L:vec3,att:f32,lightColor:vec3,roughness:f32 ,metallic:f32)-> vec3{
let H = normalize(V + L);
let Context:BxDFContext = getContext(N,V,H,L);
-
+ let alpha = pow(roughness,2.0);
let F0 = mix(vec3(materialUniform.materialF0.rgb), albedo , metallic);
- let D = DistributionGGX( Context.NoH , roughness);
- let G = GeometrySmith(Context.NoV,Context.NoL, roughness );
+ let D = DistributionGGX( Context.NoH , alpha);
+ let G = GeometrySmith(Context.NoV,Context.NoL, alpha );
let F = FresnelSchlick(Context.VoH, vec3(F0));
let specular = ( D * G * F ) / (4.0 * Context.NoV * Context.NoL + 0.001);
let kS = F;
var kd = 1.0 - kS ;
kd *= 1.0 - metallic ;
- var diffuse = kd * (albedo.rgb / PI ) ;
+
+ // #if USE_SRGB_ALBEDO
+ // var diffuse = kd ;
+ // #else
+ var diffuse = kd * (albedo.rgb / PI ) ;
+ // #endif
+
let ambient = specular.rgb ;
fragData.KD += kd;
fragData.KS += F;
- var col = (diffuse + ambient) * Context.NoL * lightColor * att ;
+ let lightAtt = Context.NoL * lightColor * att ;
+ var diffuseIBL = diffuse * lightAtt;
+ // diffuseIBL = diffuseIBL / ( 2.4 + diffuseIBL) ;
+ let ambientIBL = ambient * lightAtt;
+ var col = (diffuseIBL + ambientIBL ) ;
// var col = (diffuse + ambient) * Context.NoL * lightColor ;
- return (col.rgb ) ;
+ return (col.rgb) ;
}
fn getSpecularDominantDir ( N : vec3 , R : vec3 , roughness : f32 ) -> vec3
@@ -251,10 +261,11 @@ export let BRDF_frag: string = /*wgsl*/ `
let MAX_REFLECTION_LOD = i32(textureNumLevels(prefilterMap)) ;
let mip = roughnessToMipmapLevel(roughness,MAX_REFLECTION_LOD);
- var prefilteredColor: vec3 = (textureSampleLevel(prefilterMap, prefilterMapSampler, getSpecularDominantDir(fragData.N,R,roughness) , mip ).rgb);
- prefilteredColor = globalUniform.skyExposure * (prefilteredColor);
+ fragData.EnvColor = (textureSampleLevel(prefilterMap, prefilterMapSampler, getSpecularDominantDir(fragData.N,R,roughness) , mip ).rgb);
+ // var prefilteredColor: vec3 = (textureSampleLevel(prefilterMap, prefilterMapSampler, getSpecularDominantDir(fragData.N,R,roughness) , mip ).rgb);
+ fragData.EnvColor = globalUniform.skyExposure * (fragData.EnvColor);
var envBRDF = textureSampleLevel(brdflutMap, brdflutMapSampler, vec2(NoV, roughness) , 0.0 ) ;
- return prefilteredColor * (specularColor.rgb * envBRDF.x + saturate( 50.0 * specularColor.g ) * envBRDF.y) ;
+ return fragData.EnvColor * (specularColor.rgb * envBRDF.x + saturate( 50.0 * specularColor.g ) * envBRDF.y) ;
}
fn fresnel_coat(n:vec3,v:vec3,ior:f32) -> f32 {
diff --git a/src/assets/shader/lighting/BxDF_frag.ts b/src/assets/shader/lighting/BxDF_frag.ts
index 33e98c2e..b526f7ec 100644
--- a/src/assets/shader/lighting/BxDF_frag.ts
+++ b/src/assets/shader/lighting/BxDF_frag.ts
@@ -17,22 +17,21 @@ export let BxDF_frag: string = /*wgsl*/ `
//ORI_ShadingInput
fn initFragData() {
- fragData.Albedo = ORI_ShadingInput.BaseColor * ORI_ShadingInput.BaseColor.a ;
- fragData.Ao = ORI_ShadingInput.AmbientOcclusion ;
- fragData.Roughness = clamp(ORI_ShadingInput.Roughness,0.003,1.0) ;
+ fragData.Albedo = ORI_ShadingInput.BaseColor ;
+ fragData.Ao = clamp( pow(ORI_ShadingInput.AmbientOcclusion,materialUniform.ao) , 0.0 , 1.0 ) ;
+ fragData.Roughness = clamp((ORI_ShadingInput.Roughness),0.003,1.0) ;
fragData.Metallic = ORI_ShadingInput.Metallic ;
fragData.Emissive = ORI_ShadingInput.EmissiveColor.rgb ;
fragData.N = ORI_ShadingInput.Normal;
let viewDir = normalize(globalUniform.CameraPos.xyz - ORI_VertexVarying.vWorldPos.xyz) ;
fragData.V = viewDir ;
- // fragData.V = normalize(globalUniform.cameraWorldMatrix[3].xyz - ORI_VertexVarying.vWorldPos.xyz) ;
-
+
let R = 2.0 * dot( fragData.V , fragData.N ) * fragData.N - fragData.V ;
fragData.R = R ;//reflect( fragData.V , fragData.N ) ;
fragData.NoV = saturate(dot(fragData.N, fragData.V)) ;
- fragData.F0 = mix(vec3(materialUniform.materialF0.rgb), fragData.Albedo.rgb, fragData.Metallic);
+ fragData.F0 = mix(vec3(materialUniform.specularColor.rgb), fragData.Albedo.rgb, fragData.Metallic);
fragData.F = computeFresnelSchlick(fragData.NoV, fragData.F0);
fragData.KD = vec3(fragData.F) ;
@@ -88,16 +87,18 @@ export let BxDF_frag: string = /*wgsl*/ `
}
}
}
- fragData.LightChannel = specColor ;
+ specColor = (specColor);
+ fragData.LightChannel = specColor ;
+ let sunLight = lightBuffer[0] ;
//***********lighting-PBR part*********
var F = FresnelSchlickRoughness(fragData.NoV, fragData.F0, fragData.Roughness);
var kS = F;
var kD = vec3(1.0) - kS;
kD = kD * (1.0 - fragData.Metallic);
- let env = materialUniform.envIntensity * approximateSpecularIBL( F , fragData.Roughness , fragData.R , fragData.NoV ) ;
- fragData.EnvColor = env ;
+ let envIBL = materialUniform.envIntensity * approximateSpecularIBL( F , fragData.Roughness , fragData.R , fragData.NoV ) ;
+ // fragData.EnvColor = envIBL ;
//***********indirect-specular part*********
var surfaceReduction = 1.0/(fragData.Roughness*fragData.Roughness+1.0); //Reduce the reflection coefficient of non-metallic materials
@@ -105,16 +106,16 @@ export let BxDF_frag: string = /*wgsl*/ `
var grazingTerm = clamp((1.0 - fragData.Roughness ) + (1.0 - oneMinusReflectivity),0.0,1.0);
var t = pow5(fragData.NoV);
var fresnelLerp = FresnelLerp(fragData.NoV,fragData.F0.rgb,vec3(grazingTerm)) ; //Controlling Fresnel and metallic reflections
- var iblSpecularResult = surfaceReduction*env*fresnelLerp ;
+ var iblSpecularResult = surfaceReduction * fragData.EnvColor * fresnelLerp + envIBL;
+ // iblSpecularResult *= max(sunLight.quadratic,0.05) ;
//***********indirect-specular part*********
//***********indirect-ambient part*********
var kdLast = (1.0 - fragData.F0.r) * (1.0 - fragData.Metallic); //Dim the edges, there should be more specular reflection at the edges
- var iblDiffuseResult = irradiance * kdLast * fragData.Albedo.rgb ;
+ var iblDiffuseResult = irradiance * 2.0 * kdLast * fragData.Albedo.rgb * (vec3(1.0) - kS) ;//irradiance
//***********indirect-ambient part*********
- let sunLight = lightBuffer[0] ;
- var indirectResult = (iblSpecularResult + iblDiffuseResult) * fragData.Ao * max(sunLight.quadratic,0.05) ;
- // let test = indirectResult ;
+ var indirectResult = (iblSpecularResult + iblDiffuseResult) * fragData.Ao * max(sunLight.quadratic,0.05);
+ // debugOut = vec4f(iblDiffuseResult,1.0);
ORI_FragmentOutput.color = vec4(0.0);
@@ -147,10 +148,13 @@ export let BxDF_frag: string = /*wgsl*/ `
color = vec3(clearCoatLayer.rgb/fragData.Albedo.a) ;
#endif
- ORI_FragmentOutput.color = vec4(LinearToGammaSpace(color.rgb),fragData.Albedo.a) ;
+ let retColor = (LinearToGammaSpace(color.rgb) * fragData.Albedo.a);
+
+ ORI_FragmentOutput.color = vec4( retColor ,fragData.Albedo.a) ;
// var iblSpecularResult = surfaceReduction*env*fresnelLerp ;
- // ORI_FragmentOutput.color = vec4(vec3(test),fragData.Albedo.a) ;
+ // var test = fragData.F0.rgb ;
+ // ORI_FragmentOutput.color = vec4(LinearToGammaSpace(vec3(debugOut.rgb)),fragData.Albedo.a) ;
}
`
diff --git a/src/assets/shader/lighting/Irradiance_frag.ts b/src/assets/shader/lighting/Irradiance_frag.ts
index 8ce3a883..477348d0 100644
--- a/src/assets/shader/lighting/Irradiance_frag.ts
+++ b/src/assets/shader/lighting/Irradiance_frag.ts
@@ -1,10 +1,5 @@
export let Irradiance_frag: string = /*wgsl*/ `
#include "IrradianceVolumeData_frag"
- fn pow3( x : f32 ) -> f32
- {
- return x*x*x;
- }
-
struct IrradianceField {
probeStartPosition: vec4,
probeCounts:vec4,
@@ -23,7 +18,7 @@ export let Irradiance_frag: string = /*wgsl*/ `
@group(1) @binding(auto)
var irradianceDepthMap: texture_2d;
@group(2) @binding(7)
- var irradianceData : IrradianceVolumeData ;
+ var irradianceData : IrradianceVolumeData ;
var irradianceFieldSurface: IrradianceField;
var energyPreservation: f32 = 0.85;
diff --git a/src/assets/shader/lighting/LightingFunction_frag.ts b/src/assets/shader/lighting/LightingFunction_frag.ts
index 0682ed26..fb1274dc 100644
--- a/src/assets/shader/lighting/LightingFunction_frag.ts
+++ b/src/assets/shader/lighting/LightingFunction_frag.ts
@@ -39,7 +39,7 @@ fn directLighting( albedo:vec3, N:vec3, V:vec3, roughness:f32 ,
#if USE_LAMBERT
color = vec3(1.0,1.0,1.0) ;
#endif
-
+
#if USE_BRDF
color = simpleBRDF(albedo,N,V,L,att,lightColor,roughness,metallic) ;
#endif
diff --git a/src/assets/shader/materials/ColorLitShader.ts b/src/assets/shader/materials/ColorLitShader.ts
index a2ea1ed2..0c2bbecd 100644
--- a/src/assets/shader/materials/ColorLitShader.ts
+++ b/src/assets/shader/materials/ColorLitShader.ts
@@ -14,7 +14,7 @@ export class ColorLitShader {
ORI_ShadingInput.Roughness = materialUniform.roughness ;
ORI_ShadingInput.Metallic = materialUniform.metallic ;
ORI_ShadingInput.Specular = 0.5 ;
- ORI_ShadingInput.AmbientOcclusion = materialUniform.ao ;
+ ORI_ShadingInput.AmbientOcclusion = 1.0 ;
ORI_ShadingInput.EmissiveColor = vec4(0.0);
ORI_ShadingInput.Normal = ORI_VertexVarying.vWorldNormal.rgb ;
diff --git a/src/assets/shader/materials/LitShader.ts b/src/assets/shader/materials/LitShader.ts
index 4dae19b4..272929a5 100644
--- a/src/assets/shader/materials/LitShader.ts
+++ b/src/assets/shader/materials/LitShader.ts
@@ -13,7 +13,7 @@ export let LitShader: string = /*wgsl*/ `
ORI_ShadingInput.Roughness = materialUniform.roughness ;
ORI_ShadingInput.Metallic = materialUniform.metallic ;
ORI_ShadingInput.Specular = 0.5 ;
- ORI_ShadingInput.AmbientOcclusion = materialUniform.ao ;
+ ORI_ShadingInput.AmbientOcclusion = 1.0 ;
ORI_ShadingInput.EmissiveColor = vec4(0.0);
ORI_ShadingInput.Normal = ORI_VertexVarying.vWorldNormal.rgb ;
diff --git a/src/assets/shader/materials/PBRLItShader.ts b/src/assets/shader/materials/PBRLItShader.ts
index ba3ac3c2..ae6b3514 100644
--- a/src/assets/shader/materials/PBRLItShader.ts
+++ b/src/assets/shader/materials/PBRLItShader.ts
@@ -13,25 +13,25 @@ export let PBRLItShader: string = /*wgsl*/ `
@group(1) @binding(auto)
var normalMap: texture_2d;
- #if USE_ARMC
+ // #if USE_ARMC
+ // @group(1) @binding(auto)
+ // var maskMapSampler: sampler;
+ // @group(1) @binding(auto)
+ // var maskMap: texture_2d;
+ // #endif
+
+ // #if USE_MR
@group(1) @binding(auto)
var maskMapSampler: sampler;
@group(1) @binding(auto)
var maskMap: texture_2d;
- #endif
-
- #if USE_MR
- @group(1) @binding(auto)
- var maskMapSampler: sampler;
- @group(1) @binding(auto)
- var maskMap: texture_2d;
- #endif
+ // #endif
#if USE_AOTEX
@group(1) @binding(auto)
var aoMapSampler: sampler;
@group(1) @binding(auto)
- var aomapMap: texture_2d;
+ var aoMap: texture_2d;
#endif
@group(1) @binding(auto)
@@ -39,6 +39,8 @@ export let PBRLItShader: string = /*wgsl*/ `
@group(1) @binding(auto)
var emissiveMap: texture_2d;
+ var debugOut : vec4f = vec4f(0.0) ;
+
fn vert(inputData:VertexAttributes) -> VertexOutput {
ORI_Vert(inputData) ;
return ORI_VertexOut ;
@@ -50,9 +52,20 @@ export let PBRLItShader: string = /*wgsl*/ `
var uv = transformUV1.zw * ORI_VertexVarying.fragUV0 + transformUV1.xy;
- ORI_ShadingInput.BaseColor = textureSample(baseMap, baseMapSampler, uv ) ;
- ORI_ShadingInput.BaseColor = vec4(gammaToLiner(ORI_ShadingInput.BaseColor.rgb*ORI_ShadingInput.BaseColor.w ) * materialUniform.baseColor.rgb,ORI_ShadingInput.BaseColor.w*materialUniform.baseColor.a) ;
- #if USE_ALPHACUT
+ // let z = linearTo01Depth(ORI_VertexVarying.fragCoord.z) ;
+
+ // ORI_ShadingInput.BaseColor = textureSampleLevel(baseMap, baseMapSampler, uv , 4.0 ) ;
+
+
+ #if USE_SRGB_ALBEDO
+ ORI_ShadingInput.BaseColor = textureSample(baseMap, baseMapSampler, uv ) ;
+ ORI_ShadingInput.BaseColor = vec4(gammaToLiner(ORI_ShadingInput.BaseColor.rgb) * materialUniform.baseColor.rgb , ORI_ShadingInput.BaseColor.w * materialUniform.baseColor.a) ;
+ #else
+ ORI_ShadingInput.BaseColor = textureSample(baseMap, baseMapSampler, uv ) ;
+ ORI_ShadingInput.BaseColor = vec4(gammaToLiner(ORI_ShadingInput.BaseColor.rgb) * materialUniform.baseColor.rgb , ORI_ShadingInput.BaseColor.w * materialUniform.baseColor.a) ;
+ #endif
+
+ #if USE_ALPHACUT
if( (ORI_ShadingInput.BaseColor.a - materialUniform.alphaCutoff) <= 0.0 ){
ORI_FragmentOutput.color = vec4(0.0,0.0,0.0,1.0);
ORI_FragmentOutput.worldPos = vec4(0.0,0.0,0.0,1.0);
@@ -66,54 +79,78 @@ export let PBRLItShader: string = /*wgsl*/ `
useShadow();
#endif
- #if USE_ARMC
- var maskTex = textureSample(maskMap, maskMapSampler, uv ) ;
-
- ORI_ShadingInput.AmbientOcclusion = maskTex.r * materialUniform.ao ;
-
- #if USE_AOTEX
- var aoMap = textureSample(aomapMap, aoMapSampler, uv );
- ORI_ShadingInput.AmbientOcclusion = mix(0.0,aoMap.r,materialUniform.ao) ;
- #endif
-
- ORI_ShadingInput.Roughness = maskTex.g * materialUniform.roughness ;
- ORI_ShadingInput.Metallic = maskTex.b * materialUniform.metallic ;
-
- #elseif USE_MR
- var maskTex = textureSample(maskMap, maskMapSampler, uv ) ;
- #if USE_AOTEX
- var aoMap = textureSample(aomapMap, aoMapSampler, uv );
- ORI_ShadingInput.AmbientOcclusion = mix(0.0,aoMap.r,materialUniform.ao) ;
- #else
- ORI_ShadingInput.AmbientOcclusion = materialUniform.ao ;
- #endif
-
- ORI_ShadingInput.Roughness = maskTex.g * materialUniform.roughness ;
- ORI_ShadingInput.Metallic = maskTex.b * materialUniform.metallic;
+ var maskTex = textureSample(maskMap, maskMapSampler, uv ) ;
+
+ var roughnessChannel:f32 = 1.0 ;
+ #if USE_ROUGHNESS_A
+ roughnessChannel = maskTex.a ;
+ #else if USE_ROUGHNESS_R
+ roughnessChannel = maskTex.r ;
+ #else if USE_ROUGHNESS_G
+ roughnessChannel = maskTex.g ;
+ #else if USE_ROUGHNESS_B
+ roughnessChannel = maskTex.b ;
+ #else if USE_ALBEDO_A
+ roughnessChannel = ORI_ShadingInput.BaseColor.a ;
+ #endif
+
+ #if USE_SMOOTHNESS
+ roughnessChannel = ( 1.0 - roughnessChannel * materialUniform.roughness) ;
+ ORI_ShadingInput.Roughness = clamp(roughnessChannel ,0.084,1.0);
#else
- ORI_ShadingInput.Roughness = materialUniform.roughness ;
- ORI_ShadingInput.Metallic = materialUniform.metallic ;
- ORI_ShadingInput.AmbientOcclusion = materialUniform.ao ;
- #if USE_AOTEX
- var aoMap = textureSample(aomapMap, aoMapSampler, uv );
- ORI_ShadingInput.AmbientOcclusion = mix(0.0,aoMap.r,materialUniform.ao) ;
- #endif
+ ORI_ShadingInput.Roughness = clamp(roughnessChannel * materialUniform.roughness ,0.084,1.0);
+ #endif
+
+ var metallicChannel:f32 = 1.0 ;
+ #if USE_METALLIC_A
+ metallicChannel = maskTex.a ;
+ #else if USE_METALLIC_R
+ metallicChannel = maskTex.r ;
+ #else if USE_METALLIC_G
+ metallicChannel = maskTex.g ;
+ #else if USE_METALLIC_B
+ metallicChannel = maskTex.b ;
+ #endif
+ ORI_ShadingInput.Metallic = metallicChannel * metallicChannel * materialUniform.metallic ;
+
+ var aoChannel:f32 = 1.0 ;
+ #if USE_AOTEX
+ var aoMap = textureSample(aoMap, aoMapSampler, uv );
+ aoChannel = aoMap.g ;
+ #else
+ #if USE_AO_A
+ aoChannel = maskTex.a ;
+ #else if USE_AO_R
+ aoChannel = maskTex.r ;
+ #else if USE_AO_G
+ aoChannel = maskTex.g ;
+ #else if USE_AO_B
+ aoChannel = maskTex.b ;
+ #endif
#endif
- ORI_ShadingInput.Roughness = clamp(ORI_ShadingInput.Roughness,0.084,1.0);
- ORI_ShadingInput.Specular = 0.5 ;
+ ORI_ShadingInput.AmbientOcclusion = aoChannel ;
+
+ ORI_ShadingInput.Specular = 1.0 ;
var emissiveColor = textureSample(emissiveMap, emissiveMapSampler , ORI_VertexVarying.fragUV0.xy) ;
+
emissiveColor = vec4(gammaToLiner(emissiveColor.rgb),emissiveColor.w);
+
ORI_ShadingInput.EmissiveColor = vec4(materialUniform.emissiveColor.rgb * emissiveColor.rgb * materialUniform.emissiveIntensity,1.0);
var Normal = textureSample(normalMap,normalMapSampler,uv).rgb ;
// Normal.y = 1.0 - Normal.y ;
- // let normal = unPackNormal(Normal,1.0,materialUniform.normalScale) ;
- let normal = unPackNormal(Normal,materialUniform.normalScale) ;
+ // let normal = unPackNormal(Normal,materialUniform.normalScale) ;
+ // let normal = unPackNormal(Normal,1.0) ;
+
+ let normal = unPackRGNormal(Normal,1.0,1.0) ;
+
ORI_ShadingInput.Normal = normal ;
BxDFShading();
+
+ // ORI_FragmentOutput.color = vec4(vec3(normal.rgb),fragData.Albedo.a) ;
}
`
diff --git a/src/assets/shader/materials/PavementShader.ts b/src/assets/shader/materials/PavementShader.ts
index 6a1f306b..a3a8b752 100644
--- a/src/assets/shader/materials/PavementShader.ts
+++ b/src/assets/shader/materials/PavementShader.ts
@@ -1,4 +1,4 @@
-export let PavementShader:string = /*wgsl*/`
+export let PavementShader: string = /*wgsl*/`
#include "Common_vert"
#include "Common_frag"
#include "BxDF_frag"
@@ -57,7 +57,7 @@ export let PavementShader:string = /*wgsl*/`
ORI_ShadingInput.Roughness = ReflectMap * materialUniform.roughness ;
ORI_ShadingInput.Metallic = materialUniform.metallic ;
ORI_ShadingInput.Specular = 0.5 ;
- ORI_ShadingInput.AmbientOcclusion = Ao * materialUniform.ao ;
+ ORI_ShadingInput.AmbientOcclusion = Ao;
ORI_ShadingInput.EmissiveColor = vec4(0.0);
let normal = unPackRGNormal(Normal,Displace.r*materialUniform.normalScale,1.0) ;
diff --git a/src/assets/shader/materials/program/NormalMap_frag.ts b/src/assets/shader/materials/program/NormalMap_frag.ts
index 374ba7eb..ca9de086 100644
--- a/src/assets/shader/materials/program/NormalMap_frag.ts
+++ b/src/assets/shader/materials/program/NormalMap_frag.ts
@@ -8,11 +8,11 @@ export let NormalMap_frag: string = /*wgsl*/ `
var q1perp = cross( q1, N );
var q0perp = cross( N, q0 );
- #if USE_TANGENT
- var T = ORI_VertexVarying.TANGENT.xyz ;
- #else
+ // #if USE_TANGENT
+ // var T = ORI_VertexVarying.TANGENT.xyz ;
+ // #else
var T = q1perp * st0.x + q0perp * st1.x;
- #endif
+ // #endif
var B = q1perp * st0.y + q0perp * st1.y;
@@ -51,7 +51,7 @@ export let NormalMap_frag: string = /*wgsl*/ `
n.y = 1.0 - n.y ;
#endif
- var mapNormal: vec3 = unpackNormalMap(n) ;
+ var mapNormal: vec3 = n ;//unpackNormalMap(n) ;
return perturbNormal(ORI_VertexVarying.vWorldPos.xyz , ORI_VertexVarying.vWorldNormal.xyz , mapNormal , height , face ) ;
#endif
}
diff --git a/src/assets/shader/materials/program/ShadowMapping_frag.ts b/src/assets/shader/materials/program/ShadowMapping_frag.ts
index 457a5562..8a8a9055 100644
--- a/src/assets/shader/materials/program/ShadowMapping_frag.ts
+++ b/src/assets/shader/materials/program/ShadowMapping_frag.ts
@@ -13,22 +13,7 @@ export let ShadowMapping_frag: string = /*wgsl*/ `
directShadowVisibility: array,
pointShadows: array,
}
-
- varshadowStrut: ShadowStruct;
-
- struct ShadowBuffer{
- nDirShadowStart: i32,
- nDirShadowEnd: i32,
- nPointShadowStart: i32,
- nPointShadowEnd: i32,
- shadowLights:array
- }
-
- #if DEBUG_CLUSTER
- @group(2) @binding(6) var shadowBuffer: ShadowBuffer;
- #else
- @group(2) @binding(5) var shadowBuffer: ShadowBuffer;
- #endif
+ var shadowStrut: ShadowStruct ;
fn useShadow(){
shadowStrut.directShadowVisibility = array( 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0) ;
@@ -51,9 +36,9 @@ export let ShadowMapping_frag: string = /*wgsl*/ `
#if USE_SHADOWMAPING
let enableCSM:bool = globalUniform.enableCSM > 0.5;
for (var i: i32 = 0; i < dirCount ; i = i + 1) {
- if( i >= shadowBuffer.nDirShadowStart && i < shadowBuffer.nDirShadowEnd ){
- let ldx = shadowBuffer.shadowLights[i];
- var light = lightBuffer[ldx];
+ if( i >= globalUniform.nDirShadowStart && i < globalUniform.nDirShadowEnd ){
+ let ldx = globalUniform.shadowLights[u32(i) / 4u][u32(i) % 4u];
+ let light = lightBuffer[u32(ldx)] ;
var shadowIndex = i32(light.castShadow);
var visibility = 1.0;
var shadowMatrix:mat4x4;
@@ -96,7 +81,7 @@ export let ShadowMapping_frag: string = /*wgsl*/ `
if(validCount == 0){
visibility = 1.0;
}else{
- visibility = visibility / totalWeight;
+ visibility = visibility / totalWeight ;
}
}else{
shadowMatrix = globalUniform.shadowMatrix[shadowIndex];
@@ -161,9 +146,9 @@ export let ShadowMapping_frag: string = /*wgsl*/ `
let offset = 0.1;
for (var i: i32 = 0; i < pointCount ; i = i + 1) {
- if( i >= shadowBuffer.nPointShadowStart && i < shadowBuffer.nPointShadowEnd ){
- let ldx = shadowBuffer.shadowLights[i];
- let light = lightBuffer[ldx] ;
+ if( i >= globalUniform.nPointShadowStart && i < globalUniform.nPointShadowEnd ){
+ let ldx = globalUniform.shadowLights[u32(i) / 4u][u32(i) % 4u];
+ let light = lightBuffer[u32(ldx)] ;
#if USE_SHADOWMAPING
let lightPos = light.position.xyz;
diff --git a/src/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts b/src/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts
index a92cddcb..fd84a12b 100644
--- a/src/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts
+++ b/src/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts
@@ -6,6 +6,7 @@ export let PhysicMaterialUniform_frag = /* wgsl */`
baseColor: vec4,
emissiveColor: vec4,
materialF0: vec4,
+ specularColor: vec4,
envIntensity: f32,
normalScale: f32,
roughness: f32,
diff --git a/src/assets/shader/math/FastMathShader.ts b/src/assets/shader/math/FastMathShader.ts
index 4a4eb495..895791d6 100644
--- a/src/assets/shader/math/FastMathShader.ts
+++ b/src/assets/shader/math/FastMathShader.ts
@@ -1,11 +1,17 @@
export let FastMathShader: string = /*wgsl*/ `
- fn Pow3( x : f32 ) -> f32
+ fn pow2( x : f32 ) -> f32
+ {
+ return x * x;
+ }
+
+
+ fn pow3( x : f32 ) -> f32
{
var xx = x*x;
return x * xx;
}
- fn Pow4( x : f32 ) -> f32
+ fn pow4( x : f32 ) -> f32
{
var xx = x*x;
return xx * xx;
diff --git a/src/assets/shader/utils/ColorUtil.ts b/src/assets/shader/utils/ColorUtil.ts
index 719b8229..b2fc1803 100644
--- a/src/assets/shader/utils/ColorUtil.ts
+++ b/src/assets/shader/utils/ColorUtil.ts
@@ -97,6 +97,14 @@ export let ColorUtil: string = /*wgsl*/ `
}
}
+ fn BlendNormalRNM( n1:vec3f, n2:vec3f) -> vec3f
+ {
+ let t = n1.xyz + vec3f(0.0, 0.0, 1.0);
+ let u = n2.xyz * vec3f(-1.0, -1.0, 1.0);
+ let r = (t / t.z) * dot(t, u) - u;
+ return r;
+ }
+
// fn ReorientedBlendNormal(){
// vec3 t = texture(baseMap, uv).xyz * vec3( 2.0, 2.0, 2.0) + vec3(-1.0, -1.0, 0.0);
// vec3 u = texture(detailMap, uv).xyz * vec3(-2.0, -2.0, 2.0) + vec3( 1.0, 1.0, -1.0);
diff --git a/src/components/SkeletonAnimationComponent.ts b/src/components/SkeletonAnimationComponent.ts
index b94cfcca..d30e6b5f 100644
--- a/src/components/SkeletonAnimationComponent.ts
+++ b/src/components/SkeletonAnimationComponent.ts
@@ -1,3 +1,4 @@
+import { RegisterComponent } from "..";
import { Object3D } from "../core/entities/Object3D";
import { StorageGPUBuffer } from "../gfx/graphics/webGpu/core/buffer/StorageGPUBuffer";
import { Time } from "../util/Time";
@@ -11,6 +12,7 @@ import { SkeletonPose } from "./anim/skeletonAnim/SkeletonPose";
* skeleton animation
* @group Animation
*/
+@RegisterComponent
export class SkeletonAnimationComponent extends ComponentBase {
/**
* Whether it is playing
diff --git a/src/components/anim/AnimatorComponent.ts b/src/components/anim/AnimatorComponent.ts
new file mode 100644
index 00000000..819f3bb9
--- /dev/null
+++ b/src/components/anim/AnimatorComponent.ts
@@ -0,0 +1,153 @@
+import { GUIHelp } from "@orillusion/debug/GUIHelp";
+import { BoxGeometry, DEGREES_TO_RADIANS, Engine3D, LitMaterial, Matrix4, MeshFilter, MeshRenderer, Object3D, PrefabAvatarData, Quaternion, Skeleton, SkeletonPose, StorageGPUBuffer, Time, Vector2, Vector3, Vector4, View3D, makeMatrix44 } from "../..";
+import { PropertyAnimationClip } from "../../math/AnimationCurveClip";
+import { RegisterComponent } from "../../util/SerializeDecoration";
+import { ComponentBase } from "../ComponentBase";
+import { GUIUtil } from "@samples/utils/GUIUtil";
+
+@RegisterComponent
+export class AnimatorComponent extends ComponentBase {
+ private _currentClip: PropertyAnimationClip;
+ public jointMatrixIndexTableBuffer: StorageGPUBuffer;
+ public inverseBindMatrices: Float32Array[];
+ private _avatar: PrefabAvatarData;
+ public init(param?: any): void {
+
+ }
+
+ public set avatar(name: string) {
+ this.inverseBindMatrices = [];
+
+ this._avatar = Engine3D.res.getObj(name) as PrefabAvatarData;
+
+ let jointMapping = this.buildSkeletonPose();
+ const jointMatrixIndexTable = new Float32Array(jointMapping);
+ this.jointMatrixIndexTableBuffer = new StorageGPUBuffer(this._avatar.count, 0, jointMatrixIndexTable);
+ }
+
+ public getJointIndexTable(skinJointsName: Array) {
+ let result = new Array();
+ for (let i = 0; i < skinJointsName.length; i++) {
+ let joint = this._avatar.boneMap.get(skinJointsName[i]);
+ result[i] = joint ? joint.boneID : -1;
+ }
+ return result;
+ }
+
+ private debugObj: { [name: string]: Object3D } = {};
+ private buildSkeletonPose(): number[] {
+ let list = [];
+ let matrixList: Matrix4[] = [];
+ let totalTime = 18.06667;
+ let totalFrame = 543;
+ let frame = totalTime / totalFrame;
+ let mesh = new BoxGeometry(0.1, 0.1, 0.1);
+ let mat = new LitMaterial();
+
+ GUIHelp.addFolder("anim");
+ GUIHelp.add(this, "_auto")
+ GUIHelp.add({ frame: 0 }, "frame", 0.0, totalFrame, 1).onChange((v) => {
+ this._time = v * frame;
+ // let joint = this._skeleton.joints[0];
+ // let obj = this.debugObj[joint.name];
+ // console.log(joint.name, obj.rotationX, obj.rotationY, obj.rotationZ);
+ });
+
+
+ for (const joint of this._avatar.boneData) {
+ let obj = new Object3D();
+ // let mr = obj.addComponent(MeshRenderer);
+ // mr.geometry = mesh;
+ // mr.material = mat;
+ this.debugObj[joint.boneName] = obj;
+
+ Matrix4.getEuler(Vector3.HELP_6, joint.q, true, 'ZYX');
+
+ obj.localPosition = joint.t.clone();
+ obj.localRotation = Vector3.HELP_6.clone();
+ obj.localScale = Vector3.ONE; joint.s.clone();
+
+ if (joint.parentBoneName && joint.parentBoneName != "") {
+ this.debugObj[joint.parentBoneName].addChild(obj);
+ } else {
+ this.object3D.addChild(obj);
+ }
+
+ list.push(obj.transform.worldMatrix.index);
+
+
+ // GUIUtil.renderVector3(this.debugObj[joint.boneName], false, joint.boneName);
+ let local = new Matrix4();
+ local.copyFrom(obj.transform.worldMatrix);
+ // makeMatrix44(obj.localRotation, obj.localPosition, obj.localScale, local);
+ local.invert();
+ this.inverseBindMatrices.push(local.rawData);
+ }
+
+
+
+
+ GUIHelp.endFolder();
+
+ return list;
+ }
+
+ public set clips(clips: PropertyAnimationClip[]) {
+ console.log(clips);
+
+ let clip = clips[0];
+ this._currentClip = clip;
+
+ let hips = clip.positionCurves.get("Hips");
+
+ let value = hips.getValue(0.2);
+ console.log("Hips -> " + value);
+ }
+
+ private _time: number = 0;
+ private _auto: boolean = false;
+ private updateTime() {
+ if (this._auto)
+ this._time += Time.delta * 0.001;
+ if (this._time > 18) {
+ this._time = 0;
+ }
+ }
+
+ public onUpdate(view?: View3D) {
+ this.updateTime();
+ if (this._currentClip) {
+ let joints = this._avatar.boneData;
+ let i = 0;
+ let len = joints.length;
+ for (i = 0; i < len; i++) {
+ const joint = joints[i];
+ let pos = this.getPosition(joint.bonePath, this._time);
+ let rot = this.getRotation(joint.bonePath, this._time);
+ let scale = this.getScale(joint.bonePath, this._time);
+
+ let obj = this.debugObj[joint.boneName];
+ obj.transform.localPosition = pos;
+ obj.transform.localRotation = rot;
+ obj.transform.localScale = scale;
+ }
+ }
+ }
+
+ private getPosition(boneName: string, time: number) {
+ let t = this._currentClip.positionCurves.get(boneName).getValue(time) as Vector3;
+ return t;
+ }
+
+ private getRotation(boneName: string, time: number) {
+ let v4 = this._currentClip.rotationCurves.get(boneName).getValue(time) as Vector4;
+ Quaternion.HELP_2.set(v4.x, v4.y, v4.z, v4.w);
+ Matrix4.getEuler(Vector3.HELP_6, Quaternion.HELP_2, true, 'ZYX');
+ return Vector3.HELP_6;
+ }
+
+ private getScale(boneName: string, time: number) {
+ let x = this._currentClip.scaleCurves.get(boneName).getValue(time) as Vector3;
+ return x;
+ }
+}
\ No newline at end of file
diff --git a/src/components/anim/morphAnim/MorphTargetBlender.ts b/src/components/anim/morphAnim/MorphTargetBlender.ts
index 7e1af99a..caadeed9 100644
--- a/src/components/anim/morphAnim/MorphTargetBlender.ts
+++ b/src/components/anim/morphAnim/MorphTargetBlender.ts
@@ -7,6 +7,7 @@ import { ComponentBase } from "../../ComponentBase";
import { MorphTargetFrame } from "./MorphTargetFrame";
import { MeshRenderer } from "../../renderer/MeshRenderer";
import { RendererMask, RendererMaskUtil } from "../../../gfx/renderJob/passRenderer/state/RendererMask";
+import { SkinnedMeshRenderer } from "../../..";
export class MorphTargetBlender extends ComponentBase {
private _targetRenderers: { [key: string]: MeshRenderer[] } = {};
@@ -93,6 +94,13 @@ export class MorphTargetBlender extends ComponentBase {
result.push(renderer);
}
}
+
+ sourceRenders = obj.getComponentsInChild(SkinnedMeshRenderer);
+ for (let renderer of sourceRenders) {
+ if (renderer.hasMask(RendererMask.MorphTarget)) {
+ result.push(renderer);
+ }
+ }
return result;
}
}
\ No newline at end of file
diff --git a/src/components/anim/skeletonAnim/Joint.ts b/src/components/anim/skeletonAnim/Joint.ts
index 4a08a0af..170da8fc 100644
--- a/src/components/anim/skeletonAnim/Joint.ts
+++ b/src/components/anim/skeletonAnim/Joint.ts
@@ -17,6 +17,11 @@ export class Joint {
*/
public index: number = 0;
+ /**
+ * Bone instanceID
+ */
+ public instanceID: string = "";
+
/**
* The parent of a bone joint
*/
@@ -25,7 +30,7 @@ export class Joint {
/**
* Bone joint child object
*/
- public children: Array = [];
+ // public children: Array = [];
/**
* The scaling value of the bone joint
diff --git a/src/components/anim/skeletonAnim/SkeletonPose.ts b/src/components/anim/skeletonAnim/SkeletonPose.ts
index f398a292..f439e690 100644
--- a/src/components/anim/skeletonAnim/SkeletonPose.ts
+++ b/src/components/anim/skeletonAnim/SkeletonPose.ts
@@ -10,109 +10,117 @@ import { Skeleton } from './Skeleton';
* @group Animation
*/
export class SkeletonPose {
- /**
- * time of this pose in owner animation clip
- */
- public time: number;
- protected _skeleton: Skeleton;
- protected _jointsPose: Array;
- protected mJointMatrixIndexTable: Array;
+ /**
+ * time of this pose in owner animation clip
+ */
+ public time: number;
+ protected _skeleton: Skeleton;
+ protected _jointsPose: Array;
+ protected mJointMatrixIndexTable: Array;
- constructor(skeleton: Skeleton, useGlobalMatrix: boolean = false) {
- this._skeleton = skeleton;
- this._jointsPose = new Array(skeleton.numJoint);
- this.mJointMatrixIndexTable = new Array(skeleton.numJoint);
- for (let index = 0; index < skeleton.numJoint; index++) {
- let joint = new JointPose(index, useGlobalMatrix);
- this._jointsPose[index] = joint;
- this.mJointMatrixIndexTable[index] = joint.worldMatrix.index;
+ constructor(skeleton: Skeleton, useGlobalMatrix: boolean = false) {
+ this._skeleton = skeleton;
+ this._jointsPose = new Array(skeleton.numJoint);
+ this.mJointMatrixIndexTable = new Array(skeleton.numJoint);
+ for (let index = 0; index < skeleton.numJoint; index++) {
+ let joint = new JointPose(index, useGlobalMatrix);
+ this._jointsPose[index] = joint;
+ this.mJointMatrixIndexTable[index] = joint.worldMatrix.index;
+ }
}
- }
- /**
- * build this pose from float32 array data
- */
- public buildSkeletonPose(poseData: Float32Array) {
- let scale = new Vector3();
- let rotation = new Quaternion();
- let translation = new Vector3();
- let jointLocalMatrix = new Array(this._skeleton.numJoint);
- this.time = poseData[11] > 0 ? poseData[11] : poseData[24];
- for (let jointIndex = 0; jointIndex < this._skeleton.numJoint; jointIndex++) {
- let byteOffset = 12 * jointIndex * 4;
- let jointData = new Float32Array(poseData.buffer, poseData.byteOffset + byteOffset, 12);
+ /**
+ * build this pose from float32 array data
+ */
+ public buildSkeletonPose(poseData: Float32Array) {
+ let scale = new Vector3();
+ let rotation = new Quaternion();
+ let translation = new Vector3();
+ let jointLocalMatrix = new Array(this._skeleton.numJoint);
+ this.time = poseData[11] > 0 ? poseData[11] : poseData[24];
+ for (let jointIndex = 0; jointIndex < this._skeleton.numJoint; jointIndex++) {
+ let byteOffset = 12 * jointIndex * 4;
+ let jointData = new Float32Array(poseData.buffer, poseData.byteOffset + byteOffset, 12);
- let localMatrix = new Matrix4();
- scale.set(jointData[0], jointData[1], jointData[2]);
- rotation.set(jointData[4], jointData[5], jointData[6], jointData[7]);
- translation.set(jointData[8], jointData[9], jointData[10]);
- makeMatrix44(rotation.getEulerAngles(), translation, scale, localMatrix);
- jointLocalMatrix[jointIndex] = localMatrix;
+ let localMatrix = new Matrix4();
+ scale.set(jointData[0], jointData[1], jointData[2]);
+ rotation.set(jointData[4], jointData[5], jointData[6], jointData[7]);
+ translation.set(jointData[8], jointData[9], jointData[10]);
+ makeMatrix44(rotation.getEulerAngles(), translation, scale, localMatrix);
+ jointLocalMatrix[jointIndex] = localMatrix;
- let joint = new JointPose(jointIndex);
- const nParentIndex = this._skeleton.getJointParentIndex(jointIndex);
- if (nParentIndex < 0) {
- joint.worldMatrix.copyFrom(localMatrix);
- } else {
- let parentJoint = this._jointsPose[nParentIndex];
- multiplyMatrices4x4REF(parentJoint.worldMatrix, localMatrix, joint.worldMatrix);
- }
- this._jointsPose[jointIndex] = joint;
+ let joint = new JointPose(jointIndex);
+ const nParentIndex = this._skeleton.getJointParentIndex(jointIndex);
+ if (nParentIndex < 0) {
+ joint.worldMatrix.copyFrom(localMatrix);
+ } else {
+ let parentJoint = this._jointsPose[nParentIndex];
+ multiplyMatrices4x4REF(parentJoint.worldMatrix, localMatrix, joint.worldMatrix);
+ }
+ this._jointsPose[jointIndex] = joint;
+ }
}
- }
- /**
- * Returns joints count of owner skeleton
- */
- public get numJoint(): number {
- return this._skeleton.numJoint;
- }
+ /**
+ * Returns joints count of owner skeleton
+ */
+ public get numJoint(): number {
+ return this._skeleton.numJoint;
+ }
- /**
- * Returns all joint pose
- */
- public get joints(): Array {
- return this._jointsPose;
- }
+ /**
+ * Returns all joint pose
+ */
+ public get joints(): Array {
+ return this._jointsPose;
+ }
- /**
- * Returns list of matrix's index
- */
- public get jointMatrixIndexTable(): Array {
- return this.mJointMatrixIndexTable;
- }
+ /**
+ * Returns list of matrix's index
+ */
+ public get jointMatrixIndexTable(): Array {
+ return this.mJointMatrixIndexTable;
+ }
- /**
- * Returns lerped skeletonPose from pose a to pose b
- * @param a selected pose No.1
- * @param b selected pose No.2
- * @param weight number
- */
- public lerp(a: SkeletonPose, b: SkeletonPose, weight: number) {
- for (let index = 0; index < this._jointsPose.length; index++) {
- let jointA = a._jointsPose[index];
- let jointB = b._jointsPose[index];
- let jointDst = this._jointsPose[index];
- jointDst.worldMatrix.lerp(jointA.worldMatrix, jointB.worldMatrix, weight);
+ /**
+ * Returns lerped skeletonPose from pose a to pose b
+ * @param a selected pose No.1
+ * @param b selected pose No.2
+ * @param weight number
+ */
+ public lerp(a: SkeletonPose, b: SkeletonPose, weight: number) {
+ if (a && b) {
+ for (let index = 0; index < this._jointsPose.length; index++) {
+ let jointA = a._jointsPose[index];
+ let jointB = b._jointsPose[index];
+ let jointDst = this._jointsPose[index];
+ jointDst.worldMatrix.lerp(jointA.worldMatrix, jointB.worldMatrix, weight);
+ }
+ } else {
+ for (let index = 0; index < this._jointsPose.length; index++) {
+ let jointA = a._jointsPose[index];
+ let jointDst = this._jointsPose[index];
+ jointDst.worldMatrix.copyFrom(jointA.worldMatrix);
+ }
+ }
}
- }
- /**
- * Copy skeleton pose from other skeleton pose
- * @param other source skeleton pose
- */
- public copyFrom(other: SkeletonPose) {
- for (let index = 0; index < this._jointsPose.length; index++) {
- this._jointsPose[index].worldMatrix.copyFrom(other._jointsPose[index].worldMatrix)
+ /**
+ * Copy skeleton pose from other skeleton pose
+ * @param other source skeleton pose
+ */
+ public copyFrom(other: SkeletonPose) {
+ for (let index = 0; index < this._jointsPose.length; index++) {
+ this._jointsPose[index].worldMatrix.copyFrom(other._jointsPose[index].worldMatrix)
+ }
}
- }
- /**
- * Reset this skeleton pose
- */
- public reset() {
- for (let index = 0; index < this._jointsPose.length; index++) {
- this._jointsPose[index].worldMatrix.identity();
+ /**
+ * Reset this skeleton pose
+ */
+ public reset() {
+ for (let index = 0; index < this._jointsPose.length; index++) {
+ this._jointsPose[index].worldMatrix.identity();
+ }
}
- }
}
diff --git a/src/components/lights/DirectLight.ts b/src/components/lights/DirectLight.ts
index d81c6ad2..848cb8e2 100644
--- a/src/components/lights/DirectLight.ts
+++ b/src/components/lights/DirectLight.ts
@@ -1,5 +1,6 @@
import { Camera3D } from '../../core/Camera3D';
import { UUID } from '../../util/Global';
+import { RegisterComponent } from '../../util/SerializeDecoration';
import { LightBase } from './LightBase';
import { LightType } from './LightData';
/**
@@ -8,6 +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
export class DirectLight extends LightBase {
public shadowCamera: Camera3D;
diff --git a/src/components/lights/Light.ts b/src/components/lights/Light.ts
new file mode 100644
index 00000000..f1d1c1e4
--- /dev/null
+++ b/src/components/lights/Light.ts
@@ -0,0 +1,141 @@
+import { RegisterComponent } from '../..';
+import { Engine3D } from '../../Engine3D';
+import { View3D } from '../../core/View3D';
+import { Vector3 } from '../../math/Vector3';
+import { UUID } from '../../util/Global';
+import { LightBase } from './LightBase';
+import { LightType } from './LightData';
+/**
+ *Point light source.
+ *A single point light source that illuminates all directions.
+ *A common example is to simulate the light emitted by a light bulb, where a point light source cannot create shadows.
+ * @group Lights
+ */
+@RegisterComponent
+export class Light extends LightBase {
+
+ constructor() {
+ super();
+ }
+
+ public init(): void {
+ super.init();
+ this.lightData.lightType = LightType.PointLight;
+ if (this.object3D.name == "") {
+ this.object3D.name = "PointLight" + UUID();
+ }
+ }
+
+
+ /**
+ *
+ * Get the range of the light source
+ * @return {number}
+ */
+ public get range(): number {
+ return this.lightData.range as number;
+ }
+ /**
+ *
+ * Set the range of the light source
+ * @param {number}
+ */
+ public set range(value: number) {
+ this.lightData.range = value;
+ this.onChange();
+ }
+
+ /**
+ *
+ * Get the illumination distance of the light source
+ * @type {number}
+ * @memberof PointLight
+ */
+ public get at(): number {
+ return this.lightData.linear as number;
+ }
+
+ /**
+ *
+ * Set the illumination distance of the light source
+ * @param {value} It will decay linearly from the maximum value to the current light position at a distance of 0,
+ * with a default value of 0. This means that the intensity of the light will not decrease due to distance
+ * @memberof PointLight
+ */
+ public set at(value: number) {
+ this.lightData.linear = value;
+ this.onChange();
+ }
+
+ /**
+ * Get the radius to control the light
+ */
+ public get radius(): number {
+ return this.lightData.radius as number;
+ }
+
+ /**
+ * Set the radius of the control light
+ */
+ public set radius(value: number) {
+ this.lightData.radius = value;
+ this.onChange();
+ }
+
+ /**
+ * Get the radius to control the light
+ */
+ public get quadratic(): number {
+ return this.lightData.quadratic as number;
+ }
+
+ /**
+ * Set the radius of the control light
+ */
+ public set quadratic(value: number) {
+ this.lightData.quadratic = value;
+ this.onChange();
+ }
+
+
+
+ public start(): void {
+ this.transform.rotationX = 90;
+ super.start();
+ }
+
+ public onUpdate(): void {
+ // this.transform.updateWorldMatrix(true);
+ }
+
+ 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);
+ }
+
+ /**
+ * enable GUI debug
+ */
+ public debug() {
+ }
+
+ public debugDraw(show: boolean) {
+ // if (this.mShowDebugLine != show) {
+ // if (show) {
+ // this.drawDebugLine();
+ // } else {
+ // let view = this.transform.view3D;
+ // view.graphic3D.Clear(`PointLight_${this.object3D.uuid}`);
+ // }
+ // this.mShowDebugLine = show;
+ // }
+ }
+
+}
+
diff --git a/src/components/lights/LightBase.ts b/src/components/lights/LightBase.ts
index a5d942e1..48bc4f25 100644
--- a/src/components/lights/LightBase.ts
+++ b/src/components/lights/LightBase.ts
@@ -183,6 +183,24 @@ export class LightBase extends ComponentBase implements ILight {
this.lightData.lightColor = value;
this.onChange();
}
+
+ /**
+ * Get light source color
+ * @return Color
+ */
+ public get color(): Color {
+ return this.lightData.lightColor;
+ }
+
+ /**
+ * Set light source color
+ * @param Color
+ */
+ public set color(value: Color) {
+ this.lightData.lightColor = value;
+ this.onChange();
+ }
+
/**
* Get Illumination intensity of light source
* @return number
@@ -190,6 +208,7 @@ export class LightBase extends ComponentBase implements ILight {
public get intensity(): number {
return this.lightData.intensity as number;
}
+
/**
* Set Illumination intensity of light source
* @param value
diff --git a/src/components/lights/PointLight.ts b/src/components/lights/PointLight.ts
index f6fd1f31..5e3cfe81 100644
--- a/src/components/lights/PointLight.ts
+++ b/src/components/lights/PointLight.ts
@@ -1,7 +1,7 @@
-import { Engine3D } from '../../Engine3D';
import { View3D } from '../../core/View3D';
import { Vector3 } from '../../math/Vector3';
import { UUID } from '../../util/Global';
+import { RegisterComponent } from '../../util/SerializeDecoration';
import { LightBase } from './LightBase';
import { LightType } from './LightData';
/**
@@ -10,6 +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
export class PointLight extends LightBase {
constructor() {
diff --git a/src/components/lights/SpotLight.ts b/src/components/lights/SpotLight.ts
index 9f688031..a8060dc2 100644
--- a/src/components/lights/SpotLight.ts
+++ b/src/components/lights/SpotLight.ts
@@ -3,6 +3,7 @@ import { View3D } from '../../core/View3D';
import { clamp, DEGREES_TO_RADIANS, RADIANS_TO_DEGREES } from '../../math/MathUtil';
import { Vector3 } from '../../math/Vector3';
import { UUID } from '../../util/Global';
+import { RegisterComponent } from '../../util/SerializeDecoration';
import { LightBase } from './LightBase';
import { LightType } from './LightData';
@@ -12,6 +13,7 @@ import { LightType } from './LightData';
* Similar to a desk lamp, chandelier, or flashlight, this light source can produce shadows.
* @group Lights
*/
+@RegisterComponent
export class SpotLight extends LightBase {
constructor() {
super();
diff --git a/src/components/renderer/MeshFilter.ts b/src/components/renderer/MeshFilter.ts
new file mode 100644
index 00000000..ca9e63bc
--- /dev/null
+++ b/src/components/renderer/MeshFilter.ts
@@ -0,0 +1,25 @@
+import { Engine3D } from '../../Engine3D';
+import { RegisterComponent } from '../../util/SerializeDecoration';
+import { MeshRenderer } from './MeshRenderer';
+
+/**
+ * The mesh renderer component is a component used to render the mesh
+ * @group Components
+ */
+@RegisterComponent
+export class MeshFilter extends MeshRenderer {
+ constructor() {
+ super();
+
+ }
+
+ public set meshURL(value: string) {
+ let geometry = Engine3D.res.getGeometry(value);
+ if (geometry) {
+ this.geometry = geometry;
+ } else {
+ console.error("no geometry set", value);
+ }
+ // this.material = Engine3D.res.defaltMaterial;
+ }
+}
diff --git a/src/components/renderer/MeshRenderer.ts b/src/components/renderer/MeshRenderer.ts
index 1779f617..bc82ffa0 100644
--- a/src/components/renderer/MeshRenderer.ts
+++ b/src/components/renderer/MeshRenderer.ts
@@ -7,13 +7,14 @@ import { RendererPassState } from '../../gfx/renderJob/passRenderer/state/Render
import { RendererType } from '../../gfx/renderJob/passRenderer/state/RendererType';
import { MorphTargetData } from '../anim/morphAnim/MorphTargetData';
import { RenderNode } from './RenderNode';
-import { EditorInspector } from '../../util/SerializeDecoration';
+import { EditorInspector, RegisterComponent } from '../../util/SerializeDecoration';
import { Material } from '../..';
/**
* The mesh renderer component is a component used to render the mesh
* @group Components
*/
+@RegisterComponent
export class MeshRenderer extends RenderNode {
/**
* Enabling this option allows the grid to display any shadows cast on the grid.
@@ -71,7 +72,7 @@ export class MeshRenderer extends RenderNode {
}
this.object3D.bound = this._geometry.bounds.clone();
- if (this._readyPipeline) {
+ if (!this._readyPipeline) {
this.initPipeline();
}
}
diff --git a/src/components/renderer/RenderNode.ts b/src/components/renderer/RenderNode.ts
index e4ff1797..f8573032 100644
--- a/src/components/renderer/RenderNode.ts
+++ b/src/components/renderer/RenderNode.ts
@@ -210,7 +210,9 @@ export class RenderNode extends ComponentBase {
if (!this._readyPipeline) {
this.initPipeline();
}
+
EntityCollect.instance.addRenderNode(this.transform.scene3D, this);
+
this.updateOctreeEntity();
}
@@ -510,7 +512,6 @@ export class RenderNode extends ComponentBase {
let shadowRenderer = Engine3D.getRenderJob(view).shadowMapPassRenderer;
if (shadowRenderer && shadowRenderer.depth2DArrayTexture) {
renderShader.setTexture(`shadowMap`, Engine3D.getRenderJob(view).shadowMapPassRenderer.depth2DArrayTexture);
- renderShader.setStorageBuffer(`shadowBuffer`, ShadowLightsCollect.shadowBuffer.get(view.scene));
}
// let shadowLight = ShadowLights.list;
// if (shadowLight.length) {
@@ -534,7 +535,7 @@ export class RenderNode extends ComponentBase {
if (lightUniformEntries) {
renderShader.setStorageBuffer(`lightBuffer`, lightUniformEntries.storageGPUBuffer);
if (lightUniformEntries.irradianceVolume) {
- renderShader.setStructStorageBuffer(`irradianceData`, lightUniformEntries.irradianceVolume.irradianceVolumeBuffer);
+ renderShader.setUniformBuffer(`irradianceData`, lightUniformEntries.irradianceVolume.irradianceVolumeBuffer);
}
}
diff --git a/src/components/renderer/SkinnedMeshRenderer.ts b/src/components/renderer/SkinnedMeshRenderer.ts
index 21344dad..d685c625 100644
--- a/src/components/renderer/SkinnedMeshRenderer.ts
+++ b/src/components/renderer/SkinnedMeshRenderer.ts
@@ -7,6 +7,7 @@ import { RendererType } from "../../gfx/renderJob/passRenderer/state/RendererTyp
import { RendererPassState } from "../../gfx/renderJob/passRenderer/state/RendererPassState";
import { SkeletonAnimationComponent } from "../SkeletonAnimationComponent";
import { ClusterLightingBuffer } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer";
+import { GeometryBase, Matrix4, RegisterComponent } from "../..";
/**
* Skin Mesh Renderer Component
@@ -15,112 +16,133 @@ import { ClusterLightingBuffer } from "../../gfx/renderJob/passRenderer/cluster/
* meshes with mixed shapes, and meshes running cloth simulations.
* @group Components
*/
+@RegisterComponent
export class SkinnedMeshRenderer extends MeshRenderer {
- public skinJointsName: Array;
- protected mInverseBindMatrixData: Array;
- protected mInverseBindMatrixBuffer: StorageGPUBuffer;
- protected mSkeletonAnimation: SkeletonAnimationComponent;
- protected mJointIndexTableBuffer: StorageGPUBuffer;
+ public skinJointsName: Array;
+ protected mInverseBindMatrixData: Array;
+ protected mInverseBindMatrixBuffer: StorageGPUBuffer;
+ protected mSkeletonAnimation: SkeletonAnimationComponent;
+ protected mJointIndexTableBuffer: StorageGPUBuffer;
- constructor() {
- super();
- this.addRendererMask(RendererMask.SkinnedMesh);
- }
+ constructor() {
+ super();
+ this.addRendererMask(RendererMask.SkinnedMesh);
+ }
+
+ public get geometry(): GeometryBase {
+ return this._geometry;
+ }
- public start() {
- super.start();
- this.skeletonAnimation = this.object3D.getComponent(SkeletonAnimationComponent);
- if (!this.skeletonAnimation) {
- let comps = this.object3D.parentObject.parentObject.getComponentsInChild(SkeletonAnimationComponent);
- if (comps.length > 0) {
- this.skeletonAnimation = comps[0];
- }
- if (!this.skeletonAnimation) {
- this.skeletonAnimation = this.object3D.getComponentFromParent(SkeletonAnimationComponent);
- }
+ public set geometry(value: GeometryBase) {
+ this.skinJointsName = value.skinNames;
+ let matrixList: Float32Array[] = [];
+ for (let i = 0; i < value.bindPose.length; i++) {
+ // value.bindPose[i].transpose();
+ // matrixList.push(value.bindPose[i].rawData.slice(0, 16));
+ Matrix4.helpMatrix.identity();
+ matrixList.push(new Float32Array(Matrix4.helpMatrix.rawData));
+ }
+ this.skinInverseBindMatrices = matrixList;
+ super.geometry = value;
}
- }
- public onEnable(): void {
- super.onEnable();
- }
+ public start() {
+ super.start();
+ this.skeletonAnimation = this.object3D.getComponent(SkeletonAnimationComponent);
+ if (!this.skeletonAnimation) {
+ let comps = this.object3D.parentObject.parentObject.getComponentsInChild(SkeletonAnimationComponent);
+ if (comps.length > 0) {
+ this.skeletonAnimation = comps[0];
+ }
+ let parentObj = this.object3D;
+ while (!this.skeletonAnimation && parentObj) {
+ this.skeletonAnimation = parentObj.getComponentFromParent(SkeletonAnimationComponent);
+ if (parentObj.parent) {
+ parentObj = parentObj.parent.object3D;
+ }
+ }
+ }
+ }
- public get skeletonAnimation(): SkeletonAnimationComponent {
- return this.mSkeletonAnimation;
- }
+ public onEnable(): void {
+ super.onEnable();
+ }
- public set skeletonAnimation(value: SkeletonAnimationComponent) {
- this.mSkeletonAnimation = value;
- if (!value) {
- return;
+ public get skeletonAnimation(): SkeletonAnimationComponent {
+ return this.mSkeletonAnimation;
}
- if (!this.mJointIndexTableBuffer) {
- let skinJointIndexData = this.mSkeletonAnimation.getJointIndexTable(this.skinJointsName);
- this.mJointIndexTableBuffer = new StorageGPUBuffer(skinJointIndexData.length * 4, 0, new Float32Array(skinJointIndexData));
- this.mJointIndexTableBuffer.visibility = GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE;
+ public set skeletonAnimation(value: SkeletonAnimationComponent) {
+ this.mSkeletonAnimation = value;
+ if (!value) {
+ return;
+ }
+
+ if (!this.mJointIndexTableBuffer) {
+ let skinJointIndexData = this.mSkeletonAnimation.getJointIndexTable(this.skinJointsName);
+ this.mJointIndexTableBuffer = new StorageGPUBuffer(skinJointIndexData.length * 4, 0, new Float32Array(skinJointIndexData));
+ this.mJointIndexTableBuffer.visibility = GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE;
+ }
}
- }
- public get skinInverseBindMatrices(): Array {
- return this.mInverseBindMatrixData;
- }
+ public get skinInverseBindMatrices(): Array {
+ return this.mInverseBindMatrixData;
+ }
- public set skinInverseBindMatrices(inverseBindMatrices: Array) {
- this.mInverseBindMatrixData = inverseBindMatrices;
- var inverseBindMatricesData = new Float32Array(inverseBindMatrices.length * 16);
- for (let i = 0; i < inverseBindMatrices.length; i++) {
- let index = i * 16;
- let mat4x4 = inverseBindMatrices[i];
- inverseBindMatricesData.set(mat4x4, index);
+ public set skinInverseBindMatrices(inverseBindMatrices: Array) {
+ this.mInverseBindMatrixData = inverseBindMatrices;
+ var inverseBindMatricesData = new Float32Array(inverseBindMatrices.length * 16);
+ for (let i = 0; i < inverseBindMatrices.length; i++) {
+ let index = i * 16;
+ let mat4x4 = inverseBindMatrices[i];
+ inverseBindMatricesData.set(mat4x4, index);
+ }
+ this.mInverseBindMatrixBuffer = new StorageGPUBuffer(inverseBindMatricesData.byteLength, 0, inverseBindMatricesData);
+ this.mInverseBindMatrixBuffer.visibility = GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE;
}
- this.mInverseBindMatrixBuffer = new StorageGPUBuffer(inverseBindMatricesData.byteLength, 0, inverseBindMatricesData);
- this.mInverseBindMatrixBuffer.visibility = GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE;
- }
- public get inverseBindMatrixBuffer(): StorageGPUBuffer {
- return this.mInverseBindMatrixBuffer;
- }
+ public get inverseBindMatrixBuffer(): StorageGPUBuffer {
+ return this.mInverseBindMatrixBuffer;
+ }
- public get jointIndexTableBuffer(): GPUBuffer {
- return this.mJointIndexTableBuffer.buffer;
- }
+ public get jointIndexTableBuffer(): GPUBuffer {
+ return this.mJointIndexTableBuffer.buffer;
+ }
- public cloneTo(obj: Object3D) {
- let skinnedMesh = obj.addComponent(SkinnedMeshRenderer);
- skinnedMesh.geometry = this.geometry;
- skinnedMesh.material = this.material.clone();
- skinnedMesh.castShadow = this.castShadow;
- skinnedMesh.castGI = this.castGI;
- skinnedMesh.receiveShadow = this.receiveShadow;
- skinnedMesh.rendererMask = this.rendererMask;
- skinnedMesh.skinJointsName = this.skinJointsName;
- skinnedMesh.skinInverseBindMatrices = this.skinInverseBindMatrices;
- skinnedMesh.mJointIndexTableBuffer = this.mJointIndexTableBuffer;
- }
+ public cloneTo(obj: Object3D) {
+ let skinnedMesh = obj.addComponent(SkinnedMeshRenderer);
+ skinnedMesh.geometry = this.geometry;
+ skinnedMesh.material = this.material.clone();
+ skinnedMesh.castShadow = this.castShadow;
+ skinnedMesh.castGI = this.castGI;
+ skinnedMesh.receiveShadow = this.receiveShadow;
+ skinnedMesh.rendererMask = this.rendererMask;
+ skinnedMesh.skinJointsName = this.skinJointsName;
+ skinnedMesh.skinInverseBindMatrices = this.skinInverseBindMatrices;
+ skinnedMesh.mJointIndexTableBuffer = this.mJointIndexTableBuffer;
+ }
- /**
- * @internal
- * @param passType
- * @param renderPassState
- * @param scene3D
- * @param clusterLightingRender
- * @param probes
- */
- public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer) {
- for (let i = 0; i < this.materials.length; i++) {
- const material = this.materials[i];
- let passes = material.getPass(passType);
- if (passes) for (let i = 0; i < passes.length; i++) {
- const renderShader = passes[i];
- if (!renderShader.pipeline) {
- renderShader.setStorageBuffer('jointsMatrixIndexTable', this.mSkeletonAnimation.jointMatrixIndexTableBuffer);
- renderShader.setStorageBuffer('jointsInverseMatrix', this.mInverseBindMatrixBuffer);
- renderShader.setStorageBuffer('jointsIndexMapingTable', this.mJointIndexTableBuffer);
+ /**
+ * @internal
+ * @param passType
+ * @param renderPassState
+ * @param scene3D
+ * @param clusterLightingRender
+ * @param probes
+ */
+ public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer) {
+ for (let i = 0; i < this.materials.length; i++) {
+ const material = this.materials[i];
+ let passes = material.getPass(passType);
+ if (passes) for (let i = 0; i < passes.length; i++) {
+ const renderShader = passes[i];
+ if (!renderShader.pipeline && this.mSkeletonAnimation) {
+ renderShader.setStorageBuffer('jointsMatrixIndexTable', this.mSkeletonAnimation.jointMatrixIndexTableBuffer);
+ renderShader.setStorageBuffer('jointsInverseMatrix', this.mInverseBindMatrixBuffer);
+ renderShader.setStorageBuffer('jointsIndexMapingTable', this.mJointIndexTableBuffer);
+ }
+ }
}
- }
+ super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
}
- super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
- }
-
-}
+}
\ No newline at end of file
diff --git a/src/components/renderer/SkinnedMeshRenderer2.ts b/src/components/renderer/SkinnedMeshRenderer2.ts
new file mode 100644
index 00000000..512fe0ab
--- /dev/null
+++ b/src/components/renderer/SkinnedMeshRenderer2.ts
@@ -0,0 +1,149 @@
+import { View3D } from "../../core/View3D";
+import { Object3D } from "../../core/entities/Object3D";
+import { MeshRenderer } from "./MeshRenderer";
+import { RendererMask } from "../../gfx/renderJob/passRenderer/state/RendererMask";
+import { StorageGPUBuffer } from "../../gfx/graphics/webGpu/core/buffer/StorageGPUBuffer";
+import { RendererType } from "../../gfx/renderJob/passRenderer/state/RendererType";
+import { RendererPassState } from "../../gfx/renderJob/passRenderer/state/RendererPassState";
+import { ClusterLightingBuffer } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer";
+import { AnimatorComponent, GeometryBase, Matrix4, RegisterComponent } from "../..";
+
+/**
+ * Skin Mesh Renderer Component
+ * Renders a deformable mesh.
+ * Deformable meshes include skin meshes (meshes with bones and bound poses),
+ * meshes with mixed shapes, and meshes running cloth simulations.
+ * @group Components
+ */
+@RegisterComponent
+export class SkinnedMeshRenderer2 extends MeshRenderer {
+ public skinJointsName: Array;
+ protected mInverseBindMatrixData: Array;
+ protected mInverseBindMatrixBuffer: StorageGPUBuffer;
+ protected mSkeletonAnimation: AnimatorComponent;
+ protected mJointIndexTableBuffer: StorageGPUBuffer;
+
+ constructor() {
+ super();
+ this.addRendererMask(RendererMask.SkinnedMesh);
+ }
+
+ public get geometry(): GeometryBase {
+ return this._geometry;
+ }
+
+ public set geometry(value: GeometryBase) {
+ this.skinJointsName = value.skinNames;
+ let matrixList: Float32Array[] = [];
+ for (let i = 0; i < value.bindPose.length; i++) {
+ value.bindPose[i].transpose();
+ // value.bindPose[i].invert();
+ matrixList.push(value.bindPose[i].rawData.slice(0, 16));
+ // Matrix4.helpMatrix.identity();
+ // matrixList.push(new Float32Array(Matrix4.helpMatrix.rawData));
+ }
+ this.skinInverseBindMatrices = matrixList;
+ super.geometry = value;
+ }
+
+ public start() {
+ super.start();
+ this.skeletonAnimation = this.object3D.getComponent(AnimatorComponent);
+ if (!this.skeletonAnimation) {
+ let comps = this.object3D.parentObject.parentObject.getComponentsInChild(AnimatorComponent);
+ if (comps.length > 0) {
+ this.skeletonAnimation = comps[0];
+ }
+ let parentObj = this.object3D;
+ while (!this.skeletonAnimation && parentObj) {
+ this.skeletonAnimation = parentObj.getComponentFromParent(AnimatorComponent);
+ if (parentObj.parent) {
+ parentObj = parentObj.parent.object3D;
+ }
+ }
+ }
+ // this.skinInverseBindMatrices = this.skeletonAnimation.inverseBindMatrices;
+ }
+
+ public onEnable(): void {
+ super.onEnable();
+ }
+
+ public get skeletonAnimation(): AnimatorComponent {
+ return this.mSkeletonAnimation;
+ }
+
+ public set skeletonAnimation(value: AnimatorComponent) {
+ this.mSkeletonAnimation = value;
+ if (!value) {
+ return;
+ }
+
+ if (!this.mJointIndexTableBuffer) {
+ let skinJointIndexData = this.mSkeletonAnimation.getJointIndexTable(this.skinJointsName);
+ this.mJointIndexTableBuffer = new StorageGPUBuffer(skinJointIndexData.length, 0, new Float32Array(skinJointIndexData));
+ this.mJointIndexTableBuffer.visibility = GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE;
+ }
+ }
+
+ public get skinInverseBindMatrices(): Array {
+ return this.mInverseBindMatrixData;
+ }
+
+ public set skinInverseBindMatrices(inverseBindMatrices: Array) {
+ this.mInverseBindMatrixData = inverseBindMatrices;
+ var inverseBindMatricesData = new Float32Array(inverseBindMatrices.length * 16);
+ for (let i = 0; i < inverseBindMatrices.length; i++) {
+ let index = i * 16;
+ let mat4x4 = inverseBindMatrices[i];
+ inverseBindMatricesData.set(mat4x4, index);
+ }
+ this.mInverseBindMatrixBuffer = new StorageGPUBuffer(inverseBindMatricesData.byteLength, 0, inverseBindMatricesData);
+ this.mInverseBindMatrixBuffer.visibility = GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE;
+ }
+
+ public get inverseBindMatrixBuffer(): StorageGPUBuffer {
+ return this.mInverseBindMatrixBuffer;
+ }
+
+ public get jointIndexTableBuffer(): GPUBuffer {
+ return this.mJointIndexTableBuffer.buffer;
+ }
+
+ public cloneTo(obj: Object3D) {
+ let skinnedMesh = obj.addComponent(SkinnedMeshRenderer2);
+ skinnedMesh.geometry = this.geometry;
+ skinnedMesh.material = this.material.clone();
+ skinnedMesh.castShadow = this.castShadow;
+ skinnedMesh.castGI = this.castGI;
+ skinnedMesh.receiveShadow = this.receiveShadow;
+ skinnedMesh.rendererMask = this.rendererMask;
+ skinnedMesh.skinJointsName = this.skinJointsName;
+ skinnedMesh.skinInverseBindMatrices = this.skinInverseBindMatrices;
+ skinnedMesh.mJointIndexTableBuffer = this.mJointIndexTableBuffer;
+ }
+
+ /**
+ * @internal
+ * @param passType
+ * @param renderPassState
+ * @param scene3D
+ * @param clusterLightingRender
+ * @param probes
+ */
+ public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer) {
+ for (let i = 0; i < this.materials.length; i++) {
+ const material = this.materials[i];
+ let passes = material.getPass(passType);
+ if (passes) for (let i = 0; i < passes.length; i++) {
+ const renderShader = passes[i];
+ if (!renderShader.pipeline && this.mSkeletonAnimation) {
+ renderShader.setStorageBuffer('jointsMatrixIndexTable', this.mSkeletonAnimation.jointMatrixIndexTableBuffer);
+ renderShader.setStorageBuffer('jointsInverseMatrix', this.mInverseBindMatrixBuffer);
+ renderShader.setStorageBuffer('jointsIndexMapingTable', this.mJointIndexTableBuffer);
+ }
+ }
+ }
+ super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
+ }
+}
\ No newline at end of file
diff --git a/src/core/View3D.ts b/src/core/View3D.ts
index 7f334f66..164efecf 100644
--- a/src/core/View3D.ts
+++ b/src/core/View3D.ts
@@ -60,7 +60,7 @@ export class View3D extends CEventListener {
this._scene = value;
value.view = this;
- ShadowLightsCollect.createBuffer(value);
+ ShadowLightsCollect.createBuffer(this);
if (this.graphic3D)
value.addChild(this.graphic3D);
diff --git a/src/core/geometry/GeometryBase.ts b/src/core/geometry/GeometryBase.ts
index 385029c2..d1e766fb 100644
--- a/src/core/geometry/GeometryBase.ts
+++ b/src/core/geometry/GeometryBase.ts
@@ -8,12 +8,16 @@ import { GeometryIndicesBuffer } from "./GeometryIndicesBuffer";
import { GeometryVertexType } from "./GeometryVertexType";
import { VertexAttributeData } from "./VertexAttributeData";
import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/ArrayBufferData";
+import { Matrix4 } from "../..";
-export type LodLevel = {
+export type LODDescriptor = {
indexStart: number;
indexCount: number;
vertexStart: number;
+ vertexCount: number;
+ firstStart: number;
index: number;
+ topology: number;
}
@@ -22,7 +26,7 @@ export type LodLevel = {
* @group Geometry
*/
export class SubGeometry {
- public lodLevels: LodLevel[];
+ public lodLevels: LODDescriptor[];
}
@@ -36,6 +40,8 @@ export class GeometryBase {
public subGeometries: SubGeometry[] = [];
public morphTargetsRelative: boolean;
public morphTargetDictionary: { value: string; key: number };
+ public skinNames: string[];
+ public bindPose: Matrix4[];
private _bounds: BoundingBox;
private _attributeMap: Map;
@@ -90,7 +96,7 @@ export class GeometryBase {
this._bounds.max.z = -Number.MAX_VALUE;
let attributes = this.getAttribute(VertexAttributeName.position);
- if (attributes) {
+ if (attributes && attributes.data) {
for (let i = 0; i < attributes.data.length / 3; i++) {
const px = attributes.data[i * 3 + 0];
const py = attributes.data[i * 3 + 1];
@@ -127,9 +133,9 @@ export class GeometryBase {
/**
* add subGeometry from lod level
- * @param lodLevels @see LodLevel
+ * @param lodLevels @see LODDescriptor
*/
- public addSubGeometry(...lodLevels: LodLevel[]) {
+ public addSubGeometry(...lodLevels: LODDescriptor[]) {
let sub = new SubGeometry();
sub.lodLevels = lodLevels;
this.subGeometries.push(sub);
diff --git a/src/core/geometry/GeometryVertexBuffer.ts b/src/core/geometry/GeometryVertexBuffer.ts
index 76005495..23bef450 100644
--- a/src/core/geometry/GeometryVertexBuffer.ts
+++ b/src/core/geometry/GeometryVertexBuffer.ts
@@ -4,6 +4,7 @@ import { VertexAttributeData } from "./VertexAttributeData";
import { GeometryVertexType } from "./GeometryVertexType";
import { VertexBufferLayout, VertexAttribute } from "./VertexAttribute";
import { VertexAttributeSize } from "./VertexAttributeSize";
+import { VertexAttributeName } from "./VertexAttributeName";
export class GeometryVertexBuffer {
@@ -33,6 +34,9 @@ export class GeometryVertexBuffer {
case GeometryVertexType.compose:
this.createComposeVertexBuffer(vertexDataInfos, shaderReflection);
break;
+ case GeometryVertexType.compose_bin:
+ this.createComposBinVertexBuffer(vertexDataInfos, shaderReflection);
+ break;
}
}
@@ -62,6 +66,7 @@ export class GeometryVertexBuffer {
}
vertexDataInfos.set(attributeInfo.name, vertexInfo);
}
+
let len = vertexInfo.data.length / attributeLayout.stride;
if (this.vertexCount != 0 && this.vertexCount != len) {
console.error(" vertex count not match attribute count");
@@ -111,15 +116,69 @@ export class GeometryVertexBuffer {
}
vertexDataInfos.set(attributeInfo.name, vertexInfo);
}
- let len = vertexInfo.data.length / attributeLayout.stride;
- if (this.vertexCount != 0 && this.vertexCount != len) {
- console.error(" vertex count not match attribute count");
+ if (vertexInfo.data) {
+ let len = vertexInfo.data.length / attributeLayout.stride;
+ if (this.vertexCount != 0 && this.vertexCount != len) {
+ console.error(" vertex count not match attribute count");
+ }
+ this.vertexCount = len;
}
- this.vertexCount = len;
+ attributeOffset += attributeInfo.size;
+ }
+
+ this._vertexBufferLayouts[0] = {
+ name: `composeStruct`,
+ arrayStride: attributeOffset * 4,
+ stepMode: `vertex`,
+ attributes: this._attributeSlotLayouts[0],
+ offset: 0,
+ size: this.vertexCount * attributeOffset * 4
+ }
+
+ this.vertexGPUBuffer = new VertexGPUBuffer(this.vertexCount * attributeOffset);
+ }
+ private createComposBinVertexBuffer(vertexDataInfos: Map, shaderReflection: ShaderReflection) {
+ this._attributeSlotLayouts[0] = [];
+
+ let attributeOffset = 0;
+ for (let i = 0; i < shaderReflection.attributes.length; i++) {
+ const attributeInfo = shaderReflection.attributes[i];
+ if (attributeInfo.name == `index`) continue;
+ if (attributeInfo.type == `builtin`) continue;
+ this._attributeLocation[attributeInfo.name] = attributeInfo.location;
+
+ let attributeLayout: VertexAttribute = {
+ name: attributeInfo.name,
+ format: attributeInfo.format,
+ offset: attributeOffset * 4,
+ shaderLocation: attributeInfo.location,
+ stride: VertexAttributeSize[attributeInfo.format]
+ }
+ this._attributeSlotLayouts[0][attributeInfo.location] = attributeLayout;
+
+ let vertexInfo = vertexDataInfos.get(attributeInfo.name);
+ if (!vertexInfo) {
+ vertexInfo = {
+ attribute: attributeInfo.name,
+ data: new Float32Array(attributeInfo.size * this.vertexCount)
+ }
+ vertexDataInfos.set(attributeInfo.name, vertexInfo);
+ }
+ if (vertexInfo.data) {
+ let len = vertexInfo.data.length / attributeLayout.stride;
+ if (this.vertexCount != 0 && this.vertexCount != len) {
+ console.error(" vertex count not match attribute count");
+ }
+ this.vertexCount = len;
+ }
attributeOffset += attributeInfo.size;
}
+ let att_all = vertexDataInfos.get(VertexAttributeName.all);
+ let len = att_all.data.length / attributeOffset;
+ this.vertexCount = len;
+
this._vertexBufferLayouts[0] = {
name: `composeStruct`,
arrayStride: attributeOffset * 4,
@@ -154,6 +213,9 @@ export class GeometryVertexBuffer {
}
}
break;
+ case GeometryVertexType.compose_bin:
+ this.vertexGPUBuffer.node.setFloat32Array(0, vertexDataInfo.data as Float32Array);
+ break;
}
this.vertexGPUBuffer?.apply();
}
@@ -186,6 +248,13 @@ export class GeometryVertexBuffer {
}
}
break;
+
+ case GeometryVertexType.compose_bin:
+ {
+ let attributeData = vertexDataInfos.get(VertexAttributeName.all);
+ this.vertexGPUBuffer.node.setFloat32Array(0, attributeData.data as Float32Array);
+ }
+ break;
}
this.vertexGPUBuffer.apply();
}
diff --git a/src/core/geometry/GeometryVertexType.ts b/src/core/geometry/GeometryVertexType.ts
index 618c36a8..82983336 100644
--- a/src/core/geometry/GeometryVertexType.ts
+++ b/src/core/geometry/GeometryVertexType.ts
@@ -2,4 +2,5 @@
export enum GeometryVertexType {
split,
compose,
+ compose_bin,
}
\ No newline at end of file
diff --git a/src/core/geometry/VertexAttributeName.ts b/src/core/geometry/VertexAttributeName.ts
index 43c05ce6..d412303d 100644
--- a/src/core/geometry/VertexAttributeName.ts
+++ b/src/core/geometry/VertexAttributeName.ts
@@ -8,6 +8,11 @@ export enum VertexAttributeName {
TANGENT = 'TANGENT',
TEXCOORD_1 = 'TEXCOORD_1',
TEXCOORD_2 = 'TEXCOORD_2',
+ TEXCOORD_3 = 'TEXCOORD_3',
+ TEXCOORD_4 = 'TEXCOORD_4',
+ TEXCOORD_5 = 'TEXCOORD_5',
+ TEXCOORD_6 = 'TEXCOORD_6',
+ TEXCOORD_7 = 'TEXCOORD_7',
color = 'color',
joints0 = 'joints0',
joints1 = 'joints1',
@@ -17,4 +22,7 @@ export enum VertexAttributeName {
indices = `indices`,
vIndex = 'vIndex',
a_morphPositions_0 = 'a_morphPositions_0',
+
+
+ all = 'all',
}
diff --git a/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts b/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts
index 03fc39a9..ffb61aff 100644
--- a/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts
+++ b/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts
@@ -24,6 +24,16 @@ export class GlobalUniformGroup {
private uniformByteLength: number;
private matrixesByteLength: number;
+ private shadowMatrixRaw = new Float32Array(8 * 16);
+ private csmMatrixRaw = new Float32Array(CSM.Cascades * 16);
+ private csmShadowBias = new Float32Array(4);
+
+ public shadowLights = new Float32Array(16);
+ public dirShadowStart = 0;
+ public dirShadowEnd = 0;
+ public pointShadowStart = 0;
+ public pointShadowEnd = 0;
+
/**
*
* @param matrixBindGroup global matrix bindgroup
@@ -67,9 +77,7 @@ export class GlobalUniformGroup {
});
}
- private shadowMatrixRaw = new Float32Array(8 * 16);
- private csmMatrixRaw = new Float32Array(CSM.Cascades * 16);
- private csmShadowBias = new Float32Array(4);
+
public setCamera(camera: Camera3D) {
this.uniformGPUBuffer.setMatrix(`_projectionMatrix`, camera.projectionMatrix);
@@ -133,6 +141,12 @@ export class GlobalUniformGroup {
this.uniformGPUBuffer.setFloat(`csmMargin`, Engine3D.setting.shadow.csmMargin);
+ this.uniformGPUBuffer.setInt32(`nDirShadowStart`, this.dirShadowStart);
+ 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();
}
@@ -178,12 +192,16 @@ export class GlobalUniformGroup {
this.uniformGPUBuffer.setFloat(`enableCSM`, 0);
this.uniformGPUBuffer.setFloat(`csmMargin`, Engine3D.setting.shadow.csmMargin);
-
+ this.uniformGPUBuffer.setInt32(`nDirShadowStart`, this.dirShadowStart);
+ 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();
}
- public addUniformNode() { }
+ public setShadowLight() { }
}
diff --git a/src/gfx/graphics/webGpu/core/texture/Texture.ts b/src/gfx/graphics/webGpu/core/texture/Texture.ts
index 8afe6cd1..4a4a39d8 100644
--- a/src/gfx/graphics/webGpu/core/texture/Texture.ts
+++ b/src/gfx/graphics/webGpu/core/texture/Texture.ts
@@ -1,6 +1,7 @@
-import { GPUAddressMode } from '../../WebGPUConst';
+import { GPUAddressMode, GPUFilterMode } from '../../WebGPUConst';
import { TextureMipmapGenerator } from './TextureMipmapGenerator';
import { webGPUContext } from '../../Context3D';
+import { TextureMipmapCompute } from './TextureMipmapCompute';
/**
* Texture
@@ -203,9 +204,9 @@ export class Texture implements GPUSamplerDescriptor {
this.height = height;
this.numberLayer = numberLayer;
- this.minFilter = 'linear';
- this.magFilter = 'linear';
- this.mipmapFilter = `linear`;
+ this.minFilter = GPUFilterMode.linear;
+ this.magFilter = GPUFilterMode.linear;
+ this.mipmapFilter = GPUFilterMode.linear;
this.addressModeU = GPUAddressMode.repeat;
this.addressModeV = GPUAddressMode.repeat;
// this.visibility = GPUShaderStage.FRAGMENT;
@@ -263,6 +264,8 @@ export class Texture implements GPUSamplerDescriptor {
} else {
this.viewDescriptor = {
dimension: this.textureBindingLayout.viewDimension,
+ mipLevelCount: mipLevelCount,
+ baseMipLevel: 0
};
}
}
@@ -300,6 +303,7 @@ export class Texture implements GPUSamplerDescriptor {
if (this.useMipmap) {
TextureMipmapGenerator.webGPUGenerateMipmap(this);
+ // TextureMipmapCompute.createMipmap(this,this.mipmapCount);
}
}
@@ -348,9 +352,16 @@ export class Texture implements GPUSamplerDescriptor {
return this._sourceImageData;
}
+ public getMipmapCount() {
+ let w = this.width;
+ let h = this.height;
+ let maxSize = Math.max(w, h);
+ return 1 + Math.log2(maxSize) | 0;
+ }
+
protected updateTextureDescription() {
// let mipmapCount = this.useMipmap ? Math.floor(Math.log2(this.width)) : 1;
- this.mipmapCount = Math.floor(this.useMipmap ? Math.log2(Math.min(this.width, this.height)) : 1);
+ this.mipmapCount = Math.floor(this.useMipmap ? this.getMipmapCount() : 1);
this.createTextureDescriptor(this.width, this.height, this.mipmapCount, this.format);
}
diff --git a/src/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts b/src/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts
index 1791ea2f..5dc44dd3 100644
--- a/src/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts
+++ b/src/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts
@@ -1,5 +1,6 @@
import { GPUContext } from '../../../../renderJob/GPUContext';
import { webGPUContext } from '../../Context3D';
+import { GPUFilterMode } from '../../WebGPUConst';
import { Texture } from './Texture';
/**
* @internal
@@ -80,6 +81,13 @@ export class TextureMipmapGenerator {
return pipeline;
}
+ public static getMipmapCount(texture: Texture) {
+ let w = texture.width;
+ let h = texture.height;
+ let maxSize = Math.max(w, h);
+ return 1 + Math.log2(maxSize) | 0;
+ }
+
// TextureDescriptor should be the descriptor that the texture was created with.
// This version only works for basic 2D textures.
public static webGPUGenerateMipmap(texture: Texture) {
@@ -112,7 +120,7 @@ export class TextureMipmapGenerator {
@fragment
fn fragmentMain(@location(0) texCoord : vec2) -> @location(0) vec4 {
- var outColor: vec4 = textureSample(img, imgSampler, texCoord);
+ var outColor: vec4 = textureSampleLevel(img, imgSampler, texCoord , 0.0 );
return outColor;
}
`,
@@ -149,8 +157,8 @@ export class TextureMipmapGenerator {
});
} else {
sampler = gpuDevice.createSampler({
- minFilter: `linear`,
- magFilter: `linear`,
+ minFilter: GPUFilterMode.linear,
+ magFilter: GPUFilterMode.linear,
});
}
diff --git a/src/gfx/graphics/webGpu/shader/RenderShader.ts b/src/gfx/graphics/webGpu/shader/RenderShader.ts
index 24e6da9e..0b9838eb 100644
--- a/src/gfx/graphics/webGpu/shader/RenderShader.ts
+++ b/src/gfx/graphics/webGpu/shader/RenderShader.ts
@@ -753,13 +753,13 @@ export class RenderShader extends ShaderBase {
}
}
- let pipeline = PipelinePool.getSharePipeline(this.shaderVariant);
- if (pipeline) {
- this.pipeline = pipeline;
- } else {
- this.pipeline = GPUContext.createPipeline(renderPipelineDescriptor as GPURenderPipelineDescriptor);
- PipelinePool.setSharePipeline(this.shaderVariant, this.pipeline);
- }
+ // let pipeline = PipelinePool.getSharePipeline(this.shaderVariant);
+ // if (pipeline) {
+ // this.pipeline = pipeline;
+ // } else {
+ this.pipeline = GPUContext.createPipeline(renderPipelineDescriptor as GPURenderPipelineDescriptor);
+ // PipelinePool.setSharePipeline(this.shaderVariant, this.pipeline);
+ // }
}
private createGroupLayouts() {
@@ -807,6 +807,8 @@ export class RenderShader extends ShaderBase {
private preDefine(geometry: GeometryBase) {
// this.vertexAttributes = "" ;
// check geometry vertex attributes
+ let useSecondUV = geometry.hasAttribute(VertexAttributeName.TEXCOORD_1);
+
let isSkeleton = geometry.hasAttribute(VertexAttributeName.joints0);
let hasMorphTarget = geometry.hasAttribute(VertexAttributeName.a_morphPositions_0);
@@ -819,8 +821,16 @@ export class RenderShader extends ShaderBase {
let useLight = this.shaderState.useLight;
- this.defineValue[`USE_SKELETON`] = isSkeleton;
- this.defineValue[`USE_MORPHTARGETS`] = hasMorphTarget;
+ if (useSecondUV) {
+ this.defineValue[`USE_SECONDUV`] = true;
+ }
+
+ if (isSkeleton && hasMorphTarget) {
+ this.defineValue[`USE_METAHUMAN`] = true;
+ } else {
+ this.defineValue[`USE_SKELETON`] = isSkeleton;
+ this.defineValue[`USE_MORPHTARGETS`] = hasMorphTarget;
+ }
if (!('USE_TANGENT' in this.defineValue)) {
this.defineValue[`USE_TANGENT`] = useTangent;
diff --git a/src/gfx/renderJob/collect/RenderShaderCollect.ts b/src/gfx/renderJob/collect/RenderShaderCollect.ts
index 556cfd64..ba488ba9 100644
--- a/src/gfx/renderJob/collect/RenderShaderCollect.ts
+++ b/src/gfx/renderJob/collect/RenderShaderCollect.ts
@@ -51,11 +51,6 @@ export class RenderShaderCollect {
const pass = colorPassList[i];
let key = `${node.geometry.instanceID + pass.instanceID}`
rDic.delete(key);
- // if (!nodeMap) {
- // nodeMap = new Map();
- // rDic.set(key, nodeMap);
- // }
- // nodeMap.set(node.instanceID, node);
}
});
}
diff --git a/src/gfx/renderJob/collect/ShadowLightsCollect.ts b/src/gfx/renderJob/collect/ShadowLightsCollect.ts
index 823f3b44..38e40c50 100644
--- a/src/gfx/renderJob/collect/ShadowLightsCollect.ts
+++ b/src/gfx/renderJob/collect/ShadowLightsCollect.ts
@@ -1,12 +1,9 @@
-import { StorageGPUBuffer } from '../../..';
-import { Engine3D } from '../../../Engine3D';
import { ILight } from '../../../components/lights/ILight';
-
import { LightType } from '../../../components/lights/LightData';
import { Scene3D } from '../../../core/Scene3D';
-
+import { View3D } from '../../../core/View3D';
import { CameraUtil } from '../../../util/CameraUtil';
-import { UUID } from '../../../util/Global';
+import { GlobalBindGroup } from '../../graphics/webGpu/core/bindGroups/GlobalBindGroup';
/**
* @internal
* @group Lights
@@ -18,33 +15,18 @@ export class ShadowLightsCollect {
public static directionLightList: Map;
public static pointLightList: Map;
- public static shadowBuffer: Map;
- public static shadowLights: Map;//Uint32Array = new Uint32Array(16);
+ public static shadowLights: Map;
public static init() {
this.directionLightList = new Map();
this.pointLightList = new Map();
-
- this.shadowBuffer = new Map;
- this.shadowLights = new Map;
+ this.shadowLights = new Map;
}
- public static createBuffer(scene: Scene3D) {
- if (!this.shadowBuffer.has(scene)) {
- let buffer = new StorageGPUBuffer(4 + 16);
- buffer.visibility = GPUShaderStage.FRAGMENT;
- this.shadowBuffer.set(scene, buffer);
-
- buffer.setInt32('nDirShadowStart', 0);
- buffer.setInt32('nDirShadowEnd', 1);
- buffer.setInt32('nPointShadowStart', 0);
- buffer.setInt32('nPointShadowEnd', 0);
-
- let list = new Uint32Array(16);
- this.shadowLights.set(scene, list);
-
- buffer.setUint32Array('shadowLights', list);
- buffer.apply();
+ public static createBuffer(view: View3D) {
+ if (!this.shadowLights.has(view.scene)) {
+ let list = new Float32Array(16);
+ this.shadowLights.set(view.scene, list);
}
}
@@ -175,11 +157,11 @@ export class ShadowLightsCollect {
}
- public static update(scene3D: Scene3D) {
- let shadowBuffer = this.shadowBuffer.get(scene3D);
- let shadowLights = this.shadowLights.get(scene3D);
- let directionLightList = ShadowLightsCollect.directionLightList.get(scene3D);
- let pointLightList = ShadowLightsCollect.pointLightList.get(scene3D);
+ public static update(view: View3D) {
+ let globalUniform = GlobalBindGroup.getCameraGroup(view.camera);
+ let shadowLights = this.shadowLights.get(view.scene);
+ let directionLightList = ShadowLightsCollect.directionLightList.get(view.scene);
+ let pointLightList = ShadowLightsCollect.pointLightList.get(view.scene);
let nDirShadowStart: number = 0;
let nDirShadowEnd: number = 0;
@@ -195,8 +177,8 @@ export class ShadowLightsCollect {
}
nDirShadowEnd = directionLightList.length;
}
- shadowBuffer.setInt32('nDirShadowStart', nDirShadowStart);
- shadowBuffer.setInt32('nDirShadowEnd', nDirShadowEnd);
+ globalUniform.dirShadowStart = nDirShadowStart;
+ globalUniform.dirShadowEnd = nDirShadowEnd;
if (pointLightList) {
nPointShadowStart = nDirShadowEnd;
@@ -208,10 +190,9 @@ export class ShadowLightsCollect {
}
nPointShadowEnd = nPointShadowStart + pointLightList.length;
}
- shadowBuffer.setInt32('nPointShadowStart', nPointShadowStart);
- shadowBuffer.setInt32('nPointShadowEnd', nPointShadowEnd);
- shadowBuffer.setUint32Array(`shadowLights`, shadowLights);
- shadowBuffer.apply();
+ globalUniform.pointShadowStart = nPointShadowStart;
+ globalUniform.pointShadowEnd = nPointShadowEnd;
+ globalUniform.shadowLights = shadowLights;
}
}
diff --git a/src/gfx/renderJob/jobs/RendererJob.ts b/src/gfx/renderJob/jobs/RendererJob.ts
index 8cb6a79d..41429fba 100644
--- a/src/gfx/renderJob/jobs/RendererJob.ts
+++ b/src/gfx/renderJob/jobs/RendererJob.ts
@@ -198,7 +198,7 @@ export class RendererJob {
this.clusterLightingRender.render(view, this.occlusionSystem);
if (this.shadowMapPassRenderer) {
- ShadowLightsCollect.update(view.scene);
+ ShadowLightsCollect.update(view);
this.shadowMapPassRenderer.render(view, this.occlusionSystem);
}
diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts
index cc58cd42..a69acf5c 100644
--- a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts
+++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceComputePass.ts
@@ -43,7 +43,7 @@ export class DDGIIrradianceComputePass {
this.computeShader.setStorageBuffer(`depthRaysBuffer`, this.depthRaysBuffer);
this.computeShader.setStorageBuffer(`probes`, this.volume.probesBuffer);
- this.computeShader.setStorageBuffer(`uniformData`, this.volume.irradianceVolumeBuffer);
+ this.computeShader.setUniformBuffer(`uniformData`, this.volume.irradianceVolumeBuffer);
this.computeShader.setStorageBuffer("models", GlobalBindGroup.modelMatrixBindGroup.matrixBufferDst);
}
diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceVolume.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceVolume.ts
index 1bab3631..342ba806 100644
--- a/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceVolume.ts
+++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIIrradianceVolume.ts
@@ -3,6 +3,7 @@ import { Vector3 } from "../../../../math/Vector3";
import { Probe } from "./Probe";
import { GlobalIlluminationSetting } from "../../../../setting/GlobalIlluminationSetting";
import { StorageGPUBuffer } from "../../../graphics/webGpu/core/buffer/StorageGPUBuffer";
+import { UniformGPUBuffer } from "../../../..";
/**
* @internal
* @group Post
@@ -15,7 +16,7 @@ export class DDGIIrradianceVolume {
private randomOrientation: Matrix4;
private startPosition: Vector3 = new Vector3();
private isVolumeChange: boolean = true;
- public irradianceVolumeBuffer: StorageGPUBuffer;
+ public irradianceVolumeBuffer: UniformGPUBuffer;
//__make random direction
private readonly directionDistance: number = 20;
@@ -37,7 +38,7 @@ export class DDGIIrradianceVolume {
this.setting = setting;
this.randomOrientation = new Matrix4(false);
this.randomOrientation.identity();
- this.irradianceVolumeBuffer = new StorageGPUBuffer(80);
+ this.irradianceVolumeBuffer = new UniformGPUBuffer(80);
this.createFramesBuffer();
//center
this.arroundPositions.push(this.centerDirection.clone());
diff --git a/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts b/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts
index eb6bf5c6..f117be71 100644
--- a/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts
+++ b/src/gfx/renderJob/passRenderer/ddgi/DDGIMultiBouncePass.ts
@@ -28,7 +28,7 @@ export class DDGIMultiBouncePass {
this.computerShader = new ComputeShader(MultiBouncePass_cs);
this.computerShader.setStorageTexture("outputBuffer", this.blendTexture);
- this.computerShader.setStorageBuffer("uniformData", this.volume.irradianceVolumeBuffer);
+ this.computerShader.setUniformBuffer("uniformData", this.volume.irradianceVolumeBuffer);
}
public setInputs(inputs: VirtualTexture[]) {
diff --git a/src/index.ts b/src/index.ts
index 845da1b6..62190dc3 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -98,6 +98,7 @@ export * from "./components/ComponentBase"
export * from "./components/IComponent"
export * from "./components/SkeletonAnimationComponent"
export * from "./components/Transform"
+export * from "./components/anim/AnimatorComponent"
export * from "./components/anim/OAnimationEvent"
export * from "./components/anim/curveAnim/AnimationMonitor"
export * from "./components/anim/curveAnim/AttributeAnimCurve"
@@ -160,6 +161,7 @@ export * from "./components/lights/DirectLight"
export * from "./components/lights/GILighting"
export * from "./components/lights/IESProfiles"
export * from "./components/lights/ILight"
+export * from "./components/lights/Light"
export * from "./components/lights/LightBase"
export * from "./components/lights/LightData"
export * from "./components/lights/PointLight"
@@ -167,9 +169,11 @@ export * from "./components/lights/SpotLight"
export * from "./components/post/PostProcessingComponent"
export * from "./components/renderer/GlobalIlluminationComponent"
export * from "./components/renderer/InstanceDrawComponent"
+export * from "./components/renderer/MeshFilter"
export * from "./components/renderer/MeshRenderer"
export * from "./components/renderer/RenderNode"
export * from "./components/renderer/SkinnedMeshRenderer"
+export * from "./components/renderer/SkinnedMeshRenderer2"
export * from "./components/renderer/SkyRenderer"
export * from "./components/shape/BoxColliderShape"
export * from "./components/shape/CapsuleColliderShape"
@@ -356,6 +360,7 @@ export * from "./loader/parser/FontParser"
export * from "./loader/parser/I3DMParser"
export * from "./loader/parser/OBJParser"
export * from "./loader/parser/ParserBase"
+export * from "./loader/parser/ParserFormat"
export * from "./loader/parser/RGBEParser"
export * from "./loader/parser/b3dm/B3DMLoader"
export * from "./loader/parser/b3dm/B3DMLoaderBase"
@@ -390,6 +395,20 @@ export * from "./loader/parser/gltf/extends/KHR_texture_basisu"
export * from "./loader/parser/gltf/extends/KHR_texture_transform"
export * from "./loader/parser/i3dm/I3DMLoader"
export * from "./loader/parser/i3dm/I3DMLoaderBase"
+export * from "./loader/parser/prefab/PrefabAvatarParser"
+export * from "./loader/parser/prefab/PrefabMaterialParser"
+export * from "./loader/parser/prefab/PrefabMeshParser"
+export * from "./loader/parser/prefab/PrefabParser"
+export * from "./loader/parser/prefab/PrefabStringUtil"
+export * from "./loader/parser/prefab/PrefabTextureParser"
+export * from "./loader/parser/prefab/prefabData/KVData"
+export * from "./loader/parser/prefab/prefabData/PrefabAvatarData"
+export * from "./loader/parser/prefab/prefabData/PrefabBoneData"
+export * from "./loader/parser/prefab/prefabData/PrefabMeshData"
+export * from "./loader/parser/prefab/prefabData/PrefabNode"
+export * from "./loader/parser/prefab/prefabData/PrefabTextureData"
+export * from "./loader/parser/prefab/prefabData/ValueParser"
+export * from "./loader/parser/prefab/prefabData/ValueType"
export * from "./loader/parser/tileRenderer/TileSet"
export * from "./loader/parser/tileRenderer/TilesRenderer"
export * from "./materials/BlendMode"
@@ -410,6 +429,8 @@ export * from "./materials/multiPass/DepthMaterialPass"
export * from "./materials/multiPass/GBufferPass"
export * from "./materials/multiPass/SkyGBufferPass"
export * from "./math/AnimationCurve"
+export * from "./math/AnimationCurveClip"
+export * from "./math/AnimationCurveT"
export * from "./math/Bezier2D"
export * from "./math/Bezier3D"
export * from "./math/Color"
@@ -437,6 +458,11 @@ export * from "./math/UV"
export * from "./math/Vector2"
export * from "./math/Vector3"
export * from "./math/Vector4"
+export * from "./math/enum/FrameCache"
+export * from "./math/enum/Keyframe"
+export * from "./math/enum/T/KeyframeT"
+export * from "./math/enum/T/ValueOp"
+export * from "./math/enum/WrapTimeMode"
export * from "./setting/EngineSetting"
export * from "./setting/GlobalIlluminationSetting"
export * from "./setting/LightSetting"
@@ -477,7 +503,7 @@ export * from "./textures/Uint8ArrayTexture"
export * from "./textures/VirtualTexture"
export * from "./util/AxisObject"
export * from "./util/BoundUtil"
-export * from "./util/BytesStream"
+export * from "./util/BytesArray"
export * from "./util/CameraUtil"
export * from "./util/Convert"
export * from "./util/GeometryUtil"
@@ -487,6 +513,7 @@ export * from "./util/Object3DUtil"
export * from "./util/ProfilerUtil"
export * from "./util/Reference"
export * from "./util/SerializeDecoration"
+export * from "./util/StorageUtil"
export * from "./util/StringUtil"
export * from "./util/Time"
export * from "./util/Vector3Ex"
diff --git a/src/loader/FileLoader.ts b/src/loader/FileLoader.ts
index c5609b47..52157c9e 100644
--- a/src/loader/FileLoader.ts
+++ b/src/loader/FileLoader.ts
@@ -1,7 +1,8 @@
import { LoaderBase } from './LoaderBase';
import { LoaderFunctions } from './LoaderFunctions';
import { ParserBase } from './parser/ParserBase';
-import { Ctor } from "../util/Global";
+import { Ctor, Parser } from "../util/Global";
+import { ParserFormat } from './parser/ParserFormat';
/**
* @internal
@@ -16,9 +17,9 @@ export class FileLoader extends LoaderBase {
* @see LoaderFunctions
* @returns
*/
- public async load(url: string, c: Ctor, loaderFunctions?: LoaderFunctions, userData?: any): Promise {
- switch (c[`format`]) {
- case `bin`:
+ public async load(url: string, c: Parser, loaderFunctions?: LoaderFunctions, userData?: any): Promise {
+ switch (c.format) {
+ case ParserFormat.BIN:
{
return new Promise(async (succ, fail) => {
this.loadBinData(url, loaderFunctions).then(async (data) => {
@@ -37,8 +38,7 @@ export class FileLoader extends LoaderBase {
})
});
}
- break;
- case `json`:
+ case ParserFormat.JSON:
{
return new Promise((succ, fail) => {
this.loadJson(url, loaderFunctions)
@@ -56,8 +56,7 @@ export class FileLoader extends LoaderBase {
});
});
}
- break;
- case `text`:
+ case ParserFormat.TEXT:
{
return new Promise((succ, fail) => {
this.loadTxt(url, loaderFunctions)
@@ -79,7 +78,6 @@ export class FileLoader extends LoaderBase {
});
});
}
- break;
default:
break;
}
diff --git a/src/loader/parser/AtlasParser.ts b/src/loader/parser/AtlasParser.ts
index e5da83db..606609ba 100644
--- a/src/loader/parser/AtlasParser.ts
+++ b/src/loader/parser/AtlasParser.ts
@@ -3,9 +3,10 @@ import { GUITexture } from "../../components/gui/core/GUITexture";
import { Engine3D } from "../../Engine3D";
import { Texture } from "../../gfx/graphics/webGpu/core/texture/Texture";
import { ParserBase } from "../../loader/parser/ParserBase";
+import { ParserFormat } from "./ParserFormat";
export class AtlasParser extends ParserBase {
- static format: string = 'text';
+ static format: ParserFormat = ParserFormat.TEXT;
private _json: any;
private _texture: Texture;
diff --git a/src/loader/parser/B3DMParser.ts b/src/loader/parser/B3DMParser.ts
index 2a23e9db..77eacf90 100644
--- a/src/loader/parser/B3DMParser.ts
+++ b/src/loader/parser/B3DMParser.ts
@@ -1,8 +1,9 @@
import { Object3D } from '../../core/entities/Object3D';
import { ParserBase } from './ParserBase';
+import { ParserFormat } from './ParserFormat';
export class B3DMParser extends ParserBase {
- static format: string = 'bin';
+ static format: ParserFormat = ParserFormat.JSON;
public async parseBuffer(buffer: ArrayBuffer) {
let loader = new B3DMLoader();
diff --git a/src/loader/parser/FontParser.ts b/src/loader/parser/FontParser.ts
index 80d18038..7a99d448 100644
--- a/src/loader/parser/FontParser.ts
+++ b/src/loader/parser/FontParser.ts
@@ -3,6 +3,7 @@ import { fonts } from "../../assets/Fonts";
import { GUISprite } from "../../components/gui/core/GUISprite";
import { GUITexture } from "../../components/gui/core/GUITexture";
import { ParserBase } from "./ParserBase";
+import { ParserFormat } from "./ParserFormat";
export class FontInfo {
public face: string = '';
@@ -49,7 +50,7 @@ export class FontChar {
}
export class FontParser extends ParserBase {
- static format: string = 'text';
+ static format: ParserFormat = ParserFormat.TEXT;
public static parseSprite(guiTexture: GUITexture[], fontData: FontInfo) {
for (const key in fontData.fontChar) {
diff --git a/src/loader/parser/I3DMParser.ts b/src/loader/parser/I3DMParser.ts
index f1b402a8..15efafd4 100644
--- a/src/loader/parser/I3DMParser.ts
+++ b/src/loader/parser/I3DMParser.ts
@@ -1,9 +1,9 @@
import { ParserBase } from './ParserBase';
+import { ParserFormat } from './ParserFormat';
import { I3DMLoader } from "./i3dm/I3DMLoader";
export class I3DMParser extends ParserBase {
- static format: string = 'bin';
-
+ static format: ParserFormat = ParserFormat.BIN;
async parseBuffer(buffer: ArrayBuffer) {
let loader = new I3DMLoader();
loader.adjustmentTransform = this.userData;
diff --git a/src/loader/parser/OBJParser.ts b/src/loader/parser/OBJParser.ts
index 3bed3534..c98cef11 100644
--- a/src/loader/parser/OBJParser.ts
+++ b/src/loader/parser/OBJParser.ts
@@ -7,6 +7,7 @@ import { LitMaterial } from '../../materials/LitMaterial';
import { StringUtil } from '../../util/StringUtil';
import { FileLoader } from '../FileLoader';
import { ParserBase } from './ParserBase';
+import { ParserFormat } from './ParserFormat';
type MatData = {
@@ -54,7 +55,7 @@ type Face = {
* @group Loader
*/
export class OBJParser extends ParserBase {
- static format: string = 'text';
+ static format: ParserFormat = ParserFormat.TEXT;
private textData: string = '';
private source_vertices: number[][];
diff --git a/src/loader/parser/ParserBase.ts b/src/loader/parser/ParserBase.ts
index 052abaca..63be235b 100644
--- a/src/loader/parser/ParserBase.ts
+++ b/src/loader/parser/ParserBase.ts
@@ -1,12 +1,13 @@
import { Texture } from '../../gfx/graphics/webGpu/core/texture/Texture';
import { LoaderFunctions } from '../LoaderFunctions';
+import { ParserFormat } from './ParserFormat';
/**
* @internal
* @group Loader
*/
export class ParserBase {
- static format: string = 'bin';
+ static format: ParserFormat = ParserFormat.BIN;
public baseUrl: string;
public initUrl: string;
public loaderFunctions?: LoaderFunctions;
diff --git a/src/loader/parser/ParserFormat.ts b/src/loader/parser/ParserFormat.ts
new file mode 100644
index 00000000..ba34b29f
--- /dev/null
+++ b/src/loader/parser/ParserFormat.ts
@@ -0,0 +1,5 @@
+export enum ParserFormat {
+ TEXT,
+ BIN,
+ JSON
+}
\ No newline at end of file
diff --git a/src/loader/parser/gltf/GLBParser.ts b/src/loader/parser/gltf/GLBParser.ts
index 0608b965..b5814a27 100644
--- a/src/loader/parser/gltf/GLBParser.ts
+++ b/src/loader/parser/gltf/GLBParser.ts
@@ -1,5 +1,6 @@
import { BitmapTexture2D } from '../../../textures/BitmapTexture2D';
import { ParserBase } from '../ParserBase';
+import { ParserFormat } from '../ParserFormat';
import { GLTF_Info } from './GLTFInfo';
import { GLTFSubParser } from './GLTFSubParser';
@@ -29,7 +30,7 @@ export class GLBChunk {
* @group Loader
*/
export class GLBParser extends ParserBase {
- static format: string = 'bin';
+ static format: ParserFormat = ParserFormat.BIN;
private _gltf: GLTF_Info;
diff --git a/src/loader/parser/gltf/GLTFParser.ts b/src/loader/parser/gltf/GLTFParser.ts
index 73c34281..5a66d884 100644
--- a/src/loader/parser/gltf/GLTFParser.ts
+++ b/src/loader/parser/gltf/GLTFParser.ts
@@ -1,6 +1,7 @@
import { StringUtil } from '../../../util/StringUtil';
import { FileLoader } from '../../FileLoader';
import { ParserBase } from '../ParserBase';
+import { ParserFormat } from '../ParserFormat';
import { GLTF_Info } from './GLTFInfo';
import { GLTFSubParser } from './GLTFSubParser';
@@ -10,7 +11,7 @@ import { GLTFSubParser } from './GLTFSubParser';
* @group Loader
*/
export class GLTFParser extends ParserBase {
- static format: string = 'json';
+ static format: ParserFormat = ParserFormat.JSON;
private _gltf: GLTF_Info;
public async parseJson(obj: object) {
diff --git a/src/loader/parser/gltf/GLTFSubParserConverter.ts b/src/loader/parser/gltf/GLTFSubParserConverter.ts
index 24a3d408..0c174167 100644
--- a/src/loader/parser/gltf/GLTFSubParserConverter.ts
+++ b/src/loader/parser/gltf/GLTFSubParserConverter.ts
@@ -181,25 +181,16 @@ export class GLTFSubParserConverter {
if (`enableBlend` in primitive.material) {
if (primitive.material[`enableBlend`]) {
physicMaterial.blendMode = BlendMode.NORMAL;
- physicMaterial.depthWriteEnabled = false;
} else {
physicMaterial.blendMode = BlendMode.NONE;
}
-
- if (primitive.material.defines) {
- if (primitive.material.defines.indexOf(`ALPHA_BLEND`) != -1) {
- physicMaterial.blendMode = BlendMode.ALPHA;
- physicMaterial.transparent = true;
- physicMaterial.depthWriteEnabled = false;
- }
- }
}
- if (`alphaCutoff` in primitive.material && alphaCutoff > 0) {
+ if (`alphaCutoff` in primitive.material && alphaCutoff > 0 && alphaCutoff < 1) {
physicMaterial.alphaCutoff = alphaCutoff;
physicMaterial.blendMode = BlendMode.NORMAL;
physicMaterial.transparent = true;
- physicMaterial.depthWriteEnabled = false;
+ // physicMaterial.depthWriteEnabled = false;
}
if (primitive.material.transformUV1) physicMaterial.uvTransform_1 = primitive.material.transformUV1;
@@ -412,6 +403,9 @@ export class GLTFSubParserConverter {
indexCount: indicesAttribute.data.length,
vertexStart: 0,
index: 0,
+ vertexCount: 0,
+ firstStart: 0,
+ topology: 0
}
)
return geometry;
diff --git a/src/loader/parser/gltf/GLTFSubParserSkeleton.ts b/src/loader/parser/gltf/GLTFSubParserSkeleton.ts
index eb8f0fdc..cd130572 100644
--- a/src/loader/parser/gltf/GLTFSubParserSkeleton.ts
+++ b/src/loader/parser/gltf/GLTFSubParserSkeleton.ts
@@ -46,37 +46,48 @@ export class GLTFSubParserSkeleton {
}
count++;
let joint = skeleton.getJointByName(node.name);
- switch (property) {
- case 'scale':
- for (var nFrame: number = 0; nFrame < numFrame; nFrame++) {
- var srcOffset = nFrame * outputAccessor.numComponents;
- var dstOffset = skeletonPoseLength * nFrame + 12 * joint.index;
- bufferData[dstOffset + 0] = outputAccessor.data[srcOffset + 0]; // x
- bufferData[dstOffset + 1] = outputAccessor.data[srcOffset + 1]; // y
- bufferData[dstOffset + 2] = outputAccessor.data[srcOffset + 2]; // z
- bufferData[dstOffset + 3] = 1;
- }
- break;
- case 'rotation':
- for (var nFrame: number = 0; nFrame < numFrame; nFrame++) {
- var srcOffset = nFrame * outputAccessor.numComponents;
- var dstOffset = skeletonPoseLength * nFrame + 12 * joint.index + 4;
- bufferData[dstOffset + 0] = outputAccessor.data[srcOffset + 0]; // x
- bufferData[dstOffset + 1] = outputAccessor.data[srcOffset + 1]; // y
- bufferData[dstOffset + 2] = outputAccessor.data[srcOffset + 2]; // z
- bufferData[dstOffset + 3] = outputAccessor.data[srcOffset + 3]; // w
- }
- break;
- case 'translation':
- for (var nFrame: number = 0; nFrame < numFrame; nFrame++) {
- var srcOffset = nFrame * outputAccessor.numComponents;
- var dstOffset = skeletonPoseLength * nFrame + 12 * joint.index + 8;
- bufferData[dstOffset + 0] = outputAccessor.data[srcOffset + 0]; // x
- bufferData[dstOffset + 1] = outputAccessor.data[srcOffset + 1]; // y
- bufferData[dstOffset + 2] = outputAccessor.data[srcOffset + 2]; // z
- bufferData[dstOffset + 3] = inputAccessor.data[nFrame * inputAccessor.numComponents];
- }
- break;
+ if (!joint) {
+ switch (property) {
+ case 'scale':
+ break;
+ case 'rotation':
+ break;
+ case 'translation':
+ break;
+ }
+ } else {
+ switch (property) {
+ case 'scale':
+ for (var nFrame: number = 0; nFrame < numFrame; nFrame++) {
+ var srcOffset = nFrame * outputAccessor.numComponents;
+ var dstOffset = skeletonPoseLength * nFrame + 12 * joint.index;
+ bufferData[dstOffset + 0] = outputAccessor.data[srcOffset + 0]; // x
+ bufferData[dstOffset + 1] = outputAccessor.data[srcOffset + 1]; // y
+ bufferData[dstOffset + 2] = outputAccessor.data[srcOffset + 2]; // z
+ bufferData[dstOffset + 3] = 1;
+ }
+ break;
+ case 'rotation':
+ for (var nFrame: number = 0; nFrame < numFrame; nFrame++) {
+ var srcOffset = nFrame * outputAccessor.numComponents;
+ var dstOffset = skeletonPoseLength * nFrame + 12 * joint.index + 4;
+ bufferData[dstOffset + 0] = outputAccessor.data[srcOffset + 0]; // x
+ bufferData[dstOffset + 1] = outputAccessor.data[srcOffset + 1]; // y
+ bufferData[dstOffset + 2] = outputAccessor.data[srcOffset + 2]; // z
+ bufferData[dstOffset + 3] = outputAccessor.data[srcOffset + 3]; // w
+ }
+ break;
+ case 'translation':
+ for (var nFrame: number = 0; nFrame < numFrame; nFrame++) {
+ var srcOffset = nFrame * outputAccessor.numComponents;
+ var dstOffset = skeletonPoseLength * nFrame + 12 * joint.index + 8;
+ bufferData[dstOffset + 0] = outputAccessor.data[srcOffset + 0]; // x
+ bufferData[dstOffset + 1] = outputAccessor.data[srcOffset + 1]; // y
+ bufferData[dstOffset + 2] = outputAccessor.data[srcOffset + 2]; // z
+ bufferData[dstOffset + 3] = inputAccessor.data[nFrame * inputAccessor.numComponents];
+ }
+ break;
+ }
}
}
diff --git a/src/loader/parser/prefab/PrefabAvatarParser.ts b/src/loader/parser/prefab/PrefabAvatarParser.ts
new file mode 100644
index 00000000..f291feee
--- /dev/null
+++ b/src/loader/parser/prefab/PrefabAvatarParser.ts
@@ -0,0 +1,56 @@
+import { Engine3D } from "../../../Engine3D";
+import { GeometryBase, LODDescriptor } from "../../../core/geometry/GeometryBase";
+import { GeometryVertexType } from "../../../core/geometry/GeometryVertexType";
+import { VertexAttributeName } from "../../../core/geometry/VertexAttributeName";
+import { BytesArray } from "../../../util/BytesArray";
+import { ParserBase } from "../ParserBase";
+import { ParserFormat } from "../ParserFormat";
+import { PrefabParser } from "./PrefabParser";
+import { PrefabAvatarData } from "./prefabData/PrefabAvatarData";
+
+
+export class PrefabAvatarParser extends ParserBase {
+ static format: ParserFormat = ParserFormat.BIN;
+ public static parser(bytesStream: BytesArray, prefabParser: PrefabParser) {
+ let avatarCount = bytesStream.readInt32();
+ for (let j = 0; j < avatarCount; j++) {
+ let prefabAvatarData = new PrefabAvatarData();
+ prefabAvatarData.formBytes(bytesStream.readBytesArray());
+ Engine3D.res.addObj(prefabAvatarData.name, prefabAvatarData);
+ }
+ }
+
+ /**
+ * Verify parsing validity
+ * @param ret
+ * @returns
+ */
+ public verification(): boolean {
+ if (this.data) {
+ return true;
+ }
+ throw new Error('verify failed.');
+ }
+
+}
+
+let MeshVertexAttribute = {
+ "Position": VertexAttributeName.position,
+ "Normal": VertexAttributeName.normal,
+ "Color": VertexAttributeName.color,
+ "Tangent": VertexAttributeName.TANGENT,
+ "TexCoord0": VertexAttributeName.uv,
+ "TexCoord1": VertexAttributeName.TEXCOORD_1,
+ "TexCoord2": VertexAttributeName.TEXCOORD_2,
+ "TexCoord3": VertexAttributeName.TEXCOORD_2,
+ "TexCoord4": VertexAttributeName.TEXCOORD_4,
+ "TexCoord5": VertexAttributeName.TEXCOORD_5,
+ "TexCoord6": VertexAttributeName.TEXCOORD_6,
+ "TexCoord7": VertexAttributeName.TEXCOORD_7,
+ "BlendIndices": VertexAttributeName.joints0,
+ "BlendWeight": VertexAttributeName.weights0,
+}
+
+
+
+
diff --git a/src/loader/parser/prefab/PrefabMaterialParser.ts b/src/loader/parser/prefab/PrefabMaterialParser.ts
new file mode 100644
index 00000000..86c262e8
--- /dev/null
+++ b/src/loader/parser/prefab/PrefabMaterialParser.ts
@@ -0,0 +1,171 @@
+import { BitmapTexture2D, Engine3D } from "../../..";
+import { LitMaterial } from "../../../materials/LitMaterial";
+import { Material } from "../../../materials/Material";
+import { Color } from "../../../math/Color";
+import { BytesArray } from "../../../util/BytesArray";
+import { ParserBase } from "../ParserBase";
+import { ParserFormat } from "../ParserFormat";
+import { PrefabParser } from "./PrefabParser";
+import { KV } from "./prefabData/KVData";
+import { PrefabTextureData } from "./prefabData/PrefabTextureData";
+
+
+export class PrefabMaterialParser extends ParserBase {
+ static format: ParserFormat = ParserFormat.TEXT;
+
+ public static parserMaterial(bytesStream: BytesArray, prefabParser: PrefabParser) {
+ let matCount = bytesStream.readInt32();
+ for (let i = 0; i < matCount; i++) {
+ let matBytes = bytesStream.readBytesArray();
+
+ let matName = matBytes.readUTF();
+ let id = matBytes.readUTF();
+ let defines = matBytes.readStringArray();
+ let uvTransform_1 = matBytes.readVector4();
+ let uvTransform_2 = matBytes.readVector4();
+ let shaderName = matBytes.readUTF();
+ let properties: KV[] = [];
+ let textures: PrefabTextureData[] = [];
+ let propertyCount = matBytes.readInt32();
+ for (let j = 0; j < propertyCount; j++) {
+ let kv: KV = new KV();
+ kv.formBytes(matBytes);
+ properties.push(kv);
+ }
+
+ let textureCount = matBytes.readInt32();
+ for (let j = 0; j < textureCount; j++) {
+ let texBytes = matBytes.readBytesArray();
+ let textureData = new PrefabTextureData();
+ textureData.property = texBytes.readUTF();
+ textureData.name = texBytes.readUTF();
+ textureData.texture = Engine3D.res.getTexture(textureData.name) as BitmapTexture2D;
+ textureData.texelSize = texBytes.readVector2();
+ textureData.wrapModeU = texBytes.readUnit32();
+ textureData.wrapModeV = texBytes.readUnit32();
+ textureData.wrapModeW = texBytes.readUnit32();
+ textureData.wrapMode = texBytes.readUnit32();
+ textureData.anisoLevel = texBytes.readUnit32();
+ textureData.dimension = texBytes.readUnit32();
+ textureData.filterMode = texBytes.readUnit32();
+ textures.push(textureData);
+ }
+
+ let mat = new LitMaterial();
+ mat.name = matName;
+ mat.uvTransform_1 = uvTransform_1;
+ mat.uvTransform_2 = uvTransform_2;
+ mat.roughness = 1;
+ mat.metallic = 1;
+
+ for (let i = 0; i < defines.length; i++) {
+ const define = defines[i];
+ mat.defaultPass.setDefine(define, true);
+ }
+
+ for (let ii = 0; ii < textures.length; ii++) {
+ const tex = textures[ii];
+ if (tex.property in Texture_transformer.prototype) {
+ let { property, value } = Texture_transformer.prototype[tex.property](tex, mat);
+ if (property in mat) {
+ mat[property] = value;
+ }
+ }
+ }
+
+ for (let k = 0; k < properties.length; k++) {
+ const kv = properties[k];
+ if (kv.key in Material_transformer.prototype) {
+ Material_transformer.prototype[kv.key](kv, mat);
+ }
+ }
+
+ Engine3D.res.addMat(id, mat);
+ }
+ }
+
+
+ /**
+ * Verify parsing validity
+ * @param ret
+ * @returns
+ */
+ public verification(): boolean {
+ if (this.data) {
+ return true;
+ }
+ throw new Error('verify failed.');
+ }
+}
+
+
+class Texture_transformer {
+ public _MainTex(tex: PrefabTextureData, material: Material) {
+ material.defaultPass.setDefine("USE_SRGB_ALBEDO", true);
+ return {
+ property: "baseMap",
+ value: tex.texture
+ };
+ }
+
+ public _MetallicGlossMap(tex: PrefabTextureData) {
+ return {
+ property: "maskMap",
+ value: tex.texture
+ };
+ }
+
+ public _BumpMap(tex: PrefabTextureData) {
+ return {
+ property: "normalMap",
+ value: tex.texture
+ };
+ }
+
+ public _OcclusionMap(tex: PrefabTextureData, mat: LitMaterial) {
+ mat.defaultPass.setDefine("USE_AOTEX", true);
+ mat.ao = 1.0;
+ return {
+ property: "aoMap",
+ value: tex.texture
+ };
+ }
+}
+
+class Material_transformer {
+ _Color(kv: KV, material: LitMaterial) {
+ material.baseColor = kv.getValue();
+ }
+
+ // _Glossiness(kv: KV, material: LitMaterial) {
+ // let str = kv.value.replaceAll("[", "");
+ // str = str.replaceAll("]", "");
+ // let alpha = 1.0 - parseFloat(str);
+ // let roughness = alpha * alpha * alpha * alpha;
+ // // material.roughness = roughness;
+ // }
+ //return 1 + Math.log2(maxSize) | 0;
+
+ _GlossMapScale(kv: KV, material: LitMaterial) {
+ material.roughness = kv.getValue()[0];
+ }
+
+ _Metallic(kv: KV, material: LitMaterial) {
+ if (!material.maskMap) {
+ material.metallic = kv.getValue()[0];
+ } else {
+ material.metallic = 1.0;
+ }
+ }
+
+ _SmoothnessTextureChannel(kv: KV, material: LitMaterial) {
+ let channel = kv.getValue();
+ let type = channel == 0 ? `USE_ROUGHNESS_A` : "USE_ALBEDO_A";
+ let type2 = `USE_METALLIC_R`;
+ material.defaultPass.setDefine(type, true);
+ material.defaultPass.setDefine(type2, true);
+ }
+}
+
+let TextureChannel = ["A", "R", "G", "B"]
+
diff --git a/src/loader/parser/prefab/PrefabMeshParser.ts b/src/loader/parser/prefab/PrefabMeshParser.ts
new file mode 100644
index 00000000..72a7be2c
--- /dev/null
+++ b/src/loader/parser/prefab/PrefabMeshParser.ts
@@ -0,0 +1,140 @@
+import { Engine3D } from "../../../Engine3D";
+import { GeometryBase, LODDescriptor } from "../../../core/geometry/GeometryBase";
+import { GeometryVertexType } from "../../../core/geometry/GeometryVertexType";
+import { VertexAttributeName } from "../../../core/geometry/VertexAttributeName";
+import { BytesArray } from "../../../util/BytesArray";
+import { ParserBase } from "../ParserBase";
+import { ParserFormat } from "../ParserFormat";
+import { PrefabParser } from "./PrefabParser";
+import { PrefabMeshData } from "./prefabData/PrefabMeshData";
+
+
+export class PrefabMeshParser extends ParserBase {
+ static format: ParserFormat = ParserFormat.BIN;
+
+ public async parseBuffer(buffer: ArrayBuffer) {
+ }
+
+ public static parserMeshs(bytesStream: BytesArray, prefabParser: PrefabParser) {
+
+
+ let meshCount = bytesStream.readInt32();
+ for (let j = 0; j < meshCount; j++) {
+ let prefabMesh = new PrefabMeshData();
+ let meshBytesArray = bytesStream.readBytesArray();;
+ prefabMesh.meshName = meshBytesArray.readUTF();
+ prefabMesh.meshID = meshBytesArray.readUTF();
+
+ let useTangent = meshBytesArray.readFloat32() > 0;
+ let useColor = meshBytesArray.readFloat32() > 0;
+ let useSecondUV = meshBytesArray.readFloat32() > 0;
+ let useSkeleton = meshBytesArray.readFloat32() > 0;
+
+ if (useSkeleton) {
+ prefabMesh.bones = meshBytesArray.readStringArray();
+ prefabMesh.bindPose = meshBytesArray.readMatrix44Array();
+ }
+
+ let vertexBlock = meshBytesArray.readBytesArray();
+ let vertexBuffer = meshBytesArray.readBytesArray();
+
+ let attCount = vertexBlock.readInt32();
+ let attributes = [];
+ for (let i = 0; i < attCount; i++) {
+ attributes[i] = {};
+ attributes[i].att = MeshVertexAttribute[vertexBlock.readUTF()];
+ attributes[i].dim = vertexBlock.readInt32();
+ attributes[i].format = vertexBlock.readUTF();
+ }
+
+ prefabMesh.vertexCount = vertexBlock.readInt32();
+ prefabMesh.vertexBuffer = vertexBuffer.getFloat32Array();
+
+ let tmpIndices = meshBytesArray.readInt32Array();
+ let subMesh: LODDescriptor[] = [];
+ let subMeshCount = meshBytesArray.readInt32();
+ for (let jj = 0; jj < subMeshCount; jj++) {
+ let subMesh_topology = meshBytesArray.readInt32();
+ let subMesh_indexStart = meshBytesArray.readInt32();
+ let subMesh_indexCount = meshBytesArray.readInt32();
+ let subMesh_baseVertex = meshBytesArray.readInt32();
+ let subMesh_firstVertex = meshBytesArray.readInt32();
+ let subMesh_vertexCount = meshBytesArray.readInt32();
+ let subMesh_boundMin = meshBytesArray.readVector3();
+ let subMesh_boundMax = meshBytesArray.readVector3();
+ let subDes: LODDescriptor = {
+ indexStart: subMesh_indexStart,
+ indexCount: subMesh_indexCount,
+ vertexStart: subMesh_baseVertex,
+ vertexCount: subMesh_vertexCount,
+ firstStart: subMesh_firstVertex,
+ topology: subMesh_topology,
+ index: jj
+ }
+ subMesh.push(subDes);
+ }
+
+
+ if (tmpIndices.length > 65535) {
+ prefabMesh.indices = new Uint32Array(tmpIndices);
+ } else {
+ prefabMesh.indices = new Uint16Array(tmpIndices);
+ }
+
+ let geometry = new GeometryBase();
+ geometry.geometryType = GeometryVertexType.compose_bin;
+ geometry.setIndices(prefabMesh.indices);
+ geometry.setAttribute(VertexAttributeName.all, prefabMesh.vertexBuffer);
+ if (useSkeleton) {
+ geometry.skinNames = prefabMesh.bones;
+ geometry.bindPose = prefabMesh.bindPose;
+ }
+ for (let ii = 0; ii < attributes.length; ii++) {
+ const element = attributes[ii].att;
+ geometry.setAttribute(element, null);//3
+ }
+
+ for (let kk = 0; kk < subMesh.length; kk++) {
+ const element = subMesh[kk];
+ geometry.addSubGeometry(element);
+ }
+
+ geometry.name = prefabMesh.meshName;
+ Engine3D.res.addGeometry(prefabMesh.meshID, geometry);
+ }
+ }
+
+ /**
+ * Verify parsing validity
+ * @param ret
+ * @returns
+ */
+ public verification(): boolean {
+ if (this.data) {
+ return true;
+ }
+ throw new Error('verify failed.');
+ }
+
+}
+
+let MeshVertexAttribute = {
+ "Position": VertexAttributeName.position,
+ "Normal": VertexAttributeName.normal,
+ "Color": VertexAttributeName.color,
+ "Tangent": VertexAttributeName.TANGENT,
+ "TexCoord0": VertexAttributeName.uv,
+ "TexCoord1": VertexAttributeName.TEXCOORD_1,
+ "TexCoord2": VertexAttributeName.TEXCOORD_2,
+ "TexCoord3": VertexAttributeName.TEXCOORD_2,
+ "TexCoord4": VertexAttributeName.TEXCOORD_4,
+ "TexCoord5": VertexAttributeName.TEXCOORD_5,
+ "TexCoord6": VertexAttributeName.TEXCOORD_6,
+ "TexCoord7": VertexAttributeName.TEXCOORD_7,
+ "BlendIndices": VertexAttributeName.joints0,
+ "BlendWeight": VertexAttributeName.weights0,
+}
+
+
+
+
diff --git a/src/loader/parser/prefab/PrefabParser.ts b/src/loader/parser/prefab/PrefabParser.ts
new file mode 100644
index 00000000..f42bfe8b
--- /dev/null
+++ b/src/loader/parser/prefab/PrefabParser.ts
@@ -0,0 +1,95 @@
+import { Engine3D } from "../../../Engine3D";
+import { MeshFilter } from "../../../components/renderer/MeshFilter";
+import { SkinnedMeshRenderer } from "../../../components/renderer/SkinnedMeshRenderer";
+import { Object3D } from "../../../core/entities/Object3D";
+import { GeometryBase } from "../../../core/geometry/GeometryBase";
+import { Material } from "../../../materials/Material";
+import { Quaternion } from "../../../math/Quaternion";
+import { Vector3 } from "../../../math/Vector3";
+import { BitmapTexture2D } from "../../../textures/BitmapTexture2D";
+import { BytesArray } from "../../../util/BytesArray";
+import { GetComponentClass } from "../../../util/SerializeDecoration";
+import { ParserBase } from "../ParserBase";
+import { ParserFormat } from "../ParserFormat";
+import { PrefabAvatarParser } from "./PrefabAvatarParser";
+import { PrefabMaterialParser } from "./PrefabMaterialParser";
+import { PrefabMeshParser } from "./PrefabMeshParser";
+import { PrefabTextureParser } from "./PrefabTextureParser";
+import { PrefabAvatarData } from "./prefabData/PrefabAvatarData";
+import { PrefabNode } from "./prefabData/PrefabNode";
+
+
+export class PrefabParser extends ParserBase {
+ static format: ParserFormat = ParserFormat.BIN;
+ public avatarDic: { [name: string]: PrefabAvatarData };
+ public nodeData: PrefabNode;
+
+ public async parseBuffer(buffer: ArrayBuffer) {
+ this.avatarDic = {};
+
+ let bytesStream = new BytesArray(buffer, 0);
+
+ await PrefabTextureParser.parserTexture(bytesStream, this);
+
+ PrefabAvatarParser.parser(bytesStream, this);
+
+ PrefabMeshParser.parserMeshs(bytesStream, this);
+
+ PrefabMaterialParser.parserMaterial(bytesStream, this);
+
+ this.nodeData = this.parserPrefabNode(bytesStream);
+
+ this.data = this.data = this.parserNodeTree(this.nodeData); 0
+ }
+
+ private parserPrefabNode(bytesStream: BytesArray) {
+ let rootNodeData = PrefabNode.parser(bytesStream);
+ return rootNodeData;
+ }
+
+ private parserNodeTree(nodeData: PrefabNode) {
+ let root = new Object3D();
+ root.localPosition = Vector3.serialize(nodeData.position);
+ root.localQuaternion = Quaternion.serialize(nodeData.rotation);
+ root.localScale = Vector3.serialize(nodeData.scale);
+
+ if (nodeData.comDatas) {
+ for (let i = 0; i < nodeData.comDatas.length; i++) {
+ const comData = nodeData.comDatas[i];
+ let com = null;
+ let comClass = GetComponentClass(comData.comName);
+ if (comClass) {
+ com = root.getOrAddComponent(comClass);
+ for (let j = 0; j < comData.data.length; j++) {
+ const kv = comData.data[j];
+ if (kv.key in com) {
+ com[kv.key] = kv.getValue();
+ }
+ }
+ } else {
+ console.warn("no component", comData.comName);
+ }
+ }
+ }
+
+ if (nodeData.child && nodeData.child.length > 0) {
+ for (let j = 0; j < nodeData.child.length; j++) {
+ let child = this.parserNodeTree(nodeData.child[j]);
+ root.addChild(child);
+ }
+ }
+ return root;
+ }
+
+ /**
+ * Verify parsing validity
+ * @param ret
+ * @returns
+ */
+ public verification(): boolean {
+ if (this.data) {
+ return true;
+ }
+ throw new Error('verify failed.');
+ }
+}
diff --git a/src/loader/parser/prefab/PrefabStringUtil.ts b/src/loader/parser/prefab/PrefabStringUtil.ts
new file mode 100644
index 00000000..140f2db9
--- /dev/null
+++ b/src/loader/parser/prefab/PrefabStringUtil.ts
@@ -0,0 +1,63 @@
+import { Quaternion } from "../../..";
+
+export class PrefabStringUtil {
+
+ public static getNumber(st: string) {
+ let v = parseFloat(st);
+ return v;
+ }
+
+ public static getInt(st: string) {
+ let v = parseInt(st);
+ return v;
+ }
+
+ public static getBoolean(st: string) {
+ let v = st == "true" ? true : false;
+ return v;
+ }
+
+ public static getNumberArray(st: string) {
+ let v = st.replaceAll("[", "");
+ v = v.replaceAll("]", "");
+ let list = v.split(",");
+ let ret: number[] = [];
+ for (let i = 0; i < list.length; i++) {
+ const element = parseFloat(list[i]);
+ ret.push(element);
+ }
+ return v;
+ }
+
+ public static getStringArray(st: string) {
+ let v = st.replaceAll("[", "");
+ v = v.replaceAll("]", "");
+ let list = v.split(",");
+ let ret: string[] = [];
+ for (let i = 0; i < list.length; i++) {
+ const element = (list[i]);
+ ret.push(element);
+ }
+ return ret;
+ }
+
+ public static getVector2(st: string) {
+
+ }
+
+ public static getVector3(st: string) {
+
+ }
+
+ public static getVector4(st: string) {
+
+ }
+
+ public static getQuaternion(st: string) {
+
+ }
+
+ public static getColor(st: string) {
+
+ }
+}
\ No newline at end of file
diff --git a/src/loader/parser/prefab/PrefabTextureParser.ts b/src/loader/parser/prefab/PrefabTextureParser.ts
new file mode 100644
index 00000000..6a45aad6
--- /dev/null
+++ b/src/loader/parser/prefab/PrefabTextureParser.ts
@@ -0,0 +1,50 @@
+import { Engine3D } from "../../../Engine3D";
+import { BitmapTexture2D } from "../../../textures/BitmapTexture2D";
+import { BytesArray } from "../../../util/BytesArray";
+import { ParserBase } from "../ParserBase";
+import { ParserFormat } from "../ParserFormat";
+import { PrefabParser } from "./PrefabParser";
+
+
+export class PrefabTextureParser extends ParserBase {
+ static format: ParserFormat = ParserFormat.TEXT;
+
+ public static async parserTexture(bytesStream: BytesArray, prefabParser: PrefabParser) {
+ let preTextureCount = bytesStream.readInt32();
+
+ // for (let i = 0; i < preTextureCount; i++) {
+ // const texName = bytesStream.readUTF();
+ // let tex = await Engine3D.res.loadTexture(this.baseUrl + texName, null, true) as BitmapTexture2D;
+ // this.texDic[tex.name] = tex;
+ // }
+
+ let textures = [];
+ for (let i = 0; i < preTextureCount; i++) {
+ const texName = bytesStream.readUTF();
+ textures.push(prefabParser.baseUrl + texName);
+ }
+
+ for (let i = 0; i < textures.length; i++) {
+ const texName = textures[i];
+ let tex = await Engine3D.res.loadTexture(texName, null, true) as BitmapTexture2D;
+ Engine3D.res.addTexture(tex.name, tex);
+ }
+
+ // let textureList = await Engine3D.res.loadBitmapTextures(textures, 1);
+ // for (const tex of textureList) {
+ // this.texDic[tex.name] = tex;
+ // }
+ }
+
+ /**
+ * Verify parsing validity
+ * @param ret
+ * @returns
+ */
+ public verification(): boolean {
+ if (this.data) {
+ return true;
+ }
+ throw new Error('verify failed.');
+ }
+}
diff --git a/src/loader/parser/prefab/prefabData/KVData.ts b/src/loader/parser/prefab/prefabData/KVData.ts
new file mode 100644
index 00000000..00d8fa21
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/KVData.ts
@@ -0,0 +1,20 @@
+import { BytesArray } from "../../../../util/BytesArray";
+import { ValueParser } from "./ValueParser";
+
+
+
+export class KV {
+
+ public key: string;
+ private _data: any;
+
+ public getValue(): T {
+ return this._data as T;
+ }
+
+ formBytes(matBytes: BytesArray) {
+ this.key = matBytes.readUTF();
+ this._data = ValueParser.parser(matBytes).v;
+ }
+}
+
diff --git a/src/loader/parser/prefab/prefabData/PrefabAvatarData.ts b/src/loader/parser/prefab/prefabData/PrefabAvatarData.ts
new file mode 100644
index 00000000..3d26d0b6
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/PrefabAvatarData.ts
@@ -0,0 +1,23 @@
+import { BytesArray } from "../../../../util/BytesArray";
+import { PrefabBoneData } from "./PrefabBoneData";
+
+export class PrefabAvatarData {
+ public name: string;
+ public count: number;
+ public boneData: PrefabBoneData[];
+ public boneMap: Map;
+ public formBytes(bytes: BytesArray) {
+ this.boneData = [];
+ this.boneMap = new Map();
+
+ this.name = bytes.readUTF();
+ this.count = bytes.readInt32();
+ for (let i = 0; i < this.count; i++) {
+ let boneData = new PrefabBoneData();
+ boneData.formBytes(bytes.readBytesArray());
+ this.boneData[i] = boneData;
+
+ this.boneMap.set(boneData.boneName, boneData);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/loader/parser/prefab/prefabData/PrefabBoneData.ts b/src/loader/parser/prefab/prefabData/PrefabBoneData.ts
new file mode 100644
index 00000000..75a1269f
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/PrefabBoneData.ts
@@ -0,0 +1,32 @@
+import { Quaternion } from "../../../../math/Quaternion";
+import { Vector3 } from "../../../../math/Vector3";
+import { BytesArray } from "../../../../util/BytesArray";
+
+export class PrefabBoneData {
+ public boneName: string;
+ public bonePath: string;
+ public parentBoneName: string;
+ public boneID: number;
+ public parentBoneID: number;
+ public instanceID: string;
+ public parentInstanceID: string;
+ public t: Vector3;
+ public q: Quaternion;
+ public s: Vector3;
+
+ public formBytes(bytes: BytesArray) {
+ this.boneName = bytes.readUTF();
+ this.bonePath = bytes.readUTF();
+ this.parentBoneName = bytes.readUTF();
+
+ this.boneID = bytes.readInt32();
+ this.parentBoneID = bytes.readInt32();
+
+ this.instanceID = bytes.readUTF();
+ this.parentInstanceID = bytes.readUTF();
+
+ this.t = bytes.readVector3();
+ this.q = bytes.readQuaternion();
+ this.s = bytes.readVector3();
+ }
+}
\ No newline at end of file
diff --git a/src/loader/parser/prefab/prefabData/PrefabMeshData.ts b/src/loader/parser/prefab/prefabData/PrefabMeshData.ts
new file mode 100644
index 00000000..fb6a1f81
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/PrefabMeshData.ts
@@ -0,0 +1,20 @@
+import { Matrix4 } from "../../../..";
+
+export class PrefabMeshData {
+ public name: string;
+ public meshName: string;
+ public meshID: string;
+ public vertexCount: number;
+ public vertexStrip: number;
+ public vertexBuffer: Float32Array;
+ public indices: Uint16Array | Uint32Array;
+
+ public attributes: { attribute: string, dim: number, pos: number }[];
+ public blendShapeCount: number;
+ public blendShapeNames: string[];
+ public blendShapeWeights: string[];
+
+
+ public bones: string[];
+ public bindPose: Matrix4[];
+}
\ No newline at end of file
diff --git a/src/loader/parser/prefab/prefabData/PrefabNode.ts b/src/loader/parser/prefab/prefabData/PrefabNode.ts
new file mode 100644
index 00000000..ab4e23ec
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/PrefabNode.ts
@@ -0,0 +1,67 @@
+import { Quaternion } from "../../../../math/Quaternion";
+import { Vector3 } from "../../../../math/Vector3";
+import { BytesArray } from "../../../../util/BytesArray";
+import { KV } from "./KVData";
+
+export class ComData {
+ comName: string;
+ data: KV[];
+
+ public static parser(bytesArray: BytesArray): ComData {
+ let comBuffer = bytesArray.readBytesArray();
+
+ let comData = new ComData();
+ comData.comName = comBuffer.readUTF();
+ comData.data = [];
+
+ let count = comBuffer.readInt32();
+ for (let i = 0; i < count; i++) {
+ let kv = new KV();
+ kv.formBytes(comBuffer);
+ comData.data.push(kv);
+ }
+ return comData;
+ }
+}
+
+export class PrefabNode {
+ name: string;
+
+ parentName: string;
+
+ position: Vector3;
+
+ rotation: Quaternion;
+
+ scale: Vector3;
+
+ comDatas: ComData[];
+
+ child: PrefabNode[];
+
+ public static parser(bytesArray: BytesArray) {
+ let nodeBytes = bytesArray.readBytesArray();
+
+ let prefabNode = new PrefabNode();
+ prefabNode.name = nodeBytes.readUTF();
+ prefabNode.parentName = nodeBytes.readUTF();
+ prefabNode.position = nodeBytes.readVector3();
+ prefabNode.rotation = nodeBytes.readQuaternion();
+ prefabNode.scale = nodeBytes.readVector3();
+ prefabNode.comDatas = [];
+ prefabNode.child = [];
+
+ let comCount = nodeBytes.readInt32();
+ for (let i = 0; i < comCount; i++) {
+ const comData = ComData.parser(nodeBytes);
+ prefabNode.comDatas.push(comData);
+ }
+
+ let childCount = nodeBytes.readInt32();
+ for (let i = 0; i < childCount; i++) {
+ const childNodeData = PrefabNode.parser(nodeBytes);
+ prefabNode.child.push(childNodeData);
+ }
+ return prefabNode;
+ }
+}
\ No newline at end of file
diff --git a/src/loader/parser/prefab/prefabData/PrefabTextureData.ts b/src/loader/parser/prefab/prefabData/PrefabTextureData.ts
new file mode 100644
index 00000000..f3541ce0
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/PrefabTextureData.ts
@@ -0,0 +1,16 @@
+import { BitmapTexture2D, Vector2 } from "../../../..";
+
+export class PrefabTextureData {
+
+ public property: string;
+ public name: string;
+ public texture: BitmapTexture2D;
+ public texelSize: Vector2;
+ public wrapModeU: number;
+ public wrapModeV: number;
+ public wrapModeW: number;
+ public wrapMode: number;
+ public anisoLevel: number;
+ public dimension: number;
+ public filterMode: number;
+}
\ No newline at end of file
diff --git a/src/loader/parser/prefab/prefabData/ValueParser.ts b/src/loader/parser/prefab/prefabData/ValueParser.ts
new file mode 100644
index 00000000..e3b18dc1
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/ValueParser.ts
@@ -0,0 +1,111 @@
+import { GeometryBase, Material, PropertyAnimationClip, Texture } from "../../../..";
+import { Engine3D } from "../../../../Engine3D";
+import { Joint } from "../../../../components/anim/skeletonAnim/Joint";
+import { Skeleton } from "../../../../components/anim/skeletonAnim/Skeleton";
+import { Color } from "../../../../math/Color";
+import { Quaternion } from "../../../../math/Quaternion";
+import { Vector2 } from "../../../../math/Vector2";
+import { Vector3 } from "../../../../math/Vector3";
+import { Vector4 } from "../../../../math/Vector4";
+import { BytesArray } from "../../../../util/BytesArray";
+import { ValueEnumType } from "./ValueType";
+
+export type CurveValueType = string | number | Vector2 | Vector3 | Vector4 | Quaternion | Color | boolean | Texture | Material | string[] | number[] | Float32Array | GeometryBase | Skeleton | PropertyAnimationClip[];
+
+export class ValueParser {
+ public static parser(bytes: BytesArray): { t: ValueEnumType, v: CurveValueType } {
+ let type = bytes.readInt32();
+ switch (type) {
+ case ValueEnumType.single:
+ return { t: ValueEnumType.single, v: bytes.readFloat32() };
+ case ValueEnumType.boolean:
+ return { t: ValueEnumType.boolean, v: bytes.readBoolean() };
+ case ValueEnumType.int:
+ return { t: ValueEnumType.int, v: bytes.readInt32() };
+ case ValueEnumType.int16:
+ return { t: ValueEnumType.int16, v: bytes.readInt16() };
+ case ValueEnumType.int32:
+ return { t: ValueEnumType.int32, v: bytes.readInt32() };
+ case ValueEnumType.float:
+ return { t: ValueEnumType.float, v: bytes.readFloat32() };
+ case ValueEnumType.long:
+ return { t: ValueEnumType.long, v: bytes.readFloat64() };
+ case ValueEnumType.uint:
+ return { t: ValueEnumType.uint, v: bytes.readUnit32() };
+ case ValueEnumType.uint32:
+ return { t: ValueEnumType.uint32, v: bytes.readUnit32() };
+ case ValueEnumType.uint64:
+ return { t: ValueEnumType.uint64, v: bytes.readUnit32() };
+ case ValueEnumType.double:
+ return { t: ValueEnumType.double, v: bytes.readFloat64() };
+ case ValueEnumType.string:
+ return { t: ValueEnumType.string, v: bytes.readUTF() };
+ case ValueEnumType.singleArray:
+ return { t: ValueEnumType.singleArray, v: bytes.readFloatArray() };
+ case ValueEnumType.stringArray:
+ return { t: ValueEnumType.stringArray, v: bytes.readStringArray() };
+ case ValueEnumType.floatArray:
+ return { t: ValueEnumType.floatArray, v: bytes.readFloatArray() };
+ case ValueEnumType.vector2:
+ return { t: ValueEnumType.vector2, v: bytes.readVector2() };
+ case ValueEnumType.vector3:
+ return { t: ValueEnumType.vector3, v: bytes.readVector3() };
+ case ValueEnumType.vector4:
+ return { t: ValueEnumType.vector4, v: bytes.readVector4() };
+ case ValueEnumType.color:
+ return { t: ValueEnumType.color, v: bytes.readColor() };
+ case ValueEnumType.color32:
+ return { t: ValueEnumType.color32, v: bytes.readColor() };
+ case ValueEnumType.animationCurve:
+ return { t: ValueEnumType.animationCurve, v: null }
+ case ValueEnumType.quaternion:
+ return { t: ValueEnumType.quaternion, v: bytes.readQuaternion() };
+ case ValueEnumType.matrix4x4:
+ return { t: ValueEnumType.matrix4x4, v: null };
+ case ValueEnumType.mesh:
+ {
+ let id = bytes.readUTF();
+ let mesh = Engine3D.res.getGeometry(id);
+ return { t: ValueEnumType.mesh, v: mesh };
+ }
+ case ValueEnumType.texture:
+ {
+ let id = bytes.readUTF();
+ let texture = Engine3D.res.getTexture(id);
+ return { t: ValueEnumType.texture, v: texture };
+ }
+ case ValueEnumType.material:
+ {
+ let id = bytes.readUTF();
+ let mat = Engine3D.res.getMat(id);
+ return { t: ValueEnumType.material, v: mat };
+ }
+ case ValueEnumType.materials:
+ {
+ let str = bytes.readStringArray();
+ let mats = [];
+ for (let i = 0; i < str.length; i++) {
+ const element = str[i];
+ let mat = Engine3D.res.getMat(element);
+ mats.push(mat);
+ }
+ return { t: ValueEnumType.materials, v: mats };
+ }
+
+ case ValueEnumType.skeleton:
+ break;
+ case ValueEnumType.animClip:
+ {
+ let animClipDatas: PropertyAnimationClip[] = [];
+ let animClipCount = bytes.readInt32();
+ for (let i = 0; i < animClipCount; i++) {
+ let animationClipData = new PropertyAnimationClip();
+ animationClipData.formBytes(bytes);
+ animClipDatas.push(animationClipData);
+ }
+ return { t: ValueEnumType.animClip, v: animClipDatas };
+ }
+ }
+ }
+
+}
diff --git a/src/loader/parser/prefab/prefabData/ValueType.ts b/src/loader/parser/prefab/prefabData/ValueType.ts
new file mode 100644
index 00000000..7b4f5c2e
--- /dev/null
+++ b/src/loader/parser/prefab/prefabData/ValueType.ts
@@ -0,0 +1,33 @@
+
+
+export enum ValueEnumType {
+ single,
+ boolean,
+ int,
+ int16,
+ int32,
+ float,
+ long,
+ uint,
+ uint32,
+ uint64,
+ double,
+ string,
+ singleArray,
+ stringArray,
+ floatArray,
+ vector2,
+ vector3,
+ vector4,
+ color,
+ color32,
+ animationCurve,
+ quaternion,
+ matrix4x4,
+ mesh,
+ texture,
+ material,
+ materials,
+ skeleton,
+ animClip,
+}
\ No newline at end of file
diff --git a/src/materials/LitMaterial.ts b/src/materials/LitMaterial.ts
index 1e0bc92c..0ae0eca5 100644
--- a/src/materials/LitMaterial.ts
+++ b/src/materials/LitMaterial.ts
@@ -36,10 +36,12 @@ export class LitMaterial extends PhysicMaterial {
let litMaterial = new LitMaterial();
let colorPass = litMaterial.defaultPass;
+ colorPass.defineValue = { ...this.defaultPass.defineValue }
colorPass.setUniform(`shadowBias`, this.defaultPass.getUniform(`shadowBias`));
colorPass.setUniform(`transformUV1`, this.defaultPass.getUniform(`transformUV1`));
colorPass.setUniform(`transformUV2`, this.defaultPass.getUniform(`transformUV2`));
colorPass.setUniform(`baseColor`, this.defaultPass.getUniform(`baseColor`));
+ colorPass.setUniform(`specularColor`, this.defaultPass.getUniform(`specularColor`));
colorPass.setUniform(`emissiveColor`, this.defaultPass.getUniform(`emissiveColor`));
colorPass.setUniform(`materialF0`, this.defaultPass.getUniform(`materialF0`));
colorPass.setUniform(`envIntensity`, this.defaultPass.getUniform(`envIntensity`));
diff --git a/src/materials/PhysicMaterial.ts b/src/materials/PhysicMaterial.ts
index 06c59757..a4371fd9 100644
--- a/src/materials/PhysicMaterial.ts
+++ b/src/materials/PhysicMaterial.ts
@@ -27,6 +27,7 @@ export class PhysicMaterial extends Material {
colorPass.setUniformColor(`baseColor`, new Color());
colorPass.setUniformColor(`emissiveColor`, new Color(1, 1, 1));
colorPass.setUniformVector4(`materialF0`, new Vector4(0.04, 0.04, 0.04, 1));
+ colorPass.setUniformColor(`specularColor`, new Color(0.04, 0.04, 0.04));
colorPass.setUniformFloat(`envIntensity`, 1);
colorPass.setUniformFloat(`normalScale`, 1);
colorPass.setUniformFloat(`roughness`, 1.0);
@@ -114,7 +115,7 @@ export class PhysicMaterial extends Material {
*/
public set uvTransform_1(value: Vector4) {
// this.defaultPass.uniforms[`transformUV1`].v4 = value;
- this.defaultPass.setUniformVector4(`transformUV1`, value);
+ this.defaultPass.setUniform(`transformUV1`, value);
}
/**
@@ -129,7 +130,7 @@ export class PhysicMaterial extends Material {
*/
public set uvTransform_2(value: Vector4) {
// this.defaultPass.uniforms[`transformUV2`].v4 = value;
- this.defaultPass.setUniformVector4(`transformUV2`, value);
+ this.defaultPass.setUniform(`transformUV2`, value);
}
public get depthWriteEnabled(): boolean {
@@ -150,7 +151,21 @@ export class PhysicMaterial extends Material {
* set reflectivity
*/
public set materialF0(value: Vector4) {
- this.defaultPass.setUniformVector4(`materialF0`, value);
+ this.defaultPass.setUniform(`materialF0`, value);
+ }
+
+ /**
+ * get specularColor
+ */
+ public get specularColor(): Color {
+ return this.defaultPass.uniforms[`specularColor`].color;
+ }
+
+ /**specularColor
+ * set reflectivity
+ */
+ public set specularColor(value: Color) {
+ this.defaultPass.setUniform(`specularColor`, value);
}
/**
@@ -164,7 +179,7 @@ export class PhysicMaterial extends Material {
* set roughness
*/
public set roughness(value: number) {
- this.defaultPass.setUniformFloat(`roughness`, value);
+ this.defaultPass.setUniform(`roughness`, value);
}
/**
@@ -178,7 +193,7 @@ export class PhysicMaterial extends Material {
* set metallic
*/
public set metallic(value: number) {
- this.defaultPass.setUniformFloat(`metallic`, value);
+ this.defaultPass.setUniform(`metallic`, value);
}
/**
@@ -192,7 +207,7 @@ export class PhysicMaterial extends Material {
* set Ambient Occlussion, dealing with the effect of ambient light on object occlusion
*/
public set ao(value: number) {
- this.defaultPass.setUniformFloat(`ao`, value);
+ this.defaultPass.setUniform(`ao`, value);
}
/**
@@ -206,7 +221,7 @@ export class PhysicMaterial extends Material {
* set min metallic
*/
public set metallic_min(value: number) {
- this.defaultPass.setUniformFloat(`metallic_min`, value);
+ this.defaultPass.setUniform(`metallic_min`, value);
}
/**
@@ -220,7 +235,7 @@ export class PhysicMaterial extends Material {
* set max metallic
*/
public set metallic_max(value: number) {
- this.defaultPass.setUniformFloat(`metallic_max`, value);
+ this.defaultPass.setUniform(`metallic_max`, value);
}
/**
@@ -234,7 +249,7 @@ export class PhysicMaterial extends Material {
* set min roughness
*/
public set roughness_min(value: number) {
- this.defaultPass.setUniformFloat(`roughness_min`, value);
+ this.defaultPass.setUniform(`roughness_min`, value);
}
/**
@@ -248,7 +263,7 @@ export class PhysicMaterial extends Material {
* set max roughness
*/
public set roughness_max(value: number) {
- this.defaultPass.setUniformFloat(`roughness_max`, value);
+ this.defaultPass.setUniform(`roughness_max`, value);
}
/**
@@ -262,7 +277,7 @@ export class PhysicMaterial extends Material {
* Set the influence of Normal mapping on materials
*/
public set normalScale(value: number) {
- this.defaultPass.setUniformFloat(`normalScale`, value);
+ this.defaultPass.setUniform(`normalScale`, value);
}
/**
@@ -285,7 +300,9 @@ export class PhysicMaterial extends Material {
*/
public set maskMap(value: Texture) {
// USE_MR
- // USE_ARMC
+ // USE_ORMC
+ // USE_RMOC
+ // USE_CRMC
this.defaultPass.setDefine(`USE_MR`, true);
this.defaultPass.setTexture(`maskMap`, value);
}
diff --git a/src/math/AnimationCurve.ts b/src/math/AnimationCurve.ts
index 672c575f..4853bb93 100644
--- a/src/math/AnimationCurve.ts
+++ b/src/math/AnimationCurve.ts
@@ -1,62 +1,7 @@
import { PingPong, RepeatSE } from './MathUtil';
-
-/**
- * Time Warp Mode
- * @PingPong value min -> max -> min
- * @Repeat value = value % repeatSpace
- * @Clamp value = max(min( value , 1 ) , 0 )
- */
-export enum WrapTimeMode {
- PingPong = 0,
- Repeat = 1,
- Clamp = 2,
-}
-
-/**
- * @group Math
- */
-export class Keyframe {
- public serializedVersion: string = '2';
- public time: number;
- public value: number;
- public inSlope: number = 0;
- public outSlope: number = 0;
- public tangentMode: number = 0;
-
- constructor(time: number = 0, value: number = 0) {
- this.time = time;
- this.value = value;
- }
-
- public unSerialized(data: any) {
- this.serializedVersion = data['serializedVersion'];
- this.time = data['time'];
- this.value = data['value'];
- this.tangentMode = data['tangentMode'];
- this.inSlope = data['inSlope'] == 'Infinity' ? NaN : data['inSlope'];
- this.outSlope = data['outSlope'] == 'Infinity' ? NaN : data['outSlope'];
- }
-
- public unSerialized2(data: any) {
- this.serializedVersion = data['serializedVersion'];
- this.time = data['time'];
- this.value = data['value'];
- this.tangentMode = data['tangentMode'];
- this.inSlope = data['inTangent'] == 'Infinity' ? NaN : data['inTangent'];
- this.outSlope = data['outTangent'] == 'Infinity' ? NaN : data['outTangent'];
- }
-}
-
-/**
- * @internal
- * @group Math
- */
-export class FrameCache {
- public index: number; //= lhsIndex;
- public time: number; // = lhs.time + timeOffset;
- public timeEnd: number; // = rhs.time + timeOffset;
- public coeff: number[] = []; //= lhsIndex;
-}
+import { FrameCache } from './enum/FrameCache';
+import { WrapTimeMode } from './enum/WrapTimeMode';
+import { Keyframe } from './enum/Keyframe';
/**
* Animation Cureve
@@ -288,7 +233,11 @@ export class AnimationCurve {
private calcTotalTime() {
let maxTime = 0;
for (let curve of this.curve) {
- maxTime = Math.max(maxTime, curve.time);
+ if (curve) {
+ maxTime = Math.max(maxTime, curve.time);
+ } else {
+ console.error(curve);
+ }
}
this._totalTime = maxTime;
}
diff --git a/src/math/AnimationCurveClip.ts b/src/math/AnimationCurveClip.ts
new file mode 100644
index 00000000..16e02f01
--- /dev/null
+++ b/src/math/AnimationCurveClip.ts
@@ -0,0 +1,58 @@
+import { PingPong, RepeatSE } from './MathUtil';
+import { FrameCache } from './enum/FrameCache';
+import { WrapTimeMode } from './enum/WrapTimeMode';
+import { Keyframe } from './enum/Keyframe';
+import { AnimationCurve, AnimationCurveT, BytesArray, KeyframeT } from '..';
+
+/**
+ * Animation Cureve
+ * has frame list data
+ * @group Math
+ */
+export class PropertyAnimationClip {
+ public clipName: string;
+ public loopTime: boolean;
+ public startTime: number;
+ public stopTime: number;
+ public sampleRate: number;
+ public positionCurves: Map = new Map();
+ public rotationCurves: Map = new Map();
+ public scaleCurves: Map = new Map