diff --git a/index.html b/index.html index 96c1214a..adbfe2f2 100644 --- a/index.html +++ b/index.html @@ -72,7 +72,7 @@ - + \ No newline at end of file diff --git a/src/engine/Engine3D.ts b/src/Engine3D.ts similarity index 84% rename from src/engine/Engine3D.ts rename to src/Engine3D.ts index 5fc4120b..1798d480 100644 --- a/src/engine/Engine3D.ts +++ b/src/Engine3D.ts @@ -1,27 +1,28 @@ -import { version } from '../../package.json'; -import { Res } from './assets/Res'; -import { ShaderLib } from './assets/shader/ShaderLib'; +import { CanvasConfig } from './gfx/graphics/webGpu/CanvasConfig'; +import { Color } from './math/Color'; +import { EngineSetting } from './setting/EngineSetting'; +import { Time } from './util/Time'; +import { InputSystem } from './io/InputSystem'; import { View3D } from './core/View3D'; +import { version } from '../package.json'; import { webGPUContext } from './gfx/graphics/webGpu/Context3D'; -import { CanvasConfig } from './gfx/graphics/webGpu/CanvasConfig'; +import { FXAAPost } from './gfx/renderJob/post/FXAAPost'; +import { ForwardRenderJob } from './gfx/renderJob/jobs/ForwardRenderJob'; import { GlobalBindGroup } from './gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup'; +import { Interpolator } from './math/TimeInterpolator'; import { RTResourceMap } from './gfx/renderJob/frame/RTResourceMap'; -import { ForwardRenderJob } from './gfx/renderJob/jobs/ForwardRenderJob'; import { RendererJob } from './gfx/renderJob/jobs/RendererJob'; -import { FXAAPost } from './gfx/renderJob/post/FXAAPost'; -import { InputSystem } from './io/InputSystem'; -import { Color } from './math/Color'; -import { Interpolator } from './math/TimeInterpolator'; -import { EngineSetting } from './setting/EngineSetting'; -import { defaultRes } from './textures/DefaultRes'; -import { Time } from './util/Time'; +import { Res } from './assets/Res'; +import { ShaderLib } from './assets/shader/ShaderLib'; +import { ShaderUtil } from './gfx/graphics/webGpu/shader/util/ShaderUtil'; +import { ComponentCollect } from './gfx/renderJob/collect/ComponentCollect'; -/** +/** * Orillusion 3D Engine * @notExported * @group engine3D */ -class _Engine3D { +export class Engine3D { /** * @internal */ @@ -29,25 +30,25 @@ class _Engine3D { /** * resource manager */ - public res: Res; + public static res: Res; /** * input system */ - public inputSystem: InputSystem; - public views: View3D[]; + public static inputSystem: InputSystem; + public static views: View3D[]; - private _frameRateValue: number = 0; - private _frameRate: number = 360; - private _isRun: boolean = false; - private _frameTimeCount: number = 0; - private _deltaTime: number = 0; - private _time: number = 0; + private static _frameRateValue: number = 0; + private static _frameRate: number = 360; + private static _isRun: boolean = false; + private static _frameTimeCount: number = 0; + private static _deltaTime: number = 0; + private static _time: number = 0; - public get frameRate(): number { + public static get frameRate(): number { return this._frameRate; } - public set frameRate(value: number) { + public static set frameRate(value: number) { this._frameRate = value; this._frameRateValue = 1.0 / value; if (value >= 360) { @@ -55,18 +56,26 @@ class _Engine3D { } } - public get size(): number[] { + public static get size(): number[] { return webGPUContext.presentationSize; } - public get aspect(): number { + public static get aspect(): number { return webGPUContext.aspect; } + public static get width(): number { + return webGPUContext.windowWidth; + } + + public static get height(): number { + return webGPUContext.windowHeight; + } + /** * engine setting */ - public setting: EngineSetting = { + public static setting: EngineSetting = { occlusionQuery: { enable: true, debug: false, @@ -236,44 +245,40 @@ class _Engine3D { }, }; - private _beforeRender: Function; - private _renderLoop: Function; - private _lateRender: Function; + private static _beforeRender: Function; + private static _renderLoop: Function; + private static _lateRender: Function; /** * @internal */ - public renderJobs: Map; + public static renderJobs: Map; - public get width(): number { - return webGPUContext.windowWidth; - } - public get height(): number { - return webGPUContext.windowHeight; - } /** * create webgpu 3d engine * @param descriptor {@link CanvasConfig} * @returns */ - public async init(descriptor: { canvasConfig?: CanvasConfig; beforeRender?: Function; renderLoop?: Function; lateRender?: Function, engineSetting?: EngineSetting } = {}) { + public static async init(descriptor: { canvasConfig?: CanvasConfig; beforeRender?: Function; renderLoop?: Function; lateRender?: Function, engineSetting?: EngineSetting } = {}) { console.log('engine version', version); this.setting = { ...this.setting, ...descriptor.engineSetting } await webGPUContext.init(descriptor.canvasConfig); - ShaderLib.init(); + ComponentCollect.init(); - GlobalBindGroup.initCommon(); + ShaderLib.init(); - this.res = new Res(); + ShaderUtil.init(); - await defaultRes.initCommon(); + GlobalBindGroup.init(); RTResourceMap.init(); + this.res = new Res(); + this._beforeRender = descriptor.beforeRender; this._renderLoop = descriptor.renderLoop; this._lateRender = descriptor.lateRender; @@ -282,7 +287,7 @@ class _Engine3D { return; } - public startRenderView(view: View3D) { + public static startRenderView(view: View3D) { this.renderJobs ||= new Map(); this.views = [view]; let renderJob = new ForwardRenderJob(view); @@ -293,7 +298,7 @@ class _Engine3D { return renderJob; } - public startRenderViews(views: View3D[]) { + public static startRenderViews(views: View3D[]) { this.renderJobs ||= new Map(); this.views = views; for (let i = 0; i < views.length; i++) { @@ -306,7 +311,7 @@ class _Engine3D { this.render(0); } - public getRenderJob(view: View3D): RendererJob { + public static getRenderJob(view: View3D): RendererJob { return this.renderJobs.get(view); } @@ -314,7 +319,7 @@ class _Engine3D { /** * @internal */ - public render(time) { + public static render(time) { if (!this._isRun) { this._deltaTime = time - this._time; this._time = time; @@ -332,7 +337,7 @@ class _Engine3D { requestAnimationFrame((t) => this.render(t)); } - public updateFrame(time: number) { + public static updateFrame(time: number) { Time.delta = time - Time.time; Time.time = time; Time.frame += 1; @@ -352,4 +357,4 @@ class _Engine3D { * Orillusion 3D * @group engine3D */ -export let Engine3D = new _Engine3D(); +// export let Engine3D = new _Engine3D(); diff --git a/src/engine/assets/Res.ts b/src/assets/Res.ts similarity index 70% rename from src/engine/assets/Res.ts rename to src/assets/Res.ts index afc7c80b..e46c444c 100644 --- a/src/engine/assets/Res.ts +++ b/src/assets/Res.ts @@ -15,6 +15,8 @@ import { I3DMParser } from "../loader/parser/I3DMParser"; import { GLTF_Info } from '../loader/parser/gltf/GLTFInfo'; import { HDRTexture } from '../textures/HDRTexture'; import { LDRTextureCube } from '../textures/LDRTextureCube'; +import { BRDFLUTGenerate } from '../gfx/generate/BrdfLUTGenerate'; +import { Uint8ArrayTexture } from '../textures/Uint8ArrayTexture'; /** * Resource management classes for textures, materials, models, and preset bodies. @@ -24,6 +26,7 @@ export class Res { private _texturePool: Map; private _materialPool: Map; private _prefabPool: Map; + // private _prefabLoaderPool: Map; private _gltfPool: Map; /** @@ -33,7 +36,10 @@ export class Res { this._texturePool = new Map(); this._materialPool = new Map(); this._prefabPool = new Map(); + // this._prefabLoaderPool = new Map; this._gltfPool = new Map; + + this.initDefault(); } public getGltf(url: string): GLTF_Info { @@ -279,6 +285,10 @@ export class Res { return cubeMap; } + /** + * load json data from url. + * @param url the path of image + */ public async loadJSON(url: string, loaderFunctions?: LoaderFunctions) { return await new FileLoader() .loadJson(url, loaderFunctions) @@ -286,6 +296,92 @@ export class Res { return ret; }) .catch((e) => { + console.log(e); }); } + + /** + * normal texture + */ + public normalTexture: Uint8ArrayTexture; + public maskTexture: Uint8ArrayTexture; + public whiteTexture: Uint8ArrayTexture; + public blackTexture: Uint8ArrayTexture; + public redTexture: Uint8ArrayTexture; + public blueTexture: Uint8ArrayTexture; + public greenTexture: Uint8ArrayTexture; + public yellowTexture: Uint8ArrayTexture; + public grayTexture: Uint8ArrayTexture; + + public defaultSky: HDRTextureCube; + + /** + * create a texture + * @param width width of texture + * @param height height of texture + * @param r component-red + * @param g component-green + * @param b component-blue + * @param a component-alpha(0 for transparent,1 for opaque) + * @param name name string + * @returns + */ + public createTexture(width: number, height: number, r: number, g: number, b: number, a: number, name?: string) { + let w = 32; + let h = 32; + let textureData = new Uint8Array(w * h * 4); + this.fillColor(textureData, width, height, r, g, b, a); + let texture = new Uint8ArrayTexture(); + texture.name = name; + texture.create(16, 16, textureData, true); + if (name) { + this.addTexture(name, texture); + } + return texture; + } + + /** + * fill slod color to this texture + * @param array data of texture + * @param w width of texture + * @param h height of texture + * @param r component-red + * @param g component-green + * @param b component-blue + * @param a component-alpha(0 for transparent,1 for opaque) + */ + public fillColor(array: any, w: number, h: number, r: number, g: number, b: number, a: number) { + for (let i = 0; i < w; i++) { + for (let j = 0; j < h; j++) { + let pixelIndex = j * w + i; + array[pixelIndex * 4 + 0] = r; + array[pixelIndex * 4 + 1] = g; + array[pixelIndex * 4 + 2] = b; + array[pixelIndex * 4 + 3] = a; + } + } + } + + /** + * Initialize a common texture object. Provide a universal solid color texture object. + */ + private 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'); + this.blackTexture = this.createTexture(32, 32, 0, 0, 0, 255.0, 'default-blackTexture'); + this.redTexture = this.createTexture(32, 32, 255, 0, 0, 255.0, 'default-redTexture'); + this.blueTexture = this.createTexture(32, 32, 0, 0, 255, 255.0, 'default-blueTexture'); + this.greenTexture = this.createTexture(32, 32, 0, 255, 0, 255, 'default-greenTexture'); + this.yellowTexture = this.createTexture(32, 32, 0, 255, 255, 255.0, 'default-yellowTexture'); + this.grayTexture = this.createTexture(32, 32, 128, 128, 128, 255.0, 'default-grayTexture'); + + let brdf = new BRDFLUTGenerate(); + let texture = brdf.generateBRDFLUTTexture(); + let BRDFLUT = texture.name = 'BRDFLUT'; + this.addTexture(BRDFLUT, texture); + + this.defaultSky = new HDRTextureCube(); + this.defaultSky.createFromTexture(128, this.blackTexture); + } } diff --git a/src/engine/assets/shader/ShaderLib.ts b/src/assets/shader/ShaderLib.ts similarity index 84% rename from src/engine/assets/shader/ShaderLib.ts rename to src/assets/shader/ShaderLib.ts index a8007616..d502502d 100644 --- a/src/engine/assets/shader/ShaderLib.ts +++ b/src/assets/shader/ShaderLib.ts @@ -1,41 +1,40 @@ -import { VertexAttributes } from "./core/struct/VertexAttributes" +import BRDF_frag from "./lighting/BRDF_frag.wgsl?raw"; +import { Bloom_shader } from './post/Bloom_shader'; +import BrdfLut_frag from "./core/common/BrdfLut_frag.wgsl?raw"; +import BxDF_frag from "./lighting/BxDF_frag.wgsl?raw"; +import BxdfDebug_frag from "./materials/program/BxdfDebug_frag.wgsl?raw"; +import Clearcoat_frag from "./materials/program/Clearcoat_frag.wgsl?raw"; +import { ClusterDebug_frag } from './materials/program/ClusterDebug_frag'; import ColorPassFragmentOutput from "./core/struct/ColorPassFragmentOutput.wgsl?raw"; +import ColorUtil from './utils/ColorUtil.wgsl?raw' import Common_frag from "./core/base/Common_frag.wgsl?raw"; import Common_vert from "./core/base/Common_vert.wgsl?raw"; -import FragmentVarying from "./core/struct/FragmentVarying.wgsl?raw"; -import BxdfDebug_frag from "./materials/program/BxdfDebug_frag.wgsl?raw"; -import Clearcoat_frag from "./materials/program/Clearcoat_frag.wgsl?raw"; -import NormalMap_frag from "./materials/program/NormalMap_frag.wgsl?raw"; -import ShadowMapping_frag from "./materials/program/ShadowMapping_frag.wgsl?raw"; -import BrdfLut_frag from "./core/common/BrdfLut_frag.wgsl?raw"; +import { CubeSky_Shader } from './materials/sky/CubeSky_Shader'; import EnvMap_frag from "./core/common/EnvMap_frag.wgsl?raw"; +import FastMathShader from "./math/FastMathShader.wgsl?raw"; +import FragmentVarying from "./core/struct/FragmentVarying.wgsl?raw"; +import GenerayRandomDir from './utils/GenerayRandomDir.wgsl?raw' import GlobalUniform from "./core/common/GlobalUniform.wgsl?raw"; +import IESProfiles_frag from './lighting/IESProfiles_frag.wgsl?raw' import Inline_vert from "./core/inline/Inline_vert.wgsl?raw"; -import WorldMatrixUniform from "./core/common/WorldMatrixUniform.wgsl?raw"; import InstanceUniform from "./core/common/InstanceUniform.wgsl?raw"; -import { LightStructFrag } from "./core/struct/LightStructFrag"; -import { LightingFunction_frag } from "./lighting/LightingFunction_frag"; -import { PhysicMaterialUniform_frag } from "./materials/uniforms/PhysicMaterialUniform_frag"; -import { MathShader } from "./math/MathShader"; -import ShadingInput from "./core/struct/ShadingInput.wgsl?raw"; -import { ClusterDebug_frag } from "./materials/program/ClusterDebug_frag"; - -import FastMathShader from "./math/FastMathShader.wgsl?raw"; -import BRDF_frag from "./lighting/BRDF_frag.wgsl?raw"; -import BxDF_frag from "./lighting/BxDF_frag.wgsl?raw"; import Irradiance_frag from "./lighting/Irradiance_frag.wgsl?raw"; +import { LightStructFrag } from './core/struct/LightStructFrag'; +import { LightingFunction_frag } from './lighting/LightingFunction_frag'; import LitShader from '../shader/materials/LitShader.wgsl?raw' +import { MathShader } from './math/MathShader'; +import NormalMap_frag from "./materials/program/NormalMap_frag.wgsl?raw"; import PBRLItShader from '../shader/materials/PBRLItShader.wgsl?raw' - -import ColorUtil from './utils/ColorUtil.wgsl?raw' -import GenerayRandomDir from './utils/GenerayRandomDir.wgsl?raw' -import IESProfiles_frag from './lighting/IESProfiles_frag.wgsl?raw' -import { UnLit_frag } from "./lighting/UnLit_frag"; -import { UnLitMaterialUniform_frag } from "./materials/uniforms/UnLitMaterialUniform_frag"; -import { VideoUniform_frag } from "./materials/uniforms/VideoUniform_frag"; -import { Bloom_shader } from "./post/Bloom_shader"; -import { Quad_shader } from "./quad/Quad_shader"; -import { CubeSky_Shader } from "./materials/sky/CubeSky_Shader"; +import { PhysicMaterialUniform_frag } from './materials/uniforms/PhysicMaterialUniform_frag'; +import { Quad_shader } from './quad/Quad_shader'; +import ShadingInput from "./core/struct/ShadingInput.wgsl?raw"; +import ShadowMapping_frag from "./materials/program/ShadowMapping_frag.wgsl?raw"; +import { UnLitMaterialUniform_frag } from './materials/uniforms/UnLitMaterialUniform_frag'; +import { UnLit_frag } from './lighting/UnLit_frag'; +import { VertexAttributes } from './core/struct/VertexAttributes'; +import { VideoUniform_frag } from './materials/uniforms/VideoUniform_frag'; +import WorldMatrixUniform from "./core/common/WorldMatrixUniform.wgsl?raw"; +import { IrradianceVolumeData_frag } from "./lighting/IrradianceVolumeData_frag"; /** * @internal @@ -71,7 +70,7 @@ export class ShaderLib { ShaderLib.register('ShadowMapping_frag', ShadowMapping_frag); ShaderLib.register('Irradiance_frag', Irradiance_frag); - // ShaderLib.register('IrradianceVolumeData_frag', IrradianceVolumeData_frag); + ShaderLib.register('IrradianceVolumeData_frag', IrradianceVolumeData_frag); ShaderLib.register('BrdfLut_frag', BrdfLut_frag); ShaderLib.register('EnvMap_frag', EnvMap_frag); @@ -85,14 +84,9 @@ export class ShaderLib { ShaderLib.register('PBRLItShader', PBRLItShader); - - // ShaderLib.register('Surface', Surface_Shader.Surface_Common); - ShaderLib.register('ClusterDebug_frag', ClusterDebug_frag); ShaderLib.register('BxdfDebug_frag', BxdfDebug_frag); - ShaderLib.register('GenerayRandomDir', GenerayRandomDir); - ShaderLib.register('Quad_vert_wgsl', Quad_shader.Quad_vert_wgsl); ShaderLib.register('Quad_frag_wgsl', Quad_shader.Quad_frag_wgsl); ShaderLib.register('Quad_depth2d_frag_wgsl', Quad_shader.Quad_depth2d_frag_wgsl); diff --git a/src/engine/assets/shader/anim/SkeletonAnimation_shader.ts b/src/assets/shader/anim/SkeletonAnimation_shader.ts similarity index 100% rename from src/engine/assets/shader/anim/SkeletonAnimation_shader.ts rename to src/assets/shader/anim/SkeletonAnimation_shader.ts diff --git a/src/engine/assets/shader/cluster/ClusterBoundsSource_cs.wgsl b/src/assets/shader/cluster/ClusterBoundsSource_cs.wgsl similarity index 100% rename from src/engine/assets/shader/cluster/ClusterBoundsSource_cs.wgsl rename to src/assets/shader/cluster/ClusterBoundsSource_cs.wgsl diff --git a/src/engine/assets/shader/cluster/ClusterLighting_cs.wgsl b/src/assets/shader/cluster/ClusterLighting_cs.wgsl similarity index 100% rename from src/engine/assets/shader/cluster/ClusterLighting_cs.wgsl rename to src/assets/shader/cluster/ClusterLighting_cs.wgsl diff --git a/src/engine/assets/shader/compute/BLUR_CsShader.wgsl b/src/assets/shader/compute/BLUR_CsShader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/BLUR_CsShader.wgsl rename to src/assets/shader/compute/BLUR_CsShader.wgsl diff --git a/src/engine/assets/shader/compute/BlurEffectCreator_compute.ts b/src/assets/shader/compute/BlurEffectCreator_compute.ts similarity index 100% rename from src/engine/assets/shader/compute/BlurEffectCreator_compute.ts rename to src/assets/shader/compute/BlurEffectCreator_compute.ts diff --git a/src/engine/assets/shader/compute/DepthOfView_CsShader.wgsl b/src/assets/shader/compute/DepthOfView_CsShader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/DepthOfView_CsShader.wgsl rename to src/assets/shader/compute/DepthOfView_CsShader.wgsl diff --git a/src/engine/assets/shader/compute/ErpImage2CubeMapCreateCube_compute.wgsl b/src/assets/shader/compute/ErpImage2CubeMapCreateCube_compute.wgsl similarity index 100% rename from src/engine/assets/shader/compute/ErpImage2CubeMapCreateCube_compute.wgsl rename to src/assets/shader/compute/ErpImage2CubeMapCreateCube_compute.wgsl diff --git a/src/engine/assets/shader/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl b/src/assets/shader/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl similarity index 100% rename from src/engine/assets/shader/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl rename to src/assets/shader/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl diff --git a/src/engine/assets/shader/compute/GTAOCs.wgsl b/src/assets/shader/compute/GTAOCs.wgsl similarity index 100% rename from src/engine/assets/shader/compute/GTAOCs.wgsl rename to src/assets/shader/compute/GTAOCs.wgsl diff --git a/src/engine/assets/shader/compute/IBLEnvMapCreator_compute.wgsl b/src/assets/shader/compute/IBLEnvMapCreator_compute.wgsl similarity index 100% rename from src/engine/assets/shader/compute/IBLEnvMapCreator_compute.wgsl rename to src/assets/shader/compute/IBLEnvMapCreator_compute.wgsl diff --git a/src/engine/assets/shader/compute/MergeRGBA_Cs.wgsl b/src/assets/shader/compute/MergeRGBA_Cs.wgsl similarity index 100% rename from src/engine/assets/shader/compute/MergeRGBA_Cs.wgsl rename to src/assets/shader/compute/MergeRGBA_Cs.wgsl diff --git a/src/engine/assets/shader/compute/MultiBouncePass_Shader.wgsl b/src/assets/shader/compute/MultiBouncePass_Shader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/MultiBouncePass_Shader.wgsl rename to src/assets/shader/compute/MultiBouncePass_Shader.wgsl diff --git a/src/engine/assets/shader/compute/OutLineBlendColor.wgsl b/src/assets/shader/compute/OutLineBlendColor.wgsl similarity index 100% rename from src/engine/assets/shader/compute/OutLineBlendColor.wgsl rename to src/assets/shader/compute/OutLineBlendColor.wgsl diff --git a/src/engine/assets/shader/compute/OutlineCalcOutline.wgsl b/src/assets/shader/compute/OutlineCalcOutline.wgsl similarity index 100% rename from src/engine/assets/shader/compute/OutlineCalcOutline.wgsl rename to src/assets/shader/compute/OutlineCalcOutline.wgsl diff --git a/src/engine/assets/shader/compute/OutlineCs.wgsl b/src/assets/shader/compute/OutlineCs.wgsl similarity index 100% rename from src/engine/assets/shader/compute/OutlineCs.wgsl rename to src/assets/shader/compute/OutlineCs.wgsl diff --git a/src/engine/assets/shader/compute/Picker_CsShader.wgsl b/src/assets/shader/compute/Picker_CsShader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/Picker_CsShader.wgsl rename to src/assets/shader/compute/Picker_CsShader.wgsl diff --git a/src/engine/assets/shader/compute/SSAO_CsShader.wgsl b/src/assets/shader/compute/SSAO_CsShader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/SSAO_CsShader.wgsl rename to src/assets/shader/compute/SSAO_CsShader.wgsl diff --git a/src/engine/assets/shader/compute/SSR_BlendColor_Shader.wgsl b/src/assets/shader/compute/SSR_BlendColor_Shader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/SSR_BlendColor_Shader.wgsl rename to src/assets/shader/compute/SSR_BlendColor_Shader.wgsl diff --git a/src/engine/assets/shader/compute/SSR_IS_Shader.wgsl b/src/assets/shader/compute/SSR_IS_Shader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/SSR_IS_Shader.wgsl rename to src/assets/shader/compute/SSR_IS_Shader.wgsl diff --git a/src/engine/assets/shader/compute/SSR_RayTrace_Shader.wgsl b/src/assets/shader/compute/SSR_RayTrace_Shader.wgsl similarity index 100% rename from src/engine/assets/shader/compute/SSR_RayTrace_Shader.wgsl rename to src/assets/shader/compute/SSR_RayTrace_Shader.wgsl diff --git a/src/engine/assets/shader/compute/TAACopyTex.wgsl b/src/assets/shader/compute/TAACopyTex.wgsl similarity index 100% rename from src/engine/assets/shader/compute/TAACopyTex.wgsl rename to src/assets/shader/compute/TAACopyTex.wgsl diff --git a/src/engine/assets/shader/compute/TAASharpTex.wgsl b/src/assets/shader/compute/TAASharpTex.wgsl similarity index 100% rename from src/engine/assets/shader/compute/TAASharpTex.wgsl rename to src/assets/shader/compute/TAASharpTex.wgsl diff --git a/src/engine/assets/shader/compute/TAAcs.wgsl b/src/assets/shader/compute/TAAcs.wgsl similarity index 100% rename from src/engine/assets/shader/compute/TAAcs.wgsl rename to src/assets/shader/compute/TAAcs.wgsl diff --git a/src/engine/assets/shader/core/base/Common_frag.wgsl b/src/assets/shader/core/base/Common_frag.wgsl similarity index 100% rename from src/engine/assets/shader/core/base/Common_frag.wgsl rename to src/assets/shader/core/base/Common_frag.wgsl diff --git a/src/engine/assets/shader/core/base/Common_vert.wgsl b/src/assets/shader/core/base/Common_vert.wgsl similarity index 100% rename from src/engine/assets/shader/core/base/Common_vert.wgsl rename to src/assets/shader/core/base/Common_vert.wgsl diff --git a/src/engine/assets/shader/core/common/BrdfLut_frag.wgsl b/src/assets/shader/core/common/BrdfLut_frag.wgsl similarity index 100% rename from src/engine/assets/shader/core/common/BrdfLut_frag.wgsl rename to src/assets/shader/core/common/BrdfLut_frag.wgsl diff --git a/src/engine/assets/shader/core/common/EnvMap_frag.wgsl b/src/assets/shader/core/common/EnvMap_frag.wgsl similarity index 100% rename from src/engine/assets/shader/core/common/EnvMap_frag.wgsl rename to src/assets/shader/core/common/EnvMap_frag.wgsl diff --git a/src/engine/assets/shader/core/common/GlobalUniform.wgsl b/src/assets/shader/core/common/GlobalUniform.wgsl similarity index 100% rename from src/engine/assets/shader/core/common/GlobalUniform.wgsl rename to src/assets/shader/core/common/GlobalUniform.wgsl diff --git a/src/engine/assets/shader/core/common/InstanceUniform.wgsl b/src/assets/shader/core/common/InstanceUniform.wgsl similarity index 100% rename from src/engine/assets/shader/core/common/InstanceUniform.wgsl rename to src/assets/shader/core/common/InstanceUniform.wgsl diff --git a/src/engine/assets/shader/core/common/WorldMatrixUniform.wgsl b/src/assets/shader/core/common/WorldMatrixUniform.wgsl similarity index 100% rename from src/engine/assets/shader/core/common/WorldMatrixUniform.wgsl rename to src/assets/shader/core/common/WorldMatrixUniform.wgsl diff --git a/src/engine/assets/shader/core/inline/Inline_vert.wgsl b/src/assets/shader/core/inline/Inline_vert.wgsl similarity index 100% rename from src/engine/assets/shader/core/inline/Inline_vert.wgsl rename to src/assets/shader/core/inline/Inline_vert.wgsl diff --git a/src/engine/assets/shader/core/pass/CastShadowPass_wgsl.ts b/src/assets/shader/core/pass/CastShadowPass_wgsl.ts similarity index 100% rename from src/engine/assets/shader/core/pass/CastShadowPass_wgsl.ts rename to src/assets/shader/core/pass/CastShadowPass_wgsl.ts diff --git a/src/engine/assets/shader/core/pass/FrustumCullingShader_cs.wgsl b/src/assets/shader/core/pass/FrustumCullingShader_cs.wgsl similarity index 100% rename from src/engine/assets/shader/core/pass/FrustumCullingShader_cs.wgsl rename to src/assets/shader/core/pass/FrustumCullingShader_cs.wgsl diff --git a/src/engine/assets/shader/core/pass/GBuffer_shader.wgsl b/src/assets/shader/core/pass/GBuffer_shader.wgsl similarity index 100% rename from src/engine/assets/shader/core/pass/GBuffer_shader.wgsl rename to src/assets/shader/core/pass/GBuffer_shader.wgsl diff --git a/src/engine/assets/shader/core/pass/SkyGBuffer_fs.wgsl b/src/assets/shader/core/pass/SkyGBuffer_fs.wgsl similarity index 100% rename from src/engine/assets/shader/core/pass/SkyGBuffer_fs.wgsl rename to src/assets/shader/core/pass/SkyGBuffer_fs.wgsl diff --git a/src/engine/assets/shader/core/pass/ZPassShader_cs.wgsl b/src/assets/shader/core/pass/ZPassShader_cs.wgsl similarity index 100% rename from src/engine/assets/shader/core/pass/ZPassShader_cs.wgsl rename to src/assets/shader/core/pass/ZPassShader_cs.wgsl diff --git a/src/engine/assets/shader/core/pass/ZPassShader_fs.wgsl b/src/assets/shader/core/pass/ZPassShader_fs.wgsl similarity index 100% rename from src/engine/assets/shader/core/pass/ZPassShader_fs.wgsl rename to src/assets/shader/core/pass/ZPassShader_fs.wgsl diff --git a/src/engine/assets/shader/core/pass/ZPassShader_vs.ts b/src/assets/shader/core/pass/ZPassShader_vs.ts similarity index 100% rename from src/engine/assets/shader/core/pass/ZPassShader_vs.ts rename to src/assets/shader/core/pass/ZPassShader_vs.ts diff --git a/src/engine/assets/shader/core/struct/ColorPassFragmentOutput.wgsl b/src/assets/shader/core/struct/ColorPassFragmentOutput.wgsl similarity index 100% rename from src/engine/assets/shader/core/struct/ColorPassFragmentOutput.wgsl rename to src/assets/shader/core/struct/ColorPassFragmentOutput.wgsl diff --git a/src/engine/assets/shader/core/struct/EmptyFrag_CommonFragment.wgsl b/src/assets/shader/core/struct/EmptyFrag_CommonFragment.wgsl similarity index 100% rename from src/engine/assets/shader/core/struct/EmptyFrag_CommonFragment.wgsl rename to src/assets/shader/core/struct/EmptyFrag_CommonFragment.wgsl diff --git a/src/engine/assets/shader/core/struct/EmptyFrag_FragmentOutput.wgsl b/src/assets/shader/core/struct/EmptyFrag_FragmentOutput.wgsl similarity index 100% rename from src/engine/assets/shader/core/struct/EmptyFrag_FragmentOutput.wgsl rename to src/assets/shader/core/struct/EmptyFrag_FragmentOutput.wgsl diff --git a/src/engine/assets/shader/core/struct/FragmentVarying.wgsl b/src/assets/shader/core/struct/FragmentVarying.wgsl similarity index 100% rename from src/engine/assets/shader/core/struct/FragmentVarying.wgsl rename to src/assets/shader/core/struct/FragmentVarying.wgsl diff --git a/src/engine/assets/shader/core/struct/LightStruct.wgsl b/src/assets/shader/core/struct/LightStruct.wgsl similarity index 100% rename from src/engine/assets/shader/core/struct/LightStruct.wgsl rename to src/assets/shader/core/struct/LightStruct.wgsl diff --git a/src/engine/assets/shader/core/struct/LightStructFrag.ts b/src/assets/shader/core/struct/LightStructFrag.ts similarity index 100% rename from src/engine/assets/shader/core/struct/LightStructFrag.ts rename to src/assets/shader/core/struct/LightStructFrag.ts diff --git a/src/engine/assets/shader/core/struct/ShadingInput.wgsl b/src/assets/shader/core/struct/ShadingInput.wgsl similarity index 100% rename from src/engine/assets/shader/core/struct/ShadingInput.wgsl rename to src/assets/shader/core/struct/ShadingInput.wgsl diff --git a/src/engine/assets/shader/core/struct/VertexAttributes.ts b/src/assets/shader/core/struct/VertexAttributes.ts similarity index 100% rename from src/engine/assets/shader/core/struct/VertexAttributes.ts rename to src/assets/shader/core/struct/VertexAttributes.ts diff --git a/src/engine/assets/shader/glsl/Quad_glsl.ts b/src/assets/shader/glsl/Quad_glsl.ts similarity index 100% rename from src/engine/assets/shader/glsl/Quad_glsl.ts rename to src/assets/shader/glsl/Quad_glsl.ts diff --git a/src/engine/assets/shader/glsl/Sky_glsl.ts b/src/assets/shader/glsl/Sky_glsl.ts similarity index 100% rename from src/engine/assets/shader/glsl/Sky_glsl.ts rename to src/assets/shader/glsl/Sky_glsl.ts diff --git a/src/engine/assets/shader/glsl/post/LUT_glsl.ts b/src/assets/shader/glsl/post/LUT_glsl.ts similarity index 100% rename from src/engine/assets/shader/glsl/post/LUT_glsl.ts rename to src/assets/shader/glsl/post/LUT_glsl.ts diff --git a/src/engine/assets/shader/graphic/Graphic3DShader_fs.wgsl b/src/assets/shader/graphic/Graphic3DShader_fs.wgsl similarity index 100% rename from src/engine/assets/shader/graphic/Graphic3DShader_fs.wgsl rename to src/assets/shader/graphic/Graphic3DShader_fs.wgsl diff --git a/src/engine/assets/shader/graphic/Graphic3DShader_vs.wgsl b/src/assets/shader/graphic/Graphic3DShader_vs.wgsl similarity index 100% rename from src/engine/assets/shader/graphic/Graphic3DShader_vs.wgsl rename to src/assets/shader/graphic/Graphic3DShader_vs.wgsl diff --git a/src/engine/assets/shader/lighting/BRDF_frag.wgsl b/src/assets/shader/lighting/BRDF_frag.wgsl similarity index 100% rename from src/engine/assets/shader/lighting/BRDF_frag.wgsl rename to src/assets/shader/lighting/BRDF_frag.wgsl diff --git a/src/engine/assets/shader/lighting/BxDF_frag.wgsl b/src/assets/shader/lighting/BxDF_frag.wgsl similarity index 100% rename from src/engine/assets/shader/lighting/BxDF_frag.wgsl rename to src/assets/shader/lighting/BxDF_frag.wgsl diff --git a/src/engine/assets/shader/lighting/IESProfiles_frag.wgsl b/src/assets/shader/lighting/IESProfiles_frag.wgsl similarity index 100% rename from src/engine/assets/shader/lighting/IESProfiles_frag.wgsl rename to src/assets/shader/lighting/IESProfiles_frag.wgsl diff --git a/src/assets/shader/lighting/IrradianceVolumeData_frag.ts b/src/assets/shader/lighting/IrradianceVolumeData_frag.ts new file mode 100644 index 00000000..414a03ee --- /dev/null +++ b/src/assets/shader/lighting/IrradianceVolumeData_frag.ts @@ -0,0 +1,49 @@ +export let IrradianceVolumeData_frag: string = + ` + struct IrradianceVolumeData { + //0 + orientationIndex:f32, + hysteresis:f32, + OctRTSideSize:f32, + OctRTMaxSize:f32, + + //1 + startX:f32, + startY:f32, + startZ:f32, + ProbeSpace:f32, + + //2 + gridXCount:f32, + gridYCount:f32, + gridZCount:f32, + maxDistance:f32, + + //3 + depthSharpness:f32, + ProbeSourceTextureSize:f32, + ProbeSize:f32, + bounceIntensity:f32, + + //4 + probeRoughness:f32, + normalBias:f32, + irradianceChebyshevBias:f32, + rayNumber:f32, + + //5 + irradianceDistanceBias:f32, + indirectIntensity:f32, + ddgiGamma:f32, + lerpHysteresis:f32, + //6 + + debugX:f32, + debugY:f32, + debugZ:f32, + slot0:f32, + + //.. + v7:vec4, +} +` \ No newline at end of file diff --git a/src/engine/assets/shader/lighting/Irradiance_frag.wgsl b/src/assets/shader/lighting/Irradiance_frag.wgsl similarity index 100% rename from src/engine/assets/shader/lighting/Irradiance_frag.wgsl rename to src/assets/shader/lighting/Irradiance_frag.wgsl diff --git a/src/engine/assets/shader/lighting/LightingFunction_frag.ts b/src/assets/shader/lighting/LightingFunction_frag.ts similarity index 100% rename from src/engine/assets/shader/lighting/LightingFunction_frag.ts rename to src/assets/shader/lighting/LightingFunction_frag.ts diff --git a/src/engine/assets/shader/lighting/UnLit_frag.ts b/src/assets/shader/lighting/UnLit_frag.ts similarity index 100% rename from src/engine/assets/shader/lighting/UnLit_frag.ts rename to src/assets/shader/lighting/UnLit_frag.ts diff --git a/src/engine/assets/shader/materials/ColorLitShader.ts b/src/assets/shader/materials/ColorLitShader.ts similarity index 100% rename from src/engine/assets/shader/materials/ColorLitShader.ts rename to src/assets/shader/materials/ColorLitShader.ts diff --git a/src/engine/assets/shader/materials/GlassShader.wgsl b/src/assets/shader/materials/GlassShader.wgsl similarity index 100% rename from src/engine/assets/shader/materials/GlassShader.wgsl rename to src/assets/shader/materials/GlassShader.wgsl diff --git a/src/engine/assets/shader/materials/Lambert_shader.ts b/src/assets/shader/materials/Lambert_shader.ts similarity index 100% rename from src/engine/assets/shader/materials/Lambert_shader.ts rename to src/assets/shader/materials/Lambert_shader.ts diff --git a/src/engine/assets/shader/materials/LitShader.wgsl b/src/assets/shader/materials/LitShader.wgsl similarity index 100% rename from src/engine/assets/shader/materials/LitShader.wgsl rename to src/assets/shader/materials/LitShader.wgsl diff --git a/src/engine/assets/shader/materials/OutlinePass.wgsl b/src/assets/shader/materials/OutlinePass.wgsl similarity index 100% rename from src/engine/assets/shader/materials/OutlinePass.wgsl rename to src/assets/shader/materials/OutlinePass.wgsl diff --git a/src/engine/assets/shader/materials/PBRLItShader.wgsl b/src/assets/shader/materials/PBRLItShader.wgsl similarity index 100% rename from src/engine/assets/shader/materials/PBRLItShader.wgsl rename to src/assets/shader/materials/PBRLItShader.wgsl diff --git a/src/engine/assets/shader/materials/PavementShader.ts b/src/assets/shader/materials/PavementShader.ts similarity index 100% rename from src/engine/assets/shader/materials/PavementShader.ts rename to src/assets/shader/materials/PavementShader.ts diff --git a/src/engine/assets/shader/materials/PointShadowDebug.ts b/src/assets/shader/materials/PointShadowDebug.ts similarity index 100% rename from src/engine/assets/shader/materials/PointShadowDebug.ts rename to src/assets/shader/materials/PointShadowDebug.ts diff --git a/src/engine/assets/shader/materials/UnLit.wgsl b/src/assets/shader/materials/UnLit.wgsl similarity index 100% rename from src/engine/assets/shader/materials/UnLit.wgsl rename to src/assets/shader/materials/UnLit.wgsl diff --git a/src/assets/shader/materials/compute/BLUR_CsShader.wgsl b/src/assets/shader/materials/compute/BLUR_CsShader.wgsl new file mode 100644 index 00000000..e5dd6680 --- /dev/null +++ b/src/assets/shader/materials/compute/BLUR_CsShader.wgsl @@ -0,0 +1,40 @@ +#include "GlobalUniform" + +struct UniformData { + radius: f32 , + bias: f32, + aoPower: f32 , + blurSize: f32 , +}; + +// @group(0) @binding(0) var standUniform: GlobalUniform; +@group(0) @binding(0) var uniformData: UniformData; +@group(0) @binding(1) var colorMap : texture_2d; +// @group(0) @binding(2) var ssaoMapSampler : sampler; +@group(0) @binding(2) var ssaoMap : texture_2d; +@group(0) @binding(3) var outTex : texture_storage_2d; + +@compute @workgroup_size( 8 , 8 ) +fn CsMain( @builtin(global_invocation_id) globalInvocation_id : vec3) +{ + var fragCoord = vec2( globalInvocation_id.xy ); + + var texSize = vec2(textureDimensions(ssaoMap).xy); + var texCoord = vec2(fragCoord) / texSize ; + + let blurSize = i32(uniformData.blurSize); + + var result = vec4(0.0) ; + var ii = 0.0 ; + for (var i = -2; i < 2 ; i+=1) { + for (var j = -2; j < 2 ; j+=1) { + var offset = vec2( i , j ) ; + result += textureLoad(ssaoMap, fragCoord + offset, 0 ); + // result += textureSampleLevel(ssaoMap,ssaoMapSampler, vec2( fragCoord + offset) / texSize , 0.0 ); + ii += 1.0 ; + } + } + var fResult = result.r / ii ; + var color = textureLoad(colorMap, fragCoord , 0 ); + textureStore(outTex, fragCoord , vec4(color.rgb * fResult,1.0) ); +} \ No newline at end of file diff --git a/src/assets/shader/materials/compute/DepthOfView_CsShader.wgsl b/src/assets/shader/materials/compute/DepthOfView_CsShader.wgsl new file mode 100644 index 00000000..f8420bda --- /dev/null +++ b/src/assets/shader/materials/compute/DepthOfView_CsShader.wgsl @@ -0,0 +1,81 @@ +#include "GlobalUniform" + + struct BlurSetting{ + near: f32, + far: f32, + pixelOffset: f32, + } + + @group(0) @binding(0) var standUniform: GlobalUniform; + @group(0) @binding(1) var blurSetting: BlurSetting; + + @group(0) @binding(2) var positionBufferTex : texture_2d; + @group(0) @binding(3) var normalBufferTex : texture_2d; + @group(0) @binding(4) var inTexSampler : sampler; + @group(0) @binding(5) var inTex : texture_2d; + @group(0) @binding(6) var outTex : texture_storage_2d; + + var cameraPosition: vec3; + var texSize: vec2; + var fragCoord: vec2; + var texelSize: vec2; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(inTex).xy; + texelSize = 1.0 / vec2(texSize - 1); + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + cameraPosition = vec3(standUniform.cameraWorldMatrix[3].xyz); + let wPosition:vec3 = textureLoad(positionBufferTex, fragCoord , 0).xyz; + var distance = length(wPosition - cameraPosition); + var oc:vec4 = textureLoad(inTex, fragCoord, 0); + if(distance > blurSetting.near){ + let normal = textureLoad(normalBufferTex, fragCoord, 0); + var pixelScale = 0.5; + if(normal.w > 0.5){ + distance = min(distance, blurSetting.far); + pixelScale = (distance - blurSetting.near) / (blurSetting.far - blurSetting.near); + } + oc = mixBlurColor(oc, fragCoord, blurSetting.pixelOffset, pixelScale); + } + textureStore(outTex, fragCoord, oc); + } + + fn mixBlurColor(orginColor:vec4, coord:vec2, pixelOffset:f32, scale:f32) -> vec4 { + + let uv = vec2(coord); + var uv0 = (uv + scale * vec2( pixelOffset, pixelOffset)) * texelSize; + var uv1 = (uv + scale * vec2(-pixelOffset, pixelOffset)) * texelSize; + var uv2 = (uv + scale * vec2(-pixelOffset, -pixelOffset)) * texelSize; + var uv3 = (uv + scale * vec2( pixelOffset, -pixelOffset)) * texelSize; + + uv0.x = processUVEdge(uv0.x); + uv0.y = processUVEdge(uv0.y); + uv1.x = processUVEdge(uv1.x); + uv1.y = processUVEdge(uv1.y); + uv2.x = processUVEdge(uv2.x); + uv2.y = processUVEdge(uv2.y); + uv3.x = processUVEdge(uv3.x); + uv3.y = processUVEdge(uv3.y); + + var ob = vec4(0.0); + ob += textureSampleLevel(inTex, inTexSampler, uv0, 0.0); + ob += textureSampleLevel(inTex, inTexSampler, uv1, 0.0); + ob += textureSampleLevel(inTex, inTexSampler, uv2, 0.0); + ob += textureSampleLevel(inTex, inTexSampler, uv3, 0.0); + return mix(orginColor, ob * 0.25, scale); + } + + fn processUVEdge(v: f32) -> f32{ + var value = v; + if(value < 0.0){ + value = - value; + }else if(value > 1.0){ + value = 2.0 - value; + } + return value; + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/ErpImage2CubeMapCreateCube_compute.wgsl b/src/assets/shader/materials/compute/ErpImage2CubeMapCreateCube_compute.wgsl new file mode 100644 index 00000000..f765bfd8 --- /dev/null +++ b/src/assets/shader/materials/compute/ErpImage2CubeMapCreateCube_compute.wgsl @@ -0,0 +1,65 @@ +struct ImageSize { + srcWidth : i32, + srcHeight : i32, + dstWidth : i32, + dstHeight : i32 +}; + +@group(0) @binding(0) var size : ImageSize; +@group(0) @binding(1) var faceRotation: array>; +@group(0) @binding(2) var inputTexSampler : sampler; +@group(0) @binding(3) var inputTex : texture_2d; + +@group(1) @binding(0) var outputBuffer0 : texture_storage_2d_array; + +fn SampleSphericalMap(v: vec3) -> vec2 { + var uv:vec2 = vec2(atan2(v.z, v.x), asin(v.y)); + //uv = (uv * (vec2(0.1590999960899353, 0.3183000087738037) + vec2(0.0010000000474974513))); + uv = uv * vec2(0.1590999960899353, 0.3183000087738037); + uv = uv + vec2(0.5); + uv = clamp(uv, vec2(0.0), vec2(1.0)); + return uv; +} + + +fn applyQuaternion(position:vec3, q:vec4) -> vec3{ + let x:f32 = position.x; + let y:f32 = position.y; + let z:f32 = position.z; + + let qx:f32 = q.x; + let qy:f32 = q.y; + let qz:f32 = q.z; + let qw:f32 = q.w; + + let ix:f32 = qw * x + qy * z - qz * y; + let iy:f32 = qw * y + qz * x - qx * z; + let iz:f32 = qw * z + qx * y - qy * x; + let iw:f32 = -qx * x - qy * y - qz * z; + + var ret: vec3; + ret.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + ret.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + ret.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return ret; +} + +fn convertIdToDir3(uv_i32:vec2, quaternion:vec4) -> vec3{ + var uv_f32:vec2 = vec2(uv_i32.xy); + var halfSize:f32 = f32(size.dstWidth / 2); + var worldDirection:vec3 = vec3(uv_f32.x - halfSize, uv_f32.y - halfSize, -halfSize); + worldDirection = normalize(worldDirection); + worldDirection = applyQuaternion(worldDirection, quaternion); + return worldDirection; +} + +@compute @workgroup_size(8, 8, 1) +fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3) { + let coord = vec2(GlobalInvocationID.xy); + let quaternion = faceRotation[GlobalInvocationID.z]; + var worldDirection:vec3 = convertIdToDir3(coord, quaternion); + let uv_f32:vec2 = SampleSphericalMap(worldDirection); + let oc = textureSampleLevel(inputTex, inputTexSampler, uv_f32 , 0.0); + textureStore(outputBuffer0, coord, i32(GlobalInvocationID.z), oc); +} \ No newline at end of file diff --git a/src/assets/shader/materials/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl b/src/assets/shader/materials/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl new file mode 100644 index 00000000..aece1023 --- /dev/null +++ b/src/assets/shader/materials/compute/ErpImage2CubeMapRgbe2rgba_compute.wgsl @@ -0,0 +1,32 @@ +struct ImageSize { + srcWidth : i32, + srcHeight : i32, + dstWidth : i32, + dstHeight : i32 +}; + +@group(0) @binding(0) var size : ImageSize; +@group(0) @binding(1) var tex_in: array>; +@group(0) @binding(2) var outputBuffer : texture_storage_2d; + +@compute @workgroup_size(8, 8, 1) +fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3) { + let fragCoord = vec2(i32(GlobalInvocationID.x), i32(GlobalInvocationID.y)); + var oc:vec4 = tex_in[fragCoord.y * size.srcWidth + fragCoord.x] / 256.0; + var e = pow(2.0, oc.w * 255.0 - 128.0); + oc = oc * e; + oc = scaleByThreshold(oc, 40.0); + textureStore(outputBuffer, fragCoord , vec4(oc.xyz, 1.0) ); +} + +fn scaleByThreshold(color:vec4, threshold:f32) -> vec4{ + var oc = color; + let brightness = length(vec3(oc.xyz)); + var scale = brightness / threshold; + if(scale > 1.0){ + scale = 1.0 / pow(scale, 0.7); + oc = oc * scale; + } + oc.a = 1.0; + return oc; +} \ No newline at end of file diff --git a/src/assets/shader/materials/compute/GTAOCs.wgsl b/src/assets/shader/materials/compute/GTAOCs.wgsl new file mode 100644 index 00000000..74210c98 --- /dev/null +++ b/src/assets/shader/materials/compute/GTAOCs.wgsl @@ -0,0 +1,133 @@ +#include "GlobalUniform" + + struct GTAO{ + maxDistance: f32, + maxPixel: f32, + darkFactor: f32, + rayMarchSegment: f32, + cameraNear: f32, + cameraFar: f32, + viewPortWidth: f32, + viewPortHeight: f32, + multiBounce: f32, + blendColor: f32, + slot1: f32, + slot2: f32, + } + + @group(0) @binding(0) var standUniform: GlobalUniform; + @group(0) @binding(1) var gtaoData: GTAO; + @group(0) @binding(2) var directions : array>; + @group(0) @binding(3) var aoBuffer : array; + + @group(0) @binding(4) var posTex : texture_2d; + @group(0) @binding(5) var normalTex : texture_2d; + @group(0) @binding(6) var inTex : texture_2d; + @group(0) @binding(7) var outTex : texture_storage_2d; + + var texSize: vec2; + var fragCoord: vec2; + var wPosition: vec3; + var wNormal: vec4; + var maxPixelScaled: f32; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(inTex).xy; + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + wNormal = textureLoad(normalTex, fragCoord, 0); + wNormal = vec4(wNormal.rgb,wNormal.w) ; + var oc = textureLoad(inTex, fragCoord, 0); + let index = fragCoord.x + fragCoord.y * i32(texSize.x); + let lastFactor = aoBuffer[index]; + var newFactor = 0.0; + if(wNormal.w < 0.5){//sky + + }else{ + wPosition = textureLoad(posTex, fragCoord, 0).xyz; + let ndc = standUniform.projMat * standUniform.viewMat * vec4(wPosition, 1.0); + let ndcZ = ndc.z / ndc.w; + maxPixelScaled = calcPixelByNDC(ndcZ); + newFactor = rayMarch(); + } + + var factor:f32 = mix(lastFactor, newFactor, 0.6); + aoBuffer[index] = factor; + factor = blurFactor(factor); + factor = 1.0 - factor * gtaoData.darkFactor; + var gtao = vec3(factor); + if(gtaoData.multiBounce > 0.5){ + gtao = MultiBounce(factor, oc.xyz); + } + + var outColor = gtao; + if(gtaoData.blendColor > 0.5){ + outColor = oc.xyz * gtao; + } + textureStore(outTex, fragCoord , vec4(outColor, oc.w)); + } + + fn MultiBounce(AO:f32, Albedo:vec3) -> vec3 + { + var A = 2 * Albedo - 0.33; + var B = -4.8 * Albedo + 0.64; + var C = 2.75 * Albedo + 0.69; + return max(vec3(AO), ((AO * A + B) * AO + C) * AO); + } + + fn calcPixelByNDC(ndcZ:f32) -> f32{ + let nearAspect = gtaoData.cameraNear / (gtaoData.cameraFar - gtaoData.cameraNear); + let aspect = (1.0 + nearAspect) / (ndcZ + nearAspect); + var viewPortMax = max(gtaoData.viewPortWidth, gtaoData.viewPortHeight); + var maxPixel = min(viewPortMax, gtaoData.maxPixel * aspect); + maxPixel = max(0.1, maxPixel); + return maxPixel; + } + + fn blurFactor(centerFactor:f32) -> f32{ + var coord0 = clamp(fragCoord + vec2(1, 0) , vec2(0), vec2(texSize - 1)); + var coord1 = clamp(fragCoord + vec2(-1, 0), vec2(0), vec2(texSize - 1)); + var coord2 = clamp(fragCoord + vec2(0, 1) , vec2(0), vec2(texSize - 1)); + var coord3 = clamp(fragCoord + vec2(0, -1), vec2(0), vec2(texSize - 1)); + var index0 = coord0.x + coord0.y * i32(texSize.x); + var index1 = coord1.x + coord1.y * i32(texSize.x); + var index2 = coord2.x + coord2.y * i32(texSize.x); + var index3 = coord3.x + coord3.y * i32(texSize.x); + let factor0:f32 = aoBuffer[index0]; + let factor1:f32 = aoBuffer[index1]; + let factor2:f32 = aoBuffer[index2]; + let factor3:f32 = aoBuffer[index3]; + var factor = 0.25 * (factor0 + factor1 + factor2 + factor3); + factor = mix(factor, centerFactor, 0.8); + return factor; + } + + fn rayMarch() -> f32{ + let originNormal = normalize(vec3(wNormal.xyz) * 2.0 - 1.0); + let stepPixel = maxPixelScaled / gtaoData.rayMarchSegment; + var totalWeight:f32 = 0.001; + var darkWeight:f32 = 0.0; + for(var i:i32 = 0; i < 8; i += 1){ + let dirVec2 = directions[i]; + for(var j:f32 = 1.1; j < maxPixelScaled; j += stepPixel){ + var sampleCoord = vec2(dirVec2 * j) + fragCoord; + sampleCoord = clamp(sampleCoord, vec2(0), vec2(texSize - 1)); + let samplePosition = textureLoad(posTex, sampleCoord, 0).xyz; + let distanceVec2 = samplePosition - wPosition; + let distance = length(distanceVec2); + if(distance < gtaoData.maxDistance){ + let sampleDir = normalize(distanceVec2); + var factor = max(0.0, dot(sampleDir, originNormal) - 0.1); + factor *= 1.0 - distance / gtaoData.maxDistance; + darkWeight += factor; + totalWeight += 1.0; + } + } + } + + return darkWeight/totalWeight ; + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/IBLEnvMapCreator_compute.wgsl b/src/assets/shader/materials/compute/IBLEnvMapCreator_compute.wgsl new file mode 100644 index 00000000..4ab1a1ef --- /dev/null +++ b/src/assets/shader/materials/compute/IBLEnvMapCreator_compute.wgsl @@ -0,0 +1,174 @@ +struct ImageSize { + srcWidth : i32, + srcHeight : i32, + dstWidth : i32, + dstHeight : i32 +}; + +@group(0) @binding(0) var size : ImageSize; +@group(0) @binding(1) var faceRotation: array>; +@group(0) @binding(2) var inputTexSampler : sampler; +@group(0) @binding(3) var inputTex : texture_2d; + +@group(1) @binding(0) var blurSetting : vec4; +@group(1) @binding(1) var outputBuffer0 : texture_storage_2d_array; + +var PI: f32 = 3.14159265359; + +fn applyQuaternion(position:vec3, q:vec4) -> vec3{ + let x:f32 = position.x; + let y:f32 = position.y; + let z:f32 = position.z; + + let qx:f32 = q.x; + let qy:f32 = q.y; + let qz:f32 = q.z; + let qw:f32 = q.w; + + let ix:f32 = qw * x + qy * z - qz * y; + let iy:f32 = qw * y + qz * x - qx * z; + let iz:f32 = qw * z + qx * y - qy * x; + let iw:f32 = -qx * x - qy * y - qz * z; + + var ret: vec3; + ret.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + ret.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + ret.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return ret; +} + +fn convertIdToDir3(uv_i32:vec2, quaternion:vec4) -> vec3{ + var uv_f32:vec2 = vec2(uv_i32.xy); + var halfSize:f32 = f32(size.dstWidth / 2); + var worldDirection:vec3 = vec3(uv_f32.x - halfSize, uv_f32.y - halfSize, -halfSize); + worldDirection = normalize(worldDirection); + worldDirection = applyQuaternion(worldDirection, quaternion); + return worldDirection; +} + +fn VanDerCorpus(n0:u32, base0:u32) -> f32 +{ + var n = n0; + var base = base0; + var invBase:f32 = 1.0 / f32(base); + var denom:f32 = 1.0; + var result:f32 = 0.0; + + for(var i:u32 = 0u; i < 32u; i = i + 1u) + { + if(n > 0u) + { + denom = f32(n) % 2.0; + result = result + denom * invBase; + invBase = invBase / 2.0; + n = u32(f32(n) / 2.0); + } + } + + return result; +} + +fn HammersleyNoBitOps(i:u32, N:u32) -> vec2 +{ + return vec2(f32(i)/f32(N), VanDerCorpus(i, 2u)); +} + +fn hammersley( i : u32 , N : u32 ) -> vec2 +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + var bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + var rdi = f32(bits) * 2.3283064365386963e-10; + return vec2(f32(i) /f32(N), rdi); +} + +fn ImportanceSampleGGX( Xi:vec2, N:vec3, roughness:f32) ->vec3 +{ + var a = roughness*roughness; + + var phi = 2.0 * PI * Xi.x; + var cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + var sinTheta = sqrt(1.0 - cosTheta*cosTheta); + + // from spherical coordinates to cartesian coordinates + var H:vec3; + H.x = cos(phi) * sinTheta; + H.y = sin(phi) * sinTheta; + H.z = cosTheta; + + // from tangent-space vector to world-space sample vector + var up:vec3; + if(abs(N.z) < 0.999) + { + up = vec3(0.0, 0.0, 1.0); + } + else + { + up = vec3(1.0, 0.0, 0.0); + } + var tangent:vec3 = normalize(cross(up, N)); + var bitangent:vec3 = cross(N, tangent); + var sampleVec:vec3 = tangent * H.x + bitangent * H.y + N * H.z; + return normalize(sampleVec); +} + +fn multiSample(localPos:vec3, roughness:f32) -> vec4 +{ + var N: vec3 = normalize(localPos); + var R: vec3 = N; + var V: vec3 = R; + + let SAMPLE_COUNT:u32 = 1024u; + var totalWeight:f32 = 0.0; + var prefilteredColor:vec3 = vec3(0.0, 0.0, 0.0); + for(var i:u32 = 0u; i < SAMPLE_COUNT; i = i + 1u) + { + var Xi:vec2 = hammersley(i, SAMPLE_COUNT); + var H :vec3 = ImportanceSampleGGX(Xi, N, roughness); + var L :vec3 = normalize(2.0 * dot(V, H) * H - V); + + var NdotL:f32 = max(dot(N, L), 0.0); + if(NdotL > 0.0) + { + var att = 1.0 ;//( f32(SAMPLE_COUNT - i) / f32(SAMPLE_COUNT)) ; + + prefilteredColor = prefilteredColor + sampleColor(L).rgb * NdotL; + prefilteredColor = prefilteredColor * att ; + totalWeight = totalWeight + NdotL; + } + } + prefilteredColor = prefilteredColor / totalWeight; + + return vec4(prefilteredColor, 1.0); +} + +fn SampleSphericalMap(v: vec3) -> vec2 { + var uv:vec2 = vec2(atan2(v.z, v.x), asin(v.y)); + //uv = (uv * (vec2(0.1590999960899353, 0.3183000087738037) + vec2(0.0010000000474974513))); + uv = uv * vec2(0.1590999960899353, 0.3183000087738037); + uv = uv + vec2(0.5); + uv = clamp(uv, vec2(0.0), vec2(1.0)); + return uv; +} + +fn sampleColor(d:vec3) -> vec4 +{ + let uv_f32:vec2 = SampleSphericalMap(d); + let oc = textureSampleLevel(inputTex, inputTexSampler, uv_f32 , 0.0); + //let dir = vec3(-d.x, -d.y, d.z); + //var oc:vec4 = textureSampleLevel(cubeMap, cubeMapSampler, dir, 0.0); + return oc; +} + +@compute @workgroup_size(8, 8, 1) +fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3) { + let coord = vec2(GlobalInvocationID.xy); + let quaternion = faceRotation[GlobalInvocationID.z]; + var worldDirection:vec3 = convertIdToDir3(coord, quaternion); + var oc:vec4 = multiSample(worldDirection, blurSetting.x); + textureStore(outputBuffer0, coord, i32(GlobalInvocationID.z), oc); +} diff --git a/src/assets/shader/materials/compute/MergeRGBA_Cs.wgsl b/src/assets/shader/materials/compute/MergeRGBA_Cs.wgsl new file mode 100644 index 00000000..c4ad1034 --- /dev/null +++ b/src/assets/shader/materials/compute/MergeRGBA_Cs.wgsl @@ -0,0 +1,29 @@ + +@group(0) @binding(0) var textureR : texture_2d; +@group(0) @binding(1) var textureG : texture_2d; +@group(0) @binding(2) var textureB : texture_2d; +@group(0) @binding(3) var textureA : texture_2d; +@group(0) @binding(4) var outTex : texture_storage_2d; + +@compute @workgroup_size(8, 8, 1) +fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3) { + let size = textureDimensions(outTex); + let fragCoord : vec2 = vec2(GlobalInvocationID.xy); + var uv:vec2; + uv.x = f32(fragCoord.x)/f32(size.x); + uv.y = f32(fragCoord.y)/f32(size.y); + var oc:vec4 = textureSampleLevel(atlasTexture, atlasTextureSampler, targetUV, 0.0); + + let sizeR = textureDimensions(textureR); + let sizeG = textureDimensions(textureG); + let sizeB = textureDimensions(textureB); + let sizeA = textureDimensions(textureA); + + var tr = textureLoad(textureR, vec2(uv * sizeR) , 0 ) ; + var tg = textureLoad(textureG, vec2(uv * sizeG) , 0 ) ; + var tb = textureLoad(textureB, vec2(uv * sizeB) , 0 ) ; + var ta = textureLoad(textureA, vec2(uv * sizeA) , 0 ) ; + + let color = vec4(tr,tg,tb,ta); + textureStore(outTex, fragCoord , vec4(color)); +} diff --git a/src/assets/shader/materials/compute/MultiBouncePass_Shader.wgsl b/src/assets/shader/materials/compute/MultiBouncePass_Shader.wgsl new file mode 100644 index 00000000..a5eb8983 --- /dev/null +++ b/src/assets/shader/materials/compute/MultiBouncePass_Shader.wgsl @@ -0,0 +1,185 @@ + + #include "MathShader" + #include "IrradianceVolumeData_frag" + + +struct IrradianceField { + probeStartPosition: vec4, + probeCounts:vec4, + probeStep:f32, + irradianceTextureWidth:f32, + irradianceTextureHeight:f32, + irradianceProbeSideLength:f32, +}; + + @group(0) @binding(0) var outputBuffer : texture_storage_2d; + @group(0) @binding(1) var uniformData : IrradianceVolumeData ; + + @group(1) @binding(0) var normalMapSampler : sampler; + @group(1) @binding(1) var normalMap : texture_2d; + + @group(1) @binding(2) var colorMapSampler : sampler; + @group(1) @binding(3) var colorMap : texture_2d; + + @group(1) @binding(4) var litMapSampler : sampler; + @group(1) @binding(5) var litMap : texture_2d; + + @group(1) @binding(6) var irradianceMapSampler : sampler; + @group(1) @binding(7) var irradianceMap : texture_2d; + + var wsn:vec3; + var ulitColor:vec4; + var litColor:vec4; + var irradianceFieldSurface : IrradianceField ; + var probeID:u32; + + var quaternion:vec4 = vec4(0.0, -0.7071067811865475, 0.7071067811865475, 0.0); + +fn getIrradianceFieldSurface() -> IrradianceField{ + let data = uniformData; + irradianceFieldSurface.probeStartPosition = vec4(data.startX, data.startY, data.startZ, 0.0); + irradianceFieldSurface.probeCounts = vec4(data.gridXCount, data.gridYCount, data.gridZCount, 0.0); + irradianceFieldSurface.probeStep = data.ProbeSpace; + irradianceFieldSurface.irradianceTextureWidth = data.OctRTMaxSize; + irradianceFieldSurface.irradianceTextureHeight = data.OctRTMaxSize; + irradianceFieldSurface.irradianceProbeSideLength = data.OctRTSideSize; + return irradianceFieldSurface; +} + + fn rotateDir(n:vec3) -> vec3{ + return normalize(applyQuaternion(-n, quaternion)); + } + + fn sampleLitColor(uv:vec2) -> vec4 + { + var oc1:vec4 = textureSampleLevel(litMap, litMapSampler, vec2(0.0), 0.0); + var oc:vec4 = textureLoad(litMap, uv, 0); + return oc; + } + + fn sampleNormal(uv:vec2) -> vec4 + { + var oc1:vec4 = textureSampleLevel(normalMap, normalMapSampler, vec2(0.0), 0.0); + var oc:vec4 = textureLoad(normalMap, uv, 0); + return oc; + } + + fn sampleColor(uv:vec2) -> vec4 + { + var oc1:vec4 = textureSampleLevel(colorMap, colorMapSampler, vec2(0.0), 0.0); + var oc:vec4 = textureLoad(colorMap, uv, 0); + return oc; + } + + fn sampleProbe(fragCoord:vec2){ + var uv = vec2(i32(fragCoord.x), i32(fragCoord.y)) ; + + litColor = sampleLitColor(uv); + + var normalMap = sampleNormal(uv); + wsn = normalMap.xyz * 2.0 - 1.0; + + ulitColor = sampleColor(uv); + } + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain(@builtin(global_invocation_id) globalInvocation_id : vec3) + { + getIrradianceFieldSurface(); + var fragCoord = vec2( globalInvocation_id.x, globalInvocation_id.y); + probeID = globalInvocation_id.z; + fragCoord = fragCoord + getCoordOffset(probeID); + + sampleProbe(fragCoord); + + let irradiance = getIrradianceColor(); + let result = blendIrradianceColor(irradiance); + textureStore(outputBuffer, vec2(fragCoord), result); + } + + fn blendIrradianceColor(irradiance:vec4) -> vec4{ + var bounceColor = irradiance * ulitColor; + let bounceIntensity = getBounceIntensity(uniformData.bounceIntensity); + let conservation1 = 1.0 / sqrt((1.0 + bounceIntensity * 0.55)); + let conservation2 = 1.0 / sqrt((1.0 + bounceIntensity)); + var result = litColor * conservation2 + bounceColor * sqrt(bounceIntensity) * conservation1; + return vec4(result.xyz, litColor.w); + } + + fn getBounceIntensity(intensity:f32) -> f32 { + var value = clamp(intensity, 0.0, 1.0) * 10.0; + return value; + } + + fn getCoordOffset(id:u32) -> vec2{ + var fullCol = u32(uniformData.ProbeSourceTextureSize / uniformData.ProbeSize); + var offsetSampleUv = vec2( (id / fullCol) * 6u , id % fullCol) * u32(uniformData.ProbeSize); + return offsetSampleUv; + } + + fn getIrradianceColor() -> vec4{ + var probeIrradiance: vec4 = vec4(0.0); + if(length(wsn) > 0.01){ + probeIrradiance = getIrrdiaceIndex(i32(probeID), wsn); + } + return probeIrradiance; + } + + fn getIrrdiaceIndex(index:i32, wsn:vec3) -> vec4{ + var wsN = rotateDir(wsn.xyz); + var texCoord:vec2 = textureCoordFromDirection(wsN, + index, + irradianceFieldSurface.irradianceTextureWidth, + irradianceFieldSurface.irradianceTextureHeight, + irradianceFieldSurface.irradianceProbeSideLength); + + var probeIrradiance: vec3 = textureSampleLevel(irradianceMap, irradianceMapSampler, texCoord, 0.0).xyz; + return vec4(probeIrradiance, 1.0); + } + + fn textureCoordFromDirection(dir:vec3, probeIndex:i32, width:f32, height:f32, sideLength:f32) -> vec2 + { + var uv = getWriteOctUVByID(dir, u32(probeIndex), sideLength) ; + uv.x = uv.x / irradianceFieldSurface.irradianceTextureWidth; + uv.y = uv.y / irradianceFieldSurface.irradianceTextureHeight; + return uv ; + } + + fn getWriteOctUVByID(dir:vec3 , probeID:u32, size: f32) -> vec2 + { + var blockCount = u32(irradianceFieldSurface.probeCounts.x * irradianceFieldSurface.probeCounts.z) ; + var offsetX = (probeID % blockCount) % u32(irradianceFieldSurface.probeCounts.x) ; + var offsetY = u32(irradianceFieldSurface.probeCounts.z - 1.0) - (probeID % blockCount) / u32(irradianceFieldSurface.probeCounts.x) ; + var offsetZ = probeID / blockCount ; + + var pixelCoord = (( octEncode(dir) + 1.0 ) * 0.5) * vec2(size,size) ; + + var blockOffset = vec2(0.0); + blockOffset.x = f32(offsetX) * size; + blockOffset.y = f32(offsetY) * size + f32(offsetZ) * f32(irradianceFieldSurface.probeCounts.z) * size; + + let mapHeight = u32(irradianceFieldSurface.irradianceTextureHeight); + var probeCounts:vec3 = vec3(irradianceFieldSurface.probeCounts.xyz); + + var gridOffsetFrom = vec2(blockOffset) + 1; + var gridOffsetTo = offsetByCol(gridOffsetFrom, size, mapHeight, probeCounts); + + pixelCoord = pixelCoord + vec2(gridOffsetTo - 1) + vec2(vec2(vec2(gridOffsetTo) / size) * 2); + + return pixelCoord + 1.0 ; + } + + fn offsetByCol(pixelCoord0:vec2, octSideSize:f32, mapHeight:u32, counts:vec3) -> vec2 + { + var pixelCoord = pixelCoord0; + let blockSize:vec2 = vec2(i32(octSideSize * counts.x), i32(octSideSize * counts.z)); + let blockSizeYBorder:i32 = i32((octSideSize + 2.0) * counts.z); + let blockMaxRowBorder:i32 = i32(mapHeight) / blockSizeYBorder; + let pixelCountYMax:i32 = blockMaxRowBorder * i32(octSideSize * counts.z); + let col:i32 = pixelCoord.y / pixelCountYMax; + + pixelCoord.x = col * i32(octSideSize * counts.x) + pixelCoord.x; + pixelCoord.y = pixelCoord.y % pixelCountYMax; + + return pixelCoord; + } diff --git a/src/assets/shader/materials/compute/OutLineBlendColor.wgsl b/src/assets/shader/materials/compute/OutLineBlendColor.wgsl new file mode 100644 index 00000000..70779dba --- /dev/null +++ b/src/assets/shader/materials/compute/OutLineBlendColor.wgsl @@ -0,0 +1,40 @@ +struct OutlineSettingData{ + strength: f32, + useAddMode: f32, + outlinePixel: f32, + fadeOutlinePixel: f32, + lowTexWidth: f32, + lowTexHeight: f32, + slot0: f32, + slot1: f32, + } + + @group(0) @binding(0) var outlineSetting: OutlineSettingData; + @group(0) @binding(1) var inTex : texture_2d; + @group(0) @binding(2) var lowTexSampler : sampler; + @group(0) @binding(3) var lowTex : texture_2d; + @group(0) @binding(4) var outlineTex : texture_storage_2d; + + var texSize: vec2; + var fragCoord: vec2; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(outlineTex).xy; + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + + let uv01 = vec2(fragCoord) / (vec2(texSize) - 1.0); + let outLineColor = textureSampleLevel(lowTex, lowTexSampler, uv01, 0.0) * outlineSetting.strength; + var newOC = textureLoad(inTex, fragCoord, 0); + var blendColor:vec3 = vec3(0.0); + if(outlineSetting.useAddMode > 0.5){ + blendColor = vec3(newOC.xyz) + vec3(outLineColor.xyz) * outLineColor.w; + }else{ + blendColor = mix(vec3(newOC.xyz), vec3(outLineColor.xyz), outLineColor.w); + } + textureStore(outlineTex, fragCoord , vec4(blendColor, newOC.w)); + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/OutlineCalcOutline.wgsl b/src/assets/shader/materials/compute/OutlineCalcOutline.wgsl new file mode 100644 index 00000000..792dc1c1 --- /dev/null +++ b/src/assets/shader/materials/compute/OutlineCalcOutline.wgsl @@ -0,0 +1,86 @@ +struct OutlineSettingData{ + strength: f32, + useAddMode: f32, + outlinePixel: f32, + fadeOutlinePixel: f32, + lowTexWidth: f32, + lowTexHeight: f32, + slot0: f32, + slot1: f32, + } + + struct OutlineSlotData{ + color: vec3, + count: f32, + } + + struct OutlineWeightData{ + slotIndex:f32, + outerSlotIndex:f32, + entityIndex:f32, + weight:f32 + } + + struct OutlineEntities{ + list: array, + } + + @group(0) @binding(0) var outlineSetting: OutlineSettingData; + @group(0) @binding(1) var slotsBuffer : array; + @group(0) @binding(2) var weightBuffer : array; + @group(0) @binding(3) var entitiesBuffer : array; + @group(0) @binding(4) var indexTexture : texture_2d; + + var texSize: vec2; + var lowSize: vec2; + var fragCoord: vec2; + var fragCoordLow: vec2; + var coordIndex: i32; + + var fragOutline: OutlineWeightData; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoordLow = vec2( globalInvocation_id.xy ); + fragCoord = fragCoordLow * 2; + texSize = textureDimensions(indexTexture).xy; + lowSize = vec2(i32(outlineSetting.lowTexWidth), i32(outlineSetting.lowTexHeight)); + + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + if(fragCoordLow.x >= lowSize.x || fragCoordLow.y >= lowSize.y){ + return; + } + + coordIndex = fragCoordLow.x + fragCoordLow.y * lowSize.x; + fragOutline = weightBuffer[coordIndex]; + var wPos = textureLoad(indexTexture, fragCoord, 0 ) ; + + fragOutline.entityIndex = round(wPos.w); + fragOutline.slotIndex = -1.0; + fragOutline.outerSlotIndex = -1.0; + fragOutline.weight = 0.0; + + if(fragOutline.entityIndex >= 0.0){ + fragOutline.slotIndex = f32(matchOutlineSlot()); + } + weightBuffer[coordIndex] = fragOutline; + } + + fn matchOutlineSlot() -> i32 + { + for(var i:i32 = 0; i < 8; i ++){ + var slotData:OutlineSlotData = slotsBuffer[i]; + var entities:array = entitiesBuffer[i].list; + let count:i32 = i32(slotData.count); + for(var j:i32 = 0; j < count; j ++){ + var outlineIndex = entities[j]; + if(abs(fragOutline.entityIndex - outlineIndex) < 0.1){ + return i; + } + } + } + return -1; + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/OutlineCs.wgsl b/src/assets/shader/materials/compute/OutlineCs.wgsl new file mode 100644 index 00000000..fd288996 --- /dev/null +++ b/src/assets/shader/materials/compute/OutlineCs.wgsl @@ -0,0 +1,120 @@ +struct OutlineSettingData{ + strength: f32, + useAddMode: f32, + outlinePixel: f32, + fadeOutlinePixel: f32, + lowTexWidth: f32, + lowTexHeight: f32, + slot0: f32, + slot1: f32, + } + + struct OutlineSlotData{ + color: vec3, + count: f32, + } + + struct OutlineWeightData{ + slotIndex:f32, + outerSlotIndex:f32, + entityIndex:f32, + weight:f32 + } + + @group(0) @binding(0) var outlineSetting: OutlineSettingData; + @group(0) @binding(1) var slotsBuffer : array; + @group(0) @binding(2) var weightBuffer : array; + @group(0) @binding(3) var oldOutlineColor : array>; + @group(0) @binding(4) var lowTex : texture_storage_2d; + + var texSize: vec2; + var fragCoord: vec2; + var coordIndex: i32; + var fragOutline: OutlineWeightData; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(lowTex).xy; + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + + coordIndex = fragCoord.x + fragCoord.y * i32(texSize.x); + fragOutline = weightBuffer[coordIndex]; + + var blendColor = vec3(0.0); + var newOC = vec4(0.0); + + calcOutline(); + let outerSlotIndex:i32 = i32(round(fragOutline.outerSlotIndex)); + if(outerSlotIndex >= 0){ + let outLineColor = slotsBuffer[outerSlotIndex].color; + newOC = vec4(outLineColor, fragOutline.weight); + } + + let coordIndex0 = fragCoord.x + 1 + (fragCoord.y - 1) * i32(texSize.x); + let coordIndex1 = fragCoord.x - 1 + (fragCoord.y - 1) * i32(texSize.x); + let coordIndex2 = fragCoord.x + (fragCoord.y + 1) * i32(texSize.x); + + let oldOC = oldOutlineColor[coordIndex]; + let oldOC0 = oldOutlineColor[coordIndex0]; + let oldOC1 = oldOutlineColor[coordIndex1]; + let oldOC2 = oldOutlineColor[coordIndex2]; + + newOC = mix((oldOC + oldOC0 + oldOC1 + oldOC2) * 0.25, newOC, 0.4); + + oldOutlineColor[coordIndex] = newOC; + textureStore(lowTex, fragCoord, newOC); + } + + fn calcOutline() + { + let outlinePixel = outlineSetting.outlinePixel; + let fadeOutlinePixel = outlineSetting.fadeOutlinePixel; + let pixelRadius = outlinePixel + fadeOutlinePixel; + let minX = max(0.0, f32(fragCoord.x) - pixelRadius); + let maxX = min(f32(texSize.x), f32(fragCoord.x) + pixelRadius); + let minY = max(0.0, f32(fragCoord.y) - pixelRadius); + let maxY = min(f32(texSize.y), f32(fragCoord.y) + pixelRadius); + var coordTemp_f32 = vec2(0.0); + var coordCurrent_f32 = vec2(fragCoord); + var tempCoordIndex = 0; + var tempWeightData: OutlineWeightData; + for(var x:f32 = minX; x < maxX; x += 1.0){ + for(var y:f32 = minY; y < maxY; y += 1.0){ + coordTemp_f32.x = x; + coordTemp_f32.y = y; + let distanceToOuter = length(coordTemp_f32 - coordCurrent_f32); + if(distanceToOuter < pixelRadius){ + var coord_i32 = vec2(coordTemp_f32); + tempCoordIndex = coord_i32.x + coord_i32.y * i32(texSize.x); + tempWeightData = weightBuffer[tempCoordIndex]; + let outlineGap = abs(tempWeightData.slotIndex - fragOutline.slotIndex); + if(outlineGap > 0.1){ + if(tempWeightData.slotIndex > fragOutline.slotIndex){ + if(abs(tempWeightData.slotIndex - fragOutline.outerSlotIndex) < 0.1){ + fragOutline.weight = max(fragOutline.weight, calcWeight(pixelRadius, distanceToOuter, outlinePixel)); + fragOutline.outerSlotIndex = tempWeightData.slotIndex; + weightBuffer[tempCoordIndex] = tempWeightData; + }else if(tempWeightData.slotIndex > fragOutline.outerSlotIndex){ + fragOutline.weight = calcWeight(pixelRadius, distanceToOuter, outlinePixel); + fragOutline.outerSlotIndex = tempWeightData.slotIndex; + weightBuffer[tempCoordIndex] = tempWeightData; + } + } + } + } + } + } + } + + fn calcWeight(radius:f32, distance0:f32, outlinePixel:f32) -> f32{ + let distance = distance0 - outlinePixel; + if(distance < 0.0){ + return 1.0; + } + var ret = 1.0 - distance / (radius - outlinePixel); + return ret; + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/Picker_CsShader.wgsl b/src/assets/shader/materials/compute/Picker_CsShader.wgsl new file mode 100644 index 00000000..b6257e13 --- /dev/null +++ b/src/assets/shader/materials/compute/Picker_CsShader.wgsl @@ -0,0 +1,65 @@ +struct GlobalUniform { + projMat: mat4x4, + viewMat: mat4x4, + cameraWorldMatrix: mat4x4, + pvMatrixInv : mat4x4, + shadowMatrix: array,8>, + CameraPos: vec3, + + frame: f32, + time: f32, + delta: f32, + shadowBias: f32, + skyExposure: f32, + renderPassState:f32, + quadScale: f32, + hdrExposure: f32, + + renderState_left: i32, + renderState_right: i32, + renderState_split: f32, + + mouseX: f32, + mouseY: f32, + windowWidth: f32, + windowHeight: f32, + + near: f32, + far: f32, + + pointShadowBias: f32, + shadowMapSize: f32, + shadowSoft: f32, + }; + +struct PickResult{ + pick_meshID:f32, + pick_meshID2:f32, + pick_UV:vec2, + pick_Position:vec4, + pick_Normal:vec4, + pick_Tangent:vec4, +} + +@group(0) @binding(0) var standUniform: GlobalUniform; +@group(0) @binding(1) var outBuffer: PickResult; +@group(0) @binding(2) var visibleMap : texture_2d; + +@compute @workgroup_size( 1 ) +fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) +{ + var result:PickResult ; + // result.pick_meshID + let texSize = textureDimensions(visibleMap).xy; + let screenPoint = vec2(standUniform.mouseX/standUniform.windowWidth,standUniform.mouseY/standUniform.windowHeight); + + let mouseUV = screenPoint * vec2(texSize.xy); + let info = textureLoad(visibleMap, vec2(mouseUV) , 0); + + outBuffer.pick_meshID = f32(info.w) ; + outBuffer.pick_meshID2 = f32(info.w) ; + outBuffer.pick_Tangent = vec4(2.0,2.0,2.0,2.0) ; + outBuffer.pick_UV = vec2(standUniform.mouseX,standUniform.mouseY) ; + outBuffer.pick_Position = vec4(info.xyzw) ; + outBuffer.pick_Normal = vec4(info.xyzw) ; +} \ No newline at end of file diff --git a/src/assets/shader/materials/compute/SSAO_CsShader.wgsl b/src/assets/shader/materials/compute/SSAO_CsShader.wgsl new file mode 100644 index 00000000..da8b0ac8 --- /dev/null +++ b/src/assets/shader/materials/compute/SSAO_CsShader.wgsl @@ -0,0 +1,99 @@ + + + #include "GlobalUniform" + + struct UniformData { + radius: f32 , + bias: f32, + aoPower: f32 , + blurSize: f32 , + }; + + @group(0) @binding(0) var standUniform: GlobalUniform; + @group(0) @binding(1) var uniformData: UniformData; + @group(0) @binding(2) var sampleData: array>; + + // @group(0) @binding(3) var colorMap : texture_2d; + @group(0) @binding(3) var positionMap : texture_2d; + @group(0) @binding(4) var normalMap : texture_2d; + + @group(0) @binding(5) var noiseMapSampler: sampler; + @group(0) @binding(6) var noiseMap : texture_2d; + + @group(0) @binding(7) var outTex : texture_storage_2d; + + var kernelSize: i32 = 32 ; + + @compute @workgroup_size( 8 , 8 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + var fragCoord = vec2( globalInvocation_id.xy ); + + var texSize = textureDimensions(positionMap).xy; + var texCoord = vec2(fragCoord) / vec2(texSize); + + var fragColor = vec4(1.0); + + var viewMat = standUniform.viewMat ; + // var color = textureLoad(colorMap, fragCoord , 0 ) ; + var wPos = textureLoad(positionMap, fragCoord , 0 ) ; + + var fragPosition = viewMat * vec4(wPos.xyz,1.0); + fragPosition = vec4(fragPosition.xyz / fragPosition.w,1.0) ; + + var texNormal = textureLoad(normalMap, fragCoord , 0 ) ; + var sampleNormal = texNormal.xyz ; + sampleNormal = sampleNormal * 2.0 - 1.0; + var fragNormal = viewMat * vec4((sampleNormal.xyz),0.0); + + var pes = vec2(texSize.xy) / 4.0 ; + var noiseTex:vec4 = textureSampleLevel(noiseMap, noiseMapSampler, texCoord * pes , 0.0); + var randomVec = (viewMat * vec4(normalize(noiseTex.xyz),0.0)).xyz; + + var tangent = normalize(randomVec - fragNormal.xyz * dot(randomVec , fragNormal.xyz)); + var bTangent = cross(fragNormal.xyz, tangent) + 0.0001 ; + var tbn = mat3x3(tangent, bTangent, fragNormal.xyz); + + var offset:vec4; + var samplePos :vec3; + var offsetPosition:f32; + var sample_depth_v:vec4; + var occlusion:f32 = 0.0; + var rangeCheck:f32 = 0.0 ; + var radius:f32 = uniformData.radius * 32.0 * fragPosition.z ; + + for(var i:i32 = 0; i < 32 ; i = i + 1 ){ + samplePos = (tbn * sampleData[i].xyz ) ; + samplePos = fragPosition.xyz + samplePos * radius ; + + offset = vec4(samplePos, 1.0); + offset = standUniform.projMat * offset; + + var off = offset.xyz / offset.w; + off = (off.xyz * 0.5 ) + 0.5 ; + off.y = 1.0 - off.y ; + var offsetUV = vec2(off.xy * vec2(texSize.xy)); + + sample_depth_v = textureLoad(positionMap, offsetUV.xy , 0 ) ; + sample_depth_v = vec4((viewMat * vec4(sample_depth_v.xyz,1.0)).xyz,1.0); + offsetPosition = sample_depth_v.z / sample_depth_v.w ; + + rangeCheck = smoothstep(0.0, 1.0, radius / abs(offsetPosition - fragPosition.z )); + // rangeCheck = smoothstep(0.0, 1.0, radius / uniformData.bias); + + var a = 1.0 ; + if(offsetPosition >= (samplePos.z + uniformData.bias)){ + a = 0.0 ; + } + a = a * rangeCheck ; + occlusion = occlusion + a ; + } + + occlusion = 1.0 - ( occlusion / f32(kernelSize) * texNormal.w ); + occlusion = pow(occlusion, uniformData.aoPower) ; + + // color = color * occlusion ; + + textureStore(outTex, fragCoord , vec4(occlusion)); + } + diff --git a/src/assets/shader/materials/compute/SSR_BlendColor_Shader.wgsl b/src/assets/shader/materials/compute/SSR_BlendColor_Shader.wgsl new file mode 100644 index 00000000..e6d6e3df --- /dev/null +++ b/src/assets/shader/materials/compute/SSR_BlendColor_Shader.wgsl @@ -0,0 +1,45 @@ + + + @group(0) @binding(0) var rayTraceBuffer : array; + @group(0) @binding(1) var colorMap : texture_2d; + @group(0) @binding(2) var ssrMapSampler : sampler; + @group(0) @binding(3) var ssrMap : texture_2d; + @group(0) @binding(4) var outTex : texture_storage_2d; + + var colorTexSize: vec2; + var ssrTexSize: vec2; + var fragCoord: vec2; + var ssrCoord: vec2; + + struct RayTraceRetData{ + skyColor:vec3, + roughness:f32, + + hitCoord:vec2, + alpha:f32, + fresnel:f32, + } + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + colorTexSize = textureDimensions(colorMap).xy; + ssrTexSize = textureDimensions(ssrMap).xy; + if(fragCoord.x >= i32(colorTexSize.x) || fragCoord.y >= i32(colorTexSize.y)){ + return; + } + let scale:f32 = f32(ssrTexSize.x) / f32(colorTexSize.x); + ssrCoord = vec2(vec2(fragCoord.xy) * scale); + let index = ssrCoord.x + ssrCoord.y * i32(ssrTexSize.x); + let hitData = rayTraceBuffer[index]; + var color = textureLoad(colorMap, fragCoord , 0); + var uv01 = vec2(f32(fragCoord.x), f32(fragCoord.y)); + uv01 = uv01 / vec2(colorTexSize - 1); + + var ssrColor = textureSampleLevel(ssrMap, ssrMapSampler, uv01, 0.0); + var tc = mix(color, ssrColor, hitData.fresnel) ; + var outColor = tc ; + outColor.a = color.a ; + textureStore(outTex, fragCoord , outColor ); + } diff --git a/src/assets/shader/materials/compute/SSR_IS_Shader.wgsl b/src/assets/shader/materials/compute/SSR_IS_Shader.wgsl new file mode 100644 index 00000000..e110ad1b --- /dev/null +++ b/src/assets/shader/materials/compute/SSR_IS_Shader.wgsl @@ -0,0 +1,82 @@ + + + struct SSRUniformData { + ssrBufferSizeX: f32, + ssrBufferSizeY: f32, + colorMapSizeX: f32, + colorMapSizeY: f32, + + fadeEdgeRatio: f32, + rayMarchRatio: f32, + fadeDistanceMin: f32, + fadeDistanceMax: f32, + + mixThreshold: f32, + roughnessThreshold: f32, + reflectionRatio: f32, + powDotRN: f32, + + randomSeedX: f32, + randomSeedY: f32, + slot1: f32, + slot2: f32, + }; + + struct RayTraceRetData{ + skyColor:vec3, + roughness:f32, + + hitCoord:vec2, + alpha:f32, + fresnel:f32, + } + + @group(0) @binding(0) var ssrUniform: SSRUniformData; + @group(0) @binding(1) var rayTraceBuffer : array; + @group(0) @binding(2) var ssrColorData : array>; + @group(0) @binding(3) var historyPosition : array>; + + @group(0) @binding(4) var colorMap: texture_2d; + @group(0) @binding(5) var outTex : texture_storage_2d; + + var ssrBufferCoord: vec2; + var colorTexSize: vec2; + var bufferData: RayTraceRetData; + var ssrBufferSize: vec2; + var coordIndex: i32; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + ssrBufferCoord = vec2( globalInvocation_id.xy ); + ssrBufferSize = vec2(i32(ssrUniform.ssrBufferSizeX), i32(ssrUniform.ssrBufferSizeY)); + colorTexSize = vec2(i32(ssrUniform.colorMapSizeX), i32(ssrUniform.colorMapSizeY)); + + if(ssrBufferCoord.x >= ssrBufferSize.x || ssrBufferCoord.y >= ssrBufferSize.y){ + return; + } + + coordIndex = ssrBufferCoord.x + ssrBufferCoord.y * ssrBufferSize.x; + bufferData = rayTraceBuffer[coordIndex]; + var oc = vec4(0.0, 0.0, 0.0, -1.0); + + var mixFactor = historyPosition[coordIndex].w; + + if(bufferData.alpha >= 0.0 && bufferData.roughness < ssrUniform.roughnessThreshold){ + let roughness = clamp(bufferData.roughness, 0.0, 1.0); + let prefilterColor = bufferData.skyColor; + var ssrColor = textureLoad(colorMap, vec2(bufferData.hitCoord), 0); + ssrColor.w = bufferData.alpha; + oc = ssrColor; + } + let skyColor = vec4(bufferData.skyColor, 1.0); + oc = mix(oc, skyColor, 1.0 - bufferData.alpha); + + let lastColor = ssrColorData[coordIndex]; + var newColor = mix(oc, lastColor, mixFactor); + newColor.w = oc.w; + + ssrColorData[coordIndex] = newColor; + + textureStore(outTex, ssrBufferCoord , newColor); + } diff --git a/src/assets/shader/materials/compute/SSR_RayTrace_Shader.wgsl b/src/assets/shader/materials/compute/SSR_RayTrace_Shader.wgsl new file mode 100644 index 00000000..cc3d8261 --- /dev/null +++ b/src/assets/shader/materials/compute/SSR_RayTrace_Shader.wgsl @@ -0,0 +1,315 @@ + + + #include "GlobalUniform" + + struct SSRUniformData { + ssrBufferSizeX: f32, + ssrBufferSizeY: f32, + colorMapSizeX: f32, + colorMapSizeY: f32, + + fadeEdgeRatio: f32, + rayMarchRatio: f32, + fadeDistanceMin: f32, + fadeDistanceMax: f32, + + mixThreshold: f32, + roughnessThreshold: f32, + reflectionRatio: f32, + powDotRN: f32, + + randomSeedX: f32, + randomSeedY: f32, + slot1: f32, + slot2: f32, + }; + + struct HitData{ + hitPos:vec3, + hitNormal:vec3, + fadeAlpha:vec4, + hitCoord:vec2, + hitResult:i32, + hitSky:i32, + }; + + struct RayTraceRetData{ + skyColor:vec3, + roughness:f32, + + hitCoord:vec2, + alpha:f32, + fresnel:f32, + } + + @group(0) @binding(0) var standUniform: GlobalUniform; + @group(0) @binding(1) var ssrUniform: SSRUniformData; + @group(0) @binding(2) var rayTraceBuffer : array; + @group(0) @binding(4) var historyPosition : array>; + + @group(0) @binding(5) var zBufferTexture : texture_2d; + @group(0) @binding(6) var normalBufferTex : texture_2d; + @group(0) @binding(7) var materialBufferTex : texture_2d; + @group(0) @binding(8) var prefilterMapSampler: sampler; + @group(0) @binding(9) var prefilterMap: texture_cube; + + var rayOrigin: vec3; + var rayDirection: vec3; + var cameraPosition: vec3; + var reflectionDir: vec3; + var colorTexSize: vec2; + var fragCoordColor: vec2; + var ssrBufferCoord: vec2; + var ssrBufferSize: vec2; + var hitData: HitData; + var rayTraceRet: RayTraceRetData; + var worldPosition: vec3; + var worldNormal: vec3; + var roughness: f32; + var fresnel: f32; + + var historyPos: vec3; + var coordIndex: i32; + + var PI: f32 = 3.14159; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + ssrBufferCoord = vec2( globalInvocation_id.xy); + ssrBufferSize = vec2(i32(ssrUniform.ssrBufferSizeX), i32(ssrUniform.ssrBufferSizeY)); + if(ssrBufferCoord.x >= ssrBufferSize.x || ssrBufferCoord.y >= ssrBufferSize.y){ + return; + } + coordIndex = ssrBufferCoord.x + ssrBufferCoord.y * ssrBufferSize.x; + + colorTexSize = vec2(i32(ssrUniform.colorMapSizeX), i32(ssrUniform.colorMapSizeY)); + fragCoordColor = convertColorCoordFromSSRCoord(ssrBufferCoord); + + hitData.fadeAlpha = vec4(0.0); + hitData.hitCoord = vec2(0); + hitData.hitResult = 0; + hitData.hitNormal = vec3(0.0, 1.0, 0.0); + hitData.hitSky = 1; + + worldPosition = textureLoad(zBufferTexture, fragCoordColor , 0).xyz; + historyPos = historyPosition[coordIndex].xyz; + + var mixFactor = 0.2; + if(length(historyPos - worldPosition) < ssrUniform.mixThreshold){ + mixFactor = 0.9; + } + historyPosition[coordIndex] = vec4(worldPosition, mixFactor); + + let normal_v4 = textureLoad(normalBufferTex, fragCoordColor , 0); + worldNormal = normalize(vec3(normal_v4.xyz) * 2.0 - 1.0); + let materialData = textureLoad(materialBufferTex, fragCoordColor , 0 ); + let roughness = materialData.g * (1.0 - materialData.b); + fresnel = (1.0 - roughness) * ssrUniform.reflectionRatio; + + cameraPosition = vec3(standUniform.cameraWorldMatrix[3].xyz); + rayOrigin = vec3(worldPosition.xyz); + + rayDirection = normalize(vec3(worldPosition.xyz - cameraPosition)); + + var randomSeed = fract(ssrUniform.randomSeedX + worldPosition.x); + rand_seed.x = randomSeed; + rand_seed.y = fract(ssrUniform.randomSeedY + worldPosition.y + worldPosition.z); + randomSeed = rand(); + + let normalRandom = makeRandomDirection(worldNormal, u32(randomSeed * 256.0), 256, roughness); + + reflectionDir = normalize(reflect(rayDirection, normalRandom)); + + if(normal_v4.w > 0.5 && roughness < ssrUniform.roughnessThreshold){ + let uvOrigin = vec2(f32(fragCoordColor.x), f32(fragCoordColor.y)); + let rayMarchPosition = rayOrigin + reflectionDir * 100.0; + var uvRayMarch = standUniform.projMat * (standUniform.viewMat * vec4(rayMarchPosition, 1.0)); + var uvOffset = (vec2(uvRayMarch.xy / uvRayMarch.w) + 1.0) * 0.5; + uvOffset.y = 1.0 - uvOffset.y; + uvOffset = uvOffset * vec2(colorTexSize - 1) - uvOrigin; + uvOffset = normalize(uvOffset); + + rayTrace(uvOffset); + if(hitData.hitResult == 1){ + hidingArtifact(); + rayTraceRet.alpha = hitData.fadeAlpha.x * hitData.fadeAlpha.y * hitData.fadeAlpha.z * hitData.fadeAlpha.w; + if(hitData.hitSky == 1){ + rayTraceRet.alpha = 0.0; + } + }else{ + rayTraceRet.alpha = 0.0; + } + rayTraceRet.skyColor = getSkyColor(); + }else{ + rayTraceRet.alpha = -1.0; + rayTraceRet.skyColor = vec3(0.0); + } + + rayTraceRet.roughness = roughness; + rayTraceRet.fresnel = fresnel; + rayTraceRet.hitCoord = vec2(hitData.hitCoord); + + let index:i32 = ssrBufferCoord.x + ssrBufferCoord.y * ssrBufferSize.x; + rayTraceBuffer[index] = rayTraceRet; + } + +fn makeRandomDirection(srcDirection:vec3, i:u32, SAMPLE_COUNT:u32, roughness:f32) -> vec3 +{ + var N: vec3 = normalize(srcDirection); + var Xi:vec2 = hammersley(i, SAMPLE_COUNT); + return ImportanceSampleGGX(Xi, N, roughness); +} + +fn hammersley( i : u32 , N : u32 ) -> vec2 +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + var bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + var rdi = f32(bits) * 2.3283064365386963e-10; + return vec2(f32(i) /f32(N), rdi); +} + +fn ImportanceSampleGGX( Xi:vec2, N:vec3, roughness:f32) ->vec3 +{ + var a = roughness*roughness; + + var phi = 2.0 * PI * Xi.x; + var cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + var sinTheta = sqrt(1.0 - cosTheta*cosTheta); + + // from spherical coordinates to cartesian coordinates + var H:vec3; + H.x = cos(phi) * sinTheta; + H.y = sin(phi) * sinTheta; + H.z = cosTheta; + + // from tangent-space vector to world-space sample vector + var up:vec3; + if(abs(N.z) < 0.999) + { + up = vec3(0.0, 0.0, 1.0); + } + else + { + up = vec3(1.0, 0.0, 0.0); + } + var tangent:vec3 = normalize(cross(up, N)); + var bitangent:vec3 = cross(N, tangent); + var sampleVec:vec3 = tangent * H.x + bitangent * H.y + N * H.z; + return normalize(sampleVec); +} + + var rand_seed :vec2 = vec2(0.0); + fn rand() -> f32 { + rand_seed.x = fract(cos(dot(rand_seed, vec2(23.14077926, 232.61690225))) * 136.8168); + rand_seed.y = fract(cos(dot(rand_seed, vec2(54.47856553, 345.84153136))) * 534.7645); + return rand_seed.y; + } + + fn getSkyColor() -> vec3{ + let calcRoughness = clamp(roughness, 0.0, 1.0); + let MAX_REFLECTION_LOD = f32(textureNumLevels(prefilterMap)) ; + var prefilterColor = textureSampleLevel(prefilterMap, prefilterMapSampler, reflectionDir, calcRoughness * MAX_REFLECTION_LOD); + return LinearToGammaSpace(vec3(prefilterColor.xyz)) * standUniform.skyExposure; + } + + fn LinearToGammaSpace(linRGB: vec3) -> vec3 { + var linRGB1 = max(linRGB, vec3(0.0)); + linRGB1 = pow(linRGB1, vec3(0.4166666567325592)); + return max(((1.0549999475479126 * linRGB1) - vec3(0.054999999701976776)), vec3(0.0)); + } + + fn convertColorCoordFromSSRCoord(coord:vec2) -> vec2{ + let color_ssr_ratio = ssrUniform.colorMapSizeX / ssrUniform.ssrBufferSizeX; + let targetCoord = vec2(coord) * color_ssr_ratio; + return vec2(targetCoord); + } + + fn hidingArtifact(){ + let texSizeF32 = vec2(f32(colorTexSize.x), f32(colorTexSize.y)); + let halfTexSizeF32 = texSizeF32 * 0.5; + + //near screen edge + var distance2Center = abs(vec2(f32(hitData.hitCoord.x), f32(hitData.hitCoord.y)) - halfTexSizeF32); + let halfEdgeSize:f32 = min(texSizeF32.x, texSizeF32.y) * clamp(0.01, ssrUniform.fadeEdgeRatio, 1.0) * 0.5; + var distance2Edge = min(vec2(halfEdgeSize), halfTexSizeF32 - distance2Center); + var ratioXY = distance2Edge / halfEdgeSize; + hitData.fadeAlpha.x = sqrt(ratioXY.x * ratioXY.y); + + //back face hit + var backFaceBias = max(0.0, dot(hitData.hitNormal, -reflectionDir)); + hitData.fadeAlpha.y = pow(backFaceBias, max(0.0001, ssrUniform.powDotRN)); + + //screen distance ratio + let maxLength = max(f32(colorTexSize.x), f32(colorTexSize.y)) * ssrUniform.rayMarchRatio; + let screenPointer = hitData.hitCoord - fragCoordColor; + var screenDistance = length(vec2(f32(screenPointer.x), f32(screenPointer.y))); + screenDistance = clamp(screenDistance / maxLength, 0.0, 1.0); + hitData.fadeAlpha.z = 1.0 - screenDistance; + + //position distance ratio + var fadeDistance = length(vec3(hitData.hitPos - cameraPosition)); + var dFar = ssrUniform.fadeDistanceMax; + var dNear = ssrUniform.fadeDistanceMin; + dFar = max(1.0, dFar); + dNear = clamp(dNear, 0.001, dFar - 0.001); + fadeDistance = clamp(fadeDistance, dNear, dFar); + fadeDistance = (fadeDistance - dNear) / (dFar - dNear); + hitData.fadeAlpha.w = 1.0 - fadeDistance; + } + + fn rayTrace(rayMarchDir:vec2){ + let stepLength = 4.0; + let maxLength = max(f32(colorTexSize.x), f32(colorTexSize.y)) * ssrUniform.rayMarchRatio; + for(var i:f32 = 1.0; i < maxLength; i = i + stepLength){ + let offsetFloat32 = i * rayMarchDir; + var uv = fragCoordColor + vec2(i32(offsetFloat32.x), i32(offsetFloat32.y)); + let hitRet = rayInterestScene(uv); + if(hitRet > 0){ + hitData.hitResult = hitRet; + break; + } + } + if(hitData.hitResult == 1){ + let fromUV = hitData.hitCoord; + for(var i:f32 = -stepLength; i <= 0.0; i = i + 1.0){ + let offsetFloat32 = i * rayMarchDir; + var uv = fromUV + vec2(i32(offsetFloat32.x), i32(offsetFloat32.y)); + let hitRet = rayInterestScene(uv); + if(hitRet == 1){ + let WN = textureLoad(normalBufferTex, hitData.hitCoord , 0 ); + if(WN.w > 0.5){ + hitData.hitSky = 0; + } + let normal = vec3(WN.xyz) * 2.0 - 1.0; + hitData.hitNormal = normalize(vec3(normal.xyz)); + break; + } + } + } + } + + fn rayInterestScene(uv:vec2) -> i32 { + if(uv.x < 0 || uv.y < 0 || uv.x >= colorTexSize.x || uv.y >= colorTexSize.y){ + return 2; + }else{ + let hitPos = textureLoad(zBufferTexture, uv , 0 ); + let testDir = normalize(vec3(hitPos.xyz - rayOrigin)); + let cosValue = dot(reflectionDir, testDir); + + if(cosValue > 0.9996){ + let cross1 = cross(reflectionDir, -rayDirection); + let cross2 = cross(reflectionDir, testDir); + if(dot(cross1, cross2) > 0.0){ + hitData.hitPos = vec3(hitPos.xyz); + hitData.hitCoord = uv; + return 1; + } + } + } + return 0; + } diff --git a/src/assets/shader/materials/compute/TAACopyTex.wgsl b/src/assets/shader/materials/compute/TAACopyTex.wgsl new file mode 100644 index 00000000..4993fda2 --- /dev/null +++ b/src/assets/shader/materials/compute/TAACopyTex.wgsl @@ -0,0 +1,18 @@ + @group(0) @binding(0) var preColor : array>; + @group(0) @binding(1) var preColorTex : texture_storage_2d; + + var texSize: vec2; + var fragCoord: vec2; + var coordIndex: i32; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(preColorTex).xy; + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + coordIndex = fragCoord.x + fragCoord.y * i32(texSize.x); + textureStore(preColorTex, fragCoord , preColor[coordIndex]); + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/TAASharpTex.wgsl b/src/assets/shader/materials/compute/TAASharpTex.wgsl new file mode 100644 index 00000000..e57576c8 --- /dev/null +++ b/src/assets/shader/materials/compute/TAASharpTex.wgsl @@ -0,0 +1,41 @@ + + struct TAAData{ + preProjMatrix: mat4x4, + preViewMatrix: mat4x4, + jitterFrameIndex: f32, + blendFactor: f32, + sharpFactor: f32, + sharpPreBlurFactor: f32, + jitterX: f32, + jitterY: f32, + slot0: f32, + slot1: f32, + } + @group(0) @binding(0) var taaData: TAAData; + @group(0) @binding(1) var inTex : texture_2d; + @group(0) @binding(2) var outTex : texture_storage_2d; + + var texSize: vec2; + var fragCoord: vec2; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(outTex).xy; + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + + let c0 = textureLoad(inTex, vec2(fragCoord.x, fragCoord.y - 1), 0); + let c1 = textureLoad(inTex, vec2(fragCoord.x, fragCoord.y + 1), 0); + let c2 = textureLoad(inTex, vec2(fragCoord.x - 1, fragCoord.y), 0); + let c3 = textureLoad(inTex, vec2(fragCoord.x + 1, fragCoord.y), 0); + + var roundColor = (c0 + c1 + c2 + c3) * 0.25; + let originColor = textureLoad(inTex, fragCoord, 0); + let blurColor = mix(roundColor, originColor, taaData.sharpPreBlurFactor); + var oc = (originColor - blurColor * taaData.sharpFactor) / (1.0 - taaData.sharpFactor); + oc = clamp(oc, vec4(0.0), oc); + textureStore(outTex, fragCoord , oc); + } \ No newline at end of file diff --git a/src/assets/shader/materials/compute/TAAcs.wgsl b/src/assets/shader/materials/compute/TAAcs.wgsl new file mode 100644 index 00000000..6c82bc0a --- /dev/null +++ b/src/assets/shader/materials/compute/TAAcs.wgsl @@ -0,0 +1,155 @@ + + #include "GlobalUniform" + + struct TAAData{ + preProjMatrix: mat4x4, + preViewMatrix: mat4x4, + jitterFrameIndex: f32, + blendFactor: f32, + sharpFactor: f32, + sharpPreBlurFactor: f32, + jitterX: f32, + jitterY: f32, + slot0: f32, + slot1: f32, + } + + @group(0) @binding(0) var standUniform: GlobalUniform; + @group(0) @binding(1) var taaData: TAAData; + @group(0) @binding(2) var preColorBuffer : array>; + + @group(0) @binding(3) var preColorTexSampler : sampler; + @group(0) @binding(4) var preColorTex : texture_2d; + @group(0) @binding(5) var posTex : texture_2d; + @group(0) @binding(6) var inTexSampler : sampler; + @group(0) @binding(7) var inTex : texture_2d; + @group(0) @binding(8) var outTex : texture_storage_2d; + + var texSize: vec2; + var fragCoord: vec2; + var coordIndex: i32; + var color_min: vec4; + var color_max: vec4; + var color_avg: vec4; + var re_proj_uv01: vec2; + var FLT_EPS:f32 = 5.960464478e-8; // 2^-24, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f) + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2( globalInvocation_id.xy ); + texSize = textureDimensions(inTex).xy; + if(fragCoord.x >= i32(texSize.x) || fragCoord.y >= i32(texSize.y)){ + return; + } + let frame = standUniform.frame; + coordIndex = fragCoord.x + fragCoord.y * i32(texSize.x); + + let oc = blendColor(); + preColorBuffer[coordIndex] = oc; + textureStore(outTex, fragCoord , oc); + } + + fn blendColor() -> vec4 + { + var preCoord = fragCoord; + var mixWeight = 1.0; + re_proj_uv01 = vec2(0.0); + var reProjectionCoord:vec2 = vec2(fragCoord); + //var jitterUVOffset = 0.5 * vec2(taaData.jitterX, -taaData.jitterY); + if(taaData.jitterFrameIndex > 0.5){ + var wPos = textureLoad(posTex, fragCoord, 0); + let ndc = taaData.preProjMatrix * (taaData.preViewMatrix * vec4(wPos.xyz, 1.0)); + re_proj_uv01 = vec2(ndc.x, -ndc.y) / ndc.w; + re_proj_uv01 = (re_proj_uv01 + 1.0) * 0.5; + + if(re_proj_uv01.x >= 0.0 && re_proj_uv01.x <= 1.0 && re_proj_uv01.y >= 0.0 && re_proj_uv01.y <= 1.0){ + mixWeight = taaData.blendFactor; + //reProjectionCoord = re_proj_uv01 + jitterUVOffset; + reProjectionCoord.x = re_proj_uv01.x * f32(texSize.x - 1); + reProjectionCoord.y = re_proj_uv01.y * f32(texSize.y - 1); + preCoord = vec2(reProjectionCoord); + }else{ + //outside of screen + mixWeight = 1.0; + } + } + + var curUV01 = vec2(fragCoord) / vec2(texSize - 1); + //curUV01 += jitterUVOffset; + + let curColor = textureSampleLevel(inTex, inTexSampler, curUV01, 0.0); + + let preIndex = preCoord.x + preCoord.y * i32(texSize.x); + var preColor = textureSampleLevel(preColorTex, preColorTexSampler, re_proj_uv01, 0.0); + + //minmax9(fragCoord); + minmax4(fragCoord); + + preColor = clip_aabb(color_min.xyz, color_max.xyz, color_avg, preColor); + var outColor = mix(preColor, curColor, mixWeight); + + return outColor; + } + + fn clampCoord(coord0:vec2) -> vec2{ + return clamp(coord0, vec2(0), vec2(texSize - 1)); + } + + fn minmax4(coord:vec2) { + let uv0 = clampCoord(vec2(coord.x - 1, coord.y)); + let uv1 = clampCoord(vec2(coord.x, coord.y - 1)); + let uv2 = clampCoord(vec2(coord.x, coord.y + 1)); + let uv3 = clampCoord(vec2(coord.x + 1, coord.y)); + + let c0 = textureLoad(inTex, uv0, 0); + let c1 = textureLoad(inTex, uv1, 0); + let c2 = textureLoad(inTex, uv2, 0); + let c3 = textureLoad(inTex, uv3, 0); + + color_min = min(c0, min(c1, min(c2, c3))); + color_max = max(c0, max(c1, max(c2, c3))); + color_avg = (c0 + c1 + c2 + c3) * 0.25; + } + + fn minmax9(coord:vec2) { + let uv0 = clampCoord(vec2(coord.x - 1, coord.y - 1)); + let uv1 = clampCoord(vec2(coord.x - 1, coord.y)); + let uv2 = clampCoord(vec2(coord.x - 1, coord.y + 1)); + let uv3 = clampCoord(vec2(coord.x, coord.y - 1)); + let uv4 = clampCoord(vec2(coord.x, coord.y)); + let uv5 = clampCoord(vec2(coord.x, coord.y + 1)); + let uv6 = clampCoord(vec2(coord.x + 1, coord.y - 1)); + let uv7 = clampCoord(vec2(coord.x + 1, coord.y)); + let uv8 = clampCoord(vec2(coord.x + 1, coord.y + 1)); + + let ctl = textureLoad(inTex, uv0, 0); + let ctc = textureLoad(inTex, uv1, 0); + let ctr = textureLoad(inTex, uv2, 0); + let cml = textureLoad(inTex, uv3, 0); + let cmc = textureLoad(inTex, uv4, 0); + let cmr = textureLoad(inTex, uv5, 0); + let cbl = textureLoad(inTex, uv6, 0); + let cbc = textureLoad(inTex, uv7, 0); + let cbr = textureLoad(inTex, uv8, 0); + + color_min = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr)))))))); + color_max = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr)))))))); + color_avg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0; + } + + fn clip_aabb(aabb_max:vec3, aabb_min:vec3, color_avg:vec4, input_texel:vec4) -> vec4 + { + var p_clip:vec3 = 0.5 * (aabb_max + aabb_min); + var e_clip:vec3 = 0.5 * (aabb_max - aabb_min) + FLT_EPS; + var v_clip:vec4 = input_texel - vec4(p_clip, color_avg.w); + var v_unit:vec3 = v_clip.xyz / e_clip; + var a_unit:vec3 = abs(v_unit); + var ma_unit:f32 = max(a_unit.x, max(a_unit.y, a_unit.z)); + + if (ma_unit > 1.0){ + return vec4(p_clip, color_avg.w) + v_clip / ma_unit; + }else{ + return input_texel; + } + } \ No newline at end of file diff --git a/src/assets/shader/materials/core/base/Common_frag.wgsl b/src/assets/shader/materials/core/base/Common_frag.wgsl new file mode 100644 index 00000000..cf46db9c --- /dev/null +++ b/src/assets/shader/materials/core/base/Common_frag.wgsl @@ -0,0 +1,26 @@ +#include "GlobalUniform" +#include "FragmentVarying" +#include "ColorPassFragmentOutput" +#include "ShadingInput" + +var ORI_FragmentOutput: FragmentOutput; +var ORI_VertexVarying: FragmentVarying; +var ORI_ShadingInput: ShadingInput; +@fragment +fn FragMain( vertex_varying:FragmentVarying ) -> FragmentOutput { + ORI_VertexVarying = vertex_varying; + ORI_FragmentOutput.color = vec4(1.0, 0.0, 0.0, 1.0); + #if USE_WORLDPOS + ORI_FragmentOutput.worldPos = ORI_VertexVarying.vWorldPos; + #endif + #if USEGBUFFER + ORI_FragmentOutput.worldNormal = vec4(ORI_ShadingInput.Normal.rgb ,1.0); + ORI_FragmentOutput.material = vec4(0.0,1.0,0.0,0.0); + #endif + frag(); + #if USE_DEBUG + debugFragmentOut(); + #endif + + return ORI_FragmentOutput ; +} diff --git a/src/assets/shader/materials/core/base/Common_vert.wgsl b/src/assets/shader/materials/core/base/Common_vert.wgsl new file mode 100644 index 00000000..e5b674ae --- /dev/null +++ b/src/assets/shader/materials/core/base/Common_vert.wgsl @@ -0,0 +1,11 @@ +#include "WorldMatrixUniform" +#include "VertexAttributes_vert" +#include "GlobalUniform" +#include "Inline_vert" +@vertex +fn VertMain( vertex:VertexAttributes ) -> VertexOutput { + vertex_inline(vertex); + vert(vertex); + return ORI_VertexOut ; +} + diff --git a/src/assets/shader/materials/core/common/BrdfLut_frag.wgsl b/src/assets/shader/materials/core/common/BrdfLut_frag.wgsl new file mode 100644 index 00000000..6a10ea79 --- /dev/null +++ b/src/assets/shader/materials/core/common/BrdfLut_frag.wgsl @@ -0,0 +1,4 @@ +@group(1) @binding(auto) +var brdflutMapSampler: sampler; +@group(1) @binding(auto) +var brdflutMap: texture_2d; \ No newline at end of file diff --git a/src/assets/shader/materials/core/common/EnvMap_frag.wgsl b/src/assets/shader/materials/core/common/EnvMap_frag.wgsl new file mode 100644 index 00000000..a26b3e5e --- /dev/null +++ b/src/assets/shader/materials/core/common/EnvMap_frag.wgsl @@ -0,0 +1,9 @@ + +@group(1) @binding(auto) +var prefilterMapSampler: sampler; +@group(1) @binding(auto) +var prefilterMap: texture_cube; +@group(1) @binding(auto) +var envMapSampler: sampler; +@group(1) @binding(auto) +var envMap: texture_cube; \ No newline at end of file diff --git a/src/assets/shader/materials/core/common/GlobalUniform.wgsl b/src/assets/shader/materials/core/common/GlobalUniform.wgsl new file mode 100644 index 00000000..8cd5e057 --- /dev/null +++ b/src/assets/shader/materials/core/common/GlobalUniform.wgsl @@ -0,0 +1,37 @@ + + struct GlobalUniform { + projMat: mat4x4, + viewMat: mat4x4, + cameraWorldMatrix: mat4x4, + pvMatrixInv : mat4x4, + shadowMatrix: array,8>, + CameraPos: vec3, + + frame: f32, + time: f32, + delta: f32, + shadowBias: f32, + skyExposure: f32, + renderPassState:f32, + quadScale: f32, + hdrExposure: f32, + + renderState_left: i32, + renderState_right: i32, + renderState_split: f32, + + mouseX: f32, + mouseY: f32, + windowWidth: f32, + windowHeight: f32, + + near: f32, + far: f32, + + pointShadowBias: f32, + shadowMapSize: f32, + shadowSoft: f32, + }; + + @group(0) @binding(0) + var globalUniform: GlobalUniform; diff --git a/src/assets/shader/materials/core/common/InstanceUniform.wgsl b/src/assets/shader/materials/core/common/InstanceUniform.wgsl new file mode 100644 index 00000000..b3b943e4 --- /dev/null +++ b/src/assets/shader/materials/core/common/InstanceUniform.wgsl @@ -0,0 +1,7 @@ +#if USE_INSTANCEDRAW + struct InstanceUniform { + matrixIDs : array + }; + @group(2) @binding(7) + var instanceDrawID : InstanceUniform; +#endif \ No newline at end of file diff --git a/src/assets/shader/materials/core/common/WorldMatrixUniform.wgsl b/src/assets/shader/materials/core/common/WorldMatrixUniform.wgsl new file mode 100644 index 00000000..2f61b771 --- /dev/null +++ b/src/assets/shader/materials/core/common/WorldMatrixUniform.wgsl @@ -0,0 +1,9 @@ + + struct Uniforms { + matrix : array> + }; + + @group(0) @binding(1) + var models : Uniforms; + + diff --git a/src/assets/shader/materials/core/inline/Inline_vert.wgsl b/src/assets/shader/materials/core/inline/Inline_vert.wgsl new file mode 100644 index 00000000..d3ce06cf --- /dev/null +++ b/src/assets/shader/materials/core/inline/Inline_vert.wgsl @@ -0,0 +1,49 @@ + + #include "MathShader" + #include "FastMathShader" + #include "InstanceUniform" + + var ORI_MATRIX_P: mat4x4; + var ORI_MATRIX_V: mat4x4; + var ORI_MATRIX_M: mat4x4; + var ORI_MATRIX_PV: mat4x4; + var ORI_MATRIX_PVInv: mat4x4; + var ORI_MATRIX_World: mat4x4; + var ORI_CAMERAMATRIX: mat4x4; + var ORI_NORMALMATRIX: mat3x3; + var ORI_CameraWorldDir: vec3; + + var TIME: vec4; + var MOUSE: vec4; + var SCREEN: vec4; + + var ProjectionParams: vec4; + + fn vertex_inline(vertex:VertexAttributes){ + TIME.x = globalUniform.frame; + TIME.y = globalUniform.time; + TIME.z = globalUniform.delta; + + MOUSE.x = globalUniform.mouseX; + MOUSE.y = globalUniform.mouseY; + + SCREEN.x = globalUniform.windowWidth; + SCREEN.y = globalUniform.windowHeight; + + ProjectionParams.x = globalUniform.near; + ProjectionParams.y = globalUniform.far; + ProjectionParams.z = 1.0 + 1.0 / globalUniform.far; + + ORI_MATRIX_P = globalUniform.projMat ; + ORI_MATRIX_V = globalUniform.viewMat ; + ORI_MATRIX_PV = ORI_MATRIX_P * ORI_MATRIX_V ; + ORI_MATRIX_PVInv = globalUniform.pvMatrixInv ; + ORI_CAMERAMATRIX = globalUniform.cameraWorldMatrix ; + + ORI_MATRIX_M = models.matrix[u32(vertex.index)]; + + #if USE_INSTANCEDRAW + let modelID = instanceDrawID.matrixIDs[vertex.index]; + ORI_MATRIX_M = models.matrix[modelID]; + #endif + } \ No newline at end of file diff --git a/src/assets/shader/materials/graphic/Graphic3DShader_fs.wgsl b/src/assets/shader/materials/graphic/Graphic3DShader_fs.wgsl new file mode 100644 index 00000000..f0b039eb --- /dev/null +++ b/src/assets/shader/materials/graphic/Graphic3DShader_fs.wgsl @@ -0,0 +1,30 @@ +struct FragmentOutput { + @location(0) color: vec4, + // #if USE_WORLDPOS + @location(1) worldPos: vec4, + // #endif + // #if USEGBUFFER + @location(2) worldNormal: vec4, + @location(3) material: vec4 + // #endif +}; + +@fragment +fn main( + @location(0) vWorldPos: vec4, + @location(1) varying_Color: vec4, +) -> FragmentOutput { + var result: FragmentOutput; + + // #if USE_WORLDPOS + result.worldPos = vWorldPos; + // #endif + + // #if USEGBUFFER + // result.worldNormal = vec4(0.0, 0.0, 0.0, 1.0); + result.material = vec4(0.0, 1.0, 0.0, 0.0); + // #endif + + result.color = varying_Color; + return result; +} diff --git a/src/assets/shader/materials/graphic/Graphic3DShader_vs.wgsl b/src/assets/shader/materials/graphic/Graphic3DShader_vs.wgsl new file mode 100644 index 00000000..336abcde --- /dev/null +++ b/src/assets/shader/materials/graphic/Graphic3DShader_vs.wgsl @@ -0,0 +1,27 @@ +#include "WorldMatrixUniform" +#include "GlobalUniform" + +struct VertexAttributes { + @location(0) position: vec4, + @location(1) color: vec4, +} + +struct VertexOutput { + @location(0) varying_WPos: vec4, + @location(1) varying_Color: vec4, + @builtin(position) member: vec4 +}; + +@vertex +fn main( vertex:VertexAttributes ) -> VertexOutput { + var worldMatrix = models.matrix[u32(vertex.position.w)]; + var worldPos = (worldMatrix * vec4(vertex.position.xyz, 1.0)); + var viewPosition = ((globalUniform.viewMat) * worldPos); + var clipPosition = globalUniform.projMat * viewPosition; + + var ORI_VertexOut: VertexOutput; + ORI_VertexOut.varying_WPos = worldPos; + ORI_VertexOut.varying_Color = vertex.color; + ORI_VertexOut.member = clipPosition; + return ORI_VertexOut; +} diff --git a/src/assets/shader/materials/materials/GlassShader.wgsl b/src/assets/shader/materials/materials/GlassShader.wgsl new file mode 100644 index 00000000..19e5b95d --- /dev/null +++ b/src/assets/shader/materials/materials/GlassShader.wgsl @@ -0,0 +1,36 @@ + + #include "Common_vert" + #include "Common_frag" + #include "UnLit_frag" + #include "UnLitMaterialUniform_frag" + + // @group(1) @binding(auto) + // var noes_MapSampler: sampler; + // @group(1) @binding(auto) + // var noes_Map: texture_2d; + + @group(1) @binding(auto) + var splitTexture_MapSampler: sampler; + @group(1) @binding(auto) + var splitTexture_Map: texture_2d; + + fn vert(inputData:VertexAttributes) -> VertexOutput { + ORI_Vert(inputData) ; + return ORI_VertexOut ; + } + + fn frag(){ + var screenUV = ORI_VertexVarying.fragPosition.xy / ORI_VertexVarying.fragPosition.w; + screenUV = (screenUV.xy + 1.0) * 0.5; + screenUV.y = 1.0 - screenUV.y; + + screenUV.x = clamp(sin(screenUV.x * 1.0),0.0,1.0) ; + screenUV.y = clamp(sin(screenUV.y * 1.0),0.0,1.0) ; + // screenUV.y = cos(ORI_VertexVarying.fragPosition.y/7.15); + + let frameMap = textureSample(splitTexture_Map,splitTexture_MapSampler,screenUV); + // let noesMap = textureSample(noes_Map,noes_MapSampler,screenUV); + + ORI_ShadingInput.BaseColor = vec4( frameMap.rgb , 1.0) ; + UnLit(); + } diff --git a/src/assets/shader/materials/materials/LitShader.wgsl b/src/assets/shader/materials/materials/LitShader.wgsl new file mode 100644 index 00000000..7e9aad9c --- /dev/null +++ b/src/assets/shader/materials/materials/LitShader.wgsl @@ -0,0 +1,22 @@ + + #include "Common_vert" + #include "Common_frag" + #include "BxDF_frag" + + fn vert(inputData:VertexAttributes) -> VertexOutput { + ORI_Vert(inputData) ; + return ORI_VertexOut ; + } + + fn frag(){ + ORI_ShadingInput.BaseColor = materialUniform.baseColor ; + ORI_ShadingInput.Roughness = materialUniform.roughness ; + ORI_ShadingInput.Metallic = materialUniform.metallic ; + ORI_ShadingInput.Specular = 0.5 ; + ORI_ShadingInput.AmbientOcclusion = materialUniform.ao ; + ORI_ShadingInput.EmissiveColor = vec4(0.0); + + ORI_ShadingInput.Normal = ORI_VertexVarying.vWorldNormal.rgb ; + + BxDFShading(); + } diff --git a/src/assets/shader/materials/materials/OutlinePass.wgsl b/src/assets/shader/materials/materials/OutlinePass.wgsl new file mode 100644 index 00000000..028cc2c4 --- /dev/null +++ b/src/assets/shader/materials/materials/OutlinePass.wgsl @@ -0,0 +1,80 @@ + #include "Common_vert" + #include "Common_frag" + #include "UnLit_frag" + + @group(1) @binding(0) + var baseMapSampler: sampler; + @group(1) @binding(1) + var baseMap: texture_2d; + + +struct MaterialUniform { + baseColor:vec4, + lineWeight:f32 +}; + +@group(2) @binding(0) +var materialUniform: MaterialUniform; + + fn vert(vertex:VertexAttributes) -> VertexOutput { + var vertexPosition = vertex.position; + var vertexNormal = vertex.normal; + + #if USE_MORPHTARGETS + vertexPosition = vertexPosition * morphTargetData.morphBaseInfluence + vertex.a_morphPositions_0 * morphTargetData.morphInfluence0; + #if USE_MORPHNORMALS + vertexNormal = vertexNormal * morphTargetData.morphBaseInfluence + vertex.a_morphNormals_0 * morphTargetData.morphInfluence0; + #endif + #endif + + #if USE_SKELETON + #if USE_JOINT_VEC8 + let skeletonNormal = getSkeletonWorldMatrix_8(vertex.joints0, vertex.weights0, vertex.joints1, vertex.weights1); + ORI_MATRIX_M *= skeletonNormal ; + // vertexNormal = vec4(vec4(vertexNormal,0.0) * skeletonNormal).xyz; + #else + let skeletonNormal = getSkeletonWorldMatrix_4(vertex.joints0, vertex.weights0); + ORI_MATRIX_M *= skeletonNormal ; + // vertexNormal = vec4(vec4(vertexNormal,0.0) * skeletonNormal).xyz; + #endif + #endif + + + #if USE_TANGENT + ORI_VertexOut.varying_Tangent = vertex.TANGENT ; + #endif + + ORI_NORMALMATRIX = transpose(inverse( mat3x3(ORI_MATRIX_M[0].xyz,ORI_MATRIX_M[1].xyz,ORI_MATRIX_M[2].xyz) )); + + let worldNormal = normalize(ORI_NORMALMATRIX * vertexNormal.xyz) ; + + vertexPosition = vertexPosition + worldNormal * materialUniform.lineWeight ; + + var worldPos = (ORI_MATRIX_M * vec4(vertexPosition.xyz, 1.0)); + var viewPosition = ORI_MATRIX_V * worldPos; + var clipPosition = ORI_MATRIX_P * viewPosition ; + + ORI_VertexOut.varying_UV0 = vertex.uv.xy ; + ORI_VertexOut.varying_UV1 = vertex.TEXCOORD_1.xy; + ORI_VertexOut.varying_ViewPos = viewPosition / viewPosition.w; + ORI_VertexOut.varying_Clip = clipPosition ; + ORI_VertexOut.varying_WPos = worldPos ; + ORI_VertexOut.varying_WPos.w = f32(vertex.index); + ORI_VertexOut.varying_WNormal = worldNormal ; + ORI_VertexOut.member = clipPosition ; + + + return ORI_VertexOut ; + } + + fn frag(){ + let color = textureSample(baseMap,baseMapSampler,ORI_VertexVarying.fragUV0) ; + ORI_ShadingInput.BaseColor = color * materialUniform.baseColor ; + ORI_ShadingInput.Roughness = 0.5 ; + ORI_ShadingInput.Metallic = 0.5 ; + ORI_ShadingInput.Specular = 0.5 ; + ORI_ShadingInput.AmbientOcclusion = 1.0 ; + ORI_ShadingInput.EmissiveColor = vec4(0.0); + ORI_ShadingInput.Normal = ORI_VertexVarying.vWorldNormal.rgb ; + UnLit(); + } \ No newline at end of file diff --git a/src/assets/shader/materials/materials/PBRLItShader.wgsl b/src/assets/shader/materials/materials/PBRLItShader.wgsl new file mode 100644 index 00000000..228dac62 --- /dev/null +++ b/src/assets/shader/materials/materials/PBRLItShader.wgsl @@ -0,0 +1,106 @@ + + #include "Common_vert" + #include "Common_frag" + #include "BxDF_frag" + + @group(1) @binding(auto) + var baseMapSampler: sampler; + @group(1) @binding(auto) + var baseMap: texture_2d; + + @group(1) @binding(auto) + var normalMapSampler: sampler; + @group(1) @binding(auto) + var normalMap: texture_2d; + + #if USE_ARMC + @group(1) @binding(auto) + var maskMapSampler: sampler; + @group(1) @binding(auto) + var maskMap: texture_2d; + #endif + + #if USE_AOTEX + @group(1) @binding(auto) + var aoMapSampler: sampler; + @group(1) @binding(auto) + var aomapMap: texture_2d; + #endif + + @group(1) @binding(auto) + var emissiveMapSampler: sampler; + @group(1) @binding(auto) + var emissiveMap: texture_2d; + + fn vert(inputData:VertexAttributes) -> VertexOutput { + ORI_Vert(inputData) ; + return ORI_VertexOut ; + } + + fn frag(){ + var transformUV1 = materialUniform.transformUV1; + var transformUV2 = materialUniform.transformUV2; + + var uv = transformUV1.zw * ORI_VertexVarying.fragUV0 + transformUV1.xy; + + ORI_ShadingInput.BaseColor = textureSample(baseMap, baseMapSampler, uv ) * materialUniform.baseColor ; + + // #if USE_ALPHACUT + // ORI_ShadingInput.BaseColor.a = clamp(ORI_ShadingInput.BaseColor.a, 0.001 , 1.0 ); + 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); + ORI_FragmentOutput.worldNormal = vec4(0.0,0.0,0.0,1.0); + ORI_FragmentOutput.material = vec4(0.0,0.0,0.0,1.0); + discard; + } + // #endif + + #if USE_SHADOWMAPING + directShadowMaping(globalUniform.shadowBias); + pointShadowMapCompare(globalUniform.pointShadowBias); + #endif + + + // ORI_ShadingInput.BaseColor = vec4(sRGBToLinear(ORI_ShadingInput.BaseColor.xyz),ORI_ShadingInput.BaseColor.w); + + #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 ; + + #else + ORI_ShadingInput.Roughness = materialUniform.roughness ; + ORI_ShadingInput.Metallic = materialUniform.metallic ; + ORI_ShadingInput.AmbientOcclusion = materialUniform.ao ; + #if USE_AOTEX + var aoMap = textureSample(aomapMap, aoMapSampler, ORI_VertexVarying.fragUV0.xy ); + ORI_ShadingInput.AmbientOcclusion = mix(0.0,aoMap.r,materialUniform.ao) ; + #endif + #endif + + ORI_ShadingInput.Roughness = clamp(ORI_ShadingInput.Roughness,0.084,1.0); + ORI_ShadingInput.Specular = 0.5 ; + + var emissiveColor = textureSample(emissiveMap, emissiveMapSampler , ORI_VertexVarying.fragUV0.xy) ; + ORI_ShadingInput.EmissiveColor = vec4(materialUniform.emissiveColor.rgb * emissiveColor.rgb * materialUniform.emissiveIntensity,1.0); + + var Normal = textureSample(normalMap,normalMapSampler,ORI_VertexVarying.fragUV0).rgb ; + // Normal.y = 1.0 - Normal.y ; + // let normal = unPackNormal(Normal,1.0,materialUniform.normalScale) ; + let normal = unPackNormal(Normal,materialUniform.normalScale) ; + ORI_ShadingInput.Normal = normal ; + + BxDFShading(); + + + + } diff --git a/src/assets/shader/materials/materials/UnLit.wgsl b/src/assets/shader/materials/materials/UnLit.wgsl new file mode 100644 index 00000000..0c31f8b2 --- /dev/null +++ b/src/assets/shader/materials/materials/UnLit.wgsl @@ -0,0 +1,28 @@ + #include "Common_vert" + #include "Common_frag" + #include "UnLit_frag" + #include "UnLitMaterialUniform_frag" + + @group(1) @binding(0) + var baseMapSampler: sampler; + @group(1) @binding(1) + var baseMap: texture_2d; + + fn vert(inputData:VertexAttributes) -> VertexOutput { + ORI_Vert(inputData) ; + return ORI_VertexOut ; + } + + fn frag(){ + var transformUV1 = materialUniform.transformUV1; + var transformUV2 = materialUniform.transformUV2; + + var uv = transformUV1.zw * ORI_VertexVarying.fragUV0 + transformUV1.xy; + let color = textureSample(baseMap,baseMapSampler,uv) ; + if(color.w < 0.5){ + discard ; + } + + ORI_ShadingInput.BaseColor = color * materialUniform.baseColor ; + UnLit(); + } \ No newline at end of file diff --git a/src/engine/assets/shader/materials/sky/AtmosphericScatteringSky_shader.ts b/src/assets/shader/materials/materials/sky/AtmosphericScatteringSky_shader.ts similarity index 100% rename from src/engine/assets/shader/materials/sky/AtmosphericScatteringSky_shader.ts rename to src/assets/shader/materials/materials/sky/AtmosphericScatteringSky_shader.ts diff --git a/src/engine/assets/shader/materials/sky/CubeSky_Shader.ts b/src/assets/shader/materials/materials/sky/CubeSky_Shader.ts similarity index 100% rename from src/engine/assets/shader/materials/sky/CubeSky_Shader.ts rename to src/assets/shader/materials/materials/sky/CubeSky_Shader.ts diff --git a/src/engine/assets/shader/math/FastMathShader.wgsl b/src/assets/shader/materials/math/FastMathShader.wgsl similarity index 100% rename from src/engine/assets/shader/math/FastMathShader.wgsl rename to src/assets/shader/materials/math/FastMathShader.wgsl diff --git a/src/engine/assets/shader/post/FSAAShader.wgsl b/src/assets/shader/materials/post/FSAAShader.wgsl similarity index 100% rename from src/engine/assets/shader/post/FSAAShader.wgsl rename to src/assets/shader/materials/post/FSAAShader.wgsl diff --git a/src/engine/assets/shader/materials/program/BxdfDebug_frag.wgsl b/src/assets/shader/materials/program/BxdfDebug_frag.wgsl similarity index 100% rename from src/engine/assets/shader/materials/program/BxdfDebug_frag.wgsl rename to src/assets/shader/materials/program/BxdfDebug_frag.wgsl diff --git a/src/engine/assets/shader/materials/program/Clearcoat_frag.wgsl b/src/assets/shader/materials/program/Clearcoat_frag.wgsl similarity index 100% rename from src/engine/assets/shader/materials/program/Clearcoat_frag.wgsl rename to src/assets/shader/materials/program/Clearcoat_frag.wgsl diff --git a/src/engine/assets/shader/materials/program/ClusterDebug_frag.ts b/src/assets/shader/materials/program/ClusterDebug_frag.ts similarity index 100% rename from src/engine/assets/shader/materials/program/ClusterDebug_frag.ts rename to src/assets/shader/materials/program/ClusterDebug_frag.ts diff --git a/src/engine/assets/shader/materials/program/NormalMap_frag.wgsl b/src/assets/shader/materials/program/NormalMap_frag.wgsl similarity index 100% rename from src/engine/assets/shader/materials/program/NormalMap_frag.wgsl rename to src/assets/shader/materials/program/NormalMap_frag.wgsl diff --git a/src/engine/assets/shader/materials/program/ShadowMapping_frag.wgsl b/src/assets/shader/materials/program/ShadowMapping_frag.wgsl similarity index 100% rename from src/engine/assets/shader/materials/program/ShadowMapping_frag.wgsl rename to src/assets/shader/materials/program/ShadowMapping_frag.wgsl diff --git a/src/assets/shader/materials/sky/AtmosphericScatteringSky_shader.ts b/src/assets/shader/materials/sky/AtmosphericScatteringSky_shader.ts new file mode 100644 index 00000000..278c3d3a --- /dev/null +++ b/src/assets/shader/materials/sky/AtmosphericScatteringSky_shader.ts @@ -0,0 +1,311 @@ +/** + * @internal + */ +export class AtmosphericScatteringSky_shader { + public static cs: string = /* wgsl */ ` + struct UniformData { + width: f32, + height: f32, + sunU: f32, + sunV: f32, + eyePos: f32, + sunRadius: f32, // = 500.0; + sunRadiance: f32, // = 20.0; + mieG: f32, // = 0.76; + mieHeight: f32, // = 1200; + sunBrightness: f32, // = 1.0; + displaySun: f32, // > 0.5: true + }; + + @group(0) @binding(0) var uniformBuffer: UniformData; + @group(0) @binding(1) var outTexture : texture_storage_2d; + + var uv01: vec2; + var fragCoord: vec2; + var texSizeF32: vec2; + + var PI:f32 = 3.1415926535; + var PI_2:f32 = 0.0; + var EPSILON:f32 = 0.00001; + var SAMPLES_NUMS:i32 = 16; + + var transmittance:vec3; + var insctrMie:vec3; + var insctrRayleigh:vec3; + + @compute @workgroup_size( 8 , 8 , 1 ) + fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(global_invocation_id) globalInvocation_id : vec3) + { + fragCoord = vec2(globalInvocation_id.xy); + texSizeF32 = vec2( uniformBuffer.width, uniformBuffer.height); + uv01 = vec2(globalInvocation_id.xy) / texSizeF32; + uv01.y = 1.0 - uv01.y - EPSILON; + PI_2 = PI * 2.0; + textureStore(outTexture, fragCoord , mainImage(uv01));//vec4(uv01, 0.0, 1.0)); + } + + struct ScatteringParams + { + sunRadius:f32, + sunRadiance:f32, + + mieG:f32, + mieHeight:f32, + + rayleighHeight:f32, + + waveLambdaMie:vec3, + waveLambdaOzone:vec3, + waveLambdaRayleigh:vec3, + + earthRadius:f32, + earthAtmTopRadius:f32, + earthCenter:vec3, + } + + fn ComputeSphereNormal(coord:vec2, phiStart:f32, phiLength:f32, thetaStart:f32, thetaLength:f32) -> vec3 + { + var normal:vec3; + normal.x = -sin(thetaStart + coord.y * thetaLength) * sin(phiStart + coord.x * phiLength); + normal.y = -cos(thetaStart + coord.y * thetaLength); + normal.z = -sin(thetaStart + coord.y * thetaLength) * cos(phiStart + coord.x * phiLength); + return normalize(normal); + } + + fn ComputeRaySphereIntersection(position:vec3, dir:vec3, center:vec3, radius:f32) -> vec2 + { + var origin:vec3 = position - center; + var B = dot(origin, dir); + var C = dot(origin, origin) - radius * radius; + var D = B * B - C; + + var minimaxIntersections:vec2; + if (D < 0.0) + { + minimaxIntersections = vec2(-1.0, -1.0); + } + else + { + D = sqrt(D); + minimaxIntersections = vec2(-B - D, -B + D); + } + + return minimaxIntersections; + } + + fn ComputeWaveLambdaRayleigh(lambda: vec3) -> vec3 + { + var n:f32 = 1.0003; + var N:f32 = 2.545E25; + var pn:f32 = 0.035; + var n2:f32 = n * n; + var pi3:f32 = PI * PI * PI; + var rayleighConst:f32 = (8.0 * pi3 * pow(n2 - 1.0,2.0)) / (3.0 * N) * ((6.0 + 3.0 * pn) / (6.0 - 7.0 * pn)); + return vec3(rayleighConst) / (lambda * lambda * lambda * lambda); + } + + fn ComputePhaseMie(theta: f32, g:f32) -> f32 + { + var g2 = g * g; + return (1.0 - g2) / pow(1.0 + g2 - 2.0 * g * saturate(theta), 1.5) / (4.0 * PI); + } + + fn ComputePhaseRayleigh(theta: f32) -> f32 + { + var theta2 = theta * theta; + return (theta2 * 0.75 + 0.75) / (4.0 * PI); + } + + fn ChapmanApproximation(X: f32, h: f32, cosZenith: f32) -> f32 + { + var c = sqrt(X + h); + var c_exp_h = c * exp(-h); + + if (cosZenith >= 0.0) + { + return c_exp_h / (c * cosZenith + 1.0); + } + else + { + var x0 = sqrt(1.0 - cosZenith * cosZenith) * (X + h); + var c0 = sqrt(x0); + + return 2.0 * c0 * exp(X - x0) - c_exp_h / (1.0 - c * cosZenith); + } + } + + fn GetOpticalDepthSchueler(h: f32, H: f32, earthRadius: f32, cosZenith: f32) -> f32 + { + return H * ChapmanApproximation(earthRadius / H, h / H, cosZenith); + } + + fn GetTransmittance(setting: ScatteringParams, L:vec3, V: vec3) -> vec3 + { + var ch = GetOpticalDepthSchueler(L.y, setting.rayleighHeight, setting.earthRadius, V.y); + return exp(-(setting.waveLambdaMie + setting.waveLambdaRayleigh) * ch); + } + + fn ComputeOpticalDepth(setting: ScatteringParams, samplePoint: vec3, V: vec3, L: vec3, neg: f32) -> vec2 + { + var rl = length(samplePoint); + var h = rl - setting.earthRadius; + var r: vec3 = samplePoint / rl; + + var cos_chi_sun = dot(r, L); + var cos_chi_ray = dot(r, V * neg); + + var opticalDepthSun = GetOpticalDepthSchueler(h, setting.rayleighHeight, setting.earthRadius, cos_chi_sun); + var opticalDepthCamera = GetOpticalDepthSchueler(h, setting.rayleighHeight, setting.earthRadius, cos_chi_ray) * neg; + + return vec2(opticalDepthSun, opticalDepthCamera); + } + + fn AerialPerspective(setting:ScatteringParams, start: vec3, end: vec3, V: vec3, L: vec3, infinite:i32) + { + var inf_neg:f32 = 1.0; + if( infinite == 0){ + inf_neg = -1.0; + } + + var sampleStep: vec3 = (end - start) / f32(SAMPLES_NUMS); + var samplePoint: vec3 = end - sampleStep; + var sampleLambda: vec3 = setting.waveLambdaMie + setting.waveLambdaRayleigh + setting.waveLambdaOzone; + + var sampleLength:f32 = length(sampleStep); + + var scattering:vec3 = vec3(0.0); + var lastOpticalDepth:vec2 = ComputeOpticalDepth(setting, end, V, L, inf_neg); + + for (var i:i32 = 1; i < SAMPLES_NUMS; i = i + 1) + { + var opticalDepth: vec2 = ComputeOpticalDepth(setting, samplePoint, V, L, inf_neg); + + var segment_s: vec3 = exp(-sampleLambda * (opticalDepth.x + lastOpticalDepth.x)); + var segment_t: vec3 = exp(-sampleLambda * (opticalDepth.y - lastOpticalDepth.y)); + + transmittance *= segment_t; + + scattering = scattering * segment_t; + scattering += exp(-(length(samplePoint) - setting.earthRadius) / setting.rayleighHeight) * segment_s; + + lastOpticalDepth = opticalDepth; + samplePoint = samplePoint - sampleStep; + } + + insctrMie = scattering * setting.waveLambdaMie * sampleLength; + insctrRayleigh = scattering * setting.waveLambdaRayleigh * sampleLength; + } + + fn ComputeSkyboxChapman(setting: ScatteringParams, eye:vec3, V:vec3, L:vec3) -> f32 + { + var neg:i32 = 1; + var outerIntersections: vec2 = ComputeRaySphereIntersection(eye, V, setting.earthCenter, setting.earthAtmTopRadius); + if (outerIntersections.y < 0.0){ + return 0.0; + } + var innerIntersections: vec2 = ComputeRaySphereIntersection(eye, V, setting.earthCenter, setting.earthRadius); + if (innerIntersections.x > 0.0) + { + neg = 0; + outerIntersections.y = innerIntersections.x; + } + + let eye0 = eye - setting.earthCenter; + + var start : vec3 = eye0 + V * max(0.0, outerIntersections.x); + var end : vec3= eye0 + V * outerIntersections.y; + + AerialPerspective(setting, start, end, V, L, neg); + + //bool intersectionTest = innerIntersections.x < 0.0 && innerIntersections.y < 0.0; + //return intersectionTest ? 1.0 : 0.0; + + if(innerIntersections.x < 0.0 && innerIntersections.y < 0.0){ + return 1.0; + } + return 0.0; + } + + fn ComputeSkyInscattering(setting: ScatteringParams, eye: vec3, V: vec3, L: vec3) -> vec4 + { + transmittance = vec3(1.0); + insctrMie = vec3(0.0); + insctrRayleigh = vec3(0.0); + var intersectionTest:f32 = ComputeSkyboxChapman(setting, eye, V, L); + + var phaseTheta = dot(V, L); + var phaseMie = ComputePhaseMie(phaseTheta, setting.mieG); + var phaseRayleigh = ComputePhaseRayleigh(phaseTheta); + var phaseNight = 1.0 - saturate(transmittance.x * EPSILON); + + var insctrTotalMie: vec3 = insctrMie * phaseMie; + var insctrTotalRayleigh: vec3 = insctrRayleigh * phaseRayleigh; + + var sky: vec3 = (insctrTotalMie + insctrTotalRayleigh) * setting.sunRadiance; + if(uniformBuffer.displaySun > 0.5){ + var angle:f32 = saturate((1.0 - phaseTheta) * setting.sunRadius); + var cosAngle:f32 = cos(angle * PI * 0.5); + var edge:f32 = 0.0; + if(angle >= 0.9){ + edge = smoothstep(0.9, 1.0, angle); + } + + var limbDarkening: vec3 = GetTransmittance(setting, -L, V); + limbDarkening *= pow(vec3(cosAngle), vec3(0.420, 0.503, 0.652)) * mix(vec3(1.0), vec3(1.2,0.9,0.5), edge) * intersectionTest; + sky += limbDarkening * uniformBuffer.sunBrightness; + } + return vec4(sky, phaseNight * intersectionTest); + } + + fn TonemapACES(x: vec3) -> vec3 + { + var A:f32 = 2.51f; + var B:f32 = 0.03f; + var C:f32 = 2.43f; + var D:f32 = 0.59f; + var E:f32 = 0.14f; + return (x * (A * x + B)) / (x * (C * x + D) + E); + } + + fn noise(uv:vec2) -> f32 + { + return fract(dot(sin(vec3(uv.xyx) * vec3(uv.xyy) * 1024.0), vec3(341896.483, 891618.637, 602649.7031))); + } + + fn mainImage( uv:vec2 ) -> vec4 + { + let eyePosition = uniformBuffer.eyePos; + var sun = vec2(uniformBuffer.sunU, uniformBuffer.sunV); + var V: vec3 = ComputeSphereNormal(uv, 0.0, PI_2, 0.0, PI); + var L: vec3 = ComputeSphereNormal(vec2(sun.x, sun.y), 0.0, PI_2, 0.0, PI); + + var setting: ScatteringParams; + setting.sunRadius = uniformBuffer.sunRadius;//500.0; + setting.sunRadiance = uniformBuffer.sunRadiance;//20.0; + setting.mieG = uniformBuffer.mieG;//0.76; + setting.mieHeight = uniformBuffer.mieHeight;// 1200.0; + setting.rayleighHeight = 8000.0; + setting.earthRadius = 6360000.0; + setting.earthAtmTopRadius = 6420000.0; + setting.earthCenter = vec3(0, -setting.earthRadius, 0); + setting.waveLambdaMie = vec3(0.0000002); + + // wavelength with 680nm, 550nm, 450nm + setting.waveLambdaRayleigh = ComputeWaveLambdaRayleigh(vec3(0.000000680, 0.000000550, 0.000000450)); + + // see https://www.shadertoy.com/view/MllBR2 + setting.waveLambdaOzone = vec3(1.36820899679147, 3.31405330400124, 0.13601728252538) * 0.0000006 * 2.504; + + var eye:vec3 = vec3(0,eyePosition,0); + var sky0:vec4 = ComputeSkyInscattering(setting, eye, V, L); + var sky = vec3(sky0.rgb); + + // sky = TonemapACES(sky.rgb * 2.0); + // sky = pow(sky.rgb, vec3(2.4)); // gamma + // sky.rgb += noise(uv*iTime) / 255.0; // dither + + var fragColor:vec4 = vec4(sky, 1.0); + return fragColor; + } + `; +} diff --git a/src/assets/shader/materials/sky/CubeSky_Shader.ts b/src/assets/shader/materials/sky/CubeSky_Shader.ts new file mode 100644 index 00000000..dca45731 --- /dev/null +++ b/src/assets/shader/materials/sky/CubeSky_Shader.ts @@ -0,0 +1,98 @@ +export class CubeSky_Shader { + public static sky_vs_frag_wgsl: string = /* wgsl */ ` + #include "WorldMatrixUniform" + #include "GlobalUniform" + + struct VertexOutput { + @location(0) fragUV: vec2, + @location(1) vWorldPos: vec4, + @location(2) vWorldNormal: vec3, + @builtin(position) member: vec4 + }; + + var ORI_VertexOut: VertexOutput ; + + @vertex + fn main( + @builtin(instance_index) index : u32, + @location(0) position: vec3, + @location(1) normal: vec3, + @location(2) uv: vec2 + ) -> VertexOutput { + ORI_VertexOut.fragUV = uv; + let modelMat = models.matrix[u32(index)]; + let vm = globalUniform.viewMat * modelMat; + let normalMatrix = mat3x3(vm[0].xyz,vm[1].xyz,vm[2].xyz); + ORI_VertexOut.vWorldNormal = normalize( normalMatrix * normal ); + ORI_VertexOut.vWorldPos = modelMat * vec4(position.xyz,1.0) ; + + var fixProjMat = globalUniform.projMat ; + fixProjMat[2].z = 1.0 ;//99999.0 / (99999.0 - 1.0) ; + fixProjMat[3].z = -1.0 ;//(-1.0 * 99999.0) / (99999.0 - 1.0) ; + + var fixViewMat = globalUniform.viewMat ; + fixViewMat[3].x = 0.0 ; + fixViewMat[3].y = 0.0 ; + fixViewMat[3].z = 0.0 ; + + var clipPos = fixProjMat * fixViewMat * ORI_VertexOut.vWorldPos; + ORI_VertexOut.member = clipPos; + return ORI_VertexOut; + } + ` + + public static sky_fs_frag_wgsl: string = /* wgsl */ ` + #include "GlobalUniform" + + struct uniformData { + exposure: f32, + roughness: f32 + }; + + struct FragmentOutput { + @location(0) o_Target: vec4, + #if USE_WORLDPOS + @location(1) o_Position: vec4, + #endif + #if USEGBUFFER + @location(2) o_Normal: vec4, + @location(3) o_Material: vec4 + #endif + }; + + @group(1) @binding(0) + var baseMapSampler: sampler; + @group(1) @binding(1) + var baseMap: texture_cube; + + @group(2) @binding(0) + var global: uniformData; + + fn LinearToGammaSpace(linRGB: vec3) -> vec3 { + var linRGB1 = max(linRGB, vec3(0.0)); + linRGB1 = pow(linRGB1, vec3(0.4166666567325592)); + return max(((1.0549999475479126 * linRGB1) - vec3(0.054999999701976776)), vec3(0.0)); + } + + @fragment + fn main(@location(0) fragUV: vec2, @location(1) vWorldPos: vec4, @location(2) vWorldNormal: vec3) -> FragmentOutput { + let maxLevel: u32 = textureNumLevels(baseMap); + let textureColor:vec3 = textureSampleLevel(baseMap, baseMapSampler, normalize(vWorldPos.xyz), global.roughness * f32(maxLevel) ).xyz; + let o_Target: vec4 = vec4(LinearToGammaSpace(textureColor),1.0) * globalUniform.skyExposure ; + var normal_rgba8unorm = (vWorldNormal + 1.0) * 0.5; + normal_rgba8unorm = clamp(normal_rgba8unorm, vec3(0.0), vec3(1.0)); + + return FragmentOutput( + o_Target, + #if USE_WORLDPOS + vWorldPos, + #endif + #if USEGBUFFER + vec4(normal_rgba8unorm,0.0), + vec4(0.0,1.0,0.0,0.0) + #endif + ); + } + `; + +} \ No newline at end of file diff --git a/src/engine/assets/shader/materials/uniforms/MaterialUniform.ts b/src/assets/shader/materials/uniforms/MaterialUniform.ts similarity index 100% rename from src/engine/assets/shader/materials/uniforms/MaterialUniform.ts rename to src/assets/shader/materials/uniforms/MaterialUniform.ts diff --git a/src/engine/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts b/src/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts similarity index 100% rename from src/engine/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts rename to src/assets/shader/materials/uniforms/PhysicMaterialUniform_frag.ts diff --git a/src/engine/assets/shader/materials/uniforms/UnLitMaterialUniform_frag.ts b/src/assets/shader/materials/uniforms/UnLitMaterialUniform_frag.ts similarity index 100% rename from src/engine/assets/shader/materials/uniforms/UnLitMaterialUniform_frag.ts rename to src/assets/shader/materials/uniforms/UnLitMaterialUniform_frag.ts diff --git a/src/engine/assets/shader/materials/uniforms/VideoUniform_frag.ts b/src/assets/shader/materials/uniforms/VideoUniform_frag.ts similarity index 100% rename from src/engine/assets/shader/materials/uniforms/VideoUniform_frag.ts rename to src/assets/shader/materials/uniforms/VideoUniform_frag.ts diff --git a/src/engine/assets/shader/utils/BRDFLUT.wgsl b/src/assets/shader/materials/utils/BRDFLUT.wgsl similarity index 100% rename from src/engine/assets/shader/utils/BRDFLUT.wgsl rename to src/assets/shader/materials/utils/BRDFLUT.wgsl diff --git a/src/engine/assets/shader/utils/ColorUtil.wgsl b/src/assets/shader/materials/utils/ColorUtil.wgsl similarity index 100% rename from src/engine/assets/shader/utils/ColorUtil.wgsl rename to src/assets/shader/materials/utils/ColorUtil.wgsl diff --git a/src/engine/assets/shader/utils/GenerayRandomDir.wgsl b/src/assets/shader/materials/utils/GenerayRandomDir.wgsl similarity index 100% rename from src/engine/assets/shader/utils/GenerayRandomDir.wgsl rename to src/assets/shader/materials/utils/GenerayRandomDir.wgsl diff --git a/src/assets/shader/math/FastMathShader.wgsl b/src/assets/shader/math/FastMathShader.wgsl new file mode 100644 index 00000000..d10eaf7c --- /dev/null +++ b/src/assets/shader/math/FastMathShader.wgsl @@ -0,0 +1,31 @@ +fn Pow3( x : f32 ) -> f32 +{ + var xx = x*x; + return x * xx; +} + +fn Pow4( x : f32 ) -> f32 +{ + var xx = x*x; + return xx * xx; +} + +fn pow5(x: f32) -> f32 { + var x2 = x * x; + return x2 * x2 * x; +} + +fn rcp( x:f32 ) -> f32 +{ + return 1.0 / x; +} + +fn rsqrt3( a : vec3 ) -> vec3 +{ + return pow(a, vec3(-0.5)); +} + +fn rsqrt( a : f32 ) -> f32 +{ + return pow(a, -0.5); +} diff --git a/src/engine/assets/shader/math/MathShader.ts b/src/assets/shader/math/MathShader.ts similarity index 100% rename from src/engine/assets/shader/math/MathShader.ts rename to src/assets/shader/math/MathShader.ts diff --git a/src/engine/assets/shader/post/Bloom_shader.ts b/src/assets/shader/post/Bloom_shader.ts similarity index 100% rename from src/engine/assets/shader/post/Bloom_shader.ts rename to src/assets/shader/post/Bloom_shader.ts diff --git a/src/assets/shader/post/FSAAShader.wgsl b/src/assets/shader/post/FSAAShader.wgsl new file mode 100644 index 00000000..67ba238e --- /dev/null +++ b/src/assets/shader/post/FSAAShader.wgsl @@ -0,0 +1,76 @@ +struct FragmentOutput { + @location(0) o_Target: vec4 +}; + +var varying_uv: vec2; +@group(1) @binding(0) +var baseMapSampler: sampler; +@group(1) @binding(1) +var baseMap: texture_2d; + +struct MaterialUniform{ + u_texel: vec2, + u_strength: f32, +} + + @group(2) @binding(0) + var materialUniform: MaterialUniform; + + +fn LinearToGammaSpace(linRGB0: vec3) -> vec3 { + var linRGB = max(linRGB0, vec3(0.0, 0.0, 0.0)); + linRGB.r = pow(linRGB.r,0.416666667); + linRGB.g = pow(linRGB.g,0.416666667); + linRGB.b = pow(linRGB.b,0.416666667); + return max(1.055 * linRGB - 0.055, vec3(0.0, 0.0, 0.0)); +} + +fn texture2D( uv:vec2 , offset:vec2 ) -> vec4 { + return textureSample(baseMap, baseMapSampler, uv.xy + offset ).rgba ; +} + +@fragment +fn main(@location(0) fragUV: vec2) -> FragmentOutput { + var v_vTexcoord = fragUV ; + // v_vTexcoord.x = 1.0 - v_vTexcoord.x ; + v_vTexcoord.y = 1.0 - v_vTexcoord.y ; + + var reducemul = 1.0 / 8.0; + var reducemin = 1.0 / 128.0; + + var basecol = texture2D(v_vTexcoord , vec2(0.0)).rgba; + var baseNW = texture2D(v_vTexcoord , -materialUniform.u_texel).rgb; + var baseNE = texture2D(v_vTexcoord , vec2(materialUniform.u_texel.x, -materialUniform.u_texel.y)).rgb; + var baseSW = texture2D(v_vTexcoord , vec2(-materialUniform.u_texel.x, materialUniform.u_texel.y)).rgb; + var baseSE = texture2D(v_vTexcoord , materialUniform.u_texel ).rgb; + + // var gray = vec3(0.299, 0.587, 0.114); + var gray = vec3(0.213, 0.715, 0.072); + var monocol = dot(basecol.rgb, gray); + var monoNW = dot(baseNW, gray); + var monoNE = dot(baseNE, gray); + var monoSW = dot(baseSW, gray); + var monoSE = dot(baseSE, gray); + + var monomin = min(monocol, min(min(monoNW, monoNE), min(monoSW, monoSE))); + var monomax = max(monocol, max(max(monoNW, monoNE), max(monoSW, monoSE))); + + var dir = vec2(-((monoNW + monoNE) - (monoSW + monoSE)), ((monoNW + monoSW) - (monoNE + monoSE))); + var dirreduce = max((monoNW + monoNE + monoSW + monoSE) * reducemul * 0.25, reducemin); + var dirmin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirreduce); + dir = min(vec2(materialUniform.u_strength), max(vec2(-materialUniform.u_strength), dir * dirmin)) * materialUniform.u_texel; + + var resultA = 0.5 * (texture2D(v_vTexcoord , dir * -0.166667).rgb + + texture2D(v_vTexcoord , dir * 0.166667).rgb); + var resultB = resultA * 0.5 + 0.25 * (texture2D( v_vTexcoord , dir * -0.5).rgb + + texture2D( v_vTexcoord , dir * 0.5).rgb); + var monoB = dot(resultB.rgb, gray); + + var color:vec3 ; + if(monoB < monomin || monoB > monomax) { + color = resultA ;//* v_vColour; + } else { + color = resultB ;//* v_vColour; + } + return FragmentOutput(vec4(color.rgb,basecol.a)); +} \ No newline at end of file diff --git a/src/engine/assets/shader/post/GlobalFog_shader.ts b/src/assets/shader/post/GlobalFog_shader.ts similarity index 100% rename from src/engine/assets/shader/post/GlobalFog_shader.ts rename to src/assets/shader/post/GlobalFog_shader.ts diff --git a/src/engine/assets/shader/quad/Quad_shader.ts b/src/assets/shader/quad/Quad_shader.ts similarity index 100% rename from src/engine/assets/shader/quad/Quad_shader.ts rename to src/assets/shader/quad/Quad_shader.ts diff --git a/src/assets/shader/utils/BRDFLUT.wgsl b/src/assets/shader/utils/BRDFLUT.wgsl new file mode 100644 index 00000000..4a898192 --- /dev/null +++ b/src/assets/shader/utils/BRDFLUT.wgsl @@ -0,0 +1,112 @@ + var PI:f32 = 3.141592653589793 ; + + // fn saturate( x : f32 ) -> f32 { + // return clamp(x, 0.0, 1.0); + // } + + fn hammersley( i : u32 , N : u32 ) -> vec2 + { + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + var bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + var rdi = f32(bits) * 2.3283064365386963e-10; + return vec2(f32(i) /f32(N), rdi); + } + + fn G_Smith( NoV:f32 , NoL : f32 , roughness : f32 ) -> f32 + { + var k = (roughness * roughness) / 2.0; + var GGXL = NoL / (NoL * (1.0 - k) + k); + var GGXV = NoV / (NoV * (1.0 - k) + k); + return GGXL * GGXV; + } + + fn V_SmithGGXCorrelated( NoV:f32 , NoL : f32 , roughness : f32 ) -> f32 + { + var a2 = pow(roughness, 4.0); + var GGXV = NoL * sqrt(NoV * NoV * (1.0 - a2) + a2); + var GGXL = NoV * sqrt(NoL * NoL * (1.0 - a2) + a2); + return 0.5 / (GGXV + GGXL); + } + + + // Based on Karis 2014 + fn importanceSampleGGX( Xi:vec2, roughness:f32 , N:vec3 ) -> vec3 + { + var a = roughness * roughness; + // Sample in spherical coordinates + var Phi = 2.0 * PI * Xi.x; + var CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + var SinTheta = sqrt(1.0 - CosTheta * CosTheta); + // Construct tangent space vector + var H:vec3; + H.x = SinTheta * cos(Phi); + H.y = SinTheta * sin(Phi); + H.z = CosTheta; + + // Tangent to world space + var UpVector = vec3(1.0,0.0,0.0); + if(abs(N.z) < 0.999){ + UpVector = vec3(0.0,0.0,1.0) ; + } + var TangentX = normalize(cross(UpVector, N)); + var TangentY = cross(N, TangentX); + return TangentX * H.x + TangentY * H.y + N * H.z; + } + + + // Karis 2014 + fn integrateBRDF( roughness:f32 , NoV: f32) -> vec2 + { + var V : vec3 ; + V.x = sqrt(1.0 - NoV * NoV); // sin + V.y = 0.0; + V.z = NoV; // cos + + // N points straight upwards for this integration + var N = vec3(0.0, 0.0, 1.0); + + var A = 0.0; + var B = 0.0; + var numSamples = 1024u; + + for (var i = 0u; i < numSamples; i+=1u) { + var Xi = hammersley(i, numSamples); + // Sample microfacet direction + var H = importanceSampleGGX(Xi, roughness, N); + + // Get the light direction + var L = 2.0 * dot(V, H) * H - V; + + var NoL = saturate(dot(N, L)); + var NoH = saturate(dot(N, H)); + var VoH = saturate(dot(V, H)); + + if(NoL > 0.0) { + var V_pdf = V_SmithGGXCorrelated(NoV, NoL, roughness) * VoH * NoL / NoH; + var Fc = pow(1.0 - VoH, 5.0); + A += (1.0 - Fc) * V_pdf; + B += Fc * V_pdf; + } + } + + return 4.0 * vec2(A, B) / f32(numSamples); + } + + @group(0) @binding(0) var brdflutTexture : texture_storage_2d; + + @compute @workgroup_size(8,8,1) + // fn CsMain( @builtin(workgroup_id) workgroup_id : vec3 , @builtin(local_invocation_id) local_invocation_id : vec3 ){ + fn CsMain( @builtin(global_invocation_id) global_invocation_id : vec3){ + var fragCoord = vec2( global_invocation_id.x, global_invocation_id.y); + + var fragColor = vec4(0.0) ; + // Output to screen + var res = integrateBRDF( f32(fragCoord.y+1u) / 256.0 , f32(fragCoord.x+1u) / 256.0 ); + fragColor = vec4(res.x, res.y, 0.0, 1.0) ; + + textureStore(brdflutTexture, vec2(fragCoord.xy), fragColor ); + } diff --git a/src/assets/shader/utils/ColorUtil.wgsl b/src/assets/shader/utils/ColorUtil.wgsl new file mode 100644 index 00000000..5db84e7a --- /dev/null +++ b/src/assets/shader/utils/ColorUtil.wgsl @@ -0,0 +1,99 @@ + + + fn getHDRColor(color:vec3,exposure:f32)-> vec3{ + // var newColor = color * ( 1.0 / 255.0 ) ; + return color * pow(2.4 , exposure) ; + } + + fn lambda2rgb( lambda : f32 ) -> vec3 { + let ultraviolet = 400.0; + let infrared = 700.0; + + var a = (lambda - ultraviolet)/(infrared - ultraviolet); + let c = 10.0; + var b = vec3(a) - vec3(0.75,0.5,0.25); + return max((1.0 - c*b*b), vec3(0.0) ); + } + + fn CEToneMapping( color:vec3, adapted_lum:f32)-> vec3 + { + return 1.0 - exp(-adapted_lum * color); + } + + fn ACESToneMapping( color:vec3, adapted_lum:f32 )-> vec3 + { + let A = 2.51; + let B = 0.03; + let C = 2.43; + let D = 0.59; + let E = 0.14; + + var color2 = color * adapted_lum; + color2 = (color2 * (A * color2 + B)) / (color2 * (C * color2 + D) + E); + return color2 ; + } + + fn gammaToLiner(color:vec4) -> vec4 { + let gammaCorrect = 2.4; + var color2 = pow(color, vec4(gammaCorrect)); + return color2 ; + } + + fn linerToGamma4(color:vec4) -> vec4 { + let gammaCorrect = 1.0 / 2.4; + var color2 = pow(color, vec4(gammaCorrect)); + return color2 ; + } + + fn linerToGamma3(color:vec3) -> vec3 { + let gammaCorrect = 1.0 / 2.4; + var color2 = pow(color, vec3(gammaCorrect)); + return color2 ; + } + + fn LinearToGammaSpace(linRGB0: vec3) -> vec3 { + var linRGB = max(linRGB0, vec3(0.0, 0.0, 0.0)); + linRGB.r = pow(linRGB.r,0.416666667); + linRGB.g = pow(linRGB.g,0.416666667); + linRGB.b = pow(linRGB.b,0.416666667); + return max(1.055 * linRGB - 0.055, vec3(0.0, 0.0, 0.0)); + } + + var sRGB_2_LMS_MAT:mat3x3 = mat3x3( + 17.8824, 43.5161, 4.1193, + 3.4557, 27.1554, 3.8671, + 0.02996, 0.18431, 1.4670, + ) ; + + var LMS_2_sRGB_MAT:mat3x3 = mat3x3( + 0.0809, -0.1305, 0.1167, + -0.0102, 0.0540, -0.1136, + -0.0003, -0.0041, 0.6935, + ); + + fn sRGB_2_LMS( RGB:vec3 ) -> vec3 + { + return sRGB_2_LMS_MAT * RGB ; + } + + fn LMS_2_sRGB( LMS:vec3 ) -> vec3 + { + return LMS_2_sRGB_MAT * LMS; + } + + fn LinearToSrgbBranchless( lin:vec3 ) -> vec3 + { + var lin2 = max(vec3(6.10352e-5), lin); + return min(lin2 * 12.92, pow(max(lin2, vec3(0.00313067)), vec3(1.0/2.4)) * vec3(1.055) - vec3(0.055)); + } + + fn sRGBToLinear( color : vec3 ) -> vec3 + { + let color2 = max(vec3(6.10352e-5), color); + let c = 0.04045 ; + if(color2.r > c && color2.g > c && color2.b > c){ + return pow( color2 * (1.0 / 1.055) + 0.0521327, vec3(2.4) ) ; + }else{ + return color2 * (1.0 / 12.92); + } + } diff --git a/src/assets/shader/utils/GenerayRandomDir.wgsl b/src/assets/shader/utils/GenerayRandomDir.wgsl new file mode 100644 index 00000000..74a72796 --- /dev/null +++ b/src/assets/shader/utils/GenerayRandomDir.wgsl @@ -0,0 +1,23 @@ + +fn madfrac(A:f32, B:f32)-> f32 { + return A*B-floor(A*B) ; +} + +fn sampleRandomDir(count:u32,SAMPLE_COUNT:u32) -> vec3{ + var ray_dir = sphericalFibonacci(f32((count)), f32(SAMPLE_COUNT) ); + return normalize(ray_dir) ; +} + +fn sphericalFibonacci( i : f32 , n : f32 ) -> vec3{ + const PHI = sqrt(5.0) * 0.5 + 0.5; + let phi = 2.0 * PI * madfrac(i, PHI - 1); + let cosTheta = 1.0 - (2.0 * i + 1.0) * (1.0 / n); + let sinTheta = sqrt(saturate(1.0 - cosTheta*cosTheta)); + + return vec3( + cos(phi) * sinTheta, + sin(phi) * sinTheta, + cosTheta); + +} + diff --git a/src/engine/components/AtmosphericComponent.ts b/src/components/AtmosphericComponent.ts similarity index 95% rename from src/engine/components/AtmosphericComponent.ts rename to src/components/AtmosphericComponent.ts index e637920a..1749b083 100644 --- a/src/engine/components/AtmosphericComponent.ts +++ b/src/components/AtmosphericComponent.ts @@ -73,23 +73,23 @@ export class AtmosphericComponent extends SkyRenderer { this._atmosphericScatteringSky.apply(); } - protected init(): void { + public init(): void { super.init(); this._atmosphericScatteringSky = new AtmosphericScatteringSky(new AtmosphericScatteringSkySetting()); } - protected start(): void { + public start(): void { let scene = this.transform.scene3D; this.map = this._atmosphericScatteringSky; scene.envMap = this._atmosphericScatteringSky; super.start(); } - protected onEnable(): void { + public onEnable(): void { } - protected onDisable(): void { + public onDisable(): void { } diff --git a/src/engine/components/BillboardComponent.ts b/src/components/BillboardComponent.ts similarity index 98% rename from src/engine/components/BillboardComponent.ts rename to src/components/BillboardComponent.ts index 1419e2bd..6c3d8d2b 100644 --- a/src/engine/components/BillboardComponent.ts +++ b/src/components/BillboardComponent.ts @@ -19,7 +19,7 @@ export class BillboardComponent extends ComponentBase { this._cameraDirection = new Vector3(); } - protected onUpdate() { + public onUpdate() { super.onUpdate(); if (this.enable && this.transform.view3D.camera) { this.updateBillboardMatrix(); diff --git a/src/engine/components/ColliderComponent.ts b/src/components/ColliderComponent.ts similarity index 98% rename from src/engine/components/ColliderComponent.ts rename to src/components/ColliderComponent.ts index 9d25b2ff..9e8e8a7e 100644 --- a/src/engine/components/ColliderComponent.ts +++ b/src/components/ColliderComponent.ts @@ -19,7 +19,7 @@ export class ColliderComponent extends ComponentBase { /** * @internal */ - protected start(): void { + public start(): void { if (Engine3D.setting.pick.mode == `pixel`) { this.transform.scene3D.view.pickFire.mouseEnableMap.set(this.transform.worldMatrix.index, this); } diff --git a/src/engine/components/ComponentBase.ts b/src/components/ComponentBase.ts similarity index 74% rename from src/engine/components/ComponentBase.ts rename to src/components/ComponentBase.ts index 1dc9a660..3328b02b 100644 --- a/src/engine/components/ComponentBase.ts +++ b/src/components/ComponentBase.ts @@ -1,6 +1,8 @@ import { View3D } from "../core/View3D"; import { Object3D } from "../core/entities/Object3D"; import { CEventDispatcher } from "../event/CEventDispatcher"; +import { ComponentCollect } from "../gfx/renderJob/collect/ComponentCollect"; +import { IComponent } from "./IComponent"; import { Transform } from "./Transform"; /** @@ -8,7 +10,7 @@ import { Transform } from "./Transform"; * The component can receive update events at each frame. * @group Components */ -export class ComponentBase { +export class ComponentBase implements IComponent { /** * owner object3D */ @@ -99,25 +101,19 @@ export class ComponentBase { this._onCompute(null); this._onGraphic(null); - this.onEnable = null; - this.onDisable = null; - this.onUpdate = null; - this.onLateUpdate = null; - this.onBeforeUpdate = null; - this.onCompute = null; - this.onGraphic = null; + } - protected init(param?: any) { } - protected start() { } - protected stop() { } - protected onEnable?(view?: View3D); - protected onDisable?(view?: View3D); - protected onUpdate?(view?: View3D); - protected onLateUpdate?(view?: View3D); - protected onBeforeUpdate?(view?: View3D); - protected onCompute?(view?: View3D, command?: GPUCommandEncoder); - protected onGraphic?(view?: View3D); + public init(param?: any) { } + public start() { } + public stop() { } + public onEnable?(view?: View3D); + public onDisable?(view?: View3D); + public onUpdate?(view?: View3D); + public onLateUpdate?(view?: View3D); + public onBeforeUpdate?(view?: View3D); + public onCompute?(view?: View3D, command?: GPUCommandEncoder); + public onGraphic?(view?: View3D); /** * @@ -133,9 +129,9 @@ export class ComponentBase { */ private _onUpdate(call: Function) { if (call != null) { - ComponentBase.componentsUpdateList.set(this, call); + ComponentCollect.componentsUpdateList.set(this, call); } else { - ComponentBase.componentsUpdateList.delete(this); + ComponentCollect.componentsUpdateList.delete(this); } } @@ -146,9 +142,9 @@ export class ComponentBase { private _onLateUpdate(call: Function) { // if(!this.enable) return; if (call != null) { - ComponentBase.componentsLateUpdateList.set(this, call); + ComponentCollect.componentsLateUpdateList.set(this, call); } else { - ComponentBase.componentsLateUpdateList.delete(this); + ComponentCollect.componentsLateUpdateList.delete(this); } } @@ -159,9 +155,9 @@ export class ComponentBase { private _onBeforeUpdate(call: Function) { // if(!this.enable) return; if (call != null) { - ComponentBase.componentsBeforeUpdateList.set(this, call); + ComponentCollect.componentsBeforeUpdateList.set(this, call); } else { - ComponentBase.componentsBeforeUpdateList.delete(this); + ComponentCollect.componentsBeforeUpdateList.delete(this); } } @@ -172,9 +168,9 @@ export class ComponentBase { */ private _onCompute(call: Function) { if (call != null) { - ComponentBase.componentsComputeList.set(this, call); + ComponentCollect.componentsComputeList.set(this, call); } else { - ComponentBase.componentsComputeList.delete(this); + ComponentCollect.componentsComputeList.delete(this); } } @@ -184,9 +180,9 @@ export class ComponentBase { */ private _onGraphic(call: Function) { if (call != null) { - ComponentBase.graphicComponent.set(this, call); + ComponentCollect.graphicComponent.set(this, call); } else { - ComponentBase.graphicComponent.delete(this); + ComponentCollect.graphicComponent.delete(this); } } @@ -199,27 +195,17 @@ export class ComponentBase { this._onBeforeUpdate(null); this._onUpdate(null); this._onLateUpdate(null); - } - /** - * @internal - */ - static componentsUpdateList: Map = new Map(); - - /** - * @internal - */ - static componentsLateUpdateList: Map = new Map(); + this.onEnable = null; + this.onDisable = null; + this.onUpdate = null; + this.onLateUpdate = null; + this.onBeforeUpdate = null; + this.onCompute = null; + this.onGraphic = null; + } - /** - * @internal - */ - static componentsBeforeUpdateList: Map = new Map(); - /** - * @internal - */ - static componentsComputeList: Map = new Map(); /** * @internal diff --git a/src/components/IComponent.ts b/src/components/IComponent.ts new file mode 100644 index 00000000..d6b5a28e --- /dev/null +++ b/src/components/IComponent.ts @@ -0,0 +1,23 @@ +import { View3D } from "../core/View3D"; +import { Object3D } from "../core/entities/Object3D"; +import { CEventDispatcher } from "../event/CEventDispatcher"; +import { Transform } from "./Transform"; + +export interface IComponent { + object3D: Object3D; + eventDispatcher: CEventDispatcher; + transform: Transform; + enable: boolean; + init(param?: any); + start(); + stop(); + onEnable?(view?: View3D); + onDisable?(view?: View3D); + onUpdate?(view?: View3D); + onLateUpdate?(view?: View3D); + onBeforeUpdate?(view?: View3D); + onCompute?(view?: View3D, command?: GPUCommandEncoder); + onGraphic?(view?: View3D); + cloneTo(obj: Object3D); + destroy() +} \ No newline at end of file diff --git a/src/engine/components/SkeletonAnimationComponent.ts b/src/components/SkeletonAnimationComponent.ts similarity index 99% rename from src/engine/components/SkeletonAnimationComponent.ts rename to src/components/SkeletonAnimationComponent.ts index e5403baa..313bc754 100644 --- a/src/engine/components/SkeletonAnimationComponent.ts +++ b/src/components/SkeletonAnimationComponent.ts @@ -36,7 +36,7 @@ export class SkeletonAnimationComponent extends ComponentBase { super(); } - protected start() { + public start() { } diff --git a/src/engine/components/Transform.ts b/src/components/Transform.ts similarity index 100% rename from src/engine/components/Transform.ts rename to src/components/Transform.ts diff --git a/src/engine/components/anim/OAnimationEvent.ts b/src/components/anim/OAnimationEvent.ts similarity index 100% rename from src/engine/components/anim/OAnimationEvent.ts rename to src/components/anim/OAnimationEvent.ts diff --git a/src/engine/components/anim/curveAnim/curveAnim/AnimationMonitor.ts b/src/components/anim/curveAnim/curveAnim/AnimationMonitor.ts similarity index 100% rename from src/engine/components/anim/curveAnim/curveAnim/AnimationMonitor.ts rename to src/components/anim/curveAnim/curveAnim/AnimationMonitor.ts diff --git a/src/engine/components/anim/curveAnim/curveAnim/AttributeAnimCurve.ts b/src/components/anim/curveAnim/curveAnim/AttributeAnimCurve.ts similarity index 100% rename from src/engine/components/anim/curveAnim/curveAnim/AttributeAnimCurve.ts rename to src/components/anim/curveAnim/curveAnim/AttributeAnimCurve.ts diff --git a/src/engine/components/anim/curveAnim/curveAnim/PropertyAnimClip.ts b/src/components/anim/curveAnim/curveAnim/PropertyAnimClip.ts similarity index 100% rename from src/engine/components/anim/curveAnim/curveAnim/PropertyAnimClip.ts rename to src/components/anim/curveAnim/curveAnim/PropertyAnimClip.ts diff --git a/src/engine/components/anim/curveAnim/curveAnim/PropertyAnimation.ts b/src/components/anim/curveAnim/curveAnim/PropertyAnimation.ts similarity index 100% rename from src/engine/components/anim/curveAnim/curveAnim/PropertyAnimation.ts rename to src/components/anim/curveAnim/curveAnim/PropertyAnimation.ts diff --git a/src/engine/components/anim/curveAnim/curveAnim/PropertyAnimationEvent.ts b/src/components/anim/curveAnim/curveAnim/PropertyAnimationEvent.ts similarity index 100% rename from src/engine/components/anim/curveAnim/curveAnim/PropertyAnimationEvent.ts rename to src/components/anim/curveAnim/curveAnim/PropertyAnimationEvent.ts diff --git a/src/engine/components/anim/curveAnim/curveAnim/PropertyHelp.ts b/src/components/anim/curveAnim/curveAnim/PropertyHelp.ts similarity index 100% rename from src/engine/components/anim/curveAnim/curveAnim/PropertyHelp.ts rename to src/components/anim/curveAnim/curveAnim/PropertyHelp.ts diff --git a/src/engine/components/anim/morphAnim/MorphTargetBlender.ts b/src/components/anim/morphAnim/MorphTargetBlender.ts similarity index 99% rename from src/engine/components/anim/morphAnim/MorphTargetBlender.ts rename to src/components/anim/morphAnim/MorphTargetBlender.ts index 13d33aaf..7e1af99a 100644 --- a/src/engine/components/anim/morphAnim/MorphTargetBlender.ts +++ b/src/components/anim/morphAnim/MorphTargetBlender.ts @@ -14,7 +14,7 @@ export class MorphTargetBlender extends ComponentBase { private _matrix4: Matrix4 = new Matrix4(); private _quaternion: Quaternion = new Quaternion(); - protected init(param?: any): void { + public init(param?: any): void { let meshRenders: MeshRenderer[] = this.fetchMorphRenderers(this.object3D); for (const renderer of meshRenders) { let hasMorphTarget = RendererMaskUtil.hasMask(renderer.rendererMask, RendererMask.MorphTarget); diff --git a/src/engine/components/anim/morphAnim/MorphTargetData.ts b/src/components/anim/morphAnim/MorphTargetData.ts similarity index 100% rename from src/engine/components/anim/morphAnim/MorphTargetData.ts rename to src/components/anim/morphAnim/MorphTargetData.ts diff --git a/src/engine/components/anim/morphAnim/MorphTargetFrame.ts b/src/components/anim/morphAnim/MorphTargetFrame.ts similarity index 100% rename from src/engine/components/anim/morphAnim/MorphTargetFrame.ts rename to src/components/anim/morphAnim/MorphTargetFrame.ts diff --git a/src/engine/components/anim/morphAnim/MorphTargetKey.ts b/src/components/anim/morphAnim/MorphTargetKey.ts similarity index 100% rename from src/engine/components/anim/morphAnim/MorphTargetKey.ts rename to src/components/anim/morphAnim/MorphTargetKey.ts diff --git a/src/engine/components/anim/morphAnim/MorphTarget_shader.ts b/src/components/anim/morphAnim/MorphTarget_shader.ts similarity index 100% rename from src/engine/components/anim/morphAnim/MorphTarget_shader.ts rename to src/components/anim/morphAnim/MorphTarget_shader.ts diff --git a/src/engine/components/anim/skeletonAnim/Joint.ts b/src/components/anim/skeletonAnim/Joint.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/Joint.ts rename to src/components/anim/skeletonAnim/Joint.ts diff --git a/src/engine/components/anim/skeletonAnim/JointPose.ts b/src/components/anim/skeletonAnim/JointPose.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/JointPose.ts rename to src/components/anim/skeletonAnim/JointPose.ts diff --git a/src/engine/components/anim/skeletonAnim/Skeleton.ts b/src/components/anim/skeletonAnim/Skeleton.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/Skeleton.ts rename to src/components/anim/skeletonAnim/Skeleton.ts diff --git a/src/engine/components/anim/skeletonAnim/SkeletonAnimationClip.ts b/src/components/anim/skeletonAnim/SkeletonAnimationClip.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/SkeletonAnimationClip.ts rename to src/components/anim/skeletonAnim/SkeletonAnimationClip.ts diff --git a/src/engine/components/anim/skeletonAnim/SkeletonAnimationClipState.ts b/src/components/anim/skeletonAnim/SkeletonAnimationClipState.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/SkeletonAnimationClipState.ts rename to src/components/anim/skeletonAnim/SkeletonAnimationClipState.ts diff --git a/src/engine/components/anim/skeletonAnim/SkeletonAnimationCompute.ts b/src/components/anim/skeletonAnim/SkeletonAnimationCompute.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/SkeletonAnimationCompute.ts rename to src/components/anim/skeletonAnim/SkeletonAnimationCompute.ts diff --git a/src/engine/components/anim/skeletonAnim/SkeletonPose.ts b/src/components/anim/skeletonAnim/SkeletonPose.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/SkeletonPose.ts rename to src/components/anim/skeletonAnim/SkeletonPose.ts diff --git a/src/engine/components/anim/skeletonAnim/buffer/SkeletonBlendComputeArgs.ts b/src/components/anim/skeletonAnim/buffer/SkeletonBlendComputeArgs.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/buffer/SkeletonBlendComputeArgs.ts rename to src/components/anim/skeletonAnim/buffer/SkeletonBlendComputeArgs.ts diff --git a/src/engine/components/anim/skeletonAnim/buffer/SkeletonTransformComputeArgs.ts b/src/components/anim/skeletonAnim/buffer/SkeletonTransformComputeArgs.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/buffer/SkeletonTransformComputeArgs.ts rename to src/components/anim/skeletonAnim/buffer/SkeletonTransformComputeArgs.ts diff --git a/src/engine/components/anim/skeletonAnim/shader/compute_skeleton_blend.ts b/src/components/anim/skeletonAnim/shader/compute_skeleton_blend.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/shader/compute_skeleton_blend.ts rename to src/components/anim/skeletonAnim/shader/compute_skeleton_blend.ts diff --git a/src/engine/components/anim/skeletonAnim/shader/compute_skeleton_transform.ts b/src/components/anim/skeletonAnim/shader/compute_skeleton_transform.ts similarity index 100% rename from src/engine/components/anim/skeletonAnim/shader/compute_skeleton_transform.ts rename to src/components/anim/skeletonAnim/shader/compute_skeleton_transform.ts diff --git a/src/engine/components/audio/AudioListener.ts b/src/components/audio/AudioListener.ts similarity index 94% rename from src/engine/components/audio/AudioListener.ts rename to src/components/audio/AudioListener.ts index ef73fe67..0148945b 100644 --- a/src/engine/components/audio/AudioListener.ts +++ b/src/components/audio/AudioListener.ts @@ -1,54 +1,54 @@ -import { ComponentBase } from '../ComponentBase'; - -/** - * Audio Listener - * Used in conjunction {@link PositionAudio} or {@link StaticAudio} - * @internal - * @group Audio - */ -export class AudioListener extends ComponentBase { - public readonly context: AudioContext; - public readonly gain: GainNode; - constructor() { - super(); - this.context = new AudioContext(); - this.gain = this.context.createGain(); - this.gain.connect(this.context.destination); - } - protected start() { - - } - protected update() { - if (!this.context) { - return; - } - const listener = this.context.listener; - const _position = this.object3D.transform.worldPosition; - const _orientation = this.object3D.transform.forward; - const up = this.object3D.transform.up; - if (isNaN(_orientation.x)) { - return; - } - if (listener.positionX) { - const endTime = this.context.currentTime; - listener.positionX.linearRampToValueAtTime(_position.x, endTime); - listener.positionY.linearRampToValueAtTime(_position.y, endTime); - listener.positionZ.linearRampToValueAtTime(_position.z, endTime); - listener.forwardX.linearRampToValueAtTime(_orientation.x, endTime); - listener.forwardY.linearRampToValueAtTime(_orientation.y, endTime); - listener.forwardZ.linearRampToValueAtTime(_orientation.z, endTime); - listener.upX.linearRampToValueAtTime(up.x, endTime); - listener.upY.linearRampToValueAtTime(up.y, endTime); - listener.upZ.linearRampToValueAtTime(up.z, endTime); - } else { - listener.setPosition(_position.x, _position.y, _position.z); - listener.setOrientation(_orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z); - } - } - - destroy() { - this.gain.disconnect(); - this.context.close(); - super.destroy(); - } -} +import { ComponentBase } from '../ComponentBase'; + +/** + * Audio Listener + * Used in conjunction {@link PositionAudio} or {@link StaticAudio} + * @internal + * @group Audio + */ +export class AudioListener extends ComponentBase { + public readonly context: AudioContext; + public readonly gain: GainNode; + constructor() { + super(); + this.context = new AudioContext(); + this.gain = this.context.createGain(); + this.gain.connect(this.context.destination); + } + public start() { + + } + public onUpdate() { + if (!this.context) { + return; + } + const listener = this.context.listener; + const _position = this.object3D.transform.worldPosition; + const _orientation = this.object3D.transform.forward; + const up = this.object3D.transform.up; + if (isNaN(_orientation.x)) { + return; + } + if (listener.positionX) { + const endTime = this.context.currentTime; + listener.positionX.linearRampToValueAtTime(_position.x, endTime); + listener.positionY.linearRampToValueAtTime(_position.y, endTime); + listener.positionZ.linearRampToValueAtTime(_position.z, endTime); + listener.forwardX.linearRampToValueAtTime(_orientation.x, endTime); + listener.forwardY.linearRampToValueAtTime(_orientation.y, endTime); + listener.forwardZ.linearRampToValueAtTime(_orientation.z, endTime); + listener.upX.linearRampToValueAtTime(up.x, endTime); + listener.upY.linearRampToValueAtTime(up.y, endTime); + listener.upZ.linearRampToValueAtTime(up.z, endTime); + } else { + listener.setPosition(_position.x, _position.y, _position.z); + listener.setOrientation(_orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z); + } + } + + destroy() { + this.gain.disconnect(); + this.context.close(); + super.destroy(); + } +} diff --git a/src/engine/components/audio/PositionAudio.ts b/src/components/audio/PositionAudio.ts similarity index 96% rename from src/engine/components/audio/PositionAudio.ts rename to src/components/audio/PositionAudio.ts index 73439adb..d7ab1008 100644 --- a/src/engine/components/audio/PositionAudio.ts +++ b/src/components/audio/PositionAudio.ts @@ -1,181 +1,181 @@ -import { Object3D } from '../../core/entities/Object3D'; -import { UnLitMaterial } from '../../materials/UnLitMaterial'; -import { Color } from '../../math/Color'; -import { Vector3 } from '../../math/Vector3'; -import { BoxGeometry } from '../../shape/BoxGeometry'; -import { MeshRenderer } from '../renderer/MeshRenderer'; -import { AudioListener } from './AudioListener'; -import { StaticAudio } from './StaticAudio'; -/** - * Dynamic audio component, with volume varying based on the relative position of the monitor - * @internal - * @group Audio - */ -export class PositionAudio extends StaticAudio { - public panner: PannerNode; - private _helper: boolean = false; - private _thickness: number = 0.1; - private _step: number = 16; - private _lines: Object3D[] = []; - constructor() { - super(); - } - public setLister(listener: AudioListener): this { - super.setLister(listener); - this.panner = this.context?.createPanner() as PannerNode; - this.panner.panningModel = 'HRTF'; - this.panner.connect(this.gainNode as GainNode); - return this; - } - public showHelper(thickness?: number, step?: number) { - this._helper = true - if (thickness) { - this._thickness = thickness; - } - if (step) { - this._step = step; - } - const innerAngle = this.panner.coneInnerAngle; - const outerAngle = this.panner.coneOuterAngle; - const diffAngle = (outerAngle - innerAngle) / 2; - let refLength = this.panner.refDistance; - let maxLength = this.panner.maxDistance; - let box = new BoxGeometry(1, 1, 1); - - let m1 = new UnLitMaterial(); - m1.baseColor = new Color(1, 0, 0); - let m2 = new UnLitMaterial(); - m2.baseColor = new Color(0, 0, 1); - let m3 = new UnLitMaterial(); - m3.baseColor = new Color(0, 1, 0); - let m4 = new UnLitMaterial(); - m4.baseColor = new Color(1, 1, 0); - for (let i = 0; i < this._step; i++) { - let group = new Object3D(); - let angle = (i * outerAngle) / (this._step - 1); - let isOuterAngle = angle < diffAngle || angle > innerAngle + diffAngle; - { - let line = new Object3D(); - let mr = line.addComponent(MeshRenderer); - mr.geometry = box; - mr.material = isOuterAngle ? m2 : m1; - mr.castShadow = false; - mr.castGI = false; - line.localScale = new Vector3(refLength, this._thickness, this._thickness); - line.x = refLength / 2; - group.addChild(line); - } - { - let line = new Object3D(); - let mr = line.addComponent(MeshRenderer); - mr.geometry = box; - mr.material = isOuterAngle ? m4 : m3; - mr.castShadow = false; - mr.castGI = false; - line.localScale = new Vector3(maxLength, this._thickness / 2, this._thickness / 2); - line.x = maxLength / 2; - group.addChild(line); - } - group.rotationY = -90 + outerAngle / 2 - angle; - this.object3D.addChild(group); - this._lines.push(group); - } - } - public hideHelper() { - this._helper = false; - for (let l of this._lines) { - l.removeAllChild(); - l.removeFromParent(); - l.dispose(); - } - this._lines.length = 0; - } - public toggleHelper() { - if (this._helper) { - this.hideHelper(); - } - else { - this.showHelper(); - } - } - public updateHeler() { - this.hideHelper(); - this.showHelper(); - } - public get refDistance() { - return this.panner.refDistance; - } - public set refDistance(value: number) { - this.panner.refDistance = value; - if (this._helper) { - this.updateHeler(); - } - } - public get rolloffFactor() { - return this.panner.rolloffFactor; - } - public set rolloffFactor(value: number) { - this.panner.rolloffFactor = value; - } - public get distanceModel() { - return this.panner.distanceModel; - } - public set distanceModel(value: DistanceModelType) { - this.panner.distanceModel = value; - } - public get maxDistance() { - return this.panner.maxDistance; - } - public set maxDistance(value: number) { - this.panner.maxDistance = value; - if (this._helper) { - this.updateHeler(); - } - } - - public setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number) { - this.panner.coneInnerAngle = coneInnerAngle; - this.panner.coneOuterAngle = coneOuterAngle; - this.panner.coneOuterGain = coneOuterGain; - if (this._helper) { - this.updateHeler(); - } - return this; - } - protected connect() { - this.source?.connect(this.panner); - } - public start() { - } - public stop(): this { - return super.stop(); - } - protected onUpdate() { - if (!this.playing) { - return; - } - const panner = this.panner; - const _position = this.object3D.transform.worldPosition; - const _orientation = this.object3D.transform.forward; - if (isNaN(_orientation.x)) { - return; - } - if (panner.positionX && this.context) { - const endTime = this.context.currentTime; - panner.positionX.linearRampToValueAtTime(_position.x, endTime); - panner.positionY.linearRampToValueAtTime(_position.y, endTime); - panner.positionZ.linearRampToValueAtTime(_position.z, endTime); - panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime); - panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime); - panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime); - } else { - panner.setPosition(_position.x, _position.y, _position.z); - panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); - } - } - public destroy() { - this.panner.disconnect(); - this.hideHelper(); - super.destroy(); - } -} +import { Object3D } from '../../core/entities/Object3D'; +import { UnLitMaterial } from '../../materials/UnLitMaterial'; +import { Color } from '../../math/Color'; +import { Vector3 } from '../../math/Vector3'; +import { BoxGeometry } from '../../shape/BoxGeometry'; +import { MeshRenderer } from '../renderer/MeshRenderer'; +import { AudioListener } from './AudioListener'; +import { StaticAudio } from './StaticAudio'; +/** + * Dynamic audio component, with volume varying based on the relative position of the monitor + * @internal + * @group Audio + */ +export class PositionAudio extends StaticAudio { + public panner: PannerNode; + private _helper: boolean = false; + private _thickness: number = 0.1; + private _step: number = 16; + private _lines: Object3D[] = []; + constructor() { + super(); + } + public setLister(listener: AudioListener): this { + super.setLister(listener); + this.panner = this.context?.createPanner() as PannerNode; + this.panner.panningModel = 'HRTF'; + this.panner.connect(this.gainNode as GainNode); + return this; + } + public showHelper(thickness?: number, step?: number) { + this._helper = true + if (thickness) { + this._thickness = thickness; + } + if (step) { + this._step = step; + } + const innerAngle = this.panner.coneInnerAngle; + const outerAngle = this.panner.coneOuterAngle; + const diffAngle = (outerAngle - innerAngle) / 2; + let refLength = this.panner.refDistance; + let maxLength = this.panner.maxDistance; + let box = new BoxGeometry(1, 1, 1); + + let m1 = new UnLitMaterial(); + m1.baseColor = new Color(1, 0, 0); + let m2 = new UnLitMaterial(); + m2.baseColor = new Color(0, 0, 1); + let m3 = new UnLitMaterial(); + m3.baseColor = new Color(0, 1, 0); + let m4 = new UnLitMaterial(); + m4.baseColor = new Color(1, 1, 0); + for (let i = 0; i < this._step; i++) { + let group = new Object3D(); + let angle = (i * outerAngle) / (this._step - 1); + let isOuterAngle = angle < diffAngle || angle > innerAngle + diffAngle; + { + let line = new Object3D(); + let mr = line.addComponent(MeshRenderer); + mr.geometry = box; + mr.material = isOuterAngle ? m2 : m1; + mr.castShadow = false; + mr.castGI = false; + line.localScale = new Vector3(refLength, this._thickness, this._thickness); + line.x = refLength / 2; + group.addChild(line); + } + { + let line = new Object3D(); + let mr = line.addComponent(MeshRenderer); + mr.geometry = box; + mr.material = isOuterAngle ? m4 : m3; + mr.castShadow = false; + mr.castGI = false; + line.localScale = new Vector3(maxLength, this._thickness / 2, this._thickness / 2); + line.x = maxLength / 2; + group.addChild(line); + } + group.rotationY = -90 + outerAngle / 2 - angle; + this.object3D.addChild(group); + this._lines.push(group); + } + } + public hideHelper() { + this._helper = false; + for (let l of this._lines) { + l.removeAllChild(); + l.removeFromParent(); + l.dispose(); + } + this._lines.length = 0; + } + public toggleHelper() { + if (this._helper) { + this.hideHelper(); + } + else { + this.showHelper(); + } + } + public updateHeler() { + this.hideHelper(); + this.showHelper(); + } + public get refDistance() { + return this.panner.refDistance; + } + public set refDistance(value: number) { + this.panner.refDistance = value; + if (this._helper) { + this.updateHeler(); + } + } + public get rolloffFactor() { + return this.panner.rolloffFactor; + } + public set rolloffFactor(value: number) { + this.panner.rolloffFactor = value; + } + public get distanceModel() { + return this.panner.distanceModel; + } + public set distanceModel(value: DistanceModelType) { + this.panner.distanceModel = value; + } + public get maxDistance() { + return this.panner.maxDistance; + } + public set maxDistance(value: number) { + this.panner.maxDistance = value; + if (this._helper) { + this.updateHeler(); + } + } + + public setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number) { + this.panner.coneInnerAngle = coneInnerAngle; + this.panner.coneOuterAngle = coneOuterAngle; + this.panner.coneOuterGain = coneOuterGain; + if (this._helper) { + this.updateHeler(); + } + return this; + } + protected connect() { + this.source?.connect(this.panner); + } + public start() { + } + public stop(): this { + return super.stop(); + } + public onUpdate() { + if (!this.playing) { + return; + } + const panner = this.panner; + const _position = this.object3D.transform.worldPosition; + const _orientation = this.object3D.transform.forward; + if (isNaN(_orientation.x)) { + return; + } + if (panner.positionX && this.context) { + const endTime = this.context.currentTime; + panner.positionX.linearRampToValueAtTime(_position.x, endTime); + panner.positionY.linearRampToValueAtTime(_position.y, endTime); + panner.positionZ.linearRampToValueAtTime(_position.z, endTime); + panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime); + panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime); + panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime); + } else { + panner.setPosition(_position.x, _position.y, _position.z); + panner.setOrientation(_orientation.x, _orientation.y, _orientation.z); + } + } + public destroy() { + this.panner.disconnect(); + this.hideHelper(); + super.destroy(); + } +} diff --git a/src/engine/components/audio/StaticAudio.ts b/src/components/audio/StaticAudio.ts similarity index 96% rename from src/engine/components/audio/StaticAudio.ts rename to src/components/audio/StaticAudio.ts index 448b9c0a..cdc18294 100644 --- a/src/engine/components/audio/StaticAudio.ts +++ b/src/components/audio/StaticAudio.ts @@ -1,114 +1,114 @@ -import { ComponentBase } from '../ComponentBase'; -import { AudioListener } from './AudioListener'; -/** - * Static audio component, volume level does not vary depending on the position of the monitor - * @internal - * @group Audio - */ -export class StaticAudio extends ComponentBase { - private listener: AudioListener | null = null; - public context: AudioContext | null = null; - public gainNode: GainNode | null = null; - public source: AudioBufferSourceNode | null = null - private _options = { - loop: true, - volume: 1, - }; - public playing = false; - private _currentTime: number = 0; - private _buffer: AudioBuffer | null = null - constructor() { - super(); - } - public setLister(listener: AudioListener): this { - this.listener = listener; - this.context = listener.context as AudioContext; - this.gainNode = this.context.createGain(); - this.gainNode.connect(this.listener.gain); - - this.context.addEventListener('statechange', () => { - if (this.context?.state === 'closed') { - console.warn('AudioListener removed'); - this.stop(); - this.gainNode?.disconnect(); - this.listener = null; - this.context = null; - this.gainNode = null; - } - }) - return this; - } - async load(url: string, options: {} = {}) { - Object.assign(this._options, options); - let req = await fetch(url); - let buffer = await req.arrayBuffer(); - this._buffer = await this.context?.decodeAudioData(buffer) as AudioBuffer; - } - async loadBuffer(buffer: ArrayBuffer, options: {} = {}) { - Object.assign(this._options, options); - this._buffer = await this.context?.decodeAudioData(buffer) as AudioBuffer; - } - // loadAudio(mediaElement: HTMLAudioElement) { - // this.element = mediaElement; - // this.source = this.context.createMediaElementSource(mediaElement); - // this.connect(); - // } - public play(): this { - if (!this.context) { - console.warn('no audio source yet'); - return this; - } - if (this.playing) { - console.warn('Audio is alredy playing'); - return this; - } - if (!this._buffer) { - console.warn('Audio is not ready'); - return this; - } - const source = this.context.createBufferSource(); - source.buffer = this._buffer; - source.loop = this._options.loop; - this.source = source; - this.connect(); - this.source.start(0, this._currentTime); - this.setVolume(this._options.volume); - this.playing = true; - return this; - } - public pause(): this { - if (!this.playing) { - console.warn('Audio is not playing'); - return this; - } - this._currentTime = this.context?.currentTime || 0; - this.source?.stop(); - this.source?.disconnect(); - this.playing = false; - return this; - } - public stop(): this { - this.pause(); - this._currentTime = 0; - return this; - } - public setVolume(value: number): this { - if (!this.context) { - console.warn('no audio source yet'); - return this; - } - this.gainNode?.gain.setTargetAtTime(value, this.context ? this.context.currentTime : 0, 0.01); - return this; - } - protected connect() { - this.source?.connect(this.gainNode as GainNode); - } - protected onUpdate() { - super.onUpdate(); - } - public destroy() { - this.stop(); - this.gainNode?.disconnect(); - super.destroy(); - } -} +import { ComponentBase } from '../ComponentBase'; +import { AudioListener } from './AudioListener'; +/** + * Static audio component, volume level does not vary depending on the position of the monitor + * @internal + * @group Audio + */ +export class StaticAudio extends ComponentBase { + private listener: AudioListener | null = null; + public context: AudioContext | null = null; + public gainNode: GainNode | null = null; + public source: AudioBufferSourceNode | null = null + private _options = { + loop: true, + volume: 1, + }; + public playing = false; + private _currentTime: number = 0; + private _buffer: AudioBuffer | null = null + constructor() { + super(); + } + public setLister(listener: AudioListener): this { + this.listener = listener; + this.context = listener.context as AudioContext; + this.gainNode = this.context.createGain(); + this.gainNode.connect(this.listener.gain); + + this.context.addEventListener('statechange', () => { + if (this.context?.state === 'closed') { + console.warn('AudioListener removed'); + this.stop(); + this.gainNode?.disconnect(); + this.listener = null; + this.context = null; + this.gainNode = null; + } + }) + return this; + } + async load(url: string, options: {} = {}) { + Object.assign(this._options, options); + let req = await fetch(url); + let buffer = await req.arrayBuffer(); + this._buffer = await this.context?.decodeAudioData(buffer) as AudioBuffer; + } + async loadBuffer(buffer: ArrayBuffer, options: {} = {}) { + Object.assign(this._options, options); + this._buffer = await this.context?.decodeAudioData(buffer) as AudioBuffer; + } + // loadAudio(mediaElement: HTMLAudioElement) { + // this.element = mediaElement; + // this.source = this.context.createMediaElementSource(mediaElement); + // this.connect(); + // } + public play(): this { + if (!this.context) { + console.warn('no audio source yet'); + return this; + } + if (this.playing) { + console.warn('Audio is alredy playing'); + return this; + } + if (!this._buffer) { + console.warn('Audio is not ready'); + return this; + } + const source = this.context.createBufferSource(); + source.buffer = this._buffer; + source.loop = this._options.loop; + this.source = source; + this.connect(); + this.source.start(0, this._currentTime); + this.setVolume(this._options.volume); + this.playing = true; + return this; + } + public pause(): this { + if (!this.playing) { + console.warn('Audio is not playing'); + return this; + } + this._currentTime = this.context?.currentTime || 0; + this.source?.stop(); + this.source?.disconnect(); + this.playing = false; + return this; + } + public stop(): this { + this.pause(); + this._currentTime = 0; + return this; + } + public setVolume(value: number): this { + if (!this.context) { + console.warn('no audio source yet'); + return this; + } + this.gainNode?.gain.setTargetAtTime(value, this.context ? this.context.currentTime : 0, 0.01); + return this; + } + protected connect() { + this.source?.connect(this.gainNode as GainNode); + } + public onUpdate() { + super.onUpdate(); + } + public destroy() { + this.stop(); + this.gainNode?.disconnect(); + super.destroy(); + } +} diff --git a/src/engine/components/controller/CameraControllerBase.ts b/src/components/controller/CameraControllerBase.ts similarity index 100% rename from src/engine/components/controller/CameraControllerBase.ts rename to src/components/controller/CameraControllerBase.ts diff --git a/src/engine/components/controller/FirstPersonCameraController.ts b/src/components/controller/FirstPersonCameraController.ts similarity index 99% rename from src/engine/components/controller/FirstPersonCameraController.ts rename to src/components/controller/FirstPersonCameraController.ts index 7bd75f43..4f047849 100644 --- a/src/engine/components/controller/FirstPersonCameraController.ts +++ b/src/components/controller/FirstPersonCameraController.ts @@ -20,7 +20,7 @@ export class FirstPersonCameraController extends ComponentBase { super(); } - protected start() { + public start() { this._camera = this.object3D.getOrAddComponent(Camera3D); if (!this._camera) { console.error('FirstPersonCameraController need camera'); diff --git a/src/engine/components/controller/FlyCameraController.ts b/src/components/controller/FlyCameraController.ts similarity index 99% rename from src/engine/components/controller/FlyCameraController.ts rename to src/components/controller/FlyCameraController.ts index d902df9a..09897f96 100644 --- a/src/engine/components/controller/FlyCameraController.ts +++ b/src/components/controller/FlyCameraController.ts @@ -80,7 +80,7 @@ export class FlyCameraController extends ComponentBase { /** * @internal */ - protected start(): void { + public start(): void { Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_WHEEL, this.mouseWheel, this); Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_UP, this.mouseUp, this); Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_DOWN, this.mouseDown, this); diff --git a/src/engine/components/controller/HoverCameraController.ts b/src/components/controller/HoverCameraController.ts similarity index 99% rename from src/engine/components/controller/HoverCameraController.ts rename to src/components/controller/HoverCameraController.ts index 8416b625..9c9be517 100644 --- a/src/engine/components/controller/HoverCameraController.ts +++ b/src/components/controller/HoverCameraController.ts @@ -115,7 +115,7 @@ export class HoverCameraController extends ComponentBase { /** * @internal */ - protected start(): void { + public start(): void { this.camera = this.object3D.getOrAddComponent(Camera3D); Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_DOWN, this.onMouseDown, this); Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_MOVE, this.onMouseMove, this); diff --git a/src/engine/components/controller/OrbitController.ts b/src/components/controller/OrbitController.ts similarity index 96% rename from src/engine/components/controller/OrbitController.ts rename to src/components/controller/OrbitController.ts index a3b6d1e1..bdf3700a 100644 --- a/src/engine/components/controller/OrbitController.ts +++ b/src/components/controller/OrbitController.ts @@ -1,338 +1,338 @@ -import { Engine3D } from '../../Engine3D'; -import { Camera3D } from '../../core/Camera3D'; -import { ComponentBase } from '../ComponentBase'; -import { Vector3 } from '../../math/Vector3'; -import { Vector3Ex } from '../../util/Vector3Ex'; -import { clamp } from '../../math/MathUtil'; -import { PointerEvent3D } from '../../event/eventConst/PointerEvent3D'; - -/** - * Orbit Camera Controller - * @group CameraController - */ -export class OrbitController extends ComponentBase { - /** - * internal camera - */ - private _camera: Camera3D; - /** - * Whether to enable automatic rotation - */ - public autoRotate: boolean = false; - /** - * Automatic rotation speed coefficient - */ - public autoRotateSpeed: number = 0.1; - /** - * Rotation speed coefficient - */ - public rotateFactor: number = 0.5; - /** - * Scale speed coefficient - */ - public zoomFactor: number = 0.1; - /** - * Angle translation velocity coefficient - */ - public panFactor: number = 0.25; - - private _smooth: number = 5; - private _minDistance: number = 1; - private _maxDistance: number = 100000; - private _maxPolarAngle: number = 90; - private _minPolarAngle: number = -90; - private _target: Vector3 = new Vector3(0, 0, 0); - private _cTarget: Vector3 = new Vector3(0, 0, 0); - private _position: Vector3 = new Vector3(0, 0, 0); - private _cPosition: Vector3 = new Vector3(0, 0, 0); - private _spherical: Spherical = new Spherical() - private _isMouseDown: boolean = false; - private _lastMouseX: number = -1; - private _lastMouseY: number = -1; - private _isPanning: boolean = false - - /** - * @constructor - */ - constructor() { - super(); - } - /** - * Get the target position - */ - public get target(): Vector3 { - return this._target; - } - /** - * Set the target position - */ - public set target(v: Vector3) { - this._target = v; - } - - /** - * Set smoothing coefficient of controller - */ - public get smooth(): number { - return this._smooth; - } - /** - * Get smoothing coefficient of controller - */ - public set smooth(v: number) { - this._smooth = Math.max(v, 1) - } - /** - * Get the minimum distance between the camera and the target coordinate - * @defaultValue 1 - */ - public get minDistance(): number { - return this._minDistance; - } - /** - * Set the minimum distance between the camera and the target position - * min value: 0.000002 - * max value: `this._maxDistance` {@link maxDistance} - */ - public set minDistance(v: number) { - this._minDistance = clamp(v, 0.000002, this._maxDistance); - } - /** - * Get the max distance between the camera and the target position - * @defaultValue 100000 - */ - public get maxDistance(): number { - return this._maxDistance; - } - /** - * Set the max distance between the camera and the target position - * min - `this._maxDistance` - * max - Infinity - */ - public set maxDistance(v: number) { - this._maxDistance = clamp(v, this._minDistance, Infinity); - } - - /** - * Get the lower elevation limit of the camera from the xz plane - * @defaultValue -90 - */ - public get minPolarAngle(): number { - return this._minPolarAngle; - } - /** - * Set the lower elevation limit of the camera from the xz plane - * min - -90 - * max - {@link maxPolarAngle} - */ - public set minPolarAngle(v: number) { - this._minPolarAngle = clamp(v, -90, this._maxPolarAngle); - } - /** - * Get the upper elevation limit of the camera from the xz plane - * @defaultValue 90 - */ - public get maxPolarAngle(): number { - return this._maxPolarAngle; - } - /** - * Set the upper elevation limit of the camera to the xz plane - * min - less than {@link minPolarAngle} - * max - 90 - */ - public set maxPolarAngle(v: number) { - this._maxPolarAngle = clamp(v, this._minPolarAngle, 90); - } - /** - * @internal - */ - protected start() { - this._camera = this.object3D.getComponent(Camera3D); - this._position = this.object3D.transform.localPosition.clone(); - this._cPosition = this._position.clone(); - this._target = this._camera.lookTarget.clone() - this._cTarget = this._target.clone() - this._spherical.setCoords(this._position.x - this._target.x, this._position.y - this._target.y, this._position.z - this._target.z) - this._camera.lookAt(this._cPosition, this._cTarget, Vector3.UP); - this.addEventListener() - } - /** - * @internal - */ - protected onEnable() { - this.addEventListener() - } - /** - * @internal - */ - protected onDisable() { - this.removeEventListener() - } - /** - * @internal - */ - protected onUpdate() { - let step = this._isPanning ? 1 : this.smooth - let changed = false - if (!this._cPosition.equals(this.object3D.transform.localPosition)) { - this._position.copyFrom(this.object3D.transform.localPosition) - step = 1 - changed = true - } - if (!this._cTarget.equals(this._target)) { - this._cTarget.copyFrom(this._target) - step = 1 - changed = true - } - if (changed) { - this._spherical.setCoords(this._position.x - this._target.x, this._position.y - this._target.y, this._position.z - this._target.z) - } else if (!this._isMouseDown && this.autoRotate) { - this._spherical.theta -= this.autoRotateSpeed * Math.PI / 180; - this.updateCamera(); - } - let x = (this._position.x - this._cPosition.x) / step - let y = (this._position.y - this._cPosition.y) / step - let z = (this._position.z - this._cPosition.z) / step - this._cPosition.x = Math.abs(x) > 1e-10 ? this._cPosition.x + x : this._position.x - this._cPosition.y = Math.abs(y) > 1e-10 ? this._cPosition.y + y : this._position.y - this._cPosition.z = Math.abs(z) > 1e-10 ? this._cPosition.z + z : this._position.z - this._camera.lookAt(this._cPosition, this._cTarget, Vector3.UP); - } - /** - * @internal - */ - private onWheel(e: PointerEvent3D) { - this._spherical.radius += e.deltaY * this.zoomFactor; - this._spherical.radius = clamp(this._spherical.radius, this.minDistance, this.maxDistance); - this.updateCamera(); - } - /** - * @internal - */ - private onPointerDown(e: PointerEvent3D) { - this._isMouseDown = true; - this._lastMouseX = e.mouseX; - this._lastMouseY = e.mouseY; - if (e.mouseCode === 2) - this._isPanning = true - } - /** - * @internal - */ - private onPointerMove(e: PointerEvent3D) { - if (!this._isMouseDown || !this.enable) return; - let mousex = e.mouseX; - let mousey = e.mouseY; - // rotate - if (e.mouseCode === 0 && this._lastMouseX > 0 && this._lastMouseY > 0) { - const ra = -(mousex - this._lastMouseX) * this.rotateFactor; - const rb = (mousey - this._lastMouseY) * this.rotateFactor; - this._spherical.theta += ra * Math.PI / 180; - this._spherical.phi -= rb * Math.PI / 180; - this._spherical.phi = clamp(this._spherical.phi, this.minPolarAngle, this.maxPolarAngle); - this.updateCamera(); - // pan - } else if (e.mouseCode === 2) { - Vector3Ex.mulScale(this.object3D.transform.up, e.movementY * this.panFactor * this._camera.aspect, Vector3.HELP_1); - this._target.y += Vector3.HELP_1.y; - Vector3Ex.mulScale(this.object3D.transform.right, -e.movementX * this.panFactor, Vector3.HELP_1); - this._target.x -= Vector3.HELP_1.x; - this._target.z -= Vector3.HELP_1.z; - this._cTarget.copyFrom(this._target) - this.updateCamera(); - } - this._lastMouseX = mousex; - this._lastMouseY = mousey; - } - /** - * @internal - */ - private onPointerUp(e: PointerEvent3D) { - this._isMouseDown = false; - if (e.mouseCode === 2) { - this._isPanning = false; - } - } - private onPointerLeave() { - this._isMouseDown = false; - this._isPanning = false; - } - /** - * @internal - */ - private updateCamera() { - this._spherical.makeSafe(); - let pos = this._spherical.getCoords(); - this._position.set(pos.x + this._target.x, pos.y + this._target.y, pos.z + this._target.z); - } - /** - * @internal - */ - private addEventListener() { - Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_WHEEL, this.onWheel, this); - Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_DOWN, this.onPointerDown, this); - Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_MOVE, this.onPointerMove, this); - Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_UP, this.onPointerUp, this); - Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_OUT, this.onPointerLeave, this); - } - /** - * @internal - */ - private removeEventListener() { - Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_WHEEL, this.onWheel, this); - Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_DOWN, this.onPointerDown, this); - Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_MOVE, this.onPointerMove, this); - Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_UP, this.onPointerUp, this); - Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_OUT, this.onPointerLeave, this); - } -} - -/** - * @internal - */ -class Spherical { - public radius: number; - public phi: number; - public theta: number; - public coords: Vector3; - constructor(radius = 1, phi = 0, theta = 0) { - this.radius = radius; - this.phi = phi; // polar angle - this.theta = theta; // azimuthal angle - this.coords = new Vector3() - return this; - } - public set(radius: number, phi: number, theta: number) { - this.radius = radius; - this.phi = phi; - this.theta = theta; - return this; - } - // restrict phi to be between EPS and PI-EPS - public makeSafe(): this { - const EPS = 0.0002; - this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); - return this; - } - public setFromVector3(v: Vector3): this { - return this.setCoords(v.x, v.y, v.z); - } - public setCoords(x: number, y: number, z: number): this { - this.radius = Math.sqrt(x * x + y * y + z * z); - if (this.radius === 0) { - this.theta = 0; - this.phi = 0; - } else { - this.theta = Math.atan2(x, z); - this.phi = Math.acos(clamp(y / this.radius, - 1, 1)); - } - return this; - } - public getCoords(): Vector3 { - const sinPhiRadius = Math.sin(this.phi) * this.radius; - this.coords.x = sinPhiRadius * Math.sin(this.theta); - this.coords.y = Math.cos(this.phi) * this.radius; - this.coords.z = sinPhiRadius * Math.cos(this.theta); - return this.coords; - } +import { Engine3D } from '../../Engine3D'; +import { Camera3D } from '../../core/Camera3D'; +import { ComponentBase } from '../ComponentBase'; +import { Vector3 } from '../../math/Vector3'; +import { Vector3Ex } from '../../util/Vector3Ex'; +import { clamp } from '../../math/MathUtil'; +import { PointerEvent3D } from '../../event/eventConst/PointerEvent3D'; + +/** + * Orbit Camera Controller + * @group CameraController + */ +export class OrbitController extends ComponentBase { + /** + * internal camera + */ + private _camera: Camera3D; + /** + * Whether to enable automatic rotation + */ + public autoRotate: boolean = false; + /** + * Automatic rotation speed coefficient + */ + public autoRotateSpeed: number = 0.1; + /** + * Rotation speed coefficient + */ + public rotateFactor: number = 0.5; + /** + * Scale speed coefficient + */ + public zoomFactor: number = 0.1; + /** + * Angle translation velocity coefficient + */ + public panFactor: number = 0.25; + + private _smooth: number = 5; + private _minDistance: number = 1; + private _maxDistance: number = 100000; + private _maxPolarAngle: number = 90; + private _minPolarAngle: number = -90; + private _target: Vector3 = new Vector3(0, 0, 0); + private _cTarget: Vector3 = new Vector3(0, 0, 0); + private _position: Vector3 = new Vector3(0, 0, 0); + private _cPosition: Vector3 = new Vector3(0, 0, 0); + private _spherical: Spherical = new Spherical() + private _isMouseDown: boolean = false; + private _lastMouseX: number = -1; + private _lastMouseY: number = -1; + private _isPanning: boolean = false + + /** + * @constructor + */ + constructor() { + super(); + } + /** + * Get the target position + */ + public get target(): Vector3 { + return this._target; + } + /** + * Set the target position + */ + public set target(v: Vector3) { + this._target = v; + } + + /** + * Set smoothing coefficient of controller + */ + public get smooth(): number { + return this._smooth; + } + /** + * Get smoothing coefficient of controller + */ + public set smooth(v: number) { + this._smooth = Math.max(v, 1) + } + /** + * Get the minimum distance between the camera and the target coordinate + * @defaultValue 1 + */ + public get minDistance(): number { + return this._minDistance; + } + /** + * Set the minimum distance between the camera and the target position + * min value: 0.000002 + * max value: `this._maxDistance` {@link maxDistance} + */ + public set minDistance(v: number) { + this._minDistance = clamp(v, 0.000002, this._maxDistance); + } + /** + * Get the max distance between the camera and the target position + * @defaultValue 100000 + */ + public get maxDistance(): number { + return this._maxDistance; + } + /** + * Set the max distance between the camera and the target position + * min - `this._maxDistance` + * max - Infinity + */ + public set maxDistance(v: number) { + this._maxDistance = clamp(v, this._minDistance, Infinity); + } + + /** + * Get the lower elevation limit of the camera from the xz plane + * @defaultValue -90 + */ + public get minPolarAngle(): number { + return this._minPolarAngle; + } + /** + * Set the lower elevation limit of the camera from the xz plane + * min - -90 + * max - {@link maxPolarAngle} + */ + public set minPolarAngle(v: number) { + this._minPolarAngle = clamp(v, -90, this._maxPolarAngle); + } + /** + * Get the upper elevation limit of the camera from the xz plane + * @defaultValue 90 + */ + public get maxPolarAngle(): number { + return this._maxPolarAngle; + } + /** + * Set the upper elevation limit of the camera to the xz plane + * min - less than {@link minPolarAngle} + * max - 90 + */ + public set maxPolarAngle(v: number) { + this._maxPolarAngle = clamp(v, this._minPolarAngle, 90); + } + /** + * @internal + */ + public start() { + this._camera = this.object3D.getComponent(Camera3D); + this._position = this.object3D.transform.localPosition.clone(); + this._cPosition = this._position.clone(); + this._target = this._camera.lookTarget.clone() + this._cTarget = this._target.clone() + this._spherical.setCoords(this._position.x - this._target.x, this._position.y - this._target.y, this._position.z - this._target.z) + this._camera.lookAt(this._cPosition, this._cTarget, Vector3.UP); + this.addEventListener() + } + /** + * @internal + */ + public onEnable() { + this.addEventListener() + } + /** + * @internal + */ + public onDisable() { + this.removeEventListener() + } + /** + * @internal + */ + public onUpdate() { + let step = this._isPanning ? 1 : this.smooth + let changed = false + if (!this._cPosition.equals(this.object3D.transform.localPosition)) { + this._position.copyFrom(this.object3D.transform.localPosition) + step = 1 + changed = true + } + if (!this._cTarget.equals(this._target)) { + this._cTarget.copyFrom(this._target) + step = 1 + changed = true + } + if (changed) { + this._spherical.setCoords(this._position.x - this._target.x, this._position.y - this._target.y, this._position.z - this._target.z) + } else if (!this._isMouseDown && this.autoRotate) { + this._spherical.theta -= this.autoRotateSpeed * Math.PI / 180; + this.updateCamera(); + } + let x = (this._position.x - this._cPosition.x) / step + let y = (this._position.y - this._cPosition.y) / step + let z = (this._position.z - this._cPosition.z) / step + this._cPosition.x = Math.abs(x) > 1e-10 ? this._cPosition.x + x : this._position.x + this._cPosition.y = Math.abs(y) > 1e-10 ? this._cPosition.y + y : this._position.y + this._cPosition.z = Math.abs(z) > 1e-10 ? this._cPosition.z + z : this._position.z + this._camera.lookAt(this._cPosition, this._cTarget, Vector3.UP); + } + /** + * @internal + */ + private onWheel(e: PointerEvent3D) { + this._spherical.radius += e.deltaY * this.zoomFactor; + this._spherical.radius = clamp(this._spherical.radius, this.minDistance, this.maxDistance); + this.updateCamera(); + } + /** + * @internal + */ + private onPointerDown(e: PointerEvent3D) { + this._isMouseDown = true; + this._lastMouseX = e.mouseX; + this._lastMouseY = e.mouseY; + if (e.mouseCode === 2) + this._isPanning = true + } + /** + * @internal + */ + private onPointerMove(e: PointerEvent3D) { + if (!this._isMouseDown || !this.enable) return; + let mousex = e.mouseX; + let mousey = e.mouseY; + // rotate + if (e.mouseCode === 0 && this._lastMouseX > 0 && this._lastMouseY > 0) { + const ra = -(mousex - this._lastMouseX) * this.rotateFactor; + const rb = (mousey - this._lastMouseY) * this.rotateFactor; + this._spherical.theta += ra * Math.PI / 180; + this._spherical.phi -= rb * Math.PI / 180; + this._spherical.phi = clamp(this._spherical.phi, this.minPolarAngle, this.maxPolarAngle); + this.updateCamera(); + // pan + } else if (e.mouseCode === 2) { + Vector3Ex.mulScale(this.object3D.transform.up, e.movementY * this.panFactor * this._camera.aspect, Vector3.HELP_1); + this._target.y += Vector3.HELP_1.y; + Vector3Ex.mulScale(this.object3D.transform.right, -e.movementX * this.panFactor, Vector3.HELP_1); + this._target.x -= Vector3.HELP_1.x; + this._target.z -= Vector3.HELP_1.z; + this._cTarget.copyFrom(this._target) + this.updateCamera(); + } + this._lastMouseX = mousex; + this._lastMouseY = mousey; + } + /** + * @internal + */ + private onPointerUp(e: PointerEvent3D) { + this._isMouseDown = false; + if (e.mouseCode === 2) { + this._isPanning = false; + } + } + private onPointerLeave() { + this._isMouseDown = false; + this._isPanning = false; + } + /** + * @internal + */ + private updateCamera() { + this._spherical.makeSafe(); + let pos = this._spherical.getCoords(); + this._position.set(pos.x + this._target.x, pos.y + this._target.y, pos.z + this._target.z); + } + /** + * @internal + */ + private addEventListener() { + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_WHEEL, this.onWheel, this); + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_DOWN, this.onPointerDown, this); + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_MOVE, this.onPointerMove, this); + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_UP, this.onPointerUp, this); + Engine3D.inputSystem.addEventListener(PointerEvent3D.POINTER_OUT, this.onPointerLeave, this); + } + /** + * @internal + */ + private removeEventListener() { + Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_WHEEL, this.onWheel, this); + Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_DOWN, this.onPointerDown, this); + Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_MOVE, this.onPointerMove, this); + Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_UP, this.onPointerUp, this); + Engine3D.inputSystem.removeEventListener(PointerEvent3D.POINTER_OUT, this.onPointerLeave, this); + } +} + +/** + * @internal + */ +class Spherical { + public radius: number; + public phi: number; + public theta: number; + public coords: Vector3; + constructor(radius = 1, phi = 0, theta = 0) { + this.radius = radius; + this.phi = phi; // polar angle + this.theta = theta; // azimuthal angle + this.coords = new Vector3() + return this; + } + public set(radius: number, phi: number, theta: number) { + this.radius = radius; + this.phi = phi; + this.theta = theta; + return this; + } + // restrict phi to be between EPS and PI-EPS + public makeSafe(): this { + const EPS = 0.0002; + this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); + return this; + } + public setFromVector3(v: Vector3): this { + return this.setCoords(v.x, v.y, v.z); + } + public setCoords(x: number, y: number, z: number): this { + this.radius = Math.sqrt(x * x + y * y + z * z); + if (this.radius === 0) { + this.theta = 0; + this.phi = 0; + } else { + this.theta = Math.atan2(x, z); + this.phi = Math.acos(clamp(y / this.radius, - 1, 1)); + } + return this; + } + public getCoords(): Vector3 { + const sinPhiRadius = Math.sin(this.phi) * this.radius; + this.coords.x = sinPhiRadius * Math.sin(this.theta); + this.coords.y = Math.cos(this.phi) * this.radius; + this.coords.z = sinPhiRadius * Math.cos(this.theta); + return this.coords; + } } \ No newline at end of file diff --git a/src/engine/components/controller/ThirdPersonCameraController.ts b/src/components/controller/ThirdPersonCameraController.ts similarity index 99% rename from src/engine/components/controller/ThirdPersonCameraController.ts rename to src/components/controller/ThirdPersonCameraController.ts index d5e541ed..0cc0d980 100644 --- a/src/engine/components/controller/ThirdPersonCameraController.ts +++ b/src/components/controller/ThirdPersonCameraController.ts @@ -21,7 +21,7 @@ export class ThirdPersonCameraController extends ComponentBase { super(); } - protected start() { + public start() { this._camera = this.object3D.getOrAddComponent(Camera3D); if (!this._camera) { console.error('ThirdPersonCameraController need camera'); diff --git a/src/engine/components/lights/DirectLight.ts b/src/components/lights/DirectLight.ts similarity index 97% rename from src/engine/components/lights/DirectLight.ts rename to src/components/lights/DirectLight.ts index 9c043395..cd526f9a 100644 --- a/src/engine/components/lights/DirectLight.ts +++ b/src/components/lights/DirectLight.ts @@ -15,7 +15,7 @@ export class DirectLight extends LightBase { super(); } - protected init(): void { + public init(): void { super.init(); if (this.object3D.name == "") { this.object3D.name = "DirectionLight_" + UUID(); @@ -25,7 +25,7 @@ export class DirectLight extends LightBase { this.lightData.linear = 0; } - protected start(): void { + public start(): void { super.start(); this.castGI = true; } diff --git a/src/engine/components/lights/GILighting.ts b/src/components/lights/GILighting.ts similarity index 68% rename from src/engine/components/lights/GILighting.ts rename to src/components/lights/GILighting.ts index 947ed8a6..c6f1525e 100644 --- a/src/engine/components/lights/GILighting.ts +++ b/src/components/lights/GILighting.ts @@ -1,4 +1,4 @@ -import { LightBase } from './LightBase'; +import { ILight } from "./ILight"; /** * Collecting and storing light that affects GI @@ -6,15 +6,15 @@ import { LightBase } from './LightBase'; * @group Lights */ export class GILighting { - public static list: LightBase[] = []; - public static add(light: LightBase) { + public static list: ILight[] = []; + public static add(light: ILight) { let index = this.list.indexOf(light); if (index == -1) { this.list.push(light); } } - public static remove(light: LightBase) { + public static remove(light: ILight) { let index = this.list.indexOf(light); if (index != -1) { this.list.splice(index, 1); diff --git a/src/engine/components/lights/IESProfiles.ts b/src/components/lights/IESProfiles.ts similarity index 100% rename from src/engine/components/lights/IESProfiles.ts rename to src/components/lights/IESProfiles.ts diff --git a/src/components/lights/ILight.ts b/src/components/lights/ILight.ts new file mode 100644 index 00000000..f88ee5f3 --- /dev/null +++ b/src/components/lights/ILight.ts @@ -0,0 +1,15 @@ +import { Camera3D } from "../../core/Camera3D"; +import { Transform } from "../Transform"; +import { LightData } from "./LightData"; + +export interface ILight { + name: string; + transform: Transform; + lightData: LightData; + needUpdateShadow: boolean; + realTimeShadow: boolean; + + shadowIndex: number; + + shadowCamera?: Camera3D; +} \ No newline at end of file diff --git a/src/engine/components/lights/LightBase.ts b/src/components/lights/LightBase.ts similarity index 96% rename from src/engine/components/lights/LightBase.ts rename to src/components/lights/LightBase.ts index b6b48618..a03f15da 100644 --- a/src/engine/components/lights/LightBase.ts +++ b/src/components/lights/LightBase.ts @@ -8,12 +8,13 @@ import { GILighting } from './GILighting'; import { LightData } from './LightData'; import { ShadowLightsCollect } from '../../gfx/renderJob/collect/ShadowLightsCollect'; import { IESProfiles } from './IESProfiles'; +import { ILight } from './ILight'; /** * @internal * @group Lights */ -export class LightBase extends ComponentBase { +export class LightBase extends ComponentBase implements ILight { /** * light name */ @@ -53,7 +54,7 @@ export class LightBase extends ComponentBase { super(); } - protected init(): void { + public init(): void { this.transform.object3D.bound = new BoundingBox(new Vector3(), new Vector3()); this.lightData = new LightData(); @@ -74,7 +75,7 @@ export class LightBase extends ComponentBase { } } - protected start(): void { + public start(): void { this.transform.onScaleChange = () => this.onScaleChange(); this.transform.onRotationChange = () => this.onRotChange(); this.onRotChange(); @@ -95,12 +96,12 @@ export class LightBase extends ComponentBase { this.onChange(); } - protected onEnable(): void { + public onEnable(): void { this.onChange(); EntityCollect.instance.addLight(this.transform.scene3D, this); } - protected onDisable(): void { + public onDisable(): void { this.onChange(); EntityCollect.instance.removeLight(this.transform.scene3D, this); } diff --git a/src/engine/components/lights/LightData.ts b/src/components/lights/LightData.ts similarity index 100% rename from src/engine/components/lights/LightData.ts rename to src/components/lights/LightData.ts diff --git a/src/engine/components/lights/PointLight.ts b/src/components/lights/PointLight.ts similarity index 96% rename from src/engine/components/lights/PointLight.ts rename to src/components/lights/PointLight.ts index 1466c17d..d63f178b 100644 --- a/src/engine/components/lights/PointLight.ts +++ b/src/components/lights/PointLight.ts @@ -16,7 +16,7 @@ export class PointLight extends LightBase { super(); } - protected init(): void { + public init(): void { super.init(); this.lightData.lightType = LightType.PointLight; if (this.object3D.name == "") { @@ -106,16 +106,16 @@ export class PointLight extends LightBase { this._castShadow = value; } - protected start(): void { + public start(): void { this.transform.rotationX = 90; super.start(); } - protected onUpdate(): void { + public onUpdate(): void { this.transform.updateWorldMatrix(true); } - protected onGraphic(view?: View3D): void { + public onGraphic(view?: View3D): void { let custom = Engine3D.getRenderJob(view).graphic3D.createCustomShape( `PointLight_${this.object3D.uuid}`, this.transform, diff --git a/src/engine/components/lights/SpotLight.ts b/src/components/lights/SpotLight.ts similarity index 97% rename from src/engine/components/lights/SpotLight.ts rename to src/components/lights/SpotLight.ts index a4b183e3..b1950f4b 100644 --- a/src/engine/components/lights/SpotLight.ts +++ b/src/components/lights/SpotLight.ts @@ -17,7 +17,7 @@ export class SpotLight extends LightBase { super(); } - protected init(): void { + public init(): void { super.init(); this.lightData.lightType = LightType.SpotLight; if (this.object3D.name == "") { @@ -123,16 +123,16 @@ export class SpotLight extends LightBase { this._castShadow = value; } - protected start(): void { + public start(): void { super.start(); this.lightData.lightType = LightType.SpotLight; } - protected onUpdate(): void { + public onUpdate(): void { this.transform.updateWorldMatrix(true); } - protected onGraphic(view: View3D) { + public onGraphic(view: View3D) { let custom = Engine3D.getRenderJob(view).graphic3D.createCustomShape( `SpotLight_${this.object3D.uuid}`, this.transform, diff --git a/src/engine/components/post/PostProcessingComponent.ts b/src/components/post/PostProcessingComponent.ts similarity index 91% rename from src/engine/components/post/PostProcessingComponent.ts rename to src/components/post/PostProcessingComponent.ts index 5b81bb27..21c716e1 100644 --- a/src/engine/components/post/PostProcessingComponent.ts +++ b/src/components/post/PostProcessingComponent.ts @@ -5,23 +5,23 @@ import { ComponentBase } from "../ComponentBase"; export class PostProcessingComponent extends ComponentBase { private _postList: Map; - protected init(param?: any): void { + public init(param?: any): void { this._postList = new Map(); } - protected start(): void { + public start(): void { } - protected stop(): void { + public stop(): void { } - protected onEnable(): void { + public onEnable(): void { this.activePost(); } - protected onDisable(): void { + public onDisable(): void { this.unActivePost(); } diff --git a/src/engine/components/renderer/InstanceDrawComponent.ts b/src/components/renderer/InstanceDrawComponent.ts similarity index 94% rename from src/engine/components/renderer/InstanceDrawComponent.ts rename to src/components/renderer/InstanceDrawComponent.ts index b7bcfc82..3030f7e2 100644 --- a/src/engine/components/renderer/InstanceDrawComponent.ts +++ b/src/components/renderer/InstanceDrawComponent.ts @@ -8,16 +8,17 @@ import { StorageGPUBuffer } from "../../gfx/graphics/webGpu/core/buffer/StorageG import { View3D } from "../../core/View3D"; import { RendererPassState } from "../../gfx/renderJob/passRenderer/state/RendererPassState"; import { RendererType } from "../../gfx/renderJob/passRenderer/state/RendererType"; +import { ClusterLightingBuffer } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer"; export class InstanceDrawComponent extends RenderNode { private _keyGroup: Map; private _instanceMatrixBuffer: StorageGPUBuffer; - protected init(param?: any): void { + public init(param?: any): void { this._keyGroup = new Map(); } - protected start(): void { + public start(): void { let meshRenders: MeshRenderer[] = []; this.object3D.getComponents(MeshRenderer, meshRenders, true); @@ -47,11 +48,11 @@ export class InstanceDrawComponent extends RenderNode { this._instanceMatrixBuffer.apply(); } - protected stop(): void { + public stop(): void { } - public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingRender?: ClusterLightingRender): void { + public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer?: ClusterLightingBuffer): void { this._keyGroup.forEach((v, k) => { @@ -68,9 +69,9 @@ export class InstanceDrawComponent extends RenderNode { } } } - renderNode.nodeUpdate(view, passType, renderPassState, clusterLightingRender); + renderNode.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer); }) - super.nodeUpdate(view, passType, renderPassState, clusterLightingRender); + super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer); } diff --git a/src/engine/components/renderer/MaterialComponent.ts b/src/components/renderer/MaterialComponent.ts similarity index 100% rename from src/engine/components/renderer/MaterialComponent.ts rename to src/components/renderer/MaterialComponent.ts diff --git a/src/engine/components/renderer/MeshComponent.ts b/src/components/renderer/MeshComponent.ts similarity index 98% rename from src/engine/components/renderer/MeshComponent.ts rename to src/components/renderer/MeshComponent.ts index 79bc30f0..9b943e14 100644 --- a/src/engine/components/renderer/MeshComponent.ts +++ b/src/components/renderer/MeshComponent.ts @@ -33,7 +33,7 @@ export class MeshComponent extends ComponentBase { super(); } - protected init() { } + public init() { } public cloneTo(obj: Object3D) { let mc = obj.addComponent(MeshComponent); diff --git a/src/engine/components/renderer/MeshRenderer.ts b/src/components/renderer/MeshRenderer.ts similarity index 91% rename from src/engine/components/renderer/MeshRenderer.ts rename to src/components/renderer/MeshRenderer.ts index a5585c6e..3ec6f4ae 100644 --- a/src/engine/components/renderer/MeshRenderer.ts +++ b/src/components/renderer/MeshRenderer.ts @@ -1,7 +1,7 @@ import { Object3D } from '../../core/entities/Object3D'; -import { GeometryBase } from '../../core/geometry/GeometryBase'; import { View3D } from '../../core/View3D'; -import { ClusterLightingRender } from '../../gfx/renderJob/passRenderer/cluster/ClusterLightingRender'; +import { ClusterLightingBuffer } from '../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer'; +import { GeometryBase } from '../../core/geometry/GeometryBase'; import { RendererMask } from '../../gfx/renderJob/passRenderer/state/RendererMask'; import { RendererPassState } from '../../gfx/renderJob/passRenderer/state/RendererPassState'; import { RendererType } from '../../gfx/renderJob/passRenderer/state/RendererType'; @@ -24,9 +24,13 @@ export class MeshRenderer extends RenderNode { super(); } - protected start(): void { } + public onEnable(): void { + super.onEnable(); + } - protected stop(): void { } + public onDisable(): void { + super.onDisable(); + } /** * The geometry of the mesh determines its shape @@ -87,7 +91,7 @@ export class MeshRenderer extends RenderNode { } - protected onCompute(view: View3D, command: GPUCommandEncoder): void { + public onCompute(view: View3D, command: GPUCommandEncoder): void { if (this.morphData && this.morphData.enable) { this.morphData.computeMorphTarget(command); } @@ -101,7 +105,7 @@ export class MeshRenderer extends RenderNode { * @param clusterLightingRender * @param probes */ - public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingRender?: ClusterLightingRender) { + public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer) { if (this.morphData && this.morphData.enable) { for (let i = 0; i < this.materials.length; i++) { const material = this.materials[i]; @@ -115,7 +119,7 @@ export class MeshRenderer extends RenderNode { } } - super.nodeUpdate(view, passType, renderPassState, clusterLightingRender); + super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer); } cloneTo(obj: Object3D) { diff --git a/src/engine/components/renderer/RenderNode.ts b/src/components/renderer/RenderNode.ts similarity index 94% rename from src/engine/components/renderer/RenderNode.ts rename to src/components/renderer/RenderNode.ts index db08d8cc..07982f0e 100644 --- a/src/engine/components/renderer/RenderNode.ts +++ b/src/components/renderer/RenderNode.ts @@ -9,7 +9,7 @@ import { GPUContext } from "../../gfx/renderJob/GPUContext"; import { EntityCollect } from "../../gfx/renderJob/collect/EntityCollect"; import { RTResourceMap } from "../../gfx/renderJob/frame/RTResourceMap"; import { RenderContext } from "../../gfx/renderJob/passRenderer/RenderContext"; -import { ClusterLightingRender } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingRender"; +import { ClusterLightingBuffer } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer"; import { RendererMask, RendererMaskUtil } from "../../gfx/renderJob/passRenderer/state/RendererMask"; import { RendererPassState } from "../../gfx/renderJob/passRenderer/state/RendererPassState"; import { RendererType } from "../../gfx/renderJob/passRenderer/state/RendererType"; @@ -98,7 +98,7 @@ export class RenderNode extends ComponentBase { } } - protected init() { + public init() { // this.renderPasses = new Map(); this.instanceID = UUID(); } @@ -111,17 +111,15 @@ export class RenderNode extends ComponentBase { this._rendererMask = RendererMaskUtil.removeMask(this._rendererMask, tag); } - protected onEnable(): void { + public onEnable(): void { if (!this._readyPipeline) { this.initPipeline(); - - } EntityCollect.instance.addRenderNode(this.transform.scene3D, this); } - protected onDisable(): void { + public onDisable(): void { EntityCollect.instance.removeRenderNode(this.transform.scene3D, this); } @@ -293,9 +291,9 @@ export class RenderNode extends ComponentBase { * @param encoder * @returns */ - public renderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingRender: ClusterLightingRender, encoder: GPURenderPassEncoder, useBundle: boolean = false) { + public renderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer, encoder: GPURenderPassEncoder, useBundle: boolean = false) { if (!this.enable) return; - this.nodeUpdate(view, passType, rendererPassState, clusterLightingRender); + this.nodeUpdate(view, passType, rendererPassState, clusterLightingBuffer); let node = this; for (let i = 0; i < this.materials.length; i++) { @@ -333,9 +331,9 @@ export class RenderNode extends ComponentBase { } - public recordRenderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingRender: ClusterLightingRender, encoder: GPURenderPassEncoder, useBundle: boolean = false) { + public recordRenderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer, encoder: GPURenderPassEncoder, useBundle: boolean = false) { if (!this.enable) return; - this.nodeUpdate(view, passType, rendererPassState, clusterLightingRender); + this.nodeUpdate(view, passType, rendererPassState, clusterLightingBuffer); let node = this; for (let i = 0; i < this.materials.length; i++) { @@ -367,7 +365,7 @@ export class RenderNode extends ComponentBase { } } - public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingRender?: ClusterLightingRender) { + public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer?: ClusterLightingBuffer) { let node = this; for (let i = 0; i < this.materials.length; i++) { @@ -424,14 +422,16 @@ export class RenderNode extends ComponentBase { let lightUniformEntries = GlobalBindGroup.getLightEntries(view.scene); if (lightUniformEntries) { renderShader.setStorageBuffer(`lightBuffer`, lightUniformEntries.storageGPUBuffer); + if (lightUniformEntries.irradianceVolume) { + renderShader.setStructStorageBuffer(`irradianceData`, lightUniformEntries.irradianceVolume.irradianceVolumeBuffer); + } } - - if (clusterLightingRender) { - renderShader.setStorageBuffer(`clustersUniform`, clusterLightingRender.clustersUniformBuffer); - renderShader.setStorageBuffer(`lightAssignBuffer`, clusterLightingRender.lightAssignBuffer); - renderShader.setStorageBuffer(`assignTable`, clusterLightingRender.assignTableBuffer); - renderShader.setStorageBuffer(`clusterBuffer`, clusterLightingRender.clusterBuffer); + if (clusterLightingBuffer) { + renderShader.setStorageBuffer(`clustersUniform`, clusterLightingBuffer.clustersUniformBuffer); + renderShader.setStorageBuffer(`lightAssignBuffer`, clusterLightingBuffer.lightAssignBuffer); + renderShader.setStorageBuffer(`assignTable`, clusterLightingBuffer.assignTableBuffer); + renderShader.setStorageBuffer(`clusterBuffer`, clusterLightingBuffer.clusterBuffer); } renderShader.apply(this._geometry, pass, renderPassState); diff --git a/src/engine/components/renderer/SkinnedMeshRenderer.ts b/src/components/renderer/SkinnedMeshRenderer.ts similarity index 94% rename from src/engine/components/renderer/SkinnedMeshRenderer.ts rename to src/components/renderer/SkinnedMeshRenderer.ts index 866d1d16..31f17c2b 100644 --- a/src/engine/components/renderer/SkinnedMeshRenderer.ts +++ b/src/components/renderer/SkinnedMeshRenderer.ts @@ -1,12 +1,13 @@ 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 { ClusterLightingRender } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingRender"; -import { RendererMask } from "../../gfx/renderJob/passRenderer/state/RendererMask"; import { RendererPassState } from "../../gfx/renderJob/passRenderer/state/RendererPassState"; -import { RendererType } from "../../gfx/renderJob/passRenderer/state/RendererType"; import { SkeletonAnimationComponent } from "../SkeletonAnimationComponent"; -import { MeshRenderer } from "./MeshRenderer"; +import { ClusterLightingBuffer } from "../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer"; /** * Skin Mesh Renderer Component @@ -27,7 +28,7 @@ export class SkinnedMeshRenderer extends MeshRenderer { this.addRendererMask(RendererMask.SkinnedMesh); } - protected start() { + public start() { super.start(); this.skeletonAnimation = this.object3D.getComponent(SkeletonAnimationComponent); if (!this.skeletonAnimation) { @@ -41,6 +42,10 @@ export class SkinnedMeshRenderer extends MeshRenderer { } } + public onEnable(): void { + super.onEnable(); + } + public get skeletonAnimation(): SkeletonAnimationComponent { return this.mSkeletonAnimation; } @@ -103,7 +108,7 @@ export class SkinnedMeshRenderer extends MeshRenderer { * @param clusterLightingRender * @param probes */ - public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingRender?: ClusterLightingRender) { + 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.renderPasses.get(passType); @@ -116,7 +121,7 @@ export class SkinnedMeshRenderer extends MeshRenderer { } } } - super.nodeUpdate(view, passType, renderPassState, clusterLightingRender); + super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer); } } diff --git a/src/engine/components/renderer/SkyRenderer.ts b/src/components/renderer/SkyRenderer.ts similarity index 89% rename from src/engine/components/renderer/SkyRenderer.ts rename to src/components/renderer/SkyRenderer.ts index 2cd818c4..5c0faeca 100644 --- a/src/engine/components/renderer/SkyRenderer.ts +++ b/src/components/renderer/SkyRenderer.ts @@ -1,17 +1,17 @@ import { Engine3D } from '../../Engine3D'; import { View3D } from '../../core/View3D'; +import { MeshRenderer } from './MeshRenderer'; import { BoundingBox } from '../../core/bound/BoundingBox'; import { Texture } from '../../gfx/graphics/webGpu/core/texture/Texture'; import { EntityCollect } from '../../gfx/renderJob/collect/EntityCollect'; -import { ClusterLightingRender } from '../../gfx/renderJob/passRenderer/cluster/ClusterLightingRender'; +import { ClusterLightingBuffer } from '../../gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer'; import { RendererMask } from '../../gfx/renderJob/passRenderer/state/RendererMask'; import { RendererPassState } from '../../gfx/renderJob/passRenderer/state/RendererPassState'; import { RendererType } from '../../gfx/renderJob/passRenderer/state/RendererType'; import { SkyMaterial } from '../../materials/SkyMaterial'; import { Vector3 } from '../../math/Vector3'; import { SphereGeometry } from '../../shape/SphereGeometry'; -import { MeshRenderer } from './MeshRenderer'; /** * @@ -32,14 +32,14 @@ export class SkyRenderer extends MeshRenderer { this.alwaysRender = true; } - protected init(): void { + public init(): void { super.init(); this.object3D.bound = new BoundingBox(Vector3.ZERO.clone(), Vector3.MAX); this.geometry = new SphereGeometry(Engine3D.setting.sky.defaultFar, 20, 20); this.skyMaterial ||= new SkyMaterial(); } - protected onEnable(): void { + public onEnable(): void { if (!this._readyPipeline) { this.initPipeline(); } else { @@ -52,16 +52,16 @@ export class SkyRenderer extends MeshRenderer { } } - protected onDisable(): void { + public onDisable(): void { if (this._inRenderer && this.transform.scene3D) { this._inRenderer = false; EntityCollect.instance.sky = null; } } - public renderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingRender: ClusterLightingRender, encoder: GPURenderPassEncoder, useBundle: boolean = false) { + public renderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer, encoder: GPURenderPassEncoder, useBundle: boolean = false) { this.transform.updateWorldMatrix(); - super.renderPass2(view, passType, rendererPassState, clusterLightingRender, encoder, useBundle); + super.renderPass2(view, passType, rendererPassState, clusterLightingBuffer, encoder, useBundle); // this.transform.localPosition = Camera3D.mainCamera.transform.localPosition ; } diff --git a/src/engine/components/shape/BoxColliderShape.ts b/src/components/shape/BoxColliderShape.ts similarity index 100% rename from src/engine/components/shape/BoxColliderShape.ts rename to src/components/shape/BoxColliderShape.ts diff --git a/src/engine/components/shape/CapsuleColliderShape.ts b/src/components/shape/CapsuleColliderShape.ts similarity index 100% rename from src/engine/components/shape/CapsuleColliderShape.ts rename to src/components/shape/CapsuleColliderShape.ts diff --git a/src/engine/components/shape/ColliderShape.ts b/src/components/shape/ColliderShape.ts similarity index 100% rename from src/engine/components/shape/ColliderShape.ts rename to src/components/shape/ColliderShape.ts diff --git a/src/engine/components/shape/MeshColliderShape.ts b/src/components/shape/MeshColliderShape.ts similarity index 100% rename from src/engine/components/shape/MeshColliderShape.ts rename to src/components/shape/MeshColliderShape.ts diff --git a/src/engine/components/shape/SphereColliderShape.ts b/src/components/shape/SphereColliderShape.ts similarity index 100% rename from src/engine/components/shape/SphereColliderShape.ts rename to src/components/shape/SphereColliderShape.ts diff --git a/src/engine/core/Camera3D.ts b/src/core/Camera3D.ts similarity index 99% rename from src/engine/core/Camera3D.ts rename to src/core/Camera3D.ts index de5d80be..1084ca45 100644 --- a/src/engine/core/Camera3D.ts +++ b/src/core/Camera3D.ts @@ -99,7 +99,7 @@ export class Camera3D extends ComponentBase { super(); } - protected init() { + public init() { super.init(); this._ray = new Ray(); this.frustum = new Frustum(); @@ -111,11 +111,6 @@ export class Camera3D extends ComponentBase { this.lookTarget = new Vector3(0, 0, 0); } - /** - * @internal - */ - protected start() { } - /** * Create a perspective camera * @param fov diff --git a/src/engine/core/CameraType.ts b/src/core/CameraType.ts similarity index 100% rename from src/engine/core/CameraType.ts rename to src/core/CameraType.ts diff --git a/src/engine/core/CubeCamera.ts b/src/core/CubeCamera.ts similarity index 100% rename from src/engine/core/CubeCamera.ts rename to src/core/CubeCamera.ts diff --git a/src/engine/core/PointShadowCubeCamera.ts b/src/core/PointShadowCubeCamera.ts similarity index 100% rename from src/engine/core/PointShadowCubeCamera.ts rename to src/core/PointShadowCubeCamera.ts diff --git a/src/engine/core/Scene3D.ts b/src/core/Scene3D.ts similarity index 68% rename from src/engine/core/Scene3D.ts rename to src/core/Scene3D.ts index 8a75d6df..a5e36b0a 100644 --- a/src/engine/core/Scene3D.ts +++ b/src/core/Scene3D.ts @@ -1,7 +1,6 @@ import { Engine3D } from '../Engine3D'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { EntityCollect } from '../gfx/renderJob/collect/EntityCollect'; -import { defaultRes } from '../textures/DefaultRes'; import { View3D } from './View3D'; import { Object3D } from './entities/Object3D'; @@ -25,7 +24,7 @@ export class Scene3D extends Object3D { this.skyObject = new Object3D(); this.addChild(this.skyObject); this._isScene3D = true; - this.envMap ||= defaultRes.defaultSky; + this.envMap ||= Engine3D.res.defaultSky; } /** @@ -44,7 +43,7 @@ export class Scene3D extends Object3D { this.envMapChange = true; } this._envMap = value; - if (EntityCollect.instance.sky) + if (EntityCollect.instance.sky && `map` in EntityCollect.instance.sky) EntityCollect.instance.sky.map = value; } @@ -62,35 +61,37 @@ export class Scene3D extends Object3D { * Exposure of Sky Box. A larger value produces a sky box with stronger exposure and a brighter appearance. * A smaller value produces a sky box with weaker exposure and a darker appearance. */ - public get exposure() { - if (EntityCollect.instance.sky) - return EntityCollect.instance.sky.exposure; + public get exposure(): number { + if (EntityCollect.instance.sky && `exposure` in EntityCollect.instance.sky) + return EntityCollect.instance.sky.exposure as number; return 0; } /** * Set the exposure of the Sky Box. */ - public set exposure(value) { - if (EntityCollect.instance.sky) + public set exposure(value: number) { + if (EntityCollect.instance.sky && `exposure` in EntityCollect.instance.sky) { EntityCollect.instance.sky.exposure = value; - Engine3D.setting.sky.skyExposure = value; + Engine3D.setting.sky.skyExposure = value; + } } /** * Get the roughness of the Sky Box. */ - public get roughness() { - if (EntityCollect.instance.sky) - return EntityCollect.instance.sky.roughness; + public get roughness(): number { + if (EntityCollect.instance.sky && `roughness` in EntityCollect.instance.sky) { + return EntityCollect.instance.sky.roughness as number; + } } /** * Set the roughness of the Sky Box. */ - public set roughness(value) { - if (EntityCollect.instance.sky) - EntityCollect.instance.sky.skyMaterial.roughness = value; + public set roughness(value: number) { + if (EntityCollect.instance.sky && `roughness` in EntityCollect.instance.sky) { + EntityCollect.instance.sky.roughness = value; + } } - } diff --git a/src/engine/core/View3D.ts b/src/core/View3D.ts similarity index 100% rename from src/engine/core/View3D.ts rename to src/core/View3D.ts diff --git a/src/engine/core/ViewQuad.ts b/src/core/ViewQuad.ts similarity index 53% rename from src/engine/core/ViewQuad.ts rename to src/core/ViewQuad.ts index 5a599a65..e92ac97c 100644 --- a/src/engine/core/ViewQuad.ts +++ b/src/core/ViewQuad.ts @@ -11,10 +11,13 @@ import { BlendMode } from '../materials/BlendMode'; import { MaterialBase } from '../materials/MaterialBase'; import { Color } from '../math/Color'; import { PlaneGeometry } from '../shape/PlaneGeometry'; -import { defaultRes } from '../textures/DefaultRes'; -import { VirtualTexture } from '../textures/VirtualTexture'; + import { Object3D } from './entities/Object3D'; import { RendererPassState } from '../gfx/renderJob/passRenderer/state/RendererPassState'; +import { Engine3D } from '../Engine3D'; +import { GPUContext } from '../gfx/renderJob/GPUContext'; +import { RendererType } from '../gfx/renderJob/passRenderer/state/RendererType'; +import { View3D } from './View3D'; /** * @internal * @group Entity @@ -57,7 +60,7 @@ export class ViewQuad extends Object3D { this.quadRenderer[`__start`](); this.quadRenderer[`_enable`] = true; this.quadRenderer[`onEnable`](); - this.colorTexture = defaultRes.blackTexture; + this.colorTexture = Engine3D.res.blackTexture; shader.setUniformFloat(`x`, 0); shader.setUniformFloat(`y`, 0); @@ -84,4 +87,68 @@ export class ViewQuad extends Object3D { public set colorTexture(tex: Texture) { this.material.baseMap = tex; } + + /** + * By inputting a map to viewQuad and setting corresponding + * processing shaders, the corresponding results are output for off-screen rendering + * Can also be directly used as the final display rendering result rendering canvas + * @param viewQuad + * @see ViewQuad + * @param scene3D + * @see Scene3D + * @param command + */ + public renderTarget(view: View3D, viewQuad: ViewQuad, command: GPUCommandEncoder) { + let camera = view.camera; + let encoder = GPUContext.beginRenderPass(command, viewQuad.rendererPassState); + GPUContext.bindCamera(encoder, camera); + viewQuad.quadRenderer.nodeUpdate(view, RendererType.COLOR, viewQuad.rendererPassState, null); + viewQuad.quadRenderer.renderPass2(view, RendererType.COLOR, viewQuad.rendererPassState, null, encoder); + GPUContext.endPass(encoder); + } + + /** + * Output to screen through screen based shading + * @param viewQuad + * @see ViewQuad + * @param scene3D + * @see Scene3D + * @param command + * @param colorTexture + */ + public renderToViewQuad(view: View3D, viewQuad: ViewQuad, command: GPUCommandEncoder, colorTexture: Texture) { + let camera = view.camera; + viewQuad.colorTexture = colorTexture; + let encoder = GPUContext.beginRenderPass(command, viewQuad.rendererPassState); + GPUContext.bindCamera(encoder, camera); + + // viewQuad.x = view.viewPort.x; + // viewQuad.y = view.viewPort.y; + // viewQuad.scaleX = view.viewPort.width; + // viewQuad.scaleY = view.viewPort.height; + // viewQuad.transform.updateWorldMatrix(true); + // encoder.setViewport( + // view.viewPort.x * webGPUContext.presentationSize[0], + // view.viewPort.y * webGPUContext.presentationSize[1], + // view.viewPort.width * webGPUContext.presentationSize[0], + // view.viewPort.height * webGPUContext.presentationSize[1], + // 0.0, 1.0); + // encoder.setScissorRect( + // view.viewPort.x * webGPUContext.presentationSize[0], + // view.viewPort.y * webGPUContext.presentationSize[0], + // view.viewPort.width * webGPUContext.presentationSize[0], + // view.viewPort.height * webGPUContext.presentationSize[1], + // ); + + // encoder.setScissorRect(view.viewPort.x, view.viewPort.y, 300, 150); + // encoder.setViewport(view.viewPort.x, view.viewPort.y, view.viewPort.width / (view.viewPort.width / view.viewPort.height), view.viewPort.height, 0.0, 1.0); + // encoder.setScissorRect(view.viewPort.x, view.viewPort.y, view.viewPort.width, view.viewPort.height); + + // encoder.setViewport(camera.viewPort.x, camera.viewPort.y, camera.viewPort.width, camera.viewPort.height, 0.0, 1.0); + // encoder.setScissorRect(camera.viewPort.x, camera.viewPort.y, camera.viewPort.width, camera.viewPort.height); + + viewQuad.quadRenderer.nodeUpdate(view, RendererType.COLOR, viewQuad.rendererPassState, null); + viewQuad.quadRenderer.renderPass2(view, RendererType.COLOR, viewQuad.rendererPassState, null, encoder); + GPUContext.endPass(encoder); + } } diff --git a/src/engine/core/bound/BoundingBox.ts b/src/core/bound/BoundingBox.ts similarity index 100% rename from src/engine/core/bound/BoundingBox.ts rename to src/core/bound/BoundingBox.ts index a11622f1..1bebf601 100644 --- a/src/engine/core/bound/BoundingBox.ts +++ b/src/core/bound/BoundingBox.ts @@ -1,8 +1,8 @@ -import { Ray } from '../../math/Ray'; -import { Vector3 } from '../../math/Vector3'; -import { Object3D } from '../entities/Object3D'; import { Frustum } from './Frustum'; import { IBound } from './IBound'; +import { Object3D } from '../entities/Object3D'; +import { Ray } from '../../math/Ray'; +import { Vector3 } from '../../math/Vector3'; /** * BoundingBox diff --git a/src/engine/core/bound/BoundingSphere.ts b/src/core/bound/BoundingSphere.ts similarity index 99% rename from src/engine/core/bound/BoundingSphere.ts rename to src/core/bound/BoundingSphere.ts index d452c40d..4940a947 100644 --- a/src/engine/core/bound/BoundingSphere.ts +++ b/src/core/bound/BoundingSphere.ts @@ -1,8 +1,9 @@ -import { Ray } from '../../math/Ray'; -import { Vector3 } from '../../math/Vector3'; -import { Object3D } from '../entities/Object3D'; import { Frustum } from './Frustum'; import { IBound } from './IBound'; +import { Object3D } from '../entities/Object3D'; +import { Ray } from '../../math/Ray'; +import { Vector3 } from '../../math/Vector3'; + /** * BoundingSphere * @internal diff --git a/src/engine/core/bound/Frustum.ts b/src/core/bound/Frustum.ts similarity index 95% rename from src/engine/core/bound/Frustum.ts rename to src/core/bound/Frustum.ts index b641a0cc..492f2b70 100644 --- a/src/engine/core/bound/Frustum.ts +++ b/src/core/bound/Frustum.ts @@ -1,9 +1,7 @@ -import { Matrix4 } from "../../math/Matrix4"; -import { Vector3 } from "../../math/Vector3"; -import { Camera3D } from "../Camera3D"; -import { Object3D } from "../entities/Object3D"; -import { BoundingBox } from "./BoundingBox"; -import { BoundingSphere } from "./BoundingSphere"; +import { BoundingSphere } from './BoundingSphere'; +import { Matrix4 } from '../../math/Matrix4'; +import { Object3D } from '../entities/Object3D'; +import { Vector3 } from '../../math/Vector3'; /** * @internal diff --git a/src/engine/core/bound/IBound.ts b/src/core/bound/IBound.ts similarity index 99% rename from src/engine/core/bound/IBound.ts rename to src/core/bound/IBound.ts index f7e88906..32607e95 100644 --- a/src/engine/core/bound/IBound.ts +++ b/src/core/bound/IBound.ts @@ -1,7 +1,8 @@ +import { Frustum } from './Frustum'; +import { Object3D } from '../entities/Object3D'; import { Ray } from '../../math/Ray'; import { Vector3 } from '../../math/Vector3'; -import { Object3D } from '../entities/Object3D'; -import { Frustum } from './Frustum'; + /** * @internal */ diff --git a/src/engine/core/entities/Entity.ts b/src/core/entities/Entity.ts similarity index 95% rename from src/engine/core/entities/Entity.ts rename to src/core/entities/Entity.ts index 9863bff3..737a677f 100644 --- a/src/engine/core/entities/Entity.ts +++ b/src/core/entities/Entity.ts @@ -1,7 +1,8 @@ -import { ComponentBase } from '../../components/ComponentBase'; +import { IComponent } from '../../components/IComponent'; import { RenderNode } from '../../components/renderer/RenderNode'; import { Transform } from '../../components/Transform'; import { CEventDispatcher } from '../../event/CEventDispatcher'; +import { ComponentCollect } from '../../gfx/renderJob/collect/ComponentCollect'; import { RenderLayer } from '../../gfx/renderJob/config/RenderLayer'; import { Vector3 } from '../../math/Vector3'; import { UUID } from '../../util/Global'; @@ -70,14 +71,14 @@ export class Entity extends CEventDispatcher { * * List of components attached to an object */ - public components: Map; + public components: Map; /** * * The bounding box of an object */ public bound: IBound; - protected waitDisposeComponents: ComponentBase[]; + protected waitDisposeComponents: IComponent[]; private _dispose: boolean = false; // private _visible: boolean = true; @@ -115,7 +116,7 @@ export class Entity extends CEventDispatcher { constructor() { super(); this.entityChildren = []; - this.components = new Map(); + this.components = new Map(); this.waitDisposeComponents = []; this._uuid = UUID(); } @@ -244,7 +245,7 @@ export class Entity extends CEventDispatcher { /** * - * Search for object children and return a child object with a matching name。 + * Search for object children and return a child object with a matching name. * @param name matching name * @param loopChild Whether to traverse the children of the child object. The default value is true * @returns result @@ -303,11 +304,11 @@ export class Entity extends CEventDispatcher { }); this.components.clear(); } else { - ComponentBase.waitStartComponent.forEach((v, k) => { + ComponentCollect.waitStartComponent.forEach((v, k) => { v.forEach((v) => { v[`__start`](); }) - ComponentBase.waitStartComponent.delete(k); + ComponentCollect.waitStartComponent.delete(k); }); } } diff --git a/src/engine/core/entities/InstancedMesh.ts b/src/core/entities/InstancedMesh.ts similarity index 100% rename from src/engine/core/entities/InstancedMesh.ts rename to src/core/entities/InstancedMesh.ts diff --git a/src/engine/core/entities/Object3D.ts b/src/core/entities/Object3D.ts similarity index 87% rename from src/engine/core/entities/Object3D.ts rename to src/core/entities/Object3D.ts index 65ef26df..cb019852 100644 --- a/src/engine/core/entities/Object3D.ts +++ b/src/core/entities/Object3D.ts @@ -1,9 +1,10 @@ -import { ComponentBase } from '../../components/ComponentBase'; import { Transform } from '../../components/Transform'; import { Quaternion } from '../../math/Quaternion'; import { Vector3 } from '../../math/Vector3'; import { Entity } from './Entity'; import { Ctor } from "../../util/Global"; +import { IComponent } from '../../components/IComponent'; +import { ComponentCollect } from '../../gfx/renderJob/collect/ComponentCollect'; /** * The base class of most objects provides a series of properties and methods for manipulating objects in three-dimensional space. * @group Entity @@ -45,23 +46,23 @@ export class Object3D extends Entity { * @param c class of component * @return result component */ - public addComponent(c: Ctor, param?: any): T { - if (!this.components.has(c.prototype)) { + public addComponent(c: Ctor, param?: any): T { + let className = c.name; + if (!this.components.has(className)) { let instance: T = new c() as T; instance.object3D = this; instance[`__init`](param); - // instance[`__start`](); - this.components.set(c.prototype, instance); + this.components.set(className, instance); this.appendLateStart(instance); return instance; } return null; } - private appendLateStart(component: ComponentBase) { - let arr = ComponentBase.waitStartComponent.get(this); + private appendLateStart(component: IComponent) { + let arr = ComponentCollect.waitStartComponent.get(this); if (!arr) { - ComponentBase.waitStartComponent.set(this, [component]); + ComponentCollect.waitStartComponent.set(this, [component]); } else { let index = arr.indexOf(component); if (index == -1) { @@ -77,8 +78,9 @@ export class Object3D extends Entity { * @param c class of component * @returns result component */ - public getOrAddComponent(c: Ctor): T { - let component = this.components.get(c.prototype); + public getOrAddComponent(c: Ctor): T { + let className = c.name; + let component = this.components.get(className); if (!component) { component = this.addComponent(c); } @@ -90,10 +92,11 @@ export class Object3D extends Entity { * Remove components of the specified type * @param c class of component */ - public removeComponent(c: Ctor) { - if (this.components.has(c.prototype)) { - let component = this.components.get(c.prototype); - this.components.delete(c.prototype); + public removeComponent(c: Ctor) { + let className = c.name; + if (this.components.has(className)) { + let component = this.components.get(className); + this.components.delete(className); component[`__stop`](); component.destroy(); } @@ -105,8 +108,9 @@ export class Object3D extends Entity { * @param c type of component * @returns boolean */ - public hasComponent(c: Ctor): boolean { - return this.components.has(c.prototype); + public hasComponent(c: Ctor): boolean { + let className = c.name; + return this.components.has(className); } /** @@ -115,8 +119,9 @@ export class Object3D extends Entity { * @param c class of component * @returns result component */ - public getComponent(c: Ctor): T { - return this.components.get(c.prototype) as T; + public getComponent(c: Ctor): T { + let className = c.name; + return this.components.get(className) as T; } /** @@ -127,7 +132,7 @@ export class Object3D extends Entity { * @param c class of component * @returns reulst component */ - public getComponentFromParent(c: Ctor): T { + public getComponentFromParent(c: Ctor): T { if (!this.parent) { return null; } @@ -147,9 +152,10 @@ export class Object3D extends Entity { * @param c class of component * @returns result components */ - public getComponentsInChild(c: Ctor): T[] { + public getComponentsInChild(c: Ctor): T[] { let list: T[] = []; - let component = this.components.get(c.prototype); + let className = c.name; + let component = this.components.get(className); if (component) { list.push(component as T); } @@ -170,7 +176,7 @@ export class Object3D extends Entity { * @param includeInactive Whether to include invisible objects, default to false * @returns {outList} */ - public getComponents(c: Ctor, outList?: Array, includeInactive?: boolean): T[] { + public getComponents(c: Ctor, outList?: Array, includeInactive?: boolean): T[] { outList ||= []; let component = this.getComponent(c); if (component && (component.enable || includeInactive)) { @@ -195,9 +201,10 @@ export class Object3D extends Entity { * @return {*} {T} * @memberof ELPObject3D */ - public getComponentsExt(c: Ctor, ret?: T[], includeInactive?: boolean): T[] { + public getComponentsExt(c: Ctor, ret?: T[], includeInactive?: boolean): T[] { if (!ret) ret = []; - let component = this.components.get(c.prototype); + let className = c.name; + let component = this.components.get(className); if (component && (component.enable || includeInactive)) { ret.push(component as T); } else { diff --git a/src/engine/core/geometry/GeometryBase.ts b/src/core/geometry/GeometryBase.ts similarity index 99% rename from src/engine/core/geometry/GeometryBase.ts rename to src/core/geometry/GeometryBase.ts index e1fd6b2f..5cf15cc8 100644 --- a/src/engine/core/geometry/GeometryBase.ts +++ b/src/core/geometry/GeometryBase.ts @@ -1,4 +1,3 @@ -import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/GPUBufferBase"; import { ShaderReflection } from "../../gfx/graphics/webGpu/shader/value/ShaderReflectionInfo"; import { Vector3 } from "../../math/Vector3"; import { UUID } from "../../util/Global"; @@ -8,6 +7,7 @@ import { GeometryVertexBuffer } from "./GeometryVertexBuffer"; import { GeometryIndicesBuffer } from "./GeometryIndicesBuffer"; import { GeometryVertexType } from "./GeometryVertexType"; import { VertexAttributeData } from "./VertexAttributeData"; +import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/ArrayBufferData"; export type LodLevel = { indexStart: number; diff --git a/src/engine/core/geometry/GeometryIndicesBuffer.ts b/src/core/geometry/GeometryIndicesBuffer.ts similarity index 98% rename from src/engine/core/geometry/GeometryIndicesBuffer.ts rename to src/core/geometry/GeometryIndicesBuffer.ts index 50429331..0776cd5a 100644 --- a/src/engine/core/geometry/GeometryIndicesBuffer.ts +++ b/src/core/geometry/GeometryIndicesBuffer.ts @@ -1,4 +1,4 @@ -import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/GPUBufferBase"; +import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/ArrayBufferData"; import { IndicesGPUBuffer } from "../../gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer"; import { VertexAttributeData } from "./VertexAttributeData"; diff --git a/src/engine/core/geometry/GeometryVertexBuffer.ts b/src/core/geometry/GeometryVertexBuffer.ts similarity index 100% rename from src/engine/core/geometry/GeometryVertexBuffer.ts rename to src/core/geometry/GeometryVertexBuffer.ts diff --git a/src/engine/core/geometry/GeometryVertexType.ts b/src/core/geometry/GeometryVertexType.ts similarity index 100% rename from src/engine/core/geometry/GeometryVertexType.ts rename to src/core/geometry/GeometryVertexType.ts diff --git a/src/engine/core/geometry/VertexAttribute.ts b/src/core/geometry/VertexAttribute.ts similarity index 100% rename from src/engine/core/geometry/VertexAttribute.ts rename to src/core/geometry/VertexAttribute.ts diff --git a/src/engine/core/geometry/VertexAttributeData.ts b/src/core/geometry/VertexAttributeData.ts similarity index 85% rename from src/engine/core/geometry/VertexAttributeData.ts rename to src/core/geometry/VertexAttributeData.ts index 9d4595e6..946d492d 100644 --- a/src/engine/core/geometry/VertexAttributeData.ts +++ b/src/core/geometry/VertexAttributeData.ts @@ -1,4 +1,4 @@ -import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/GPUBufferBase"; +import { ArrayBufferData } from "../../gfx/graphics/webGpu/core/buffer/ArrayBufferData"; export type VertexAttributeData = { attribute: string, diff --git a/src/engine/core/geometry/VertexAttributeName.ts b/src/core/geometry/VertexAttributeName.ts similarity index 100% rename from src/engine/core/geometry/VertexAttributeName.ts rename to src/core/geometry/VertexAttributeName.ts diff --git a/src/engine/core/geometry/VertexAttributeSize.ts b/src/core/geometry/VertexAttributeSize.ts similarity index 100% rename from src/engine/core/geometry/VertexAttributeSize.ts rename to src/core/geometry/VertexAttributeSize.ts diff --git a/src/engine/core/geometry/VertexAttributeStride.ts b/src/core/geometry/VertexAttributeStride.ts similarity index 100% rename from src/engine/core/geometry/VertexAttributeStride.ts rename to src/core/geometry/VertexAttributeStride.ts diff --git a/src/engine/core/geometry/VertexFormat.ts b/src/core/geometry/VertexFormat.ts similarity index 100% rename from src/engine/core/geometry/VertexFormat.ts rename to src/core/geometry/VertexFormat.ts diff --git a/src/engine/core/pool/ObjectPool.ts b/src/core/pool/ObjectPool.ts similarity index 100% rename from src/engine/core/pool/ObjectPool.ts rename to src/core/pool/ObjectPool.ts diff --git a/src/engine/core/pool/memory/MatrixDO.ts b/src/core/pool/memory/MatrixDO.ts similarity index 100% rename from src/engine/core/pool/memory/MatrixDO.ts rename to src/core/pool/memory/MatrixDO.ts diff --git a/src/engine/core/pool/memory/MemoryDO.ts b/src/core/pool/memory/MemoryDO.ts similarity index 100% rename from src/engine/core/pool/memory/MemoryDO.ts rename to src/core/pool/memory/MemoryDO.ts diff --git a/src/engine/core/pool/memory/MemoryInfo.ts b/src/core/pool/memory/MemoryInfo.ts similarity index 100% rename from src/engine/core/pool/memory/MemoryInfo.ts rename to src/core/pool/memory/MemoryInfo.ts diff --git a/src/engine/core/tree/kdTree/IKDTreeUserData.ts b/src/core/tree/kdTree/IKDTreeUserData.ts similarity index 100% rename from src/engine/core/tree/kdTree/IKDTreeUserData.ts rename to src/core/tree/kdTree/IKDTreeUserData.ts diff --git a/src/engine/core/tree/kdTree/KDTreeEntity.ts b/src/core/tree/kdTree/KDTreeEntity.ts similarity index 100% rename from src/engine/core/tree/kdTree/KDTreeEntity.ts rename to src/core/tree/kdTree/KDTreeEntity.ts diff --git a/src/engine/core/tree/kdTree/KDTreeNode.ts b/src/core/tree/kdTree/KDTreeNode.ts similarity index 100% rename from src/engine/core/tree/kdTree/KDTreeNode.ts rename to src/core/tree/kdTree/KDTreeNode.ts diff --git a/src/engine/core/tree/kdTree/KDTreeSpace.ts b/src/core/tree/kdTree/KDTreeSpace.ts similarity index 100% rename from src/engine/core/tree/kdTree/KDTreeSpace.ts rename to src/core/tree/kdTree/KDTreeSpace.ts diff --git a/src/engine/textures/DefaultRes.ts b/src/engine/textures/DefaultRes.ts deleted file mode 100644 index 69de0a77..00000000 --- a/src/engine/textures/DefaultRes.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Engine3D } from '../Engine3D'; -import { BRDFLUTGenerate } from '../gfx/generate/BrdfLUTGenerate'; -import { Uint8ArrayTexture } from './Uint8ArrayTexture'; -import { Texture } from "../gfx/graphics/webGpu/core/texture/Texture"; -import { HDRTextureCube } from './HDRTextureCube'; - -/** - * default internal texture - * @internal - * @group Texture - */ -class _DefaultRes { - /** - * normal texture - */ - public normalTexture: Uint8ArrayTexture; - public maskTexture: Uint8ArrayTexture; - public whiteTexture: Uint8ArrayTexture; - public blackTexture: Uint8ArrayTexture; - public redTexture: Uint8ArrayTexture; - public blueTexture: Uint8ArrayTexture; - public greenTexture: Uint8ArrayTexture; - public yellowTexture: Uint8ArrayTexture; - public grayTexture: Uint8ArrayTexture; - public defaultTextureKVMap: { [name: string]: Texture } = {}; - public defaultTextureVKMap: Map = new Map(); - public defaultSky: HDRTextureCube; - /** - * create a texture - * @param width width of texture - * @param height height of texture - * @param r component-red - * @param g component-green - * @param b component-blue - * @param a component-alpha(0 for transparent,1 for opaque) - * @param name name string - * @returns - */ - public createTexture(width: number, height: number, r: number, g: number, b: number, a: number, name?: string) { - let w = 32; - let h = 32; - let textureData = new Uint8Array(w * h * 4); - this.fillColor(textureData, width, height, r, g, b, a); - let texture = new Uint8ArrayTexture(); - texture.name = name; - texture.create(16, 16, textureData, true); - if (name) { - this.recordTexture(name, texture); - } - return texture; - } - - public recordTexture(name: string, texture: Texture) { - this.defaultTextureKVMap[name] = texture; - this.defaultTextureVKMap.set(texture, name); - } - - /** - * fill slod color to this texture - * @param array data of texture - * @param w width of texture - * @param h height of texture - * @param r component-red - * @param g component-green - * @param b component-blue - * @param a component-alpha(0 for transparent,1 for opaque) - */ - public fillColor(array: any, w: number, h: number, r: number, g: number, b: number, a: number) { - for (let i = 0; i < w; i++) { - for (let j = 0; j < h; j++) { - let pixelIndex = j * w + i; - array[pixelIndex * 4 + 0] = r; - array[pixelIndex * 4 + 1] = g; - array[pixelIndex * 4 + 2] = b; - array[pixelIndex * 4 + 3] = a; - } - } - } - - /** - * Initialize a common texture object. Provide a universal solid color texture object. - */ - public async initCommon() { - defaultRes.normalTexture = defaultRes.createTexture(32, 32, 255 * 0.5, 255 * 0.5, 255.0, 255.0, 'default-normalTexture'); - defaultRes.maskTexture = defaultRes.createTexture(32, 32, 255, 255 * 0.5, 0.0, 255.0, 'default-maskTexture'); - defaultRes.whiteTexture = defaultRes.createTexture(32, 32, 255, 255, 255, 255, 'default-whiteTexture'); - defaultRes.blackTexture = defaultRes.createTexture(32, 32, 0, 0, 0, 255.0, 'default-blackTexture'); - defaultRes.redTexture = defaultRes.createTexture(32, 32, 255, 0, 0, 255.0, 'default-redTexture'); - defaultRes.blueTexture = defaultRes.createTexture(32, 32, 0, 0, 255, 255.0, 'default-blueTexture'); - defaultRes.greenTexture = defaultRes.createTexture(32, 32, 0, 255, 0, 255, 'default-greenTexture'); - defaultRes.yellowTexture = defaultRes.createTexture(32, 32, 0, 255, 255, 255.0, 'default-yellowTexture'); - defaultRes.grayTexture = defaultRes.createTexture(32, 32, 128, 128, 128, 255.0, 'default-grayTexture'); - - let brdf = new BRDFLUTGenerate(); - let texture = brdf.generateBRDFLUTTexture(); - let BRDFLUT = texture.name = 'BRDFLUT'; - Engine3D.res.addTexture(BRDFLUT, texture); - this.recordTexture(BRDFLUT, texture); - - defaultRes.defaultSky = new HDRTextureCube(); - defaultRes.defaultSky.createFromTexture(128, defaultRes.blackTexture); - } -} - -/** - * @internal - * default internal texture - * @group Texture - */ -export let defaultRes = new _DefaultRes(); diff --git a/src/engine/event/CEvent.ts b/src/event/CEvent.ts similarity index 95% rename from src/engine/event/CEvent.ts rename to src/event/CEvent.ts index 1eeaa660..a127526c 100644 --- a/src/engine/event/CEvent.ts +++ b/src/event/CEvent.ts @@ -1,123 +1,123 @@ -import { View3D } from '../core/View3D'; -import { Object3D } from '../core/entities/Object3D'; -import { TouchData } from '../io/TouchData'; -import { CEventListener } from './CEventListener'; -/** - * Basic class of Event - * @group Events - */ -export class CEvent { - /** - * Event target, it's usually event dispatcher - */ - public target: Object3D; - - /** - * Current event target, it's current bubble object - */ - public currentTarget: CEventListener; - - /** - * event type, it's registered string of key - */ - public type: string; - - /** - * extra data.Used for the transmission process of events, carrying data - */ - public data: any; - - /** - * - * The param data when event is registered - */ - public param: any; - - /** - * - * the time when event is - */ - public time: number = 0; - - /** - * - *the delay time when event is dispatched. - */ - public delay: number = 0; - - /** - * - * mouse code, see @MouseCode {@link MouseCode} - */ - public mouseCode: number = 0; - - /** - * Is Ctrl key pressed when the event occurs - */ - public ctrlKey: boolean; - - /** - * Is Alt key pressed when the event occurs - */ - public altKey: boolean; - - /** - * Is Shift key pressed when the event occurs - */ - public shiftKey: boolean; - - /** - * Collection of finger touch points, which registered - */ - public targetTouches: Array; - - /** - * Collection of finger touch points changed - */ - public changedTouches: Array; - - /** - * Collection of finger touch points - */ - public touches: Array; - - private _stopImmediatePropagation: boolean = false; - - /** - * binded view3D object in event. - */ - public view: View3D; - - /** - * - * Create a new event, with type and data - * @param eventType {any} eventType - * @param data {any} param - */ - constructor(eventType: string = null, data: any = null) { - this.type = eventType; - this.data = data; - } - /** - * - * Prevent bubbling of all event listeners in subsequent nodes of the current node in the event flow. - */ - public stopImmediatePropagation() { - this._stopImmediatePropagation = true; - } - - /** - * @internal - * set stopImmediatePropagation as false - */ - public reset() { - this._stopImmediatePropagation = false; - } - - /** - * Returns stopImmediatePropagation value - */ - public get isStopImmediatePropagation(): boolean { - return this._stopImmediatePropagation; - } -} +import { View3D } from '../core/View3D'; +import { Object3D } from '../core/entities/Object3D'; +import { TouchData } from '../io/TouchData'; +import { CEventListener } from './CEventListener'; +/** + * Basic class of Event + * @group Events + */ +export class CEvent { + /** + * Event target, it's usually event dispatcher + */ + public target: Object3D; + + /** + * Current event target, it's current bubble object + */ + public currentTarget: CEventListener; + + /** + * event type, it's registered string of key + */ + public type: string; + + /** + * extra data.Used for the transmission process of events, carrying data + */ + public data: any; + + /** + * + * The param data when event is registered + */ + public param: any; + + /** + * + * the time when event is + */ + public time: number = 0; + + /** + * + *the delay time when event is dispatched. + */ + public delay: number = 0; + + /** + * + * mouse code, see @MouseCode {@link MouseCode} + */ + public mouseCode: number = 0; + + /** + * Is Ctrl key pressed when the event occurs + */ + public ctrlKey: boolean; + + /** + * Is Alt key pressed when the event occurs + */ + public altKey: boolean; + + /** + * Is Shift key pressed when the event occurs + */ + public shiftKey: boolean; + + /** + * Collection of finger touch points, which registered + */ + public targetTouches: Array; + + /** + * Collection of finger touch points changed + */ + public changedTouches: Array; + + /** + * Collection of finger touch points + */ + public touches: Array; + + private _stopImmediatePropagation: boolean = false; + + /** + * binded view3D object in event. + */ + public view: View3D; + + /** + * + * Create a new event, with type and data + * @param eventType {any} eventType + * @param data {any} param + */ + constructor(eventType: string = null, data: any = null) { + this.type = eventType; + this.data = data; + } + /** + * + * Prevent bubbling of all event listeners in subsequent nodes of the current node in the event flow. + */ + public stopImmediatePropagation() { + this._stopImmediatePropagation = true; + } + + /** + * @internal + * set stopImmediatePropagation as false + */ + public reset() { + this._stopImmediatePropagation = false; + } + + /** + * Returns stopImmediatePropagation value + */ + public get isStopImmediatePropagation(): boolean { + return this._stopImmediatePropagation; + } +} diff --git a/src/engine/event/CEventDispatcher.ts b/src/event/CEventDispatcher.ts similarity index 95% rename from src/engine/event/CEventDispatcher.ts rename to src/event/CEventDispatcher.ts index 3ed52d44..f9f68891 100644 --- a/src/engine/event/CEventDispatcher.ts +++ b/src/event/CEventDispatcher.ts @@ -1,210 +1,210 @@ -import { CEvent } from './CEvent'; -import { CEventListener } from './CEventListener'; - -/** - * Basic class of event diapatcher. - * It includes the implementation of functions such as event registration, - * deregistration, distribution, and unregister. - * @group Events - */ -export class CEventDispatcher { - /** - * @internal - */ - protected listeners: any = {}; - /** - * @internal - */ - public data: any; - /** - * - * Dispatch an event to all registered objects with a specific type of listener. - * @param event3D the event is dispatched. - */ - public dispatchEvent(event: CEvent) { - var list: any = this.listeners[event.type]; - if (list != null) { - list = list.slice(); - for (var i: number = 0; i < list.length; i++) { - var listener: CEventListener = list[i]; - if (listener.handler) { - try { - event.param = listener.param; - event.currentTarget = listener; - if (!listener.thisObject) { - // log("nullListener thisObject"); - } - listener.handler.call(listener.thisObject, event); - } catch (error) { - // if (window.//console) { - //console.error(error.stack); - // } - } - if (event.isStopImmediatePropagation) { - break; - } - } - } - } - } - - /** - * - * release all registered event. - */ - public dispose() { - for (var key in this.listeners) { - var list: any = this.listeners[key]; - while (list.length > 0) { - var listener: CEventListener = list[0]; - listener.handler = null; - listener.thisObject = null; - list.splice(0, 1); - } - } - } - - /** - * - * register an event listener to event distancher. - * @param type {string} event type. - * @param callback {Function} The callback function that handles events. - * This function must accept an Event3D object as its unique parameter and cannot return any result. - * for example:function(evt:Event3D):void。 - * @param thisObject {any} Current registration object, it'll call callback function。 - * @param param {any} the data binded to registered event, the default value is null。 - * @param priority {number} The priority of callback function execution, with a larger set value having priority to call - * @returns {number} Returns register event id - */ - public addEventListener(type: string | number, callback: Function, thisObject: any, param: any = null, priority: number = 0): number { - if (this.listeners[type] == null) { - this.listeners[type] = []; - } - - if (!this.hasEventListener(type, callback, thisObject)) { - var listener: CEventListener = new CEventListener(type, thisObject, callback, param, priority); - listener.id = ++CEventListener.event_id_count; - listener.current = this; - this.listeners[type].push(listener); - this.listeners[type].sort(function (listener1: CEventListener, listener2: CEventListener) { - return listener2.priority - listener1.priority; - }); - - return listener.id; - } - - for (let i = 0; i < this.listeners[type].length; i++) { - let listener: CEventListener = this.listeners[type][i]; - if (listener.equalCurrentListener(type, callback, thisObject, param)) { - return listener.id; - } - } - - return 0; - } - - /** - * - * Remove Event Listening - * @param type {string} event type - * @param callback {Function} callback function of event register - * @param thisObject {any} The current registered object. - */ - public removeEventListener(type: string | number, callback: Function, thisObject: any): void { - if (this.hasEventListener(type, callback, thisObject)) { - for (var i: number = 0; i < this.listeners[type].length; i++) { - var listener: CEventListener = this.listeners[type][i]; - if (listener.equalCurrentListener(type, callback, thisObject, listener.param)) { - listener.handler = null; - listener.thisObject = null; - this.listeners[type].splice(i, 1); - return; - } - } - } - } - - /** - * - * Remove an event Listening with id - * @param register event id, see {@link addEventListener} - * Returns true when removed success. - */ - public removeEventListenerAt(id: number): boolean { - for (var key in this.listeners) { - for (var i: number = 0; i < this.listeners[key].length; i++) { - var listener = this.listeners[key][i]; - if (listener.id == id) { - listener.handler = null; - listener.thisObject = null; - this.listeners[key].splice(i, 1); - return true; - } - } - } - return false; - } - - /** - * - * Specify a event type to remove all related event listeners - * eventType event type, set null to remove all event listeners - */ - public removeAllEventListener(eventType: string | number = null): void { - let listener: CEventListener; - - if (eventType) { - if (this.listeners[eventType]) { - for (var i: number = 0; i < this.listeners[eventType].length; i++) { - listener = this.listeners[eventType][i]; - listener.dispose(); - this.listeners[eventType].splice(i, 1); - } - - delete this.listeners[eventType]; - } - } else { - for (let key in this.listeners) { - for (var i: number = 0; i < this.listeners[key].length; i++) { - listener = this.listeners[key][i]; - listener.dispose(); - this.listeners[key].splice(i, 1); - } - - delete this.listeners[key]; - } - } - } - - /** - * - * whether the target presence of a listener with event type. - * @param type {string} event type. - * @returns {boolean} Returns a boolean. - */ - public containEventListener(type: string): boolean { - if (this.listeners[type] == null) return false; - return this.listeners[type].length > 0; - } - - /** - * - * whether the target presence of a listener with event type. it associate more registration parameters. - * @param type {string} event name. - * @param callback {Function} callback function of event register. - * @param thisObject {any} The registered object. - * @returns {boolean} Returns a boolean. - */ - public hasEventListener(type: string | number, callback: Function = null, thisObject: any = null): boolean { - if (this.listeners[type] == null) return false; - if (thisObject && callback) { - for (var i: number = 0; i < this.listeners[type].length; i++) { - var listener: CEventListener = this.listeners[type][i]; - if (listener.equalCurrentListener(type, callback, thisObject, listener.param)) { - return true; - } - } - } - return false; - } -} +import { CEvent } from './CEvent'; +import { CEventListener } from './CEventListener'; + +/** + * Basic class of event diapatcher. + * It includes the implementation of functions such as event registration, + * deregistration, distribution, and unregister. + * @group Events + */ +export class CEventDispatcher { + /** + * @internal + */ + protected listeners: any = {}; + /** + * @internal + */ + public data: any; + /** + * + * Dispatch an event to all registered objects with a specific type of listener. + * @param event3D the event is dispatched. + */ + public dispatchEvent(event: CEvent) { + var list: any = this.listeners[event.type]; + if (list != null) { + list = list.slice(); + for (var i: number = 0; i < list.length; i++) { + var listener: CEventListener = list[i]; + if (listener.handler) { + try { + event.param = listener.param; + event.currentTarget = listener; + if (!listener.thisObject) { + // log("nullListener thisObject"); + } + listener.handler.call(listener.thisObject, event); + } catch (error) { + // if (window.//console) { + //console.error(error.stack); + // } + } + if (event.isStopImmediatePropagation) { + break; + } + } + } + } + } + + /** + * + * release all registered event. + */ + public dispose() { + for (var key in this.listeners) { + var list: any = this.listeners[key]; + while (list.length > 0) { + var listener: CEventListener = list[0]; + listener.handler = null; + listener.thisObject = null; + list.splice(0, 1); + } + } + } + + /** + * + * register an event listener to event distancher. + * @param type {string} event type. + * @param callback {Function} The callback function that handles events. + * This function must accept an Event3D object as its unique parameter and cannot return any result. + * for example: function(evt:Event3D):void. + * @param thisObject {any} Current registration object, it'll call callback function. + * @param param {any} the data binded to registered event, the default value is null. + * @param priority {number} The priority of callback function execution, with a larger set value having priority to call + * @returns {number} Returns register event id + */ + public addEventListener(type: string | number, callback: Function, thisObject: any, param: any = null, priority: number = 0): number { + if (this.listeners[type] == null) { + this.listeners[type] = []; + } + + if (!this.hasEventListener(type, callback, thisObject)) { + var listener: CEventListener = new CEventListener(type, thisObject, callback, param, priority); + listener.id = ++CEventListener.event_id_count; + listener.current = this; + this.listeners[type].push(listener); + this.listeners[type].sort(function (listener1: CEventListener, listener2: CEventListener) { + return listener2.priority - listener1.priority; + }); + + return listener.id; + } + + for (let i = 0; i < this.listeners[type].length; i++) { + let listener: CEventListener = this.listeners[type][i]; + if (listener.equalCurrentListener(type, callback, thisObject, param)) { + return listener.id; + } + } + + return 0; + } + + /** + * + * Remove Event Listening + * @param type {string} event type + * @param callback {Function} callback function of event register + * @param thisObject {any} The current registered object. + */ + public removeEventListener(type: string | number, callback: Function, thisObject: any): void { + if (this.hasEventListener(type, callback, thisObject)) { + for (var i: number = 0; i < this.listeners[type].length; i++) { + var listener: CEventListener = this.listeners[type][i]; + if (listener.equalCurrentListener(type, callback, thisObject, listener.param)) { + listener.handler = null; + listener.thisObject = null; + this.listeners[type].splice(i, 1); + return; + } + } + } + } + + /** + * + * Remove an event Listening with id + * @param register event id, see {@link addEventListener} + * Returns true when removed success. + */ + public removeEventListenerAt(id: number): boolean { + for (var key in this.listeners) { + for (var i: number = 0; i < this.listeners[key].length; i++) { + var listener = this.listeners[key][i]; + if (listener.id == id) { + listener.handler = null; + listener.thisObject = null; + this.listeners[key].splice(i, 1); + return true; + } + } + } + return false; + } + + /** + * + * Specify a event type to remove all related event listeners + * eventType event type, set null to remove all event listeners + */ + public removeAllEventListener(eventType: string | number = null): void { + let listener: CEventListener; + + if (eventType) { + if (this.listeners[eventType]) { + for (var i: number = 0; i < this.listeners[eventType].length; i++) { + listener = this.listeners[eventType][i]; + listener.dispose(); + this.listeners[eventType].splice(i, 1); + } + + delete this.listeners[eventType]; + } + } else { + for (let key in this.listeners) { + for (var i: number = 0; i < this.listeners[key].length; i++) { + listener = this.listeners[key][i]; + listener.dispose(); + this.listeners[key].splice(i, 1); + } + + delete this.listeners[key]; + } + } + } + + /** + * + * whether the target presence of a listener with event type. + * @param type {string} event type. + * @returns {boolean} Returns a boolean. + */ + public containEventListener(type: string): boolean { + if (this.listeners[type] == null) return false; + return this.listeners[type].length > 0; + } + + /** + * + * whether the target presence of a listener with event type. it associate more registration parameters. + * @param type {string} event name. + * @param callback {Function} callback function of event register. + * @param thisObject {any} The registered object. + * @returns {boolean} Returns a boolean. + */ + public hasEventListener(type: string | number, callback: Function = null, thisObject: any = null): boolean { + if (this.listeners[type] == null) return false; + if (thisObject && callback) { + for (var i: number = 0; i < this.listeners[type].length; i++) { + var listener: CEventListener = this.listeners[type][i]; + if (listener.equalCurrentListener(type, callback, thisObject, listener.param)) { + return true; + } + } + } + return false; + } +} diff --git a/src/engine/event/CEventListener.ts b/src/event/CEventListener.ts similarity index 96% rename from src/engine/event/CEventListener.ts rename to src/event/CEventListener.ts index c5f17328..833d7b94 100644 --- a/src/engine/event/CEventListener.ts +++ b/src/event/CEventListener.ts @@ -1,61 +1,61 @@ -/** - * The EventListener class is used to add or remove event listeners. - * @internal - * @group Events - */ -export class CEventListener { - /** - * @private - */ - public static event_id_count = 0; - - /** - * - * Record a id. When registering a listening event, the value will increase automatically - */ - public id: number = 0; - - /** - * - * Returns current event dispatcher - */ - public current: any; - - /** - * - * @param type {string} event type - * @param thisObject {any} the object is registerd - * @param handler {Function} The callback function that handles events. - * @param param {any} Parameters bound when registering events - * @param priority {number} The priority of callback function execution, with a larger set value having priority to call - */ - constructor(public type: string | number = null, public thisObject: any = null, public handler: Function = null, public param: any = null, public priority: number = 0) { } - - /** - * - * Compare whether two events are the same - * @param type {string} event type - * @param handler {Function} The callback function that handles events. - * @param thisObject {any} the object is registerd - * @param param {any} Parameters bound when registering events - * @returns {boolean} Returns a boolean - */ - public equalCurrentListener(type: string | number, handler: Function, thisObject: any, param: any): boolean { - if (this.type == type && this.thisObject == thisObject && this.handler == handler && this.param == param) { - return true; - } - return false; - } - - /** - * - * release all registered event. - */ - - public dispose() { - this.handler = null; - this.thisObject = null; - this.param = null; - this.priority = 0; - } -} +/** + * The EventListener class is used to add or remove event listeners. + * @internal + * @group Events + */ +export class CEventListener { + /** + * @private + */ + public static event_id_count = 0; + + /** + * + * Record a id. When registering a listening event, the value will increase automatically + */ + public id: number = 0; + + /** + * + * Returns current event dispatcher + */ + public current: any; + + /** + * + * @param type {string} event type + * @param thisObject {any} the object is registerd + * @param handler {Function} The callback function that handles events. + * @param param {any} Parameters bound when registering events + * @param priority {number} The priority of callback function execution, with a larger set value having priority to call + */ + constructor(public type: string | number = null, public thisObject: any = null, public handler: Function = null, public param: any = null, public priority: number = 0) { } + + /** + * + * Compare whether two events are the same + * @param type {string} event type + * @param handler {Function} The callback function that handles events. + * @param thisObject {any} the object is registerd + * @param param {any} Parameters bound when registering events + * @returns {boolean} Returns a boolean + */ + public equalCurrentListener(type: string | number, handler: Function, thisObject: any, param: any): boolean { + if (this.type == type && this.thisObject == thisObject && this.handler == handler && this.param == param) { + return true; + } + return false; + } + + /** + * + * release all registered event. + */ + + public dispose() { + this.handler = null; + this.thisObject = null; + this.param = null; + this.priority = 0; + } +} diff --git a/src/engine/event/CResizeEvent.ts b/src/event/CResizeEvent.ts similarity index 95% rename from src/engine/event/CResizeEvent.ts rename to src/event/CResizeEvent.ts index e3ee17f0..11f938db 100644 --- a/src/engine/event/CResizeEvent.ts +++ b/src/event/CResizeEvent.ts @@ -1,13 +1,13 @@ -import { CEvent } from './CEvent'; -/** - * size change event when canvas resized - * @internal - * @group Events - */ -export class CResizeEvent extends CEvent { - /** - * - * RESIZE:enum event type - */ - static RESIZE: string = 'resize'; -} +import { CEvent } from './CEvent'; +/** + * size change event when canvas resized + * @internal + * @group Events + */ +export class CResizeEvent extends CEvent { + /** + * + * RESIZE:enum event type + */ + static RESIZE: string = 'resize'; +} diff --git a/src/engine/event/KeyCode.ts b/src/event/KeyCode.ts similarity index 94% rename from src/engine/event/KeyCode.ts rename to src/event/KeyCode.ts index 3cb5c69f..3c0e249f 100644 --- a/src/engine/event/KeyCode.ts +++ b/src/event/KeyCode.ts @@ -1,112 +1,112 @@ -/** - * Represents a unique identifier corresponding to a keyboard button. see {@link KeyboardEvent.keyCode} - * @group Events - */ -export enum KeyCode { - Key_BackSpace = 8, - Key_Tab = 9, - Key_Clear = 12, - Key_Enter = 13, - Key_Shift_L = 16, - Key_Control_L = 17, - Key_Alt_L = 18, - Key_Pause = 19, - Key_CapsLock = 20, - Key_Escape = 21, - Key_Esc = 27, - Key_Space = 32, - Key_Prior = 33, - Key_Next = 34, - Key_End = 35, - Key_Home = 36, - Key_Left = 37, - Key_Up = 38, - Key_Right = 39, - Key_Down = 40, - Key_Select = 41, - Key_Print = 42, - Key_Execute = 43, - Key_Insert = 45, - Key_Delete = 46, - Key_Help = 47, - Key_0 = 48, - Key_1 = 49, - Key_2 = 50, - Key_3 = 51, - Key_4 = 52, - Key_5 = 53, - Key_6 = 54, - Key_7 = 55, - Key_8 = 56, - Key_9 = 57, - - Key_A = 65, - Key_B = 66, - Key_C = 67, - Key_D = 68, - Key_E = 69, - Key_F = 70, - Key_G = 71, - Key_H = 72, - Key_I = 73, - Key_J = 74, - Key_K = 75, - Key_L = 76, - Key_M = 77, - Key_N = 78, - Key_O = 79, - Key_P = 80, - Key_Q = 81, - Key_R = 82, - Key_S = 83, - Key_T = 84, - Key_U = 85, - Key_V = 86, - Key_W = 87, - Key_X = 88, - Key_Y = 89, - Key_Z = 90, - Key_KP_0 = 96, - Key_KP_1 = 97, - Key_KP_2 = 98, - Key_KP_3 = 99, - Key_KP_4 = 100, - Key_KP_5 = 101, - Key_KP_6 = 102, - Key_KP_7 = 103, - Key_KP_8 = 104, - Key_KP_9 = 105, - Key_Multiply = 106, - Key_Add = 107, - Key_Separator = 108, - Key_Subtract = 109, - Key_Decimal = 110, - Key_Divide = 111, - Key_F1 = 112, - Key_F2 = 113, - Key_F3 = 114, - Key_F4 = 115, - Key_F5 = 116, - Key_F6 = 117, - Key_F7 = 118, - Key_F8 = 119, - Key_F9 = 120, - Key_F10 = 121, - Key_F11 = 122, - Key_F12 = 123, - Key_F13 = 124, - Key_F14 = 125, - Key_F15 = 126, - Key_F16 = 127, - Key_F17 = 128, - Key_F18 = 129, - Key_F19 = 130, - Key_F20 = 131, - Key_F21 = 132, - Key_F22 = 133, - Key_F23 = 134, - Key_F24 = 135, - - Key_Num_Lock = 136, - Key_Scroll_Lock = 137, -} +/** + * Represents a unique identifier corresponding to a keyboard button. see {@link KeyboardEvent.keyCode} + * @group Events + */ +export enum KeyCode { + Key_BackSpace = 8, + Key_Tab = 9, + Key_Clear = 12, + Key_Enter = 13, + Key_Shift_L = 16, + Key_Control_L = 17, + Key_Alt_L = 18, + Key_Pause = 19, + Key_CapsLock = 20, + Key_Escape = 21, + Key_Esc = 27, + Key_Space = 32, + Key_Prior = 33, + Key_Next = 34, + Key_End = 35, + Key_Home = 36, + Key_Left = 37, + Key_Up = 38, + Key_Right = 39, + Key_Down = 40, + Key_Select = 41, + Key_Print = 42, + Key_Execute = 43, + Key_Insert = 45, + Key_Delete = 46, + Key_Help = 47, + Key_0 = 48, + Key_1 = 49, + Key_2 = 50, + Key_3 = 51, + Key_4 = 52, + Key_5 = 53, + Key_6 = 54, + Key_7 = 55, + Key_8 = 56, + Key_9 = 57, + + Key_A = 65, + Key_B = 66, + Key_C = 67, + Key_D = 68, + Key_E = 69, + Key_F = 70, + Key_G = 71, + Key_H = 72, + Key_I = 73, + Key_J = 74, + Key_K = 75, + Key_L = 76, + Key_M = 77, + Key_N = 78, + Key_O = 79, + Key_P = 80, + Key_Q = 81, + Key_R = 82, + Key_S = 83, + Key_T = 84, + Key_U = 85, + Key_V = 86, + Key_W = 87, + Key_X = 88, + Key_Y = 89, + Key_Z = 90, + Key_KP_0 = 96, + Key_KP_1 = 97, + Key_KP_2 = 98, + Key_KP_3 = 99, + Key_KP_4 = 100, + Key_KP_5 = 101, + Key_KP_6 = 102, + Key_KP_7 = 103, + Key_KP_8 = 104, + Key_KP_9 = 105, + Key_Multiply = 106, + Key_Add = 107, + Key_Separator = 108, + Key_Subtract = 109, + Key_Decimal = 110, + Key_Divide = 111, + Key_F1 = 112, + Key_F2 = 113, + Key_F3 = 114, + Key_F4 = 115, + Key_F5 = 116, + Key_F6 = 117, + Key_F7 = 118, + Key_F8 = 119, + Key_F9 = 120, + Key_F10 = 121, + Key_F11 = 122, + Key_F12 = 123, + Key_F13 = 124, + Key_F14 = 125, + Key_F15 = 126, + Key_F16 = 127, + Key_F17 = 128, + Key_F18 = 129, + Key_F19 = 130, + Key_F20 = 131, + Key_F21 = 132, + Key_F22 = 133, + Key_F23 = 134, + Key_F24 = 135, + + Key_Num_Lock = 136, + Key_Scroll_Lock = 137, +} diff --git a/src/engine/event/MouseCode.ts b/src/event/MouseCode.ts similarity index 92% rename from src/engine/event/MouseCode.ts rename to src/event/MouseCode.ts index dabc3640..1255454e 100644 --- a/src/engine/event/MouseCode.ts +++ b/src/event/MouseCode.ts @@ -1,26 +1,26 @@ -/** - * Mouse Key Code - * @group Events - */ -export enum MouseCode { - /** - * - * key code of mouse left - * - */ - MOUSE_LEFT = 0, - - /** - * - * key code of mouse middle - * - */ - MOUSE_MID = 1, - - /** - * - * key code of mouse right - * - */ - MOUSE_RIGHT = 2, -} +/** + * Mouse Key Code + * @group Events + */ +export enum MouseCode { + /** + * + * key code of mouse left + * + */ + MOUSE_LEFT = 0, + + /** + * + * key code of mouse middle + * + */ + MOUSE_MID = 1, + + /** + * + * key code of mouse right + * + */ + MOUSE_RIGHT = 2, +} diff --git a/src/engine/event/eventConst/KeyEvent.ts b/src/event/eventConst/KeyEvent.ts similarity index 100% rename from src/engine/event/eventConst/KeyEvent.ts rename to src/event/eventConst/KeyEvent.ts diff --git a/src/engine/event/eventConst/LoaderEvent.ts b/src/event/eventConst/LoaderEvent.ts similarity index 100% rename from src/engine/event/eventConst/LoaderEvent.ts rename to src/event/eventConst/LoaderEvent.ts diff --git a/src/engine/event/eventConst/Object3DEvent.ts b/src/event/eventConst/Object3DEvent.ts similarity index 100% rename from src/engine/event/eventConst/Object3DEvent.ts rename to src/event/eventConst/Object3DEvent.ts diff --git a/src/engine/event/eventConst/PointerEvent3D.ts b/src/event/eventConst/PointerEvent3D.ts similarity index 100% rename from src/engine/event/eventConst/PointerEvent3D.ts rename to src/event/eventConst/PointerEvent3D.ts diff --git a/src/engine/event/eventConst/UIEvent.ts b/src/event/eventConst/UIEvent.ts similarity index 100% rename from src/engine/event/eventConst/UIEvent.ts rename to src/event/eventConst/UIEvent.ts diff --git a/src/gfx/data/IrradianceVolume.ts b/src/gfx/data/IrradianceVolume.ts new file mode 100644 index 00000000..6094cdb6 --- /dev/null +++ b/src/gfx/data/IrradianceVolume.ts @@ -0,0 +1,56 @@ +import { StorageGPUBuffer } from "../graphics/webGpu/core/buffer/StorageGPUBuffer"; + +/** + * @internal + * @group Post + */ +export class IrradianceVolume { + private debugX: number = 0; + private debugY: number = 0; + private debugZ: number = 0; + public probesBufferData: Float32Array; //offset xyz frame + public probesBuffer: StorageGPUBuffer; + public isVolumeFrameChange: boolean = true; + public irradianceVolumeBuffer: StorageGPUBuffer; + + public constructor() { + this.irradianceVolumeBuffer = new StorageGPUBuffer(80); + this.fillIrradianceData(); + } + + private fillIrradianceData(): void { + this.irradianceVolumeBuffer.setFloat("orientationIndex", 0); + this.irradianceVolumeBuffer.setFloat("hysteresis", 0); + this.irradianceVolumeBuffer.setFloat("OctRTSideSize", 0); + this.irradianceVolumeBuffer.setFloat("OctRTMaxSize", 0); + this.irradianceVolumeBuffer.setFloat("startX", 0); + this.irradianceVolumeBuffer.setFloat("startY", 0); + this.irradianceVolumeBuffer.setFloat("startZ", 0); + this.irradianceVolumeBuffer.setFloat("ProbeSpace", 0); + this.irradianceVolumeBuffer.setFloat("probeXCount", 0); + this.irradianceVolumeBuffer.setFloat("probeYCount", 0); + this.irradianceVolumeBuffer.setFloat("probeZCount", 0); + this.irradianceVolumeBuffer.setFloat("maxDistance", 0); + this.irradianceVolumeBuffer.setFloat("depthSharpness", 0); + this.irradianceVolumeBuffer.setFloat("ProbeSourceTextureSize", 0); + this.irradianceVolumeBuffer.setFloat("ProbeSize", 0); + this.irradianceVolumeBuffer.setFloat("bounceIntensity", 0); + this.irradianceVolumeBuffer.setFloat("probeRoughness", 0); + + this.irradianceVolumeBuffer.setFloat("normalBias", 0); + this.irradianceVolumeBuffer.setFloat("irradianceChebyshevBias", 0); + this.irradianceVolumeBuffer.setFloat("rayNumber", 0); + this.irradianceVolumeBuffer.setFloat("irradianceDistanceBias", 0); + this.irradianceVolumeBuffer.setFloat("indirectIntensity", 0); + this.irradianceVolumeBuffer.setFloat("ddgiGamma", 0); + this.irradianceVolumeBuffer.setFloat("lerpHysteresis", 0); + + this.irradianceVolumeBuffer.setFloat("debugX", this.debugX); + this.irradianceVolumeBuffer.setFloat("debugY", this.debugY); + this.irradianceVolumeBuffer.setFloat("debugZ", this.debugZ); + + this.irradianceVolumeBuffer.apply(); + } + + +} diff --git a/src/engine/gfx/generate/BrdfLUTGenerate.ts b/src/gfx/generate/BrdfLUTGenerate.ts similarity index 100% rename from src/engine/gfx/generate/BrdfLUTGenerate.ts rename to src/gfx/generate/BrdfLUTGenerate.ts diff --git a/src/engine/gfx/generate/PassGenerate.ts b/src/gfx/generate/PassGenerate.ts similarity index 96% rename from src/engine/gfx/generate/PassGenerate.ts rename to src/gfx/generate/PassGenerate.ts index a84d21e0..a36ccb92 100644 --- a/src/engine/gfx/generate/PassGenerate.ts +++ b/src/gfx/generate/PassGenerate.ts @@ -1,5 +1,4 @@ import { RenderNode } from '../../components/renderer/RenderNode'; -import { GLTFParser } from '../../loader/parser/gltf/GLTFParser'; import { MaterialBase } from '../../materials/MaterialBase'; import { CastPointShadowMaterialPass } from '../../materials/multiPass/CastPointShadowMaterialPass'; import { CastShadowMaterialPass } from '../../materials/multiPass/CastShadowMaterialPass'; @@ -8,6 +7,7 @@ import { GBufferPass } from '../../materials/multiPass/GBufferPass'; import { SkyGBufferPass } from '../../materials/multiPass/SkyGBufferPass'; import { RendererMaskUtil, RendererMask } from '../renderJob/passRenderer/state/RendererMask'; import { RendererType } from '../renderJob/passRenderer/state/RendererType'; +import { GLTFType } from '../../loader/parser/gltf/GLTFType'; /** * @internal @@ -63,8 +63,8 @@ export class PassGenerate { public static createShadowPass(renderNode: RenderNode, material: MaterialBase) { let use_skeleton = RendererMaskUtil.hasMask(renderNode.rendererMask, RendererMask.SkinnedMesh); let useTangent = renderNode.geometry.hasAttribute('TANGENT'); - let useMorphTargets = renderNode.geometry.hasAttribute(GLTFParser.MORPH_POSITION_PREFIX + '0'); - let useMorphNormals = renderNode.geometry.hasAttribute(GLTFParser.MORPH_NORMAL_PREFIX + '0'); + let useMorphTargets = renderNode.geometry.hasAttribute(GLTFType.MORPH_POSITION_PREFIX + '0'); + let useMorphNormals = renderNode.geometry.hasAttribute(GLTFType.MORPH_NORMAL_PREFIX + '0'); let shadowMaterialPass = material.renderShader.getPassShader(RendererType.SHADOW); if (!shadowMaterialPass) { @@ -132,8 +132,8 @@ export class PassGenerate { // let baseMat = renderNode.materials[0]; // reflectionPass.baseMap = baseMat.baseMap; // let useTangent = renderNode.geometry.hasVertexAttribute('TANGENT'); - // let useMorphTargets = renderNode.geometry.hasVertexAttribute(GLTFParser.MORPH_POSITION_PREFIX + '0'); - // let useMorphNormals = renderNode.geometry.hasVertexAttribute(GLTFParser.MORPH_NORMAL_PREFIX + '0'); + // let useMorphTargets = renderNode.geometry.hasVertexAttribute(GLTFType.MORPH_POSITION_PREFIX + '0'); + // let useMorphNormals = renderNode.geometry.hasVertexAttribute(GLTFType.MORPH_NORMAL_PREFIX + '0'); // let use_skeleton = RendererMaskUtil.hasMask(renderNode.rendererMask, RendererMask.SkinnedMesh); @@ -172,8 +172,8 @@ export class PassGenerate { let baseMat = renderNode.materials[0]; depthMaterialPass.baseMap = baseMat.baseMap; let useTangent = renderNode.geometry.hasAttribute('TANGENT'); - let useMorphTargets = renderNode.geometry.hasAttribute(GLTFParser.MORPH_POSITION_PREFIX + '0'); - let useMorphNormals = renderNode.geometry.hasAttribute(GLTFParser.MORPH_NORMAL_PREFIX + '0'); + let useMorphTargets = renderNode.geometry.hasAttribute(GLTFType.MORPH_POSITION_PREFIX + '0'); + let useMorphNormals = renderNode.geometry.hasAttribute(GLTFType.MORPH_NORMAL_PREFIX + '0'); let use_skeleton = RendererMaskUtil.hasMask(renderNode.rendererMask, RendererMask.SkinnedMesh); diff --git a/src/engine/gfx/generate/convert/BlurEffectCreator.ts b/src/gfx/generate/convert/BlurEffectCreator.ts similarity index 100% rename from src/engine/gfx/generate/convert/BlurEffectCreator.ts rename to src/gfx/generate/convert/BlurEffectCreator.ts diff --git a/src/engine/gfx/generate/convert/ErpImage2CubeMap.ts b/src/gfx/generate/convert/ErpImage2CubeMap.ts similarity index 100% rename from src/engine/gfx/generate/convert/ErpImage2CubeMap.ts rename to src/gfx/generate/convert/ErpImage2CubeMap.ts diff --git a/src/engine/gfx/generate/convert/IBLEnvMapCreator.ts b/src/gfx/generate/convert/IBLEnvMapCreator.ts similarity index 100% rename from src/engine/gfx/generate/convert/IBLEnvMapCreator.ts rename to src/gfx/generate/convert/IBLEnvMapCreator.ts diff --git a/src/engine/gfx/generate/convert/MergeRGBACreator.ts b/src/gfx/generate/convert/MergeRGBACreator.ts similarity index 100% rename from src/engine/gfx/generate/convert/MergeRGBACreator.ts rename to src/gfx/generate/convert/MergeRGBACreator.ts diff --git a/src/engine/gfx/generate/convert/TextureCubeStdCreator.ts b/src/gfx/generate/convert/TextureCubeStdCreator.ts similarity index 100% rename from src/engine/gfx/generate/convert/TextureCubeStdCreator.ts rename to src/gfx/generate/convert/TextureCubeStdCreator.ts diff --git a/src/engine/gfx/generate/convert/TextureCubeUtils.ts b/src/gfx/generate/convert/TextureCubeUtils.ts similarity index 100% rename from src/engine/gfx/generate/convert/TextureCubeUtils.ts rename to src/gfx/generate/convert/TextureCubeUtils.ts diff --git a/src/engine/gfx/graphics/webGpu/CanvasConfig.ts b/src/gfx/graphics/webGpu/CanvasConfig.ts similarity index 94% rename from src/engine/gfx/graphics/webGpu/CanvasConfig.ts rename to src/gfx/graphics/webGpu/CanvasConfig.ts index e95a3699..ba70c9b5 100644 --- a/src/engine/gfx/graphics/webGpu/CanvasConfig.ts +++ b/src/gfx/graphics/webGpu/CanvasConfig.ts @@ -1,4 +1,3 @@ -import { Scene3D } from '../../../core/Scene3D'; /** * config data for canvas diff --git a/src/engine/gfx/graphics/webGpu/Context3D.ts b/src/gfx/graphics/webGpu/Context3D.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/Context3D.ts rename to src/gfx/graphics/webGpu/Context3D.ts diff --git a/src/engine/gfx/graphics/webGpu/WebGPUConst.ts b/src/gfx/graphics/webGpu/WebGPUConst.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/WebGPUConst.ts rename to src/gfx/graphics/webGpu/WebGPUConst.ts diff --git a/src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup.ts b/src/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup.ts similarity index 98% rename from src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup.ts rename to src/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup.ts index c7a6ccc3..24859b4d 100644 --- a/src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup.ts +++ b/src/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup.ts @@ -15,7 +15,7 @@ export class GlobalBindGroup { // public static probeEntries: ProbeEntries; public static modelMatrixBindGroup: MatrixBindGroup; - public static initCommon() { + public static init() { this.modelMatrixBindGroup = new MatrixBindGroup(); this._cameraBindGroups = new Map(); this._lightEntriesMap = new Map(); diff --git a/src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroupLayout.ts b/src/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroupLayout.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroupLayout.ts rename to src/gfx/graphics/webGpu/core/bindGroups/GlobalBindGroupLayout.ts diff --git a/src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts b/src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts rename to src/gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup.ts diff --git a/src/engine/gfx/graphics/webGpu/core/bindGroups/MatrixBindGroup.ts b/src/gfx/graphics/webGpu/core/bindGroups/MatrixBindGroup.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/bindGroups/MatrixBindGroup.ts rename to src/gfx/graphics/webGpu/core/bindGroups/MatrixBindGroup.ts diff --git a/src/engine/gfx/graphics/webGpu/core/bindGroups/TexturesBindGroup.ts b/src/gfx/graphics/webGpu/core/bindGroups/TexturesBindGroup.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/bindGroups/TexturesBindGroup.ts rename to src/gfx/graphics/webGpu/core/bindGroups/TexturesBindGroup.ts diff --git a/src/engine/gfx/graphics/webGpu/core/bindGroups/groups/LightEntries.ts b/src/gfx/graphics/webGpu/core/bindGroups/groups/LightEntries.ts similarity index 92% rename from src/engine/gfx/graphics/webGpu/core/bindGroups/groups/LightEntries.ts rename to src/gfx/graphics/webGpu/core/bindGroups/groups/LightEntries.ts index 71a0711d..c75de7d4 100644 --- a/src/engine/gfx/graphics/webGpu/core/bindGroups/groups/LightEntries.ts +++ b/src/gfx/graphics/webGpu/core/bindGroups/groups/LightEntries.ts @@ -6,6 +6,7 @@ import { Engine3D } from "../../../../../../Engine3D"; import { LightData } from "../../../../../../components/lights/LightData"; import { View3D } from "../../../../../../core/View3D"; import { MemoryInfo } from "../../../../../../core/pool/memory/MemoryInfo"; +import { IrradianceVolume } from "../../../../../data/IrradianceVolume"; import { EntityCollect } from "../../../../../renderJob/collect/EntityCollect"; import { StorageGPUBuffer } from "../../buffer/StorageGPUBuffer"; @@ -15,6 +16,7 @@ import { StorageGPUBuffer } from "../../buffer/StorageGPUBuffer"; */ export class LightEntries { public storageGPUBuffer: StorageGPUBuffer; + public irradianceVolume: IrradianceVolume; private _lightList: MemoryInfo[] = []; constructor() { @@ -23,6 +25,8 @@ export class LightEntries { GPUBufferUsage.COPY_SRC ); + this.irradianceVolume = new IrradianceVolume(); + for (let i = 0; i < Engine3D.setting.light.maxLight; i++) { let memory = this.storageGPUBuffer.memory.allocation_node(LightData.lightSize * 4); this._lightList.push(memory); diff --git a/src/gfx/graphics/webGpu/core/buffer/ArrayBufferData.ts b/src/gfx/graphics/webGpu/core/buffer/ArrayBufferData.ts new file mode 100644 index 00000000..71334cd8 --- /dev/null +++ b/src/gfx/graphics/webGpu/core/buffer/ArrayBufferData.ts @@ -0,0 +1 @@ +export type ArrayBufferData = Uint8Array | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array \ No newline at end of file diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer.ts similarity index 80% rename from src/engine/gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer.ts index cf93521b..f02d3e09 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer.ts @@ -1,4 +1,5 @@ import { GPUBufferBase } from './GPUBufferBase'; +import { GPUBufferType } from './GPUBufferType'; /** * Storage class buffer for calculating shaders @@ -8,6 +9,7 @@ import { GPUBufferBase } from './GPUBufferBase'; export class ComputeGPUBuffer extends GPUBufferBase { constructor(size: number, data?: Float32Array) { super(); + this.bufferType = GPUBufferType.ComputeGPUBuffer; this.createBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, size, data); } } diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts b/src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts similarity index 93% rename from src/engine/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts rename to src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts index f10e54c7..b3269c3b 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts +++ b/src/gfx/graphics/webGpu/core/buffer/GPUBufferBase.ts @@ -1,5 +1,5 @@ -import { MemoryDO } from "../../../../../core/pool/memory/MemoryDO"; -import { MemoryInfo } from "../../../../../core/pool/memory/MemoryInfo"; +import { ArrayBufferData } from "./ArrayBufferData"; +import { GPUBufferType } from "./GPUBufferType"; import { Color } from "../../../../../math/Color"; import { Matrix4 } from "../../../../../math/Matrix4"; import { Quaternion } from "../../../../../math/Quaternion"; @@ -7,16 +7,19 @@ import { Vector2 } from "../../../../../math/Vector2"; import { Vector3 } from "../../../../../math/Vector3"; import { Vector4 } from "../../../../../math/Vector4"; import { Struct } from "../../../../../util/struct/Struct"; -import { GPUContext } from "../../../../renderJob/GPUContext"; + import { webGPUContext } from "../../Context3D"; +import { MemoryDO } from "../../../../../core/pool/memory/MemoryDO"; +import { MemoryInfo } from "../../../../../core/pool/memory/MemoryInfo"; +import { GPUContext } from "../../../../renderJob/GPUContext"; -export type ArrayBufferData = Uint8Array | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array /** * @internal * @group GFX */ export class GPUBufferBase { + public bufferType: GPUBufferType; public buffer: GPUBuffer; public memory: MemoryDO; public memoryNodes: Map; @@ -25,7 +28,6 @@ export class GPUBufferBase { public byteSize: number; public usage: GPUBufferUsageFlags; public visibility: number = GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; - private _readBuffer: GPUBuffer; constructor() { @@ -358,16 +360,17 @@ export class GPUBufferBase { } private async read() { - this._readFlag = true; - let command = GPUContext.beginCommandEncoder(); - command.copyBufferToBuffer(this.buffer, 0, this._readBuffer, 0, this.memory.shareDataBuffer.byteLength); - GPUContext.endCommandEncoder(command); - - await this._readBuffer.mapAsync(GPUMapMode.READ); - const copyArrayBuffer = this._readBuffer.getMappedRange(); - this.outFloat32Array.set(new Float32Array(copyArrayBuffer), 0); - // this.memory.shareDataBuffer.set(new Float32Array(copyArrayBuffer), 0); - this._readBuffer.unmap(); - this._readFlag = false; + // this._readFlag = true; + + // let command = context.beginCommandEncoder(); + // command.copyBufferToBuffer(this.buffer, 0, this._readBuffer, 0, this.memory.shareDataBuffer.byteLength); + // GPUContext.endCommandEncoder(command); + + // await this._readBuffer.mapAsync(GPUMapMode.READ); + // const copyArrayBuffer = this._readBuffer.getMappedRange(); + // this.outFloat32Array.set(new Float32Array(copyArrayBuffer), 0); + // // this.memory.shareDataBuffer.set(new Float32Array(copyArrayBuffer), 0); + // this._readBuffer.unmap(); + // this._readFlag = false; } } diff --git a/src/gfx/graphics/webGpu/core/buffer/GPUBufferType.ts b/src/gfx/graphics/webGpu/core/buffer/GPUBufferType.ts new file mode 100644 index 00000000..3b4b799f --- /dev/null +++ b/src/gfx/graphics/webGpu/core/buffer/GPUBufferType.ts @@ -0,0 +1,9 @@ +export enum GPUBufferType { + IndicesGPUBuffer, + VertexGPUBuffer, + UniformGPUBuffer, + StorageGPUBuffer, + ComputeGPUBuffer, + MaterialDataUniformGPUBuffer, + StructStorageGPUBuffer +} \ No newline at end of file diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts similarity index 86% rename from src/engine/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts index 5cab421f..cde486b4 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer.ts @@ -1,6 +1,8 @@ import { MemoryInfo } from '../../../../../core/pool/memory/MemoryInfo'; import { webGPUContext } from '../../Context3D'; -import { ArrayBufferData, GPUBufferBase } from './GPUBufferBase'; +import { ArrayBufferData } from './ArrayBufferData'; +import { GPUBufferBase } from './GPUBufferBase'; +import { GPUBufferType } from './GPUBufferType'; /** * The buffer use at geometry indices @@ -12,6 +14,7 @@ export class IndicesGPUBuffer extends GPUBufferBase { public indicesNode: MemoryInfo; constructor(data?: ArrayBufferData) { super(); + this.bufferType = GPUBufferType.IndicesGPUBuffer; this.createIndicesBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.INDEX | GPUBufferUsage.INDIRECT, data); } diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer.ts similarity index 94% rename from src/engine/gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer.ts index 76facef3..ee60cfec 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer.ts @@ -1,3 +1,4 @@ +import { GPUBufferType } from './GPUBufferType'; import { UniformNode } from '../uniforms/UniformNode'; import { GPUBufferBase } from './GPUBufferBase'; /** @@ -9,6 +10,7 @@ export class MaterialDataUniformGPUBuffer extends GPUBufferBase { private _onChange: boolean = true; constructor() { super(); + this.bufferType = GPUBufferType.MaterialDataUniformGPUBuffer; } /** diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/StorageGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/StorageGPUBuffer.ts similarity index 71% rename from src/engine/gfx/graphics/webGpu/core/buffer/StorageGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/StorageGPUBuffer.ts index 36b09e42..d728a408 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/StorageGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/StorageGPUBuffer.ts @@ -1,4 +1,6 @@ -import { ArrayBufferData, GPUBufferBase } from './GPUBufferBase'; +import { ArrayBufferData } from './ArrayBufferData'; +import { GPUBufferBase } from './GPUBufferBase'; +import { GPUBufferType } from './GPUBufferType'; /** * The buffer of the storage class * written in the computer shader or CPU Coder @@ -8,6 +10,7 @@ import { ArrayBufferData, GPUBufferBase } from './GPUBufferBase'; export class StorageGPUBuffer extends GPUBufferBase { constructor(size: number, usage: number = 0, data?: ArrayBufferData) { super(); + this.bufferType = GPUBufferType.StorageGPUBuffer; this.createBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | usage, size, data); // this.createBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, size, data); } diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer.ts similarity index 84% rename from src/engine/gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer.ts index b3cff78a..0c2e14f5 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer.ts @@ -1,5 +1,6 @@ import { Struct } from '../../../../../util/struct/Struct'; import { GPUBufferBase } from './GPUBufferBase'; +import { GPUBufferType } from './GPUBufferType'; /** * Structure storage class buffer, convenient for initializing gpubuffers of structure types * written in the computer shader or CPU Coder @@ -9,6 +10,7 @@ import { GPUBufferBase } from './GPUBufferBase'; export class StructStorageGPUBuffer extends GPUBufferBase { constructor(struct: { new(): T }, count: number, usage: number = 0) { super(); + this.bufferType = GPUBufferType.StructStorageGPUBuffer; this.createBufferByStruct(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | usage, struct, count); } } diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/UniformGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/UniformGPUBuffer.ts similarity index 84% rename from src/engine/gfx/graphics/webGpu/core/buffer/UniformGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/UniformGPUBuffer.ts index d2b34fa8..1ee4860a 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/UniformGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/UniformGPUBuffer.ts @@ -1,3 +1,4 @@ +import { GPUBufferType } from './GPUBufferType'; import { GPUBufferBase } from './GPUBufferBase'; /** * CPU write, GPU read-only transmission buffer @@ -8,6 +9,7 @@ import { GPUBufferBase } from './GPUBufferBase'; export class UniformGPUBuffer extends GPUBufferBase { constructor(size: number, data?: Float32Array) { super(); + this.bufferType = GPUBufferType.UniformGPUBuffer; this.createBuffer(GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, size, data); } diff --git a/src/engine/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts b/src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts similarity index 88% rename from src/engine/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts rename to src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts index e1984534..30dcb0f7 100644 --- a/src/engine/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts +++ b/src/gfx/graphics/webGpu/core/buffer/VertexGPUBuffer.ts @@ -1,6 +1,7 @@ import { MemoryInfo } from '../../../../../core/pool/memory/MemoryInfo'; import { webGPUContext } from '../../Context3D'; -import { ArrayBufferData, GPUBufferBase } from './GPUBufferBase'; +import { GPUBufferBase } from './GPUBufferBase'; +import { GPUBufferType } from './GPUBufferType'; /** * The buffer use at geometry indices @@ -12,6 +13,7 @@ export class VertexGPUBuffer extends GPUBufferBase { public node: MemoryInfo; constructor(size: number) { super(); + this.bufferType = GPUBufferType.VertexGPUBuffer; this.createVertexBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.VERTEX, size); } diff --git a/src/engine/gfx/graphics/webGpu/core/texture/ITexture.ts b/src/gfx/graphics/webGpu/core/texture/ITexture.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/texture/ITexture.ts rename to src/gfx/graphics/webGpu/core/texture/ITexture.ts diff --git a/src/engine/gfx/graphics/webGpu/core/texture/Texture.ts b/src/gfx/graphics/webGpu/core/texture/Texture.ts similarity index 98% rename from src/engine/gfx/graphics/webGpu/core/texture/Texture.ts rename to src/gfx/graphics/webGpu/core/texture/Texture.ts index 1679b6ab..9dc523fd 100644 --- a/src/engine/gfx/graphics/webGpu/core/texture/Texture.ts +++ b/src/gfx/graphics/webGpu/core/texture/Texture.ts @@ -1,6 +1,6 @@ -import { webGPUContext } from "../../Context3D"; -import { GPUAddressMode } from "../../WebGPUConst"; -import { TextureMipmapGenerator } from "./TextureMipmapGenerator"; +import { GPUAddressMode } from '../../WebGPUConst'; +import { TextureMipmapGenerator } from './TextureMipmapGenerator'; +import { webGPUContext } from '../../Context3D'; /** * Texture diff --git a/src/engine/gfx/graphics/webGpu/core/texture/TextureCube.ts b/src/gfx/graphics/webGpu/core/texture/TextureCube.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/texture/TextureCube.ts rename to src/gfx/graphics/webGpu/core/texture/TextureCube.ts diff --git a/src/engine/gfx/graphics/webGpu/core/texture/TextureMipmapCompute.ts b/src/gfx/graphics/webGpu/core/texture/TextureMipmapCompute.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/texture/TextureMipmapCompute.ts rename to src/gfx/graphics/webGpu/core/texture/TextureMipmapCompute.ts diff --git a/src/engine/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts b/src/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts rename to src/gfx/graphics/webGpu/core/texture/TextureMipmapGenerator.ts diff --git a/src/engine/gfx/graphics/webGpu/core/uniforms/UniformNode.ts b/src/gfx/graphics/webGpu/core/uniforms/UniformNode.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/core/uniforms/UniformNode.ts rename to src/gfx/graphics/webGpu/core/uniforms/UniformNode.ts diff --git a/src/engine/gfx/graphics/webGpu/descriptor/RTDescriptor.ts b/src/gfx/graphics/webGpu/descriptor/RTDescriptor.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/descriptor/RTDescriptor.ts rename to src/gfx/graphics/webGpu/descriptor/RTDescriptor.ts diff --git a/src/engine/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts b/src/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts rename to src/gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/ComputeShader.ts b/src/gfx/graphics/webGpu/shader/ComputeShader.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/ComputeShader.ts rename to src/gfx/graphics/webGpu/shader/ComputeShader.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/RenderShader.ts b/src/gfx/graphics/webGpu/shader/RenderShader.ts similarity index 95% rename from src/engine/gfx/graphics/webGpu/shader/RenderShader.ts rename to src/gfx/graphics/webGpu/shader/RenderShader.ts index 90ca4cca..01deac09 100644 --- a/src/engine/gfx/graphics/webGpu/shader/RenderShader.ts +++ b/src/gfx/graphics/webGpu/shader/RenderShader.ts @@ -8,13 +8,12 @@ import { MaterialBase } from "../../../../materials/MaterialBase"; import { MaterialPass } from "../../../../materials/MaterialPass"; import { Color } from "../../../../math/Color"; import { Vector4 } from "../../../../math/Vector4"; -import { defaultRes } from "../../../../textures/DefaultRes"; + import { GPUContext } from "../../../renderJob/GPUContext"; import { GlobalBindGroupLayout } from "../core/bindGroups/GlobalBindGroupLayout"; import { GPUBufferBase } from "../core/buffer/GPUBufferBase"; -import { MaterialDataUniformGPUBuffer } from "../core/buffer/MaterialDataUniformGPUBuffer"; -import { Texture } from "../core/texture/Texture"; import { UniformNode } from "../core/uniforms/UniformNode"; +import { Texture } from "../core/texture/Texture"; import { webGPUContext } from "../Context3D"; import { ShaderConverter } from "./converter/ShaderConverter"; import { ShaderBase } from "./ShaderBase"; @@ -24,6 +23,10 @@ import { ShaderReflection, ShaderReflectionVarInfo } from "./value/ShaderReflect import { ShaderState } from "./value/ShaderState"; import { RendererPassState } from "../../../renderJob/passRenderer/state/RendererPassState"; import { RendererType } from "../../../renderJob/passRenderer/state/RendererType"; +import { GPUBufferType } from "../core/buffer/GPUBufferType"; + +import { MaterialDataUniformGPUBuffer } from "../core/buffer/MaterialDataUniformGPUBuffer"; +import { ShaderUtil } from "./util/ShaderUtil"; export class RenderShader extends ShaderBase { public useRz: boolean = false; @@ -72,8 +75,7 @@ export class RenderShader extends ShaderBase { protected _textureGroup: number = -1; protected _textureChange: boolean = false; - private static _renderShaderModulePool: Map = new Map(); - private static _renderShader: Map = new Map(); + private _vs_limit = []; private _fs_limit = []; private _cs_limit = []; @@ -87,11 +89,11 @@ export class RenderShader extends ShaderBase { this.fsName = fs.toLowerCase(); if (!(this.vsName in ShaderLib)) { - console.error(`Shader Not Register, Please Register Shader!`, this.vsName); + console.error(`Shader Not Register, Please Register Shader!`, this.vsName); } if (!(this.fsName in ShaderLib)) { - console.error(`Shader Not Register, Please Register Shader!`, this.fsName); + console.error(`Shader Not Register, Please Register Shader!`, this.fsName); } if (ShaderLib[this.vsName]) { @@ -204,7 +206,8 @@ export class RenderShader extends ShaderBase { */ public static createShader(vs: string, fs: string): string { let shader = new RenderShader(vs, fs); - RenderShader._renderShader.set(shader.instanceID, shader); + ShaderUtil.renderShader.set(shader.instanceID, shader); + return shader.instanceID; } @@ -213,10 +216,10 @@ export class RenderShader extends ShaderBase { * @param instanceID instance ID of the RenderShader */ public static destroyShader(instanceID: string) { - if (RenderShader._renderShader.has(instanceID)) { - let shader = RenderShader._renderShader.get(instanceID); + if (ShaderUtil.renderShader.has(instanceID)) { + let shader = ShaderUtil.renderShader.get(instanceID); shader.destroy(); - RenderShader._renderShader.delete(instanceID) + ShaderUtil.renderShader.delete(instanceID) } } @@ -226,7 +229,7 @@ export class RenderShader extends ShaderBase { * @returns RenderShader object */ public static getShader(instanceID: string) { - return RenderShader._renderShader.get(instanceID); + return ShaderUtil.renderShader.get(instanceID); } /** @@ -308,7 +311,7 @@ export class RenderShader extends ShaderBase { } /** - * Apply render shader state value + * Apply render shader state value * @param geometry * @param materialPass * @param rendererPassState @@ -479,7 +482,7 @@ export class RenderShader extends ShaderBase { key += `${k}=${this.defineValue[k]},`; } - let shaderModule = RenderShader._renderShaderModulePool.get(key); + let shaderModule = ShaderUtil.renderShaderModulePool.get(key); if (!shaderModule) { shader = this.applyPostDefine(shader, renderPassState); @@ -494,7 +497,7 @@ export class RenderShader extends ShaderBase { console.log(e); } }); - RenderShader._renderShaderModulePool.set(key, shaderModule); + ShaderUtil.renderShaderModulePool.set(key, shaderModule); } switch (stage) { @@ -551,7 +554,7 @@ export class RenderShader extends ShaderBase { case `sampler`: { let textureName = info.varName.replace(`Sampler`, ``); - let texture = this.textures[textureName] ? this.textures[textureName] : defaultRes.redTexture; + let texture = this.textures[textureName] ? this.textures[textureName] : Engine3D.res.redTexture; let entry: GPUBindGroupLayoutEntry = { binding: info.binding, visibility: texture.visibility, @@ -565,7 +568,7 @@ export class RenderShader extends ShaderBase { case `sampler_comparison`: { let textureName = info.varName.replace(`Sampler`, ``); - let texture = this.textures[textureName] ? this.textures[textureName] : defaultRes.redTexture; + let texture = this.textures[textureName] ? this.textures[textureName] : Engine3D.res.redTexture; let entry: GPUBindGroupLayoutEntry = { binding: info.binding, visibility: texture.visibility, @@ -584,7 +587,7 @@ export class RenderShader extends ShaderBase { case `texture_depth_cube`: case `texture_depth_cube_array`: { - let texture = this.textures[info.varName] ? this.textures[info.varName] : defaultRes.redTexture; + let texture = this.textures[info.varName] ? this.textures[info.varName] : Engine3D.res.redTexture; let entry: GPUBindGroupLayoutEntry = { binding: info.binding, visibility: texture.visibility, @@ -600,7 +603,7 @@ export class RenderShader extends ShaderBase { break; case `texture_external`: { - let texture = this.textures[info.varName] ? this.textures[info.varName] : defaultRes.redTexture; + let texture = this.textures[info.varName] ? this.textures[info.varName] : Engine3D.res.redTexture; let entry: GPUBindGroupLayoutEntry = { binding: info.binding, visibility: texture.visibility, @@ -613,7 +616,7 @@ export class RenderShader extends ShaderBase { break; default: { - let texture = this.textures[info.varName] ? this.textures[info.varName] : defaultRes.redTexture; + let texture = this.textures[info.varName] ? this.textures[info.varName] : Engine3D.res.redTexture; let entry: GPUBindGroupLayoutEntry = { binding: info.binding, visibility: texture.visibility, @@ -643,7 +646,7 @@ export class RenderShader extends ShaderBase { if (refs.varType == `uniform`) { let buffer = this._bufferDic.get(refs.varName); if (buffer) { - if (buffer instanceof MaterialDataUniformGPUBuffer) { + if (buffer.bufferType == GPUBufferType.MaterialDataUniformGPUBuffer) { let uniforms: UniformNode[] = []; for (let i = 0; i < refs.dataFields.length; i++) { const field = refs.dataFields[i]; @@ -691,7 +694,7 @@ export class RenderShader extends ShaderBase { let textureName = refs.varName.replace(`Sampler`, ``); let texture = this.textures[textureName]; if (!texture) { - texture = defaultRes.blackTexture; + texture = Engine3D.res.blackTexture; this.setTexture(textureName, texture); } if (texture) { @@ -720,7 +723,7 @@ export class RenderShader extends ShaderBase { } else { let texture = this.textures[refs.varName]; if (!texture) { - texture = defaultRes.whiteTexture; + texture = Engine3D.res.whiteTexture; this.setTexture(refs.varName, texture); } if (texture) { @@ -908,6 +911,8 @@ export class RenderShader extends ShaderBase { this.shaderState.splitTexture = this.shaderReflection.useSplit; } + + ; } diff --git a/src/engine/gfx/graphics/webGpu/shader/ShaderBase.ts b/src/gfx/graphics/webGpu/shader/ShaderBase.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/ShaderBase.ts rename to src/gfx/graphics/webGpu/shader/ShaderBase.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/ShaderStage.ts b/src/gfx/graphics/webGpu/shader/ShaderStage.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/ShaderStage.ts rename to src/gfx/graphics/webGpu/shader/ShaderStage.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/GLSLLexer.ts b/src/gfx/graphics/webGpu/shader/converter/GLSLLexer.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/converter/GLSLLexer.ts rename to src/gfx/graphics/webGpu/shader/converter/GLSLLexer.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/GLSLLexerToken.ts b/src/gfx/graphics/webGpu/shader/converter/GLSLLexerToken.ts similarity index 87% rename from src/engine/gfx/graphics/webGpu/shader/converter/GLSLLexerToken.ts rename to src/gfx/graphics/webGpu/shader/converter/GLSLLexerToken.ts index 3906db88..69e35b39 100644 --- a/src/engine/gfx/graphics/webGpu/shader/converter/GLSLLexerToken.ts +++ b/src/gfx/graphics/webGpu/shader/converter/GLSLLexerToken.ts @@ -221,65 +221,65 @@ export enum TokenType { UINT, // built-in type: uint[] UINT_ARRAY, - // built-in type:bool + // built-in type: bool BOOL, - // built-in type:bool[] + // built-in type: bool[] BOOL_ARRAY, - // built-in type:float + // built-in type: float FLOAT, - // built-in type:float[] + // built-in type: float[] FLOAT_ARRAY, - // built-in type:double + // built-in type: double DOUBLE, - // built-in type:double[] + // built-in type: double[] DOUBLE_ARRAY, - // built-in type:vec2 + // built-in type: vec2 VEC2, - // built-in type:vec2[] + // built-in type: vec2[] VEC2_ARRAY, - // built-in type:vec3 + // built-in type: vec3 VEC3, - // built-in type:vec3[] + // built-in type: vec3[] VEC3_ARRAY, - // built-in type:vec4 + // built-in type: vec4 VEC4, - // built-in type:vec4[] + // built-in type: vec4[] VEC4_ARRAY, - // built-in type:bvec2 + // built-in type: bvec2 BVEC2, - // built-in type:bvec2[] + // built-in type: bvec2[] BVEC2_ARRAY, - // built-in type:bvec3 + // built-in type: bvec3 BVEC3, - // built-in type:bvec3[] + // built-in type: bvec3[] BVEC3_ARRAY, - // built-in type:bvec4 + // built-in type: bvec4 BVEC4, - // built-in type:bvec4[] + // built-in type: bvec4[] BVEC4_ARRAY, - // built-in type:ivec2 + // built-in type: ivec2 IVEC2, - // built-in type:ivec2[] + // built-in type: ivec2[] IVEC2_ARRAY, - // built-in type:ivec3 + // built-in type: ivec3 IVEC3, - // built-in type:ivec3[] + // built-in type: ivec3[] IVEC3_ARRAY, - // built-in type:ivec4 + // built-in type: ivec4 IVEC4, - // built-in type:ivec4[] + // built-in type: ivec4[] IVEC4_ARRAY, - // built-in type:uvec2 + // built-in type: uvec2 UVEC2, - // built-in type:uvec2[] + // built-in type: uvec2[] UVEC2_ARRAY, - // built-in type:uvec3 + // built-in type: uvec3 UVEC3, - // built-in type:uvec3[] + // built-in type: uvec3[] UVEC3_ARRAY, - // built-in type:uvec4 + // built-in type: uvec4 UVEC4, - // built-in type:uvec4[] + // built-in type: uvec4[] UVEC4_ARRAY, // built-in type: mat2x2 MAT2x2, @@ -333,15 +333,15 @@ export enum TokenType { SAMPLER_1D_SHADOW, // built-in type: sampler2DShadow SAMPLER_2D_SHADOW, - // built-in type:texture1D + // built-in type: texture1D TEXTURE_1D, - // built-in type:texture1DArray + // built-in type: texture1DArray TEXTURE_1D_ARRAY, - // built-in type:texture2D + // built-in type: texture2D TEXTURE_2D, - // built-in type:texture2DArray + // built-in type: texture2DArray TEXTURE_2D_ARRAY, - // built-in type:texture3D + // built-in type: texture3D TEXTURE_3D, // built-in type: textureCube TEXTURE_CUBE, diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/GLSLPreprocessor.ts b/src/gfx/graphics/webGpu/shader/converter/GLSLPreprocessor.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/converter/GLSLPreprocessor.ts rename to src/gfx/graphics/webGpu/shader/converter/GLSLPreprocessor.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/GLSLSyntax.ts b/src/gfx/graphics/webGpu/shader/converter/GLSLSyntax.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/converter/GLSLSyntax.ts rename to src/gfx/graphics/webGpu/shader/converter/GLSLSyntax.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/Reader.ts b/src/gfx/graphics/webGpu/shader/converter/Reader.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/converter/Reader.ts rename to src/gfx/graphics/webGpu/shader/converter/Reader.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/ShaderConverter.ts b/src/gfx/graphics/webGpu/shader/converter/ShaderConverter.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/converter/ShaderConverter.ts rename to src/gfx/graphics/webGpu/shader/converter/ShaderConverter.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/StatementNode.ts b/src/gfx/graphics/webGpu/shader/converter/StatementNode.ts similarity index 99% rename from src/engine/gfx/graphics/webGpu/shader/converter/StatementNode.ts rename to src/gfx/graphics/webGpu/shader/converter/StatementNode.ts index 7151bbab..e410074c 100644 --- a/src/engine/gfx/graphics/webGpu/shader/converter/StatementNode.ts +++ b/src/gfx/graphics/webGpu/shader/converter/StatementNode.ts @@ -946,7 +946,7 @@ export class SN_Expression extends StatementNode { throw 'An unexpected character'; } } else if (currToken.isOperation()) { - // ++a、--a + // ++a, --a if (currToken.Type == TokenType.INC || currToken.Type == TokenType.DEC) { let op = currToken; r.skipToken(1); @@ -1325,7 +1325,7 @@ export class SN_TernaryOperation extends StatementNode { /** * @internal - * Statement node:Expression of select(a.b) + * Statement node: Expression of select(a.b) * @group GFX */ export class SN_SelectOperation extends StatementNode { @@ -1357,7 +1357,7 @@ export class SN_SelectOperation extends StatementNode { /** * @internal - * Statement node:Expression of index(a[b]) + * Statement node: Expression of index(a[b]) * @group GFX */ export class SN_IndexOperation extends StatementNode { @@ -1585,7 +1585,7 @@ export class SN_CodeBlock extends StatementNode { /** * @internal - * Statement node:precision + * Statement node: precision * @group GFX */ export class SN_Precision extends StatementNode { diff --git a/src/engine/gfx/graphics/webGpu/shader/converter/WGSLTranslator.ts b/src/gfx/graphics/webGpu/shader/converter/WGSLTranslator.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/converter/WGSLTranslator.ts rename to src/gfx/graphics/webGpu/shader/converter/WGSLTranslator.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/util/MorePassParser.ts b/src/gfx/graphics/webGpu/shader/util/MorePassParser.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/util/MorePassParser.ts rename to src/gfx/graphics/webGpu/shader/util/MorePassParser.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/util/Preprocessor.ts b/src/gfx/graphics/webGpu/shader/util/Preprocessor.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/util/Preprocessor.ts rename to src/gfx/graphics/webGpu/shader/util/Preprocessor.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/util/ShaderUtil.ts b/src/gfx/graphics/webGpu/shader/util/ShaderUtil.ts similarity index 54% rename from src/engine/gfx/graphics/webGpu/shader/util/ShaderUtil.ts rename to src/gfx/graphics/webGpu/shader/util/ShaderUtil.ts index eb9ca3bb..eb9aca29 100644 --- a/src/engine/gfx/graphics/webGpu/shader/util/ShaderUtil.ts +++ b/src/gfx/graphics/webGpu/shader/util/ShaderUtil.ts @@ -1,3 +1,5 @@ +import { RenderShader } from "../RenderShader"; + export type VertexPart = { name: string; vertex_in_struct: string; @@ -18,12 +20,11 @@ export type FragmentPart = { } export class ShaderUtil { - /** - * - * @param vsName - * @param shaderParts - */ - public static createShader(vertexParts: VertexPart, fragmentShader: FragmentPart) { + public static renderShaderModulePool: Map; + public static renderShader: Map; + public static init() { + this.renderShaderModulePool = new Map(); + this.renderShader = new Map(); } } diff --git a/src/engine/gfx/graphics/webGpu/shader/value/ConstValue.ts b/src/gfx/graphics/webGpu/shader/value/ConstValue.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/value/ConstValue.ts rename to src/gfx/graphics/webGpu/shader/value/ConstValue.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/value/DefineValue.ts b/src/gfx/graphics/webGpu/shader/value/DefineValue.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/value/DefineValue.ts rename to src/gfx/graphics/webGpu/shader/value/DefineValue.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/value/ShaderReflectionInfo.ts b/src/gfx/graphics/webGpu/shader/value/ShaderReflectionInfo.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/value/ShaderReflectionInfo.ts rename to src/gfx/graphics/webGpu/shader/value/ShaderReflectionInfo.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/value/ShaderState.ts b/src/gfx/graphics/webGpu/shader/value/ShaderState.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/value/ShaderState.ts rename to src/gfx/graphics/webGpu/shader/value/ShaderState.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/value/ShaderValue.ts b/src/gfx/graphics/webGpu/shader/value/ShaderValue.ts similarity index 100% rename from src/engine/gfx/graphics/webGpu/shader/value/ShaderValue.ts rename to src/gfx/graphics/webGpu/shader/value/ShaderValue.ts diff --git a/src/engine/gfx/graphics/webGpu/shader/value/UniformValue.ts b/src/gfx/graphics/webGpu/shader/value/UniformValue.ts similarity index 85% rename from src/engine/gfx/graphics/webGpu/shader/value/UniformValue.ts rename to src/gfx/graphics/webGpu/shader/value/UniformValue.ts index 3f62b4f5..9fa71976 100644 --- a/src/engine/gfx/graphics/webGpu/shader/value/UniformValue.ts +++ b/src/gfx/graphics/webGpu/shader/value/UniformValue.ts @@ -1,4 +1,3 @@ -import { LightBase } from '../../../../../components/lights/LightBase'; import { Color } from '../../../../../math/Color'; import { Vector2 } from '../../../../../math/Vector2'; import { Vector3 } from '../../../../../math/Vector3'; diff --git a/src/engine/gfx/renderJob/GPUContext.ts b/src/gfx/renderJob/GPUContext.ts similarity index 72% rename from src/engine/gfx/renderJob/GPUContext.ts rename to src/gfx/renderJob/GPUContext.ts index 75361633..c829f28a 100644 --- a/src/engine/gfx/renderJob/GPUContext.ts +++ b/src/gfx/renderJob/GPUContext.ts @@ -1,16 +1,11 @@ import { Camera3D } from "../../core/Camera3D"; -import { View3D } from "../../core/View3D"; -import { ViewQuad } from "../../core/ViewQuad"; import { GeometryBase } from "../../core/geometry/GeometryBase"; import { ProfilerUtil } from "../../util/ProfilerUtil"; import { webGPUContext } from "../graphics/webGpu/Context3D"; import { GlobalBindGroup } from "../graphics/webGpu/core/bindGroups/GlobalBindGroup"; -import { Texture } from "../graphics/webGpu/core/texture/Texture"; import { ComputeShader } from "../graphics/webGpu/shader/ComputeShader"; import { RenderShader } from "../graphics/webGpu/shader/RenderShader"; import { RendererPassState } from "./passRenderer/state/RendererPassState"; -import { RendererType } from "./passRenderer/state/RendererType"; - /** * WebGPU api use context @@ -213,69 +208,6 @@ export class GPUContext { } - /** - * By inputting a map to viewQuad and setting corresponding - * processing shaders, the corresponding results are output for off-screen rendering - * Can also be directly used as the final display rendering result rendering canvas - * @param viewQuad - * @see ViewQuad - * @param scene3D - * @see Scene3D - * @param command - */ - public static renderTarget(view: View3D, viewQuad: ViewQuad, command: GPUCommandEncoder) { - let camera = view.camera; - let encoder = GPUContext.beginRenderPass(command, viewQuad.rendererPassState); - GPUContext.bindCamera(encoder, camera); - viewQuad.quadRenderer.nodeUpdate(view, RendererType.COLOR, viewQuad.rendererPassState, null); - viewQuad.quadRenderer.renderPass2(view, RendererType.COLOR, viewQuad.rendererPassState, null, encoder); - GPUContext.endPass(encoder); - } - - /** - * Output to screen through screen based shading - * @param viewQuad - * @see ViewQuad - * @param scene3D - * @see Scene3D - * @param command - * @param colorTexture - */ - public static renderToViewQuad(view: View3D, viewQuad: ViewQuad, command: GPUCommandEncoder, colorTexture: Texture) { - let camera = view.camera; - viewQuad.colorTexture = colorTexture; - let encoder = GPUContext.beginRenderPass(command, viewQuad.rendererPassState); - GPUContext.bindCamera(encoder, camera); - - // viewQuad.x = view.viewPort.x; - // viewQuad.y = view.viewPort.y; - // viewQuad.scaleX = view.viewPort.width; - // viewQuad.scaleY = view.viewPort.height; - // viewQuad.transform.updateWorldMatrix(true); - // encoder.setViewport( - // view.viewPort.x * webGPUContext.presentationSize[0], - // view.viewPort.y * webGPUContext.presentationSize[1], - // view.viewPort.width * webGPUContext.presentationSize[0], - // view.viewPort.height * webGPUContext.presentationSize[1], - // 0.0, 1.0); - // encoder.setScissorRect( - // view.viewPort.x * webGPUContext.presentationSize[0], - // view.viewPort.y * webGPUContext.presentationSize[0], - // view.viewPort.width * webGPUContext.presentationSize[0], - // view.viewPort.height * webGPUContext.presentationSize[1], - // ); - - // encoder.setScissorRect(view.viewPort.x, view.viewPort.y, 300, 150); - // encoder.setViewport(view.viewPort.x, view.viewPort.y, view.viewPort.width / (view.viewPort.width / view.viewPort.height), view.viewPort.height, 0.0, 1.0); - // encoder.setScissorRect(view.viewPort.x, view.viewPort.y, view.viewPort.width, view.viewPort.height); - - // encoder.setViewport(camera.viewPort.x, camera.viewPort.y, camera.viewPort.width, camera.viewPort.height, 0.0, 1.0); - // encoder.setScissorRect(camera.viewPort.x, camera.viewPort.y, camera.viewPort.width, camera.viewPort.height); - - viewQuad.quadRenderer.nodeUpdate(view, RendererType.COLOR, viewQuad.rendererPassState, null); - viewQuad.quadRenderer.renderPass2(view, RendererType.COLOR, viewQuad.rendererPassState, null, encoder); - GPUContext.endPass(encoder); - } /** * Perform the final calculation and submit the Shader to the GPU diff --git a/src/engine/gfx/renderJob/collect/CollectInfo.ts b/src/gfx/renderJob/collect/CollectInfo.ts similarity index 100% rename from src/engine/gfx/renderJob/collect/CollectInfo.ts rename to src/gfx/renderJob/collect/CollectInfo.ts diff --git a/src/gfx/renderJob/collect/ComponentCollect.ts b/src/gfx/renderJob/collect/ComponentCollect.ts new file mode 100644 index 00000000..b72536bb --- /dev/null +++ b/src/gfx/renderJob/collect/ComponentCollect.ts @@ -0,0 +1,44 @@ +import { IComponent } from "../../../components/IComponent"; +import { Object3D } from "../../../core/entities/Object3D"; + +export class ComponentCollect { + + /** + * @internal + */ + public static componentsUpdateList: Map; + + /** + * @internal + */ + public static componentsLateUpdateList: Map; + + /** + * @internal + */ + public static componentsBeforeUpdateList: Map; + + /** + * @internal + */ + public static componentsComputeList: Map; + + /** + * @internal + */ + public static waitStartComponent: Map; + + /** + * @internal + */ + public static graphicComponent: Map; + + public static init() { + ComponentCollect.componentsUpdateList = new Map(); + ComponentCollect.componentsLateUpdateList = new Map(); + ComponentCollect.componentsBeforeUpdateList = new Map(); + ComponentCollect.componentsComputeList = new Map(); + ComponentCollect.waitStartComponent = new Map(); + ComponentCollect.graphicComponent = new Map(); + } +} diff --git a/src/engine/gfx/renderJob/collect/EntityBatchCollect.ts b/src/gfx/renderJob/collect/EntityBatchCollect.ts similarity index 100% rename from src/engine/gfx/renderJob/collect/EntityBatchCollect.ts rename to src/gfx/renderJob/collect/EntityBatchCollect.ts diff --git a/src/engine/gfx/renderJob/collect/EntityCollect.ts b/src/gfx/renderJob/collect/EntityCollect.ts similarity index 91% rename from src/engine/gfx/renderJob/collect/EntityCollect.ts rename to src/gfx/renderJob/collect/EntityCollect.ts index bf4eba4f..4ee5f637 100644 --- a/src/engine/gfx/renderJob/collect/EntityCollect.ts +++ b/src/gfx/renderJob/collect/EntityCollect.ts @@ -1,19 +1,20 @@ -import { LightBase } from '../../../components/lights/LightBase'; + +import { ILight } from '../../../components/lights/ILight'; import { RenderNode } from '../../../components/renderer/RenderNode'; -import { SkyRenderer } from '../../../components/renderer/SkyRenderer'; import { Scene3D } from '../../../core/Scene3D'; import { RenderLayerUtil, RenderLayer } from '../config/RenderLayer'; import { Graphic3DBatchRenderer } from '../passRenderer/graphic/Graphic3DBatchRenderer'; +import { RendererMask } from '../passRenderer/state/RendererMask'; import { CollectInfo } from './CollectInfo'; import { EntityBatchCollect } from './EntityBatchCollect'; -import { RenderGroup } from './RenderGroup'; + /** * @internal * @group Post */ export class EntityCollect { // private static _sceneRenderList: Map; - private _sceneLights: Map; + private _sceneLights: Map; private _source_opaqueRenderNodes: Map; private _source_transparentRenderNodes: Map; @@ -32,7 +33,7 @@ export class EntityCollect { giLightingChange: true } - public sky: SkyRenderer; + public sky: RenderNode; private _collectInfo: CollectInfo; @@ -46,7 +47,7 @@ export class EntityCollect { constructor() { // this._sceneRenderList = new Map(); - this._sceneLights = new Map(); + this._sceneLights = new Map(); this._source_opaqueRenderNodes = new Map(); this._source_transparentRenderNodes = new Map(); @@ -80,7 +81,8 @@ export class EntityCollect { public addRenderNode(root: Scene3D, renderNode: RenderNode) { if (!root) return; - if (renderNode instanceof SkyRenderer) { + + if (renderNode.hasMask(RendererMask.Sky)) { this.sky = renderNode; } else if (renderNode instanceof Graphic3DBatchRenderer) { if (this._graphics.indexOf(renderNode) == -1) { @@ -123,7 +125,7 @@ export class EntityCollect { } public removeRenderNode(root: Scene3D, renderNode: RenderNode) { - if (renderNode instanceof SkyRenderer) { + if (renderNode.hasMask(RendererMask.Sky)) { this.sky = null; } else if (!RenderLayerUtil.hasMask(renderNode.object3D.renderLayer, RenderLayer.None)) { @@ -138,7 +140,7 @@ export class EntityCollect { } } - public addLight(root: Scene3D, light: LightBase) { + public addLight(root: Scene3D, light: ILight) { if (!this._sceneLights.has(root)) { this._sceneLights.set(root, [light]); } else { @@ -148,7 +150,7 @@ export class EntityCollect { } } - public removeLight(root: Scene3D, light: LightBase) { + public removeLight(root: Scene3D, light: ILight) { if (this._sceneLights.has(root)) { let list = this._sceneLights.get(root); let index = list.indexOf(light); @@ -157,7 +159,7 @@ export class EntityCollect { } } } - public getLights(root: Scene3D): LightBase[] { + public getLights(root: Scene3D): ILight[] { let list = this._sceneLights.get(root); return list ? list : []; } diff --git a/src/engine/gfx/renderJob/collect/RenderGroup.ts b/src/gfx/renderJob/collect/RenderGroup.ts similarity index 100% rename from src/engine/gfx/renderJob/collect/RenderGroup.ts rename to src/gfx/renderJob/collect/RenderGroup.ts diff --git a/src/engine/gfx/renderJob/collect/ShadowLightsCollect.ts b/src/gfx/renderJob/collect/ShadowLightsCollect.ts similarity index 82% rename from src/engine/gfx/renderJob/collect/ShadowLightsCollect.ts rename to src/gfx/renderJob/collect/ShadowLightsCollect.ts index 4da99259..6cf8c71c 100644 --- a/src/engine/gfx/renderJob/collect/ShadowLightsCollect.ts +++ b/src/gfx/renderJob/collect/ShadowLightsCollect.ts @@ -1,9 +1,9 @@ import { Engine3D } from '../../../Engine3D'; -import { DirectLight } from '../../../components/lights/DirectLight'; -import { LightBase } from '../../../components/lights/LightBase'; +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'; /** @@ -12,15 +12,15 @@ import { UUID } from '../../../util/Global'; */ export class ShadowLightsCollect { - public static directionLightList: Map; - public static pointLightList: Map; + public static directionLightList: Map; + public static pointLightList: Map; public static init() { - this.directionLightList = new Map(); - this.pointLightList = new Map(); + this.directionLightList = new Map(); + this.pointLightList = new Map(); } - static getShadowLightList(light: LightBase) { + static getShadowLightList(light: ILight) { if (!light.transform.view3D) return null; if (light.lightData.lightType == LightType.DirectionLight) { let list = this.directionLightList.get(light.transform.view3D.scene); @@ -82,7 +82,7 @@ export class ShadowLightsCollect { return list; } - static addShadowLight(light: LightBase) { + static addShadowLight(light: ILight) { if (!light.transform.view3D) return null; if (light.lightData.lightType == LightType.DirectionLight) { let list = this.directionLightList.get(light.transform.view3D.scene); @@ -90,11 +90,11 @@ export class ShadowLightsCollect { list = []; this.directionLightList.set(light.transform.view3D.scene, list); } - if (light instanceof DirectLight && !light.shadowCamera) { - light.shadowCamera = CameraUtil.createCamera3DObject(null, 'shadowCamera'); - light.shadowCamera.name = UUID(); - light.shadowCamera.isShadowCamera = true; - light.shadowCamera.orthoOffCenter( + if (light.lightData.lightType == LightType.DirectionLight && !light['shadowCamera']) { + light['shadowCamera'] = CameraUtil.createCamera3DObject(null, 'shadowCamera'); + light['shadowCamera'].name = UUID(); + light['shadowCamera'].isShadowCamera = true; + light['shadowCamera'].orthoOffCenter( Engine3D.setting.shadow.shadowBound, -Engine3D.setting.shadow.shadowBound, Engine3D.setting.shadow.shadowBound, @@ -103,12 +103,12 @@ export class ShadowLightsCollect { 50000, ); } - let has = list.indexOf(light as DirectLight) == -1; + let has = list.indexOf(light) == -1; if (has) { if (list.length < 8) { light.lightData.castShadowIndex = list.length; } - list.push(light as DirectLight); + list.push(light); } return list; } else if (light.lightData.lightType == LightType.PointLight) { @@ -142,12 +142,12 @@ export class ShadowLightsCollect { } } - public static removeShadowLight(light: LightBase) { + public static removeShadowLight(light: ILight) { if (!light.transform.view3D) return null; if (light.lightData.lightType == LightType.DirectionLight) { let list = this.directionLightList.get(light.transform.view3D.scene); if (list) { - let index = list.indexOf(light as DirectLight); + let index = list.indexOf(light); if (index != -1) { list.splice(index, 1); } diff --git a/src/engine/gfx/renderJob/config/RTResourceConfig.ts b/src/gfx/renderJob/config/RTResourceConfig.ts similarity index 100% rename from src/engine/gfx/renderJob/config/RTResourceConfig.ts rename to src/gfx/renderJob/config/RTResourceConfig.ts diff --git a/src/engine/gfx/renderJob/config/RenderLayer.ts b/src/gfx/renderJob/config/RenderLayer.ts similarity index 100% rename from src/engine/gfx/renderJob/config/RenderLayer.ts rename to src/gfx/renderJob/config/RenderLayer.ts diff --git a/src/engine/gfx/renderJob/frame/GBufferFrame.ts b/src/gfx/renderJob/frame/GBufferFrame.ts similarity index 100% rename from src/engine/gfx/renderJob/frame/GBufferFrame.ts rename to src/gfx/renderJob/frame/GBufferFrame.ts diff --git a/src/engine/gfx/renderJob/frame/ProbeGBufferFrame.ts b/src/gfx/renderJob/frame/ProbeGBufferFrame.ts similarity index 100% rename from src/engine/gfx/renderJob/frame/ProbeGBufferFrame.ts rename to src/gfx/renderJob/frame/ProbeGBufferFrame.ts diff --git a/src/engine/gfx/renderJob/frame/RTFrame.ts b/src/gfx/renderJob/frame/RTFrame.ts similarity index 100% rename from src/engine/gfx/renderJob/frame/RTFrame.ts rename to src/gfx/renderJob/frame/RTFrame.ts diff --git a/src/engine/gfx/renderJob/frame/RTResourceMap.ts b/src/gfx/renderJob/frame/RTResourceMap.ts similarity index 96% rename from src/engine/gfx/renderJob/frame/RTResourceMap.ts rename to src/gfx/renderJob/frame/RTResourceMap.ts index b2a0eed9..3ed7f278 100644 --- a/src/engine/gfx/renderJob/frame/RTResourceMap.ts +++ b/src/gfx/renderJob/frame/RTResourceMap.ts @@ -1,6 +1,5 @@ import { ViewQuad } from '../../../core/ViewQuad'; -import { defaultRes } from '../../../textures/DefaultRes'; -import { Uint16Texture } from '../../../textures/Uint16Texture'; + import { VirtualTexture } from '../../../textures/VirtualTexture'; import { UniformNode } from '../../graphics/webGpu/core/uniforms/UniformNode'; import { RTDescriptor } from '../../graphics/webGpu/descriptor/RTDescriptor'; diff --git a/src/engine/gfx/renderJob/jobs/ForwardRenderJob.ts b/src/gfx/renderJob/jobs/ForwardRenderJob.ts similarity index 97% rename from src/engine/gfx/renderJob/jobs/ForwardRenderJob.ts rename to src/gfx/renderJob/jobs/ForwardRenderJob.ts index 9a04cf75..6be26740 100644 --- a/src/engine/gfx/renderJob/jobs/ForwardRenderJob.ts +++ b/src/gfx/renderJob/jobs/ForwardRenderJob.ts @@ -1,7 +1,7 @@ import { Engine3D } from '../../../Engine3D'; import { View3D } from '../../../core/View3D'; import { GlobalBindGroup } from '../../graphics/webGpu/core/bindGroups/GlobalBindGroup'; -import { ColorPassRenderer } from '../color/ColorPassRenderer'; +import { ColorPassRenderer } from '../passRenderer/color/ColorPassRenderer'; import { GBufferFrame } from '../frame/GBufferFrame'; import { RendererJob } from './RendererJob'; /** diff --git a/src/engine/gfx/renderJob/jobs/RenderMap.ts b/src/gfx/renderJob/jobs/RenderMap.ts similarity index 100% rename from src/engine/gfx/renderJob/jobs/RenderMap.ts rename to src/gfx/renderJob/jobs/RenderMap.ts diff --git a/src/engine/gfx/renderJob/jobs/RendererJob.ts b/src/gfx/renderJob/jobs/RendererJob.ts similarity index 92% rename from src/engine/gfx/renderJob/jobs/RendererJob.ts rename to src/gfx/renderJob/jobs/RendererJob.ts index 0b9e470a..b79ba779 100644 --- a/src/engine/gfx/renderJob/jobs/RendererJob.ts +++ b/src/gfx/renderJob/jobs/RendererJob.ts @@ -1,11 +1,10 @@ -import { ComponentBase } from '../../../components/ComponentBase'; import { Scene3D } from '../../../core/Scene3D'; import { View3D } from '../../../core/View3D'; import { Engine3D } from '../../../Engine3D'; import { PickFire } from '../../../io/PickFire'; import { GlobalBindGroup } from '../../graphics/webGpu/core/bindGroups/GlobalBindGroup'; import { ShadowLightsCollect } from '../collect/ShadowLightsCollect'; -import { ColorPassRenderer } from '../color/ColorPassRenderer'; +import { ColorPassRenderer } from '../passRenderer/color/ColorPassRenderer'; import { GBufferFrame } from '../frame/GBufferFrame'; import { GPUContext } from '../GPUContext'; import { OcclusionSystem } from '../occlusion/OcclusionSystem'; @@ -17,6 +16,7 @@ import { PreDepthPassRenderer } from '../passRenderer/preDepth/PreDepthPassRende import { RendererMap } from './RenderMap'; import { PostRenderer } from '../passRenderer/post/PostRenderer'; import { PostBase } from '../post/PostBase'; +import { ComponentCollect } from '../collect/ComponentCollect'; /** * render jobs @@ -198,7 +198,7 @@ export class RendererJob { /****** * auto update component list *****/ - ComponentBase.componentsBeforeUpdateList.forEach((v, k) => { + ComponentCollect.componentsBeforeUpdateList.forEach((v, k) => { if (k.enable) v(); }); @@ -211,12 +211,12 @@ export class RendererJob { renderLoop(); } - ComponentBase.componentsUpdateList.forEach((v, k) => { + ComponentCollect.componentsUpdateList.forEach((v, k) => { if (k.enable) v(); }); let command = GPUContext.beginCommandEncoder(); - ComponentBase.componentsComputeList.forEach((v, k) => { + ComponentCollect.componentsComputeList.forEach((v, k) => { if (k.enable) v(view, command); }); GPUContext.endCommandEncoder(command); @@ -229,7 +229,7 @@ export class RendererJob { view.scene.envMapChange = false; - ComponentBase.componentsLateUpdateList.forEach((v, k) => { + ComponentCollect.componentsLateUpdateList.forEach((v, k) => { if (k.enable) v(); }); @@ -257,9 +257,8 @@ export class RendererJob { let passList = this.rendererMap.getAllPassRenderer(); for (let i = 0; i < passList.length; i++) { const renderer = passList[i]; - renderer.clusterLightingRender = this.clusterLightingRender; renderer.beforeCompute(view, this.occlusionSystem); - renderer.render(view, this.occlusionSystem); + renderer.render(view, this.occlusionSystem, this.clusterLightingRender.clusterLightingBuffer); renderer.lateCompute(view, this.occlusionSystem); } } diff --git a/src/engine/gfx/renderJob/occlusion/OcclusionSystem.ts b/src/gfx/renderJob/occlusion/OcclusionSystem.ts similarity index 100% rename from src/engine/gfx/renderJob/occlusion/OcclusionSystem.ts rename to src/gfx/renderJob/occlusion/OcclusionSystem.ts diff --git a/src/engine/gfx/renderJob/passRenderer/RenderContext.ts b/src/gfx/renderJob/passRenderer/RenderContext.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/RenderContext.ts rename to src/gfx/renderJob/passRenderer/RenderContext.ts diff --git a/src/engine/gfx/renderJob/passRenderer/RendererBase.ts b/src/gfx/renderJob/passRenderer/RendererBase.ts similarity index 92% rename from src/engine/gfx/renderJob/passRenderer/RendererBase.ts rename to src/gfx/renderJob/passRenderer/RendererBase.ts index 63329edd..7190bc54 100644 --- a/src/engine/gfx/renderJob/passRenderer/RendererBase.ts +++ b/src/gfx/renderJob/passRenderer/RendererBase.ts @@ -17,6 +17,7 @@ import { RendererPassState } from "./state/RendererPassState"; import { RendererType } from "./state/RendererType"; import { RenderContext } from "./RenderContext"; import { ClusterLightingRender } from "./cluster/ClusterLightingRender"; +import { ClusterLightingBuffer } from "./cluster/ClusterLightingBuffer"; /** @@ -27,7 +28,6 @@ export class RendererBase extends CEventDispatcher { public rendererPassState: RendererPassState; public splitRendererPassState: RendererPassState; public useRenderBundle: boolean = false; - public clusterLightingRender: ClusterLightingRender; public debugViewQuads: ViewQuad[]; public debugTextures: Texture[]; @@ -74,7 +74,7 @@ export class RendererBase extends CEventDispatcher { public beforeCompute(view: View3D, occlusionSystem: OcclusionSystem) { } public lateCompute(view: View3D, occlusionSystem: OcclusionSystem) { } - public render(view: View3D, occlusionSystem: OcclusionSystem, maskTr: boolean = false) { + public render(view: View3D, occlusionSystem: OcclusionSystem, clusterLightingBuffer: ClusterLightingBuffer, maskTr: boolean = false) { GPUContext.cleanCache(); let camera = view.camera; @@ -97,7 +97,7 @@ export class RendererBase extends CEventDispatcher { if (!maskTr && EntityCollect.instance.sky) { GPUContext.bindCamera(renderPassEncoder, camera); - EntityCollect.instance.sky.renderPass2(view, this._rendererType, this.rendererPassState, this.clusterLightingRender, renderPassEncoder); + EntityCollect.instance.sky.renderPass2(view, this._rendererType, this.rendererPassState, clusterLightingBuffer, renderPassEncoder); } this.drawRenderNodes(view, renderPassEncoder, command, collectInfo.opaqueList, occlusionSystem); @@ -134,7 +134,7 @@ export class RendererBase extends CEventDispatcher { protected renderTr(encoder: GPURenderPassEncoder, command: GPUCommandEncoder, collectInfo: CollectInfo, scene: Scene3D, occlusionSystem: OcclusionSystem) { } - protected renderBundleOp(view: View3D, collectInfo: CollectInfo, occlusionSystem: OcclusionSystem) { + protected renderBundleOp(view: View3D, collectInfo: CollectInfo, occlusionSystem: OcclusionSystem, clusterLightingBuffer?: ClusterLightingBuffer) { let entityBatchCollect = EntityCollect.instance.getOpRenderGroup(view.scene); if (entityBatchCollect) { let bundlerList = []; @@ -143,7 +143,7 @@ export class RendererBase extends CEventDispatcher { bundlerList.push(v.bundleMap.get(this._rendererType)); } else { let renderBundleEncoder = GPUContext.recordBundleEncoder(this.rendererPassState.renderBundleEncoderDescriptor); - this.recordRenderBundleNode(view, renderBundleEncoder, v.renderNodes); + this.recordRenderBundleNode(view, renderBundleEncoder, v.renderNodes, clusterLightingBuffer); let newBundle = renderBundleEncoder.finish(); v.bundleMap.set(this._rendererType, newBundle); bundlerList.push(newBundle); @@ -154,7 +154,7 @@ export class RendererBase extends CEventDispatcher { return []; } - protected renderBundleTr(view: View3D, collectInfo: CollectInfo, occlusionSystem: OcclusionSystem) { + protected renderBundleTr(view: View3D, collectInfo: CollectInfo, occlusionSystem: OcclusionSystem, clusterLightingBuffer?: ClusterLightingBuffer) { let entityBatchCollect = EntityCollect.instance.getTrRenderGroup(view.scene); if (entityBatchCollect) { let bundlerList = []; @@ -163,7 +163,7 @@ export class RendererBase extends CEventDispatcher { bundlerList.push(v.bundleMap.get(this._rendererType)); } else { let renderBundleEncoder = GPUContext.recordBundleEncoder(this.rendererPassState.renderBundleEncoderDescriptor); - this.recordRenderBundleNode(view, renderBundleEncoder, v.renderNodes); + this.recordRenderBundleNode(view, renderBundleEncoder, v.renderNodes, clusterLightingBuffer); let newBundle = renderBundleEncoder.finish(); v.bundleMap.set(this._rendererType, newBundle); bundlerList.push(newBundle); @@ -174,7 +174,7 @@ export class RendererBase extends CEventDispatcher { return []; } - protected recordRenderBundleNode(view: View3D, encoder, nodes: RenderNode[]) { + protected recordRenderBundleNode(view: View3D, encoder, nodes: RenderNode[], clusterLightingBuffer?: ClusterLightingBuffer) { GPUContext.bindCamera(encoder, view.camera); GPUContext.bindGeometryBuffer(encoder, nodes[0].geometry); for (let i = 0; i < nodes.length; ++i) { @@ -182,11 +182,11 @@ export class RendererBase extends CEventDispatcher { let matrixIndex = renderNode.transform.worldMatrix.index; if (!renderNode.transform.enable) continue; - renderNode.recordRenderPass2(view, this._rendererType, this.rendererPassState, this.clusterLightingRender, encoder); + renderNode.recordRenderPass2(view, this._rendererType, this.rendererPassState, clusterLightingBuffer, encoder); } } - protected drawRenderNodes(view: View3D, encoder: GPURenderPassEncoder, command: GPUCommandEncoder, nodes: RenderNode[], occlusionSystem: OcclusionSystem) { + protected drawRenderNodes(view: View3D, encoder: GPURenderPassEncoder, command: GPUCommandEncoder, nodes: RenderNode[], occlusionSystem: OcclusionSystem, clusterLightingBuffer?: ClusterLightingBuffer) { GPUContext.bindCamera(encoder, view.camera); for (let i = Engine3D.setting.render.drawOpMin; i < Math.min(nodes.length, Engine3D.setting.render.drawOpMax); ++i) { let renderNode = nodes[i]; @@ -196,7 +196,7 @@ export class RendererBase extends CEventDispatcher { continue; if (!renderNode.enable) continue; - renderNode.renderPass2(view, this._rendererType, this.rendererPassState, this.clusterLightingRender, encoder); + renderNode.renderPass2(view, this._rendererType, this.rendererPassState, clusterLightingBuffer, encoder); } } @@ -227,7 +227,4 @@ export class RendererBase extends CEventDispatcher { this.debugViewQuads.push(viewQuad); } } - - - } diff --git a/src/gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer.ts b/src/gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer.ts new file mode 100644 index 00000000..a59c258f --- /dev/null +++ b/src/gfx/renderJob/passRenderer/cluster/ClusterLightingBuffer.ts @@ -0,0 +1,37 @@ +import { ComputeGPUBuffer } from "../../../graphics/webGpu/core/buffer/ComputeGPUBuffer"; +import { UniformGPUBuffer } from "../../../graphics/webGpu/core/buffer/UniformGPUBuffer"; + +export class ClusterLightingBuffer { + + public clusterBuffer: ComputeGPUBuffer; + public lightAssignBuffer: ComputeGPUBuffer; + public assignTableBuffer: ComputeGPUBuffer; + public clustersUniformBuffer: UniformGPUBuffer; + + constructor(numClusters: number, maxNumLightsPerCluster: number) { + this.clusterBuffer = new ComputeGPUBuffer(numClusters * /*two vec4*/ 2 * /*vec4*/4); + this.clustersUniformBuffer = new UniformGPUBuffer(10); + this.clustersUniformBuffer.visibility = GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; + + this.lightAssignBuffer = new ComputeGPUBuffer(numClusters * maxNumLightsPerCluster); + this.lightAssignBuffer.visibility = GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; + this.assignTableBuffer = new ComputeGPUBuffer(numClusters * 4); // it has start and count + this.assignTableBuffer.visibility = GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; + } + + public update(width: number, height: number, clusterPix: number, clusterTileX: number, clusterTileY: number, clusterTileZ: number, maxNumLights: number, maxNumLightsPerCluster: number, near: number, far: number) { + this.clustersUniformBuffer.setFloat('clusterTileX', clusterTileX); + this.clustersUniformBuffer.setFloat('clusterTileY', clusterTileY); + this.clustersUniformBuffer.setFloat('clusterTileZ', clusterTileZ); + this.clustersUniformBuffer.setFloat('numLights', maxNumLights); + this.clustersUniformBuffer.setFloat('maxNumLightsPerCluster', maxNumLightsPerCluster); + + this.clustersUniformBuffer.setFloat('near', near); + this.clustersUniformBuffer.setFloat('far', far); + + this.clustersUniformBuffer.setFloat('screenWidth', width); + this.clustersUniformBuffer.setFloat('screenHeight', height); + this.clustersUniformBuffer.setFloat('clusterPix', clusterPix); + this.clustersUniformBuffer.apply(); + } +} \ No newline at end of file diff --git a/src/engine/gfx/renderJob/passRenderer/cluster/ClusterLightingRender.ts b/src/gfx/renderJob/passRenderer/cluster/ClusterLightingRender.ts similarity index 62% rename from src/engine/gfx/renderJob/passRenderer/cluster/ClusterLightingRender.ts rename to src/gfx/renderJob/passRenderer/cluster/ClusterLightingRender.ts index cce8ef61..9f91c364 100644 --- a/src/engine/gfx/renderJob/passRenderer/cluster/ClusterLightingRender.ts +++ b/src/gfx/renderJob/passRenderer/cluster/ClusterLightingRender.ts @@ -1,11 +1,8 @@ import ClusterBoundsSource_cs from '../../../../assets/shader/cluster/ClusterBoundsSource_cs.wgsl?raw'; import ClusterLighting_cs from '../../../../assets/shader/cluster/ClusterLighting_cs.wgsl?raw'; -import { LightBase } from '../../../../components/lights/LightBase'; import { View3D } from '../../../../core/View3D'; import { GlobalBindGroup } from '../../../graphics/webGpu/core/bindGroups/GlobalBindGroup'; -import { ComputeGPUBuffer } from '../../../graphics/webGpu/core/buffer/ComputeGPUBuffer'; -import { UniformGPUBuffer } from '../../../graphics/webGpu/core/buffer/UniformGPUBuffer'; import { ComputeShader } from '../../../graphics/webGpu/shader/ComputeShader'; import { webGPUContext } from '../../../graphics/webGpu/Context3D'; import { EntityCollect } from '../../collect/EntityCollect'; @@ -13,6 +10,8 @@ import { GPUContext } from '../../GPUContext'; import { OcclusionSystem } from '../../occlusion/OcclusionSystem'; import { RendererBase } from '../RendererBase'; import { RendererType } from '../state/RendererType'; +import { ILight } from '../../../../components/lights/ILight'; +import { ClusterLightingBuffer } from './ClusterLightingBuffer'; /** * @internal * @group Post @@ -24,10 +23,7 @@ export class ClusterLightingRender extends RendererBase { public maxNumLights = 128; public maxNumLightsPerCluster = 100; public clusterPix = 1; - public clusterBuffer: ComputeGPUBuffer; - public lightAssignBuffer: ComputeGPUBuffer; - public assignTableBuffer: ComputeGPUBuffer; - public clustersUniformBuffer: UniformGPUBuffer; + public clusterLightingBuffer: ClusterLightingBuffer; private _clusterGenerateCompute: ComputeShader; private _clusterLightingCompute: ComputeShader; @@ -50,41 +46,22 @@ export class ClusterLightingRender extends RendererBase { let near = camera.near; let far = camera.far; - this.clusterBuffer = new ComputeGPUBuffer(numClusters * /*two vec4*/ 2 * /*vec4*/4); - this.clustersUniformBuffer = new UniformGPUBuffer(10); - this.clustersUniformBuffer.visibility = GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; - - this.clustersUniformBuffer.setFloat('clusterTileX', this.clusterTileX); - this.clustersUniformBuffer.setFloat('clusterTileY', this.clusterTileY); - this.clustersUniformBuffer.setFloat('clusterTileZ', this.clusterTileZ); - this.clustersUniformBuffer.setFloat('numLights', this.maxNumLights); - this.clustersUniformBuffer.setFloat('maxNumLightsPerCluster', this.maxNumLightsPerCluster); - - this.clustersUniformBuffer.setFloat('near', near); - this.clustersUniformBuffer.setFloat('far', far); - - this.clustersUniformBuffer.setFloat('screenWidth', size[0]); - this.clustersUniformBuffer.setFloat('screenHeight', size[1]); - this.clustersUniformBuffer.setFloat('clusterPix', this.clusterPix); - this.clustersUniformBuffer.apply(); + this.clusterLightingBuffer = new ClusterLightingBuffer(numClusters, this.maxNumLightsPerCluster); + this.clusterLightingBuffer.update(size[0], size[1], this.clusterPix, this.clusterTileX, this.clusterTileY, this.clusterTileZ, this.maxNumLights, this.maxNumLightsPerCluster, near, far); let standBindGroup = GlobalBindGroup.getCameraGroup(camera); this._clusterGenerateCompute.setUniformBuffer(`globalUniform`, standBindGroup.uniformGPUBuffer); this._clusterLightingCompute.setUniformBuffer(`globalUniform`, standBindGroup.uniformGPUBuffer); - this._clusterGenerateCompute.setUniformBuffer(`clustersUniform`, this.clustersUniformBuffer); - this._clusterGenerateCompute.setStorageBuffer(`clusterBuffer`, this.clusterBuffer); + this._clusterGenerateCompute.setUniformBuffer(`clustersUniform`, this.clusterLightingBuffer.clustersUniformBuffer); + this._clusterGenerateCompute.setStorageBuffer(`clusterBuffer`, this.clusterLightingBuffer.clusterBuffer); let lightBuffer = GlobalBindGroup.getLightEntries(view.scene); - this.lightAssignBuffer = new ComputeGPUBuffer(numClusters * this.maxNumLightsPerCluster); - this.lightAssignBuffer.visibility = GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; - this.assignTableBuffer = new ComputeGPUBuffer(numClusters * 4); // it has start and count - this.assignTableBuffer.visibility = GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE; this._clusterLightingCompute.setStorageBuffer(`models`, GlobalBindGroup.modelMatrixBindGroup.matrixBufferDst); - this._clusterLightingCompute.setUniformBuffer(`clustersUniform`, this.clustersUniformBuffer); - this._clusterLightingCompute.setStorageBuffer(`clusterBuffer`, this.clusterBuffer); + this._clusterLightingCompute.setUniformBuffer(`clustersUniform`, this.clusterLightingBuffer.clustersUniformBuffer); + this._clusterLightingCompute.setStorageBuffer(`clusterBuffer`, this.clusterLightingBuffer.clusterBuffer); this._clusterLightingCompute.setStorageBuffer(`lightBuffer`, lightBuffer.storageGPUBuffer); - this._clusterLightingCompute.setStorageBuffer(`lightAssignBuffer`, this.lightAssignBuffer); - this._clusterLightingCompute.setStorageBuffer(`assignTable`, this.assignTableBuffer); + this._clusterLightingCompute.setStorageBuffer(`lightAssignBuffer`, this.clusterLightingBuffer.lightAssignBuffer); + this._clusterLightingCompute.setStorageBuffer(`assignTable`, this.clusterLightingBuffer.assignTableBuffer); this.debug(view); } @@ -95,13 +72,12 @@ export class ClusterLightingRender extends RendererBase { let near = camera.near; let far = camera.far; - let lights: LightBase[] = EntityCollect.instance.getLights(scene); + let lights: ILight[] = EntityCollect.instance.getLights(scene); let size = webGPUContext.presentationSize; // this.clustersUniformBuffer.setFloat('screenWidth', size[0] ); // this.clustersUniformBuffer.setFloat('screenHeight', size[1] ); - this.clustersUniformBuffer.setFloat('numLights', lights.length); - - this.clustersUniformBuffer.apply(); + this.clusterLightingBuffer.clustersUniformBuffer.setFloat('numLights', lights.length); + this.clusterLightingBuffer.clustersUniformBuffer.apply(); this._clusterGenerateCompute.workerSizeX = this.clusterTileZ; this._clusterLightingCompute.workerSizeX = this.clusterTileZ; diff --git a/src/engine/gfx/renderJob/color/ColorPassRenderer.ts b/src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts similarity index 78% rename from src/engine/gfx/renderJob/color/ColorPassRenderer.ts rename to src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts index 89ac1341..47f2b418 100644 --- a/src/engine/gfx/renderJob/color/ColorPassRenderer.ts +++ b/src/gfx/renderJob/passRenderer/color/ColorPassRenderer.ts @@ -1,13 +1,14 @@ -import { Engine3D } from "../../../Engine3D"; -import { RenderNode } from "../../../components/renderer/RenderNode"; -import { View3D } from "../../../core/View3D"; -import { ProfilerUtil } from "../../../util/ProfilerUtil"; -import { GPUContext } from "../GPUContext"; -import { EntityCollect } from "../collect/EntityCollect"; -import { OcclusionSystem } from "../occlusion/OcclusionSystem"; -import { RenderContext } from "../passRenderer/RenderContext"; -import { RendererBase } from "../passRenderer/RendererBase"; -import { RendererType } from "../passRenderer/state/RendererType"; +import { Engine3D } from "../../../../Engine3D"; +import { RenderNode } from "../../../../components/renderer/RenderNode"; +import { View3D } from "../../../../core/View3D"; +import { ProfilerUtil } from "../../../../util/ProfilerUtil"; +import { GPUContext } from "../../GPUContext"; +import { EntityCollect } from "../../collect/EntityCollect"; +import { OcclusionSystem } from "../../occlusion/OcclusionSystem"; +import { RenderContext } from "../RenderContext"; +import { RendererBase } from "../RendererBase"; +import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer"; +import { RendererType } from "../state/RendererType"; /** @@ -22,7 +23,7 @@ export class ColorPassRenderer extends RendererBase { this.passType = RendererType.COLOR; } - public render(view: View3D, occlusionSystem: OcclusionSystem, maskTr: boolean = false) { + public render(view: View3D, occlusionSystem: OcclusionSystem, clusterLightingBuffer?: ClusterLightingBuffer, maskTr: boolean = false) { // return ; this.renderContext.clean(); @@ -67,11 +68,11 @@ export class ColorPassRenderer extends RendererBase { if (!maskTr && EntityCollect.instance.sky) { GPUContext.bindCamera(renderPassEncoder, camera); - EntityCollect.instance.sky.renderPass2(view, this._rendererType, this.rendererPassState, this.clusterLightingRender, renderPassEncoder); + EntityCollect.instance.sky.renderPass2(view, this._rendererType, this.rendererPassState, clusterLightingBuffer, renderPassEncoder); } GPUContext.bindCamera(renderPassEncoder, camera); - this.drawNodes(view, this.renderContext, collectInfo.opaqueList, occlusionSystem); + this.drawNodes(view, this.renderContext, collectInfo.opaqueList, occlusionSystem, clusterLightingBuffer); this.renderContext.endRenderPass(); ProfilerUtil.end("ColorPass Draw Opaque"); } @@ -90,15 +91,15 @@ export class ColorPassRenderer extends RendererBase { if (!maskTr) { GPUContext.bindCamera(renderPassEncoder, camera); - this.drawNodes(view, this.renderContext, collectInfo.transparentList, occlusionSystem); + this.drawNodes(view, this.renderContext, collectInfo.transparentList, occlusionSystem, clusterLightingBuffer); } let graphicsList = EntityCollect.instance.getGraphicList(); for (let i = 0; i < graphicsList.length; i++) { const graphic3DRenderNode = graphicsList[i]; let matrixIndex = graphic3DRenderNode.transform.worldMatrix.index; - graphic3DRenderNode.nodeUpdate(view, this._rendererType, this.splitRendererPassState, this.clusterLightingRender); - graphic3DRenderNode.renderPass2(view, this._rendererType, this.splitRendererPassState, this.clusterLightingRender, renderPassEncoder); + graphic3DRenderNode.nodeUpdate(view, this._rendererType, this.splitRendererPassState, clusterLightingBuffer); + graphic3DRenderNode.renderPass2(view, this._rendererType, this.splitRendererPassState, clusterLightingBuffer, renderPassEncoder); } this.renderContext.endRenderPass(); @@ -108,14 +109,14 @@ export class ColorPassRenderer extends RendererBase { ProfilerUtil.end("colorPass Renderer"); } - public drawNodes(view: View3D, renderContext: RenderContext, nodes: RenderNode[], occlusionSystem: OcclusionSystem) { + public drawNodes(view: View3D, renderContext: RenderContext, nodes: RenderNode[], occlusionSystem: OcclusionSystem, clusterLightingBuffer: ClusterLightingBuffer) { { for (let i = Engine3D.setting.render.drawOpMin; i < Math.min(nodes.length, Engine3D.setting.render.drawOpMax); ++i) { let renderNode = nodes[i]; if (!renderNode.transform.enable) continue; if (!renderNode.enable) continue; - renderNode.nodeUpdate(view, this._rendererType, this.rendererPassState, this.clusterLightingRender); + renderNode.nodeUpdate(view, this._rendererType, this.rendererPassState, clusterLightingBuffer); renderNode.renderPass(view, this.passType, this.renderContext); } } diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer.ts similarity index 93% rename from src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer.ts rename to src/gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer.ts index 2944b3ee..083411af 100644 --- a/src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer.ts +++ b/src/gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer.ts @@ -10,6 +10,7 @@ import { ClusterLightingRender } from "../cluster/ClusterLightingRender"; import { Graphic3DFixedRenderPipeline } from "./Graphic3DFixedRenderPipeline"; import { GraphicConfig } from "./GraphicConfig"; import { Graphics3DShape } from "./Graphics3DShape"; +import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer"; /** * @internal @@ -62,7 +63,7 @@ export class Graphic3DBatchRenderer extends RenderNode { this.shapes.set(uuid, data); } - protected init() { + public init() { super.init(); this.castGI = false; this.castShadow = false; @@ -81,7 +82,7 @@ export class Graphic3DBatchRenderer extends RenderNode { this._readyPipeline = true; } - public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingRender?: ClusterLightingRender) { + public nodeUpdate(view: View3D, passType: RendererType, renderPassState: RendererPassState, clusterLightingBuffer?: ClusterLightingBuffer) { // if(!this.enable || passType != RendererType.COLOR ) return ; if (this.mDirtyData) { this.mRenderPipeline.reset(); @@ -93,7 +94,7 @@ export class Graphic3DBatchRenderer extends RenderNode { return; } - public renderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingRender: ClusterLightingRender, encoder: GPURenderPassEncoder, useBundle: boolean = false) { + public renderPass2(view: View3D, passType: RendererType, rendererPassState: RendererPassState, clusterLightingBuffer: ClusterLightingBuffer, encoder: GPURenderPassEncoder, useBundle: boolean = false) { // if(!this.enable || passType != RendererType.COLOR ) return ; this.mRenderPipeline.render(rendererPassState, encoder); } diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DFillRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/Graphic3DFillRenderer.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DFillRenderer.ts rename to src/gfx/renderJob/passRenderer/graphic/Graphic3DFillRenderer.ts diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DFixedRenderPipeline.ts b/src/gfx/renderJob/passRenderer/graphic/Graphic3DFixedRenderPipeline.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DFixedRenderPipeline.ts rename to src/gfx/renderJob/passRenderer/graphic/Graphic3DFixedRenderPipeline.ts diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DLineBatchRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/Graphic3DLineBatchRenderer.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DLineBatchRenderer.ts rename to src/gfx/renderJob/passRenderer/graphic/Graphic3DLineBatchRenderer.ts diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DRender.ts b/src/gfx/renderJob/passRenderer/graphic/Graphic3DRender.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/graphic/Graphic3DRender.ts rename to src/gfx/renderJob/passRenderer/graphic/Graphic3DRender.ts diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/GraphicConfig.ts b/src/gfx/renderJob/passRenderer/graphic/GraphicConfig.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/graphic/GraphicConfig.ts rename to src/gfx/renderJob/passRenderer/graphic/GraphicConfig.ts diff --git a/src/engine/gfx/renderJob/passRenderer/graphic/Graphics3DShape.ts b/src/gfx/renderJob/passRenderer/graphic/Graphics3DShape.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/graphic/Graphics3DShape.ts rename to src/gfx/renderJob/passRenderer/graphic/Graphics3DShape.ts diff --git a/src/engine/gfx/renderJob/passRenderer/post/PostRenderer.ts b/src/gfx/renderJob/passRenderer/post/PostRenderer.ts similarity index 89% rename from src/engine/gfx/renderJob/passRenderer/post/PostRenderer.ts rename to src/gfx/renderJob/passRenderer/post/PostRenderer.ts index ac310c98..275a61f1 100644 --- a/src/engine/gfx/renderJob/passRenderer/post/PostRenderer.ts +++ b/src/gfx/renderJob/passRenderer/post/PostRenderer.ts @@ -60,11 +60,11 @@ export class PostRenderer extends RendererBase { } let lastTexture = GPUContext.lastRenderPassState.getLastRenderTexture(); - GPUContext.renderToViewQuad(view, this.finalQuadView, command, lastTexture); + this.finalQuadView.renderToViewQuad(view, this.finalQuadView, command, lastTexture); { if (this.debugViewQuads.length) { let debugIndex = Engine3D.setting.render.debugQuad; - if (debugIndex >= 0) GPUContext.renderToViewQuad(view, this.debugViewQuads[debugIndex], command, this.debugTextures[debugIndex]); + if (debugIndex >= 0) this.debugViewQuads[debugIndex].renderToViewQuad(view, this.debugViewQuads[debugIndex], command, this.debugTextures[debugIndex]); } } GPUContext.endCommandEncoder(command); diff --git a/src/engine/gfx/renderJob/passRenderer/preDepth/PreDepthPassRenderer.ts b/src/gfx/renderJob/passRenderer/preDepth/PreDepthPassRenderer.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/preDepth/PreDepthPassRenderer.ts rename to src/gfx/renderJob/passRenderer/preDepth/PreDepthPassRenderer.ts diff --git a/src/engine/gfx/renderJob/passRenderer/preDepth/ZCullingCompute.ts b/src/gfx/renderJob/passRenderer/preDepth/ZCullingCompute.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/preDepth/ZCullingCompute.ts rename to src/gfx/renderJob/passRenderer/preDepth/ZCullingCompute.ts diff --git a/src/engine/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts b/src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts similarity index 97% rename from src/engine/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts rename to src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts index 93732fb2..af9683cb 100644 --- a/src/engine/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts +++ b/src/gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer.ts @@ -1,9 +1,7 @@ -import { LightBase } from '../../../../components/lights/LightBase'; import { LightType } from '../../../../components/lights/LightData'; import { ShadowLightsCollect } from '../../collect/ShadowLightsCollect'; import { Camera3D } from '../../../../core/Camera3D'; import { CubeCamera } from '../../../../core/CubeCamera'; -import { Scene3D } from '../../../../core/Scene3D'; import { Engine3D } from '../../../../Engine3D'; import { VirtualTexture } from '../../../../textures/VirtualTexture'; import { GPUTextureFormat } from '../../../graphics/webGpu/WebGPUConst'; @@ -22,6 +20,7 @@ import { RTDescriptor } from '../../../graphics/webGpu/descriptor/RTDescriptor'; import { WebGPUDescriptorCreator } from '../../../graphics/webGpu/descriptor/WebGPUDescriptorCreator'; import { RendererPassState } from '../state/RendererPassState'; import { RendererType } from '../state/RendererType'; +import { ILight } from '../../../../components/lights/ILight'; type CubeShadowMapInfo = { cubeCamera: CubeCamera, @@ -36,7 +35,7 @@ type CubeShadowMapInfo = { export class PointLightShadowRenderer extends RendererBase { public shadowPassCount: number; private _forceUpdate = false; - private _shadowCameraDic: Map; + private _shadowCameraDic: Map; public shadowCamera: Camera3D; public cubeTextureArray: DepthCubeArrayTexture; public colorTexture: VirtualTexture; @@ -46,14 +45,14 @@ export class PointLightShadowRenderer extends RendererBase { this.passType = RendererType.POINT_SHADOW; // this.shadowSize = Engine3D.setting.shadow.pointShadowSize; - this._shadowCameraDic = new Map(); + this._shadowCameraDic = new Map(); this.cubeTextureArray = new DepthCubeArrayTexture(this.shadowSize, this.shadowSize, 8); this.colorTexture = new VirtualTexture(this.shadowSize, this.shadowSize, GPUTextureFormat.bgra8unorm, false); } - public getShadowCamera(view: View3D, lightBase: LightBase): CubeShadowMapInfo { + public getShadowCamera(view: View3D, lightBase: ILight): CubeShadowMapInfo { let cubeShadowMapInfo: CubeShadowMapInfo; if (this._shadowCameraDic.has(lightBase)) { cubeShadowMapInfo = this._shadowCameraDic.get(lightBase); diff --git a/src/engine/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts b/src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts similarity index 96% rename from src/engine/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts rename to src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts index 383868f3..6a37b927 100644 --- a/src/engine/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts +++ b/src/gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer.ts @@ -19,6 +19,7 @@ import { OcclusionSystem } from "../../occlusion/OcclusionSystem"; import { RendererPassState } from "../state/RendererPassState"; import { RendererType } from "../state/RendererType"; import { RendererBase } from "../RendererBase"; +import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer"; /** * @internal @@ -203,7 +204,7 @@ export class ShadowMapPassRenderer extends RendererBase { } - protected recordShadowRenderBundleNode(view: View3D, shadowCamera: Camera3D, encoder, nodes: RenderNode[]) { + protected recordShadowRenderBundleNode(view: View3D, shadowCamera: Camera3D, encoder, nodes: RenderNode[], clusterLightingBuffer?: ClusterLightingBuffer) { GPUContext.bindCamera(encoder, shadowCamera); GPUContext.bindGeometryBuffer(encoder, nodes[0].geometry); for (let i = 0; i < nodes.length; ++i) { @@ -211,11 +212,11 @@ export class ShadowMapPassRenderer extends RendererBase { let matrixIndex = renderNode.transform.worldMatrix.index; if (!renderNode.transform.enable) continue; - renderNode.recordRenderPass2(view, this._rendererType, this.rendererPassState, this.clusterLightingRender, encoder); + renderNode.recordRenderPass2(view, this._rendererType, this.rendererPassState, clusterLightingBuffer, encoder); } } - protected drawShadowRenderNodes(view: View3D, shadowCamera: Camera3D, encoder: GPURenderPassEncoder, nodes: RenderNode[]) { + protected drawShadowRenderNodes(view: View3D, shadowCamera: Camera3D, encoder: GPURenderPassEncoder, nodes: RenderNode[], clusterLightingBuffer?: ClusterLightingBuffer) { GPUContext.bindCamera(encoder, shadowCamera); for (let i = Engine3D.setting.render.drawOpMin; i < Math.min(nodes.length, Engine3D.setting.render.drawOpMax); ++i) { let renderNode = nodes[i]; @@ -225,7 +226,7 @@ export class ShadowMapPassRenderer extends RendererBase { continue; if (!renderNode.enable) continue; - renderNode.renderPass2(view, this._rendererType, this.rendererPassState, this.clusterLightingRender, encoder); + renderNode.renderPass2(view, this._rendererType, this.rendererPassState, clusterLightingBuffer, encoder); } } } diff --git a/src/engine/gfx/renderJob/passRenderer/state/RendererMask.ts b/src/gfx/renderJob/passRenderer/state/RendererMask.ts similarity index 95% rename from src/engine/gfx/renderJob/passRenderer/state/RendererMask.ts rename to src/gfx/renderJob/passRenderer/state/RendererMask.ts index cfb50d30..9c02ab28 100644 --- a/src/engine/gfx/renderJob/passRenderer/state/RendererMask.ts +++ b/src/gfx/renderJob/passRenderer/state/RendererMask.ts @@ -29,6 +29,6 @@ export class RendererMaskUtil { } public static hasMask(m1: RendererMask, m2: RendererMask): boolean { - return (m1 & m2) != 0; + return (m1 & m2) == m2; } } diff --git a/src/engine/gfx/renderJob/passRenderer/state/RendererPassState.ts b/src/gfx/renderJob/passRenderer/state/RendererPassState.ts similarity index 91% rename from src/engine/gfx/renderJob/passRenderer/state/RendererPassState.ts rename to src/gfx/renderJob/passRenderer/state/RendererPassState.ts index ea80fae5..46ee9a45 100644 --- a/src/engine/gfx/renderJob/passRenderer/state/RendererPassState.ts +++ b/src/gfx/renderJob/passRenderer/state/RendererPassState.ts @@ -1,5 +1,6 @@ +import { Engine3D } from "../../../../Engine3D"; import { Camera3D } from "../../../../core/Camera3D"; -import { defaultRes } from "../../../../textures/DefaultRes"; + import { VirtualTexture } from "../../../../textures/VirtualTexture"; import { Texture } from "../../../graphics/webGpu/core/texture/Texture"; import { RTDescriptor } from "../../../graphics/webGpu/descriptor/RTDescriptor"; @@ -36,9 +37,9 @@ export class RendererPassState { getLastRenderTexture() { if (this.renderTargets) { - return this.renderTargets.length > 0 ? this.renderTargets[0] : defaultRes.redTexture; + return this.renderTargets.length > 0 ? this.renderTargets[0] : Engine3D.res.redTexture; } else { - return defaultRes.redTexture + return Engine3D.res.redTexture } } } diff --git a/src/engine/gfx/renderJob/passRenderer/state/RendererType.ts b/src/gfx/renderJob/passRenderer/state/RendererType.ts similarity index 100% rename from src/engine/gfx/renderJob/passRenderer/state/RendererType.ts rename to src/gfx/renderJob/passRenderer/state/RendererType.ts diff --git a/src/engine/gfx/renderJob/post/DepthOfFieldPost.ts b/src/gfx/renderJob/post/DepthOfFieldPost.ts similarity index 99% rename from src/engine/gfx/renderJob/post/DepthOfFieldPost.ts rename to src/gfx/renderJob/post/DepthOfFieldPost.ts index 111d37a2..068e7605 100644 --- a/src/engine/gfx/renderJob/post/DepthOfFieldPost.ts +++ b/src/gfx/renderJob/post/DepthOfFieldPost.ts @@ -18,7 +18,7 @@ import { RTResourceConfig } from '../config/RTResourceConfig'; import { GBufferFrame } from '../frame/GBufferFrame'; import { RTFrame } from '../frame/RTFrame'; /** - * depth of field effect。 + * depth of field effect. * A common post-processing effect that simulates the focusing characteristics of a camera lens. * ``` * //Configure parameters related to depth of field diff --git a/src/engine/gfx/renderJob/post/FXAAPost.ts b/src/gfx/renderJob/post/FXAAPost.ts similarity index 89% rename from src/engine/gfx/renderJob/post/FXAAPost.ts rename to src/gfx/renderJob/post/FXAAPost.ts index 56cfb16a..2d8a7482 100644 --- a/src/engine/gfx/renderJob/post/FXAAPost.ts +++ b/src/gfx/renderJob/post/FXAAPost.ts @@ -14,14 +14,6 @@ import { View3D } from '../../../core/View3D'; * A deformation anti-aliasing method that pays more attention to performance. * It only needs one pass to get the result. FXAA focuses on fast visual anti-aliasing effect, * rather than pursuing perfect real anti-aliasing effect. - * ``` - * let cfg = {@link Engine3D.setting.render.postProcessing.fxaa}; - * let view = new View3D(); - view.scene = this.scene; - view.camera = mainCamera; - - * Engine3D.startRender(renderJob); - *``` * @group Post Effects */ export class FXAAPost extends PostBase { diff --git a/src/engine/gfx/renderJob/post/GTAOPost.ts b/src/gfx/renderJob/post/GTAOPost.ts similarity index 100% rename from src/engine/gfx/renderJob/post/GTAOPost.ts rename to src/gfx/renderJob/post/GTAOPost.ts diff --git a/src/engine/gfx/renderJob/post/GlobalFog.ts b/src/gfx/renderJob/post/GlobalFog.ts similarity index 93% rename from src/engine/gfx/renderJob/post/GlobalFog.ts rename to src/gfx/renderJob/post/GlobalFog.ts index 99422b83..63d4024e 100644 --- a/src/engine/gfx/renderJob/post/GlobalFog.ts +++ b/src/gfx/renderJob/post/GlobalFog.ts @@ -13,16 +13,6 @@ import { View3D } from '../../../core/View3D'; import { GBufferFrame } from '../frame/GBufferFrame'; /** * screen space fog - * ``` - * //setting - * let cfg = {@link Engine3D.setting.render.postProcessing.globalFog}; - * let view = new View3D(); - view.scene = this.scene; - view.camera = mainCamera; - - * - * Engine3D.startRender(renderJob); - *``` * @group Post Effects */ export class GlobalFog extends PostBase { @@ -143,7 +133,7 @@ export class GlobalFog extends PostBase { render(view: View3D, command: GPUCommandEncoder) { const renderShader = this.viewQuad.material.renderShader; renderShader.setTexture('colorMap', this.getOutTexture()); - GPUContext.renderTarget(view, this.viewQuad, command); + this.viewQuad.renderTarget(view, this.viewQuad, command); } } diff --git a/src/engine/gfx/renderJob/post/HDRBloomPost.ts b/src/gfx/renderJob/post/HDRBloomPost.ts similarity index 83% rename from src/engine/gfx/renderJob/post/HDRBloomPost.ts rename to src/gfx/renderJob/post/HDRBloomPost.ts index 9a8621af..c75e78ca 100644 --- a/src/engine/gfx/renderJob/post/HDRBloomPost.ts +++ b/src/gfx/renderJob/post/HDRBloomPost.ts @@ -12,15 +12,6 @@ import { View3D } from '../../../core/View3D'; /** * HDR Bloom effect * ``` - * //setting - * let cfg = {@link Engine3D.setting.render.postProcessing.bloom}; - * let view = new View3D(); - view.scene = this.scene; - view.camera = mainCamera; - - * - * Engine3D.startRender(renderJob); - *``` * @group Post Effects */ export class HDRBloomPost extends PostBase { @@ -135,7 +126,7 @@ export class HDRBloomPost extends PostBase { { let colorTexture = this.getOutTexture(); { - GPUContext.renderToViewQuad(view, this.brightnessView, command, colorTexture); + this.brightnessView.renderToViewQuad(view, this.brightnessView, command, colorTexture); } { let tex = this.brightnessView.rendererPassState.renderTargets[0]; @@ -146,13 +137,13 @@ export class HDRBloomPost extends PostBase { ql.material.renderShader.setUniformFloat(`horizontal`, 0.5); ql.material.renderShader.setUniformFloat(`vScale`, i * this.blurX); - GPUContext.renderToViewQuad(view, ql, command, tex); + ql.renderToViewQuad(view, ql, command, tex); tex = ql.rendererPassState.renderTargets[0]; qr.material.renderShader.setUniformFloat(`horizontal`, 2.0); qr.material.renderShader.setUniformFloat(`hScale`, i * this.blurY); - GPUContext.renderToViewQuad(view, qr, command, tex); + qr.renderToViewQuad(view, qr, command, tex); tex = qr.rendererPassState.renderTargets[0]; } } @@ -165,12 +156,7 @@ export class HDRBloomPost extends PostBase { shader.setTexture(`blurTex4`, this.blurList[3].qr.rendererPassState.renderTargets[0]); shader.setTexture(`blurTex5`, this.blurList[4].qr.rendererPassState.renderTargets[0]); - // this.compositeView.material.blurTex5[1] = this.blurList[0].qr.rendererPassState.renderTargets[0]; - // this.compositeView.material.textures[2] = this.blurList[1].qr.rendererPassState.renderTargets[0]; - // this.compositeView.material.textures[3] = this.blurList[2].qr.rendererPassState.renderTargets[0]; - // this.compositeView.material.textures[4] = this.blurList[3].qr.rendererPassState.renderTargets[0]; - // this.compositeView.material.textures[5] = this.blurList[4].qr.rendererPassState.renderTargets[0]; - GPUContext.renderToViewQuad(view, this.compositeView, command, colorTexture); + this.compositeView.renderToViewQuad(view, this.compositeView, command, colorTexture); } } // GPUContext.endCommandEncoder(command); diff --git a/src/engine/gfx/renderJob/post/OutlinePost.ts b/src/gfx/renderJob/post/OutlinePost.ts similarity index 96% rename from src/engine/gfx/renderJob/post/OutlinePost.ts rename to src/gfx/renderJob/post/OutlinePost.ts index 5a914537..92c73700 100644 --- a/src/engine/gfx/renderJob/post/OutlinePost.ts +++ b/src/gfx/renderJob/post/OutlinePost.ts @@ -85,11 +85,9 @@ export class OutlinePostData { } } -export let outlinePostData: OutlinePostData = new OutlinePostData(); - /** * post effect out line - * OutlinePostManager, + * OutlinePostManager, * ``` * //setting * let cfg = {@link Engine3D.setting.render.postProcessing.outline}; @@ -141,8 +139,11 @@ export class OutlinePost extends PostBase { oldOutlineColor: StorageGPUBuffer; rtFrame: RTFrame; + outlineData: OutlinePostData; + constructor() { super(); + this.outlineData = new OutlinePostData(); } /** @@ -280,12 +281,12 @@ export class OutlinePost extends PostBase { this.weightBuffer = new StorageGPUBuffer(this.lowTexSize.x * this.lowTexSize.y * 4, GPUBufferUsage.COPY_SRC); this.oldOutlineColor = new StorageGPUBuffer(this.lowTexSize.x * this.lowTexSize.y * 4, GPUBufferUsage.COPY_SRC); - this.slotsArray = new Float32Array(outlinePostData.SlotCount * 4); + this.slotsArray = new Float32Array(this.outlineData.SlotCount * 4); this.slotsBuffer = new StorageGPUBuffer(this.slotsArray.length); this.slotsBuffer.setFloat32Array('slotsArray', this.slotsArray); this.slotsBuffer.apply(); - this.entitiesArray = new Float32Array(outlinePostData.SlotCount * outlinePostData.MaxEntities); + this.entitiesArray = new Float32Array(this.outlineData.SlotCount * this.outlineData.MaxEntities); this.entitiesBuffer = new StorageGPUBuffer(this.entitiesArray.length); this.entitiesBuffer.setFloat32Array('entitiesArray', this.entitiesArray); this.slotsBuffer.apply(); @@ -296,10 +297,10 @@ export class OutlinePost extends PostBase { private fetchData: { dirty: boolean; slots: OutlinePostSlot[] }; private fetchOutlineData(): void { - outlinePostData.fetchData(this.fetchData); + this.outlineData.fetchData(this.fetchData); if (this.fetchData.dirty) { - let slotCount = outlinePostData.SlotCount; - let maxEntities = outlinePostData.MaxEntities; + let slotCount = this.outlineData.SlotCount; + let maxEntities = this.outlineData.MaxEntities; for (let i = 0; i < slotCount; i++) { let offset = 4 * i; let slot = this.fetchData.slots[i]; diff --git a/src/engine/gfx/renderJob/post/PostBase.ts b/src/gfx/renderJob/post/PostBase.ts similarity index 96% rename from src/engine/gfx/renderJob/post/PostBase.ts rename to src/gfx/renderJob/post/PostBase.ts index 7b66d20c..0ba36633 100644 --- a/src/engine/gfx/renderJob/post/PostBase.ts +++ b/src/gfx/renderJob/post/PostBase.ts @@ -70,9 +70,9 @@ export class PostBase { */ public render(view: View3D, command: GPUCommandEncoder) { this.compute(view); - this.rtViewQuad.forEach((v, k) => { + this.rtViewQuad.forEach((viewQuad, k) => { let lastTexture = GPUContext.lastRenderPassState.getLastRenderTexture(); - GPUContext.renderToViewQuad(view, v, command, lastTexture); + viewQuad.renderToViewQuad(view, viewQuad, command, lastTexture); }); } diff --git a/src/engine/gfx/renderJob/post/SSRPost.ts b/src/gfx/renderJob/post/SSRPost.ts similarity index 98% rename from src/engine/gfx/renderJob/post/SSRPost.ts rename to src/gfx/renderJob/post/SSRPost.ts index 1cda19e1..af4e84ac 100644 --- a/src/engine/gfx/renderJob/post/SSRPost.ts +++ b/src/gfx/renderJob/post/SSRPost.ts @@ -23,6 +23,7 @@ import { RTFrame } from '../frame/RTFrame'; import { GBufferFrame } from '../frame/GBufferFrame'; import { SSRSetting } from '../../../setting/post/SSRSetting'; import { View3D } from '../../../core/View3D'; +import { SkyRenderer } from '../../../components/renderer/SkyRenderer'; /** * Screen space reflection * ``` @@ -170,7 +171,9 @@ export class SSRPost extends PostBase { this.SSR_RayTraceCompute.setSamplerTexture("zBufferTexture", rtFrame.getPositionMap()); this.SSR_RayTraceCompute.setSamplerTexture(RTResourceConfig.normalBufferTex_NAME, rtFrame.attachments[2]); this.SSR_RayTraceCompute.setSamplerTexture(RTResourceConfig.materialBufferTex_NAME, rtFrame.attachments[3]); - this.SSR_RayTraceCompute.setSamplerTexture(`prefilterMap`, EntityCollect.instance.sky.map); + + if (EntityCollect.instance.sky instanceof SkyRenderer) + this.SSR_RayTraceCompute.setSamplerTexture(`prefilterMap`, EntityCollect.instance.sky.map); this.SSR_RayTraceCompute.workerSizeX = Math.ceil(this.isRetTexture.width / 8); this.SSR_RayTraceCompute.workerSizeY = Math.ceil(this.isRetTexture.height / 8); diff --git a/src/engine/gfx/renderJob/post/TAAPost.ts b/src/gfx/renderJob/post/TAAPost.ts similarity index 100% rename from src/engine/gfx/renderJob/post/TAAPost.ts rename to src/gfx/renderJob/post/TAAPost.ts diff --git a/src/index.ts b/src/index.ts index ef2d8dd8..ecf6a3fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,377 @@ -let foo = 1 -export { foo } \ No newline at end of file +export * from "./Engine3D" +export * from "./assets/Res" +export * from "./assets/shader/ShaderLib" +export * from "./assets/shader/anim/SkeletonAnimation_shader" +export * from "./assets/shader/compute/BlurEffectCreator_compute" +export * from "./assets/shader/core/pass/CastShadowPass_wgsl" +export * from "./assets/shader/core/pass/ZPassShader_vs" +export * from "./assets/shader/core/struct/LightStructFrag" +export * from "./assets/shader/core/struct/VertexAttributes" +export * from "./assets/shader/glsl/Quad_glsl" +export * from "./assets/shader/glsl/Sky_glsl" +export * from "./assets/shader/glsl/post/LUT_glsl" +export * from "./assets/shader/lighting/LightingFunction_frag" +export * from "./assets/shader/lighting/UnLit_frag" +export * from "./assets/shader/materials/ColorLitShader" +export * from "./assets/shader/materials/Lambert_shader" +export * from "./assets/shader/materials/PavementShader" +export * from "./assets/shader/materials/PointShadowDebug" +export * from "./assets/shader/materials/program/ClusterDebug_frag" +export * from "./assets/shader/materials/sky/AtmosphericScatteringSky_shader" +export * from "./assets/shader/materials/sky/CubeSky_Shader" +export * from "./assets/shader/materials/uniforms/MaterialUniform" +export * from "./assets/shader/materials/uniforms/PhysicMaterialUniform_frag" +export * from "./assets/shader/materials/uniforms/UnLitMaterialUniform_frag" +export * from "./assets/shader/materials/uniforms/VideoUniform_frag" +export * from "./assets/shader/math/MathShader" +export * from "./assets/shader/post/Bloom_shader" +export * from "./assets/shader/post/GlobalFog_shader" +export * from "./assets/shader/quad/Quad_shader" +export * from "./components/AtmosphericComponent" +export * from "./components/BillboardComponent" +export * from "./components/ColliderComponent" +export * from "./components/ComponentBase" +export * from "./components/SkeletonAnimationComponent" +export * from "./components/Transform" +export * from "./components/anim/OAnimationEvent" +export * from "./components/anim/curveAnim/curveAnim/AnimationMonitor" +export * from "./components/anim/curveAnim/curveAnim/AttributeAnimCurve" +export * from "./components/anim/curveAnim/curveAnim/PropertyAnimClip" +export * from "./components/anim/curveAnim/curveAnim/PropertyAnimation" +export * from "./components/anim/curveAnim/curveAnim/PropertyAnimationEvent" +export * from "./components/anim/curveAnim/curveAnim/PropertyHelp" +export * from "./components/anim/morphAnim/MorphTargetBlender" +export * from "./components/anim/morphAnim/MorphTargetData" +export * from "./components/anim/morphAnim/MorphTargetFrame" +export * from "./components/anim/morphAnim/MorphTargetKey" +export * from "./components/anim/morphAnim/MorphTarget_shader" +export * from "./components/anim/skeletonAnim/Joint" +export * from "./components/anim/skeletonAnim/JointPose" +export * from "./components/anim/skeletonAnim/Skeleton" +export * from "./components/anim/skeletonAnim/SkeletonAnimationClip" +export * from "./components/anim/skeletonAnim/SkeletonAnimationClipState" +export * from "./components/anim/skeletonAnim/SkeletonAnimationCompute" +export * from "./components/anim/skeletonAnim/SkeletonPose" +export * from "./components/anim/skeletonAnim/buffer/SkeletonBlendComputeArgs" +export * from "./components/anim/skeletonAnim/buffer/SkeletonTransformComputeArgs" +export * from "./components/anim/skeletonAnim/shader/compute_skeleton_blend" +export * from "./components/anim/skeletonAnim/shader/compute_skeleton_transform" +export * from "./components/audio/AudioListener" +export * from "./components/audio/PositionAudio" +export * from "./components/audio/StaticAudio" +export * from "./components/controller/CameraControllerBase" +export * from "./components/controller/FirstPersonCameraController" +export * from "./components/controller/FlyCameraController" +export * from "./components/controller/HoverCameraController" +export * from "./components/controller/OrbitController" +export * from "./components/controller/ThirdPersonCameraController" +export * from "./components/lights/DirectLight" +export * from "./components/lights/GILighting" +export * from "./components/lights/IESProfiles" +export * from "./components/lights/LightBase" +export * from "./components/lights/LightData" +export * from "./components/lights/PointLight" +export * from "./components/lights/SpotLight" +export * from "./components/post/PostProcessingComponent" +export * from "./components/renderer/InstanceDrawComponent" +export * from "./components/renderer/MaterialComponent" +export * from "./components/renderer/MeshComponent" +export * from "./components/renderer/MeshRenderer" +export * from "./components/renderer/RenderNode" +export * from "./components/renderer/SkinnedMeshRenderer" +export * from "./components/renderer/SkyRenderer" +export * from "./components/shape/BoxColliderShape" +export * from "./components/shape/CapsuleColliderShape" +export * from "./components/shape/ColliderShape" +export * from "./components/shape/MeshColliderShape" +export * from "./components/shape/SphereColliderShape" +export * from "./core/Camera3D" +export * from "./core/CameraType" +export * from "./core/CubeCamera" +export * from "./core/PointShadowCubeCamera" +export * from "./core/Scene3D" +export * from "./core/View3D" +export * from "./core/ViewQuad" +export * from "./core/bound/BoundingBox" +export * from "./core/bound/BoundingSphere" +export * from "./core/bound/Frustum" +export * from "./core/bound/IBound" +export * from "./core/entities/Entity" +export * from "./core/entities/InstancedMesh" +export * from "./core/entities/Object3D" +export * from "./core/geometry/GeometryBase" +export * from "./core/geometry/GeometryIndicesBuffer" +export * from "./core/geometry/GeometryVertexBuffer" +export * from "./core/geometry/GeometryVertexType" +export * from "./core/geometry/VertexAttribute" +export * from "./core/geometry/VertexAttributeData" +export * from "./core/geometry/VertexAttributeName" +export * from "./core/geometry/VertexAttributeSize" +export * from "./core/geometry/VertexAttributeStride" +export * from "./core/geometry/VertexFormat" +export * from "./core/pool/ObjectPool" +export * from "./core/pool/memory/MatrixDO" +export * from "./core/pool/memory/MemoryDO" +export * from "./core/pool/memory/MemoryInfo" +export * from "./core/tree/kdTree/IKDTreeUserData" +export * from "./core/tree/kdTree/KDTreeEntity" +export * from "./core/tree/kdTree/KDTreeNode" +export * from "./core/tree/kdTree/KDTreeSpace" +export * from "./event/CEvent" +export * from "./event/CEventDispatcher" +export * from "./event/CEventListener" +export * from "./event/CResizeEvent" +export * from "./event/KeyCode" +export * from "./event/MouseCode" +export * from "./event/eventConst/KeyEvent" +export * from "./event/eventConst/LoaderEvent" +export * from "./event/eventConst/Object3DEvent" +export * from "./event/eventConst/PointerEvent3D" +export * from "./event/eventConst/UIEvent" +export * from "./gfx/generate/BrdfLUTGenerate" +export * from "./gfx/generate/PassGenerate" +export * from "./gfx/generate/convert/BlurEffectCreator" +export * from "./gfx/generate/convert/ErpImage2CubeMap" +export * from "./gfx/generate/convert/IBLEnvMapCreator" +export * from "./gfx/generate/convert/MergeRGBACreator" +export * from "./gfx/generate/convert/TextureCubeStdCreator" +export * from "./gfx/generate/convert/TextureCubeUtils" +export * from "./gfx/graphics/webGpu/CanvasConfig" +export * from "./gfx/graphics/webGpu/Context3D" +export * from "./gfx/graphics/webGpu/WebGPUConst" +export * from "./gfx/graphics/webGpu/core/bindGroups/GlobalBindGroup" +export * from "./gfx/graphics/webGpu/core/bindGroups/GlobalBindGroupLayout" +export * from "./gfx/graphics/webGpu/core/bindGroups/GlobalUniformGroup" +export * from "./gfx/graphics/webGpu/core/bindGroups/MatrixBindGroup" +export * from "./gfx/graphics/webGpu/core/bindGroups/TexturesBindGroup" +export * from "./gfx/graphics/webGpu/core/bindGroups/groups/LightEntries" +export * from "./gfx/graphics/webGpu/core/buffer/ComputeGPUBuffer" +export * from "./gfx/graphics/webGpu/core/buffer/GPUBufferBase" +export * from "./gfx/graphics/webGpu/core/buffer/GPUBufferType" +export * from "./gfx/graphics/webGpu/core/buffer/IndicesGPUBuffer" +export * from "./gfx/graphics/webGpu/core/buffer/MaterialDataUniformGPUBuffer" +export * from "./gfx/graphics/webGpu/core/buffer/StorageGPUBuffer" +export * from "./gfx/graphics/webGpu/core/buffer/StructStorageGPUBuffer" +export * from "./gfx/graphics/webGpu/core/buffer/UniformGPUBuffer" +export * from "./gfx/graphics/webGpu/core/buffer/VertexGPUBuffer" +export * from "./gfx/graphics/webGpu/core/texture/ITexture" +export * from "./gfx/graphics/webGpu/core/texture/Texture" +export * from "./gfx/graphics/webGpu/core/texture/TextureCube" +export * from "./gfx/graphics/webGpu/core/texture/TextureMipmapCompute" +export * from "./gfx/graphics/webGpu/core/texture/TextureMipmapGenerator" +export * from "./gfx/graphics/webGpu/core/uniforms/UniformNode" +export * from "./gfx/graphics/webGpu/descriptor/RTDescriptor" +export * from "./gfx/graphics/webGpu/descriptor/WebGPUDescriptorCreator" +export * from "./gfx/graphics/webGpu/shader/ComputeShader" +export * from "./gfx/graphics/webGpu/shader/RenderShader" +export * from "./gfx/graphics/webGpu/shader/ShaderBase" +export * from "./gfx/graphics/webGpu/shader/ShaderStage" +export * from "./gfx/graphics/webGpu/shader/converter/GLSLLexer" +export * from "./gfx/graphics/webGpu/shader/converter/GLSLLexerToken" +export * from "./gfx/graphics/webGpu/shader/converter/GLSLPreprocessor" +export * from "./gfx/graphics/webGpu/shader/converter/GLSLSyntax" +export * from "./gfx/graphics/webGpu/shader/converter/Reader" +export * from "./gfx/graphics/webGpu/shader/converter/ShaderConverter" +export * from "./gfx/graphics/webGpu/shader/converter/StatementNode" +export * from "./gfx/graphics/webGpu/shader/converter/WGSLTranslator" +export * from "./gfx/graphics/webGpu/shader/util/MorePassParser" +export * from "./gfx/graphics/webGpu/shader/util/Preprocessor" +export * from "./gfx/graphics/webGpu/shader/util/ShaderUtil" +export * from "./gfx/graphics/webGpu/shader/value/ConstValue" +export * from "./gfx/graphics/webGpu/shader/value/DefineValue" +export * from "./gfx/graphics/webGpu/shader/value/ShaderReflectionInfo" +export * from "./gfx/graphics/webGpu/shader/value/ShaderState" +export * from "./gfx/graphics/webGpu/shader/value/ShaderValue" +export * from "./gfx/graphics/webGpu/shader/value/UniformValue" +export * from "./gfx/renderJob/GPUContext" +export * from "./gfx/renderJob/collect/CollectInfo" +export * from "./gfx/renderJob/collect/EntityBatchCollect" +export * from "./gfx/renderJob/collect/EntityCollect" +export * from "./gfx/renderJob/collect/RenderGroup" +export * from "./gfx/renderJob/collect/ShadowLightsCollect" +export * from "./gfx/renderJob/config/RTResourceConfig" +export * from "./gfx/renderJob/config/RenderLayer" +export * from "./gfx/renderJob/frame/GBufferFrame" +export * from "./gfx/renderJob/frame/ProbeGBufferFrame" +export * from "./gfx/renderJob/frame/RTFrame" +export * from "./gfx/renderJob/frame/RTResourceMap" +export * from "./gfx/renderJob/jobs/ForwardRenderJob" +export * from "./gfx/renderJob/jobs/RenderMap" +export * from "./gfx/renderJob/jobs/RendererJob" +export * from "./gfx/renderJob/occlusion/OcclusionSystem" +export * from "./gfx/renderJob/passRenderer/RenderContext" +export * from "./gfx/renderJob/passRenderer/RendererBase" +export * from "./gfx/renderJob/passRenderer/cluster/ClusterLightingRender" +export * from "./gfx/renderJob/passRenderer/color/ColorPassRenderer" +export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DBatchRenderer" +export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DFillRenderer" +export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DFixedRenderPipeline" +export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DLineBatchRenderer" +export * from "./gfx/renderJob/passRenderer/graphic/Graphic3DRender" +export * from "./gfx/renderJob/passRenderer/graphic/GraphicConfig" +export * from "./gfx/renderJob/passRenderer/graphic/Graphics3DShape" +export * from "./gfx/renderJob/passRenderer/post/PostRenderer" +export * from "./gfx/renderJob/passRenderer/preDepth/PreDepthPassRenderer" +export * from "./gfx/renderJob/passRenderer/preDepth/ZCullingCompute" +export * from "./gfx/renderJob/passRenderer/shadow/PointLightShadowRenderer" +export * from "./gfx/renderJob/passRenderer/shadow/ShadowMapPassRenderer" +export * from "./gfx/renderJob/passRenderer/state/RendererMask" +export * from "./gfx/renderJob/passRenderer/state/RendererPassState" +export * from "./gfx/renderJob/passRenderer/state/RendererType" +export * from "./gfx/renderJob/post/DepthOfFieldPost" +export * from "./gfx/renderJob/post/FXAAPost" +export * from "./gfx/renderJob/post/GTAOPost" +export * from "./gfx/renderJob/post/GlobalFog" +export * from "./gfx/renderJob/post/HDRBloomPost" +export * from "./gfx/renderJob/post/OutlinePost" +export * from "./gfx/renderJob/post/PostBase" +export * from "./gfx/renderJob/post/SSRPost" +export * from "./gfx/renderJob/post/TAAPost" +export * from "./io/InputSystem" +export * from "./io/PickFire" +export * from "./io/PickResult" +export * from "./io/RayCastMeshDetail" +export * from "./io/TouchData" +export * from "./io/picker/PickCompute" +export * from "./loader/FileLoader" +export * from "./loader/LoaderBase" +export * from "./loader/LoaderData" +export * from "./loader/LoaderFunctions" +export * from "./loader/LoaderManager" +export * from "./loader/parser/B3DMParser" +export * from "./loader/parser/I3DMParser" +export * from "./loader/parser/OBJParser" +export * from "./loader/parser/ParserBase" +export * from "./loader/parser/RGBEParser" +export * from "./loader/parser/b3dm/B3DMLoader" +export * from "./loader/parser/b3dm/B3DMLoaderBase" +export * from "./loader/parser/b3dm/FeatureTable" +export * from "./loader/parser/b3dm/arrayToString" +export * from "./loader/parser/b3dm/readMagicBytes" +export * from "./loader/parser/gltf/GLBParser" +export * from "./loader/parser/gltf/GLTFInfo" +export * from "./loader/parser/gltf/GLTFParser" +export * from "./loader/parser/gltf/GLTFSubParser" +export * from "./loader/parser/gltf/GLTFSubParserCamera" +export * from "./loader/parser/gltf/GLTFSubParserConverter" +export * from "./loader/parser/gltf/GLTFSubParserMaterial" +export * from "./loader/parser/gltf/GLTFSubParserMesh" +export * from "./loader/parser/gltf/GLTFSubParserSkeleton" +export * from "./loader/parser/gltf/GLTFSubParserSkin" +export * from "./loader/parser/gltf/TypeArray" +export * from "./loader/parser/gltf/extends/KHR_draco_mesh_compression" +export * from "./loader/parser/gltf/extends/KHR_lights_punctual" +export * from "./loader/parser/gltf/extends/KHR_materials_clearcoat" +export * from "./loader/parser/gltf/extends/KHR_materials_emissive_strength" +export * from "./loader/parser/gltf/extends/KHR_materials_ior" +export * from "./loader/parser/gltf/extends/KHR_materials_sheen" +export * from "./loader/parser/gltf/extends/KHR_materials_specular" +export * from "./loader/parser/gltf/extends/KHR_materials_transmission" +export * from "./loader/parser/gltf/extends/KHR_materials_unlit" +export * from "./loader/parser/gltf/extends/KHR_materials_variants" +export * from "./loader/parser/gltf/extends/KHR_materials_volume" +export * from "./loader/parser/gltf/extends/KHR_mesh_quantization" +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/tileRenderer/TileSet" +export * from "./loader/parser/tileRenderer/TilesRenderer" +export * from "./materials/BlendMode" +export * from "./materials/ColorLitMaterial" +export * from "./materials/GlassMaterial" +export * from "./materials/LambertMaterial" +export * from "./materials/LitMaterial" +export * from "./materials/MaterialBase" +export * from "./materials/MaterialPass" +export * from "./materials/MaterialRegister" +export * from "./materials/PavementMaterial" +export * from "./materials/PhysicMaterial" +export * from "./materials/PointMaterial" +export * from "./materials/SkyMaterial" +export * from "./materials/UnLitMaterial" +export * from "./materials/effectPass/OutLinePass" +export * from "./materials/multiPass/CastPointShadowMaterialPass" +export * from "./materials/multiPass/CastShadowMaterialPass" +export * from "./materials/multiPass/DepthMaterialPass" +export * from "./materials/multiPass/GBufferPass" +export * from "./materials/multiPass/SkyGBufferPass" +export * from "./math/AnimationCurve" +export * from "./math/Bezier2D" +export * from "./math/Bezier3D" +export * from "./math/Color" +export * from "./math/HaltonSeq" +export * from "./math/Line" +export * from "./math/MathUtil" +export * from "./math/Matrix3" +export * from "./math/Matrix4" +export * from "./math/Orientation3D" +export * from "./math/ParticleMath" +export * from "./math/ParticleSystemCurves" +export * from "./math/Plane" +export * from "./math/PolynomialCurve" +export * from "./math/Polynomials" +export * from "./math/Quaternion" +export * from "./math/Rand" +export * from "./math/Random" +export * from "./math/Ray" +export * from "./math/Rect" +export * from "./math/TimeInterpolator" +export * from "./math/Triangle" +export * from "./math/UV" +export * from "./math/Vector2" +export * from "./math/Vector3" +export * from "./math/Vector4" +export * from "./setting/EngineSetting" +export * from "./setting/GlobalIlluminationSetting" +export * from "./setting/LightSetting" +export * from "./setting/MaterialSetting" +export * from "./setting/OcclusionQuerySetting" +export * from "./setting/PickSetting" +export * from "./setting/RenderSetting" +export * from "./setting/ShadowSetting" +export * from "./setting/SkySetting" +export * from "./setting/post/BloomSetting" +export * from "./setting/post/DepthOfViewSetting" +export * from "./setting/post/GTAOSetting" +export * from "./setting/post/GlobalFogSetting" +export * from "./setting/post/OutlineSetting" +export * from "./setting/post/SSRSetting" +export * from "./setting/post/TAASetting" +export * from "./shape/BoxGeometry" +export * from "./shape/CylinderGeometry" +export * from "./shape/PlaneGeometry" +export * from "./shape/SphereGeometry" +export * from "./shape/TorusGeometry" +export * from "./textures/AtmosphericScatteringSky" +export * from "./textures/BitmapTexture2D" +export * from "./textures/BitmapTexture2DArray" +export * from "./textures/BitmapTextureCube" +export * from "./textures/Depth2DTextureArray" +export * from "./textures/DepthCubeArrayTexture" +export * from "./textures/DepthCubeTexture" +export * from "./textures/Float16ArrayTexture" +export * from "./textures/Float32ArrayTexture" +export * from "./textures/HDRTexture" +export * from "./textures/HDRTextureCube" +export * from "./textures/LDRTextureCube" +export * from "./textures/SolidColorSky" +export * from "./textures/Uint16Texture" +export * from "./textures/Uint8ArrayTexture" +export * from "./textures/VirtualTexture" +export * from "./util/AxisObject" +export * from "./util/BytesStream" +export * from "./util/CameraUtil" +export * from "./util/Convert" +export * from "./util/GeometryUtil" +export * from "./util/Global" +export * from "./util/KelvinUtil" +export * from "./util/Object3DUtil" +export * from "./util/ProfilerUtil" +export * from "./util/StringUtil" +export * from "./util/Time" +export * from "./util/Vector3Ex" +export * from "./util/ZSorterUtil" +export * from "./util/struct/Struct" +export * from "./util/struct/StructValue" +export * from "./util/struct/Vector3Struct" diff --git a/src/engine/io/InputSystem.ts b/src/io/InputSystem.ts similarity index 99% rename from src/engine/io/InputSystem.ts rename to src/io/InputSystem.ts index 74518cf6..9b9fcd15 100644 --- a/src/engine/io/InputSystem.ts +++ b/src/io/InputSystem.ts @@ -447,7 +447,7 @@ export class InputSystem extends CEventDispatcher { * @param startY {Number} * @param endX {Number} * @param endY {Number} - * @returns result {number} 1:up,2:down,3:left,4:right,0:not move + * @returns result {number} 1: up, 2: down, 3: left, 4: right, 0: not move */ public GetSlideDirection(startX: number, startY: number, endX: number, endY: number): number { var dy = startY - endY; diff --git a/src/engine/io/PickFire.ts b/src/io/PickFire.ts similarity index 100% rename from src/engine/io/PickFire.ts rename to src/io/PickFire.ts diff --git a/src/engine/io/PickResult.ts b/src/io/PickResult.ts similarity index 100% rename from src/engine/io/PickResult.ts rename to src/io/PickResult.ts diff --git a/src/engine/io/RayCastMeshDetail.ts b/src/io/RayCastMeshDetail.ts similarity index 100% rename from src/engine/io/RayCastMeshDetail.ts rename to src/io/RayCastMeshDetail.ts diff --git a/src/engine/io/TouchData.ts b/src/io/TouchData.ts similarity index 98% rename from src/engine/io/TouchData.ts rename to src/io/TouchData.ts index 4936a3ce..3aa23d0f 100644 --- a/src/engine/io/TouchData.ts +++ b/src/io/TouchData.ts @@ -1,5 +1,5 @@ /** - * the param of touch event。 + * the param of touch event. * Save as the basic data for touch events in touch event. see InputSystem. * @internal * @group IO diff --git a/src/engine/io/picker/PickCompute.ts b/src/io/picker/PickCompute.ts similarity index 100% rename from src/engine/io/picker/PickCompute.ts rename to src/io/picker/PickCompute.ts diff --git a/src/engine/loader/FileLoader.ts b/src/loader/FileLoader.ts similarity index 100% rename from src/engine/loader/FileLoader.ts rename to src/loader/FileLoader.ts diff --git a/src/engine/loader/LoaderBase.ts b/src/loader/LoaderBase.ts similarity index 100% rename from src/engine/loader/LoaderBase.ts rename to src/loader/LoaderBase.ts diff --git a/src/engine/loader/LoaderData.ts b/src/loader/LoaderData.ts similarity index 100% rename from src/engine/loader/LoaderData.ts rename to src/loader/LoaderData.ts diff --git a/src/engine/loader/LoaderFunctions.ts b/src/loader/LoaderFunctions.ts similarity index 100% rename from src/engine/loader/LoaderFunctions.ts rename to src/loader/LoaderFunctions.ts diff --git a/src/engine/loader/LoaderManager.ts b/src/loader/LoaderManager.ts similarity index 100% rename from src/engine/loader/LoaderManager.ts rename to src/loader/LoaderManager.ts diff --git a/src/engine/loader/parser/B3DMParser.ts b/src/loader/parser/B3DMParser.ts similarity index 100% rename from src/engine/loader/parser/B3DMParser.ts rename to src/loader/parser/B3DMParser.ts diff --git a/src/engine/loader/parser/I3DMParser.ts b/src/loader/parser/I3DMParser.ts similarity index 100% rename from src/engine/loader/parser/I3DMParser.ts rename to src/loader/parser/I3DMParser.ts diff --git a/src/engine/loader/parser/OBJParser.ts b/src/loader/parser/OBJParser.ts similarity index 99% rename from src/engine/loader/parser/OBJParser.ts rename to src/loader/parser/OBJParser.ts index c5241277..2510e3f4 100644 --- a/src/engine/loader/parser/OBJParser.ts +++ b/src/loader/parser/OBJParser.ts @@ -8,6 +8,7 @@ import { StringUtil } from '../../util/StringUtil'; import { FileLoader } from '../FileLoader'; import { ParserBase } from './ParserBase'; + type MatData = { name?: string, Kd?: string[], diff --git a/src/engine/loader/parser/ParserBase.ts b/src/loader/parser/ParserBase.ts similarity index 100% rename from src/engine/loader/parser/ParserBase.ts rename to src/loader/parser/ParserBase.ts diff --git a/src/engine/loader/parser/RGBEParser.ts b/src/loader/parser/RGBEParser.ts similarity index 100% rename from src/engine/loader/parser/RGBEParser.ts rename to src/loader/parser/RGBEParser.ts diff --git a/src/engine/loader/parser/b3dm/B3DMLoader.ts b/src/loader/parser/b3dm/B3DMLoader.ts similarity index 94% rename from src/engine/loader/parser/b3dm/B3DMLoader.ts rename to src/loader/parser/b3dm/B3DMLoader.ts index 3ccdff43..5f780367 100644 --- a/src/engine/loader/parser/b3dm/B3DMLoader.ts +++ b/src/loader/parser/b3dm/B3DMLoader.ts @@ -1,5 +1,5 @@ -import { B3DMLoaderBase } from "./B3DMLoaderBase"; -import { B3DMParseUtil } from "../B3DMParser"; +import {B3DMLoaderBase} from "./B3DMLoaderBase"; +import {B3DMParseUtil} from "../B3DMParser"; import { Transform } from "../../../components/Transform"; import { Matrix4 } from "../../../math/Matrix4"; import { Orientation3D } from "../../../math/Orientation3D"; @@ -24,7 +24,7 @@ export class B3DMLoader extends B3DMLoaderBase { let model = await glbLoader.parseBinary(this.gltfBuffer); - let { batchTable, featureTable } = b3dm; + let {batchTable, featureTable} = b3dm; const rtcCenter = featureTable.getData('RTC_CENTER'); if (rtcCenter) { diff --git a/src/engine/loader/parser/b3dm/B3DMLoaderBase.ts b/src/loader/parser/b3dm/B3DMLoaderBase.ts similarity index 100% rename from src/engine/loader/parser/b3dm/B3DMLoaderBase.ts rename to src/loader/parser/b3dm/B3DMLoaderBase.ts diff --git a/src/engine/loader/parser/b3dm/FeatureTable.ts b/src/loader/parser/b3dm/FeatureTable.ts similarity index 100% rename from src/engine/loader/parser/b3dm/FeatureTable.ts rename to src/loader/parser/b3dm/FeatureTable.ts diff --git a/src/engine/loader/parser/b3dm/arrayToString.ts b/src/loader/parser/b3dm/arrayToString.ts similarity index 100% rename from src/engine/loader/parser/b3dm/arrayToString.ts rename to src/loader/parser/b3dm/arrayToString.ts diff --git a/src/engine/loader/parser/b3dm/readMagicBytes.ts b/src/loader/parser/b3dm/readMagicBytes.ts similarity index 100% rename from src/engine/loader/parser/b3dm/readMagicBytes.ts rename to src/loader/parser/b3dm/readMagicBytes.ts diff --git a/src/engine/loader/parser/gltf/GLBParser.ts b/src/loader/parser/gltf/GLBParser.ts similarity index 92% rename from src/engine/loader/parser/gltf/GLBParser.ts rename to src/loader/parser/gltf/GLBParser.ts index de629e4e..5de78620 100644 --- a/src/engine/loader/parser/gltf/GLBParser.ts +++ b/src/loader/parser/gltf/GLBParser.ts @@ -91,10 +91,10 @@ export class GLBParser extends ParserBase { const buffer = this._gltf.buffers[bufferView.buffer]; let dataBuffer = new Uint8Array(buffer.dbuffer, bufferView.byteOffset, bufferView.byteLength); let imgData = new Blob([dataBuffer], { type: image.mimeType }); - let dTexture = new BitmapTexture2D(); - await dTexture.loadFromBlob(imgData); - dTexture.name = image.name; - this._gltf.resources[image.name] = dTexture; + let dtexture = new BitmapTexture2D(); + await dtexture.loadFromBlob(imgData); + dtexture.name = image.name; + this._gltf.resources[image.name] = dtexture; } } @@ -123,10 +123,10 @@ export class GLBParser extends ParserBase { const buffer = this._gltf.buffers[bufferView.buffer]; let dataBuffer = new Uint8Array(buffer.dbuffer, bufferView.byteOffset, bufferView.byteLength); let imgData = new Blob([dataBuffer], { type: image.mimeType }); - let dTexture = new BitmapTexture2D(); - await dTexture.loadFromBlob(imgData); - dTexture.name = image.name; - this._gltf.resources[image.name] = dTexture; + let dtexture = new BitmapTexture2D(); + await dtexture.loadFromBlob(imgData); + dtexture.name = image.name; + this._gltf.resources[image.name] = dtexture; } } diff --git a/src/engine/loader/parser/gltf/GLTFInfo.ts b/src/loader/parser/gltf/GLTFInfo.ts similarity index 97% rename from src/engine/loader/parser/gltf/GLTFInfo.ts rename to src/loader/parser/gltf/GLTFInfo.ts index 0006e695..72801b98 100644 --- a/src/engine/loader/parser/gltf/GLTFInfo.ts +++ b/src/loader/parser/gltf/GLTFInfo.ts @@ -46,7 +46,7 @@ export class GLTF_Info { sampler: number; source: number; name: string; - dTexture: any; + dtexture: any; }[]; cameras: any; skins: any; @@ -55,8 +55,8 @@ export class GLTF_Info { uri: string; name: string; isParsed: any; - dSampler: any; - dImage: any; + dsampler: any; + dimage: any; mimeType: string; bufferView: number; }[]; diff --git a/src/engine/loader/parser/gltf/GLTFParser.ts b/src/loader/parser/gltf/GLTFParser.ts similarity index 76% rename from src/engine/loader/parser/gltf/GLTFParser.ts rename to src/loader/parser/gltf/GLTFParser.ts index 49340271..2fdff3ff 100644 --- a/src/engine/loader/parser/gltf/GLTFParser.ts +++ b/src/loader/parser/gltf/GLTFParser.ts @@ -26,7 +26,7 @@ export class GLTFParser extends ParserBase { //await this.load_gltf_textures(); let subParser = new GLTFSubParser(); let nodes = await subParser.parse(this.initUrl, this._gltf, this._gltf.scene); - subParser.destroy(); + subParser.destory(); subParser = null if (nodes) { this.data = nodes.rootNode; @@ -48,45 +48,7 @@ export class GLTFParser extends ParserBase { throw new Error('Method not implemented.'); } - public static readonly GLTF_NODE_INDEX_PROPERTY: 'GLTF_NODE_INDEX'; - public static readonly BASE_COLOR_UNIFORM = 'u_baseColorFactor'; - - public static readonly BASE_COLOR_TEXTURE_UNIFORM = 'u_baseColorSampler'; - - public static readonly METALROUGHNESS_UNIFORM = 'u_metallicRoughnessValues'; - - public static readonly METALROUGHNESS_TEXTURE_UNIFORM = 'u_metallicRoughnessSampler'; - - public static readonly NORMAL_TEXTURE_UNIFORM = 'u_normalSampler'; - - public static readonly NORMAL_SCALE_UNIFORM = 'u_normalScale'; - - public static readonly EMISSIVE_TEXTURE_UNIFORM = 'u_emissiveSampler'; - - public static readonly EMISSIVE_FACTOR_UNIFORM = 'u_emissiveFactor'; - - public static readonly OCCLUSION_TEXTURE_UNIFORM = 'u_occlusionSampler'; - - public static readonly OCCLUSION_FACTOR_UNIFORM = 'u_occlusionFactor'; - - public static readonly MAX_MORPH_TARGETS = 8; - - public static readonly MORPH_POSITION_PREFIX = 'a_morphPositions_'; - - public static readonly MORPH_NORMAL_PREFIX = 'a_morphNormals_'; - - public static readonly MORPH_TANGENT_PREFIX = 'a_morphTangents_'; - - public static readonly MORPH_WEIGHT_UNIFORM = 'u_morphWeights'; - - public static readonly SCENE_ROOT_SKELETON = 'SCENE_ROOT'; - - public static readonly IDENTITY_INVERSE_BIND_MATRICES = 'IDENTITY_IBM'; - - public static readonly JOINT_MATRICES_UNIFORM = 'u_jointMatrix'; - - public static readonly ALPHA_CUTOFF_UNIFORM = 'u_alphaCutoff'; private static _counter = 0; public static getMeshNameCounter() { @@ -135,15 +97,15 @@ export class GLTFParser extends ParserBase { return `MORPH_TARGET_NUM ${targetNum}`; } - public static getMorphTargetPositionDefine() { + public static getMorphtargetPositionDefine() { return 'HAS_MORPH_POSITION'; } - public static getMorphTargetNormalDefine() { + public static getMorphtargetNormalDefine() { return 'HAS_MORPH_NORMAL'; } - public static getMorphTargetTangentDefine() { + public static getMorphtargetTangentDefine() { return 'HAS_MORPH_TANGENT'; } diff --git a/src/engine/loader/parser/gltf/GLTFSubParser.ts b/src/loader/parser/gltf/GLTFSubParser.ts similarity index 57% rename from src/engine/loader/parser/gltf/GLTFSubParser.ts rename to src/loader/parser/gltf/GLTFSubParser.ts index 9a945f04..18f48dda 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParser.ts +++ b/src/loader/parser/gltf/GLTFSubParser.ts @@ -1,33 +1,10 @@ import { Skeleton } from '../../../components/anim/skeletonAnim/Skeleton'; -import { SkeletonAnimationComponent } from '../../../components/SkeletonAnimationComponent'; -import { SkeletonAnimationClip } from '../../../components/anim/skeletonAnim/SkeletonAnimationClip'; -import { DirectLight } from '../../../components/lights/DirectLight'; -import { PointLight } from '../../../components/lights/PointLight'; -import { SpotLight } from '../../../components/lights/SpotLight'; -import { MeshRenderer } from '../../../components/renderer/MeshRenderer'; -import { SkinnedMeshRenderer } from '../../../components/renderer/SkinnedMeshRenderer'; import { Object3D } from '../../../core/entities/Object3D'; -import { GeometryBase } from '../../../core/geometry/GeometryBase'; -import { VertexAttributeName } from '../../../core/geometry/VertexAttributeName'; -import { Engine3D } from '../../../Engine3D'; -import { BlendMode } from '../../../materials/BlendMode'; -import { MaterialBase } from '../../../materials/MaterialBase'; -import { PhysicMaterial } from '../../../materials/PhysicMaterial'; -import { Color } from '../../../math/Color'; -import { RADIANS_TO_DEGREES } from '../../../math/MathUtil'; -import { Quaternion } from '../../../math/Quaternion'; -import { defaultRes } from '../../../textures/DefaultRes'; -import { UUID } from '../../../util/Global'; import { StringUtil } from '../../../util/StringUtil'; -import { KHR_materials_clearcoat } from './extends/KHR_materials_clearcoat'; -import { KHR_materials_unlit } from './extends/KHR_materials_unlit'; import { GLTF_Info, GLTF_Node } from './GLTFInfo'; -import { GLTFParser } from './GLTFParser'; import { getTypedArrayTypeFromGLType } from './TypeArray'; import { KHR_draco_mesh_compression } from './extends/KHR_draco_mesh_compression'; -import { KHR_materials_emissive_strength } from './extends/KHR_materials_emissive_strength'; import { BitmapTexture2D } from '../../../textures/BitmapTexture2D'; -import { LitMaterial } from '../../../materials/LitMaterial'; import { GLTFSubParserCamera } from './GLTFSubParserCamera'; import { GLTFSubParserMesh } from './GLTFSubParserMesh'; import { GLTFSubParserMaterial } from './GLTFSubParserMaterial'; @@ -56,16 +33,12 @@ export class GLTFSubParser { } public get version() { - if (this.version) - return this.version; + if (this.version) return this.version; else if (this.gltf) { - if (!this.gltf.asset) - return this.errorMiss('asset'); + if (!this.gltf.asset) return this.errorMiss('asset'); this._version = this.gltf.asset.version; - - if (this.gltf.asset.minVersion) - this._version += `\r minVersion${this.gltf.asset.minVersion}`; + if (this.gltf.asset.minVersion) this._version += `\r minVersion${this.gltf.asset.minVersion}`; return this.version; } @@ -74,7 +47,7 @@ export class GLTFSubParser { return null; } - public async parse(initUrl: string, gltf: GLTF_Info, sceneId: number) { + public async parse(initUrl: string, gltf, sceneId) { this.gltf = gltf; this.initUrl = initUrl; const { version, generator } = this.gltf.asset; @@ -93,12 +66,12 @@ export class GLTFSubParser { return await this.convertToNode(result); } - public destroy() { + public destory() { KHR_draco_mesh_compression.unload(this.gltf) this.gltf = null } - private async parseScene(sceneId: number) { + private async parseScene(sceneId) { const loadScene = sceneId || this.gltf.scene || 0; const scene = this.gltf.scenes[loadScene]; @@ -117,7 +90,7 @@ export class GLTFSubParser { return result; } - private async parseNode(nodeId: number) { + private async parseNode(nodeId) { const node = this.gltf.nodes[nodeId]; if (!node) return this.errorMiss('node', nodeId); @@ -170,14 +143,14 @@ export class GLTFSubParser { throw new Error(e + info); } - private parseCamera(cameraId: number) { + private parseCamera(cameraId) { if (!this._cameraParser) { this._cameraParser = new GLTFSubParserCamera(this.gltf); } return this._cameraParser.parse(cameraId); } - private async parseMesh(meshId: number) { + private async parseMesh(meshId) { if (!this._meshParser) { this._meshParser = new GLTFSubParserMesh(this); } @@ -186,31 +159,31 @@ export class GLTFSubParser { public async parseTexture(index: number) { let textureInfo = this.gltf.textures[index]; - if (textureInfo && !textureInfo.dTexture) { + if (textureInfo && !textureInfo.dtexture) { if (textureInfo && textureInfo.source != null) { let image = this.gltf.images[textureInfo.source]; if (image.uri) { let name = image.uri; name = StringUtil.getURLName(name); - textureInfo.dTexture = this.gltf.resources[name]; + textureInfo.dtexture = this.gltf.resources[name]; } else if (image.bufferView) { let buffer = this.parseBufferView(image.bufferView); let bitmapTexture = new BitmapTexture2D(); let img = new Blob([buffer], { type: image.mimeType }); await bitmapTexture.loadFromBlob(img); - textureInfo.dTexture = bitmapTexture; + textureInfo.dtexture = bitmapTexture; } else { - textureInfo.dTexture = this.gltf.resources[image.name]; + textureInfo.dtexture = this.gltf.resources[image.name]; } } else if (textureInfo.name) { let name = StringUtil.getURLName(textureInfo.name); - textureInfo.dTexture = this.gltf.resources[name]; + textureInfo.dtexture = this.gltf.resources[name]; } } - if (!textureInfo.dTexture) { + if (!textureInfo.dtexture) { console.log("miss texture , please check texture!", index, textureInfo); } - return textureInfo.dTexture; + return textureInfo.dtexture; } public async parseMaterial(materialId) { @@ -222,6 +195,87 @@ export class GLTFSubParser { private parseAnimations() { const result = []; + // const animations = this.gltf.animations; + // if (animations) + // for (let i = 0; i < animations.length; i++) { + // const animation = animations[i]; + // const { name, channels, samplers } = animation; + // const clips = []; + // if (channels && samplers) + // for (let j = 0; j < channels.length; j++) { + // const channel = channels[j]; + // const sampler = samplers[channel.sampler]; + // if (!sampler) { + + // this.errorMiss(`animations[${i}].channels[${j}].sampler`, channel.sampler); + // continue; + + // } + + // const input = this.parseAccessor(sampler.input).data; + // const outputData = this.parseAccessor(sampler.output); + // const output = outputData.data; + // const numComponents = outputData.numComponents; + // const interpolation = sampler.interpolation || 'LINEAR'; + // const gltfNodeIdx = channel.target.node; + // const path = channel.target.path; + + // if (!input || !output) continue; + + // let combinedOutput = output; + // if (numComponents !== 1 || input.length !== output.length) { + + // const numComp = output.length / input.length; + // combinedOutput = []; + // for (let k = 0; k < input.length; k++) + // combinedOutput.push(output.slice(numComp * k, numComp * (k + 1))); + + // } + + // let nodeProperty = path; + // const extras = {}; + // switch (path) { + + // case 'translation': + // nodeProperty = 'position'; + // break; + // case 'rotation': + // nodeProperty = 'quaternion'; + // break; + // case 'scale': + // nodeProperty = 'scale'; + // break; + // case 'weights': + // nodeProperty = 'weights'; + // // extras.uniformName = GLTFParser.MORPH_WEIGHT_UNIFORM; + // break; + // default: + // console.error(`unsupported animation sampler path ${path}`); + // nodeProperty = false; + // } + + // if (!nodeProperty) continue; + + // const clip = { + // times: input, + // values: combinedOutput, + // findFlag: GLTFParser.GLTF_NODE_INDEX_PROPERTY, + // findValue: gltfNodeIdx, + // targetProp: nodeProperty, + // method: interpolation, + // extras, + // }; + + // clips.push(clip); + + // } + + // result.push({ + // name: name || String(i), + // clips, + // }); + + // } return result; } @@ -232,7 +286,7 @@ export class GLTFSubParser { return this._converter.convertNodeToObject3D(nodeInfo, parentNode); } - public parseSkeleton(skeletonID: number) { + public parseSkeleton(skeletonID) { if (!this._skeletonParser) { this._skeletonParser = new GLTFSubParserSkeleton(this); } @@ -246,10 +300,10 @@ export class GLTFSubParser { return this._skeletonParser.parseSkeletonAnimation(skeleton, animation); } - private async traverse(parentNode, nodeInfos) { + private async trivarse(parentNode, nodeInfos) { for (let i = 0; i < nodeInfos.length; i++) { const node = await this.parseObject3D(nodeInfos[i], parentNode); - await this.traverse(node, nodeInfos[i].children); + await this.trivarse(node, nodeInfos[i].children); } } @@ -261,9 +315,151 @@ export class GLTFSubParser { const textures = []; const skins = []; const cameras = []; - await this.traverse(rootNode, nodes); + await this.trivarse(rootNode, nodes); let animas; + // apply skins + // if ( skins.length ) { + + // const handlers = []; // help uglify use different name + // for ( let i = 0; i < skins.length; i ++ ) { + + // const { + // joints, skeleton, inverseBindMatrices, models, + // } = skins[ i ]; + + // const jointNum = joints.length; + // const globalJointTransformNodes = []; + // for ( let j = 0; j < jointNum; j ++ ) + // globalJointTransformNodes[ j ] = rootNode.findInChildren( GLTFParser.GLTF_NODE_INDEX_PROPERTY, joints[ j ] ); + + // let skeletonNode; + // if ( skeleton !== GLTFParser.SCENE_ROOT_SKELETON ) + // skeletonNode = rootNode.findInChildren( GLTFParser.GLTF_NODE_INDEX_PROPERTY, skeleton ); + // else + // skeletonNode = rootNode; + // skins[ i ].skeletonNode = skeletonNode; // do not know how to use it + + // const frag = new Array( 16 ); + // const fragWorld = new Array( 16 ); + // handlers[ i ] = function updateJointUniformFunc() { + + // for ( let k = 0; k < models.length; k ++ ) { + + // const model = models[ k ]; + // const globalTransformNode = model.node; + // let jointMats = []; + // Matrix4.invert( fragWorld, globalTransformNode.transform.getWorldMatrix() ); + + // for ( let n = 0; n < jointNum; n ++ ) { + + // Matrix4.mult( frag, fragWorld, globalJointTransformNodes[ n ].transform.getWorldMatrix() ); + // if ( inverseBindMatrices[ n ] !== GLTFParser.IDENTITY_INVERSE_BIND_MATRICES ) + // Matrix4.mult( frag, frag, inverseBindMatrices[ n ] ); + // jointMats = jointMats.concat( frag ); + + // } + + // const uniformObj = {}; + // uniformObj[ GLTFParser.JOINT_MATRICES_UNIFORM ] = jointMats; + // model.setUniformObj( uniformObj ); + + // } + + // }; + + // rootNode.afterUpdateMatrix.push( { + // type: 'skin', skinName: skins[ i ].name, handler: handlers[ i ], trigerNodes: [ skeletonNode, ...globalJointTransformNodes ], + // } ); + + // } + + // } + + // // animations + // for ( let i = 0; i < animations.length; i ++ ) { + + // const { clips } = animations[ i ]; + // let animateMaxTime = Number.NEGATIVE_INFINITY; + // let animateMinTime = Number.POSITIVE_INFINITY; + // for ( let j = 0; j < clips.length; j ++ ) { + + // const { + // findFlag, findValue, targetProp, times, extras, // method, + // } = clips[ j ]; + + // const node = rootNode.findInChildren( findFlag, findValue ); + // let targetNodes = [ node ]; + // if ( ! node.model && node.gltfPrimitives ) + // targetNodes = node.gltfPrimitives; + + // let setTarget; + // let resetTarget; + // if ( targetProp === 'weights' ) { + + // const resetObj = {}; + // resetObj[ GLTFParser.MORPH_WEIGHT_UNIFORM ] = targetNodes[ 0 ].model.uniformObj[ GLTFParser.MORPH_WEIGHT_UNIFORM ]; + // resetTarget = function () { + + // targetNodes.forEach( ( n ) => { + + // n.model.setUniformObj( resetObj ); + + // } ); + + // }; + + // setTarget = function ( v ) { + + // const uniformobj = {}; + // uniformobj[ extras.uniformName ] = v; + + // targetNodes.forEach( ( n ) => { + + // n.model.setUniformObj( uniformobj ); + + // } ); + + // }; + + // } else { + + // const defaultValues = []; + // for ( let m = 0; m < targetNodes.length; m ++ ) + // defaultValues[ m ] = targetNodes[ m ][ targetProp ]; + + // resetTarget = function () { + + // for ( let m = 0; m < targetNodes.length; m ++ ) + // targetNodes[ m ][ targetProp ] = defaultValues[ m ]; + + // }; + + // setTarget = function ( v ) { + + // targetNodes.forEach( ( n ) => { + + // n[ targetProp ] = v; // eslint-disable-line + + // } ); + + // }; + + // } + + // animateMinTime = animateMinTime < times[ 0 ] ? animateMinTime : times[ 0 ]; + // animateMaxTime = animateMaxTime > times[ times.length - 1 ] ? animateMaxTime : times[ times.length - 1 ]; + + // Object.assign( clips[ j ], { setTarget, resetTarget } ); + + // } + + // Object.assign( animations[ i ], { animateMinTime, animateMaxTime } ); + + // } + + // animas = { animations, type: 'gltf' }; + return { rootNode, textures, @@ -272,14 +468,14 @@ export class GLTFSubParser { }; } - private parseSkin(skinId: number) { + private parseSkin(skinId) { if (!this._skinParser) { this._skinParser = new GLTFSubParserSkin(this); } return this._skinParser.parse(skinId); } - public parseAccessor(accessorId: number) { + public parseAccessor(accessorId) { const accessor = this.gltf.accessors[accessorId]; if (!accessor) return this.errorMiss('accessor', accessorId); @@ -379,7 +575,7 @@ export class GLTFSubParser { return typedArray; } - public parseBufferView(bufferViewId: number) { + public parseBufferView(bufferViewId) { const bufferView = this.gltf.bufferViews[bufferViewId]; if (!bufferView) return this.errorMiss('bufferView', bufferViewId); @@ -398,7 +594,7 @@ export class GLTFSubParser { return bufferView.dbufferView; } - private parseBuffer(bufferId: number) { + private parseBuffer(bufferId) { const buffer = this.gltf.buffers[bufferId]; if (!buffer) return this.errorMiss('buffer', bufferId); diff --git a/src/engine/loader/parser/gltf/GLTFSubParserCamera.ts b/src/loader/parser/gltf/GLTFSubParserCamera.ts similarity index 97% rename from src/engine/loader/parser/gltf/GLTFSubParserCamera.ts rename to src/loader/parser/gltf/GLTFSubParserCamera.ts index 2e482357..1b96cb69 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParserCamera.ts +++ b/src/loader/parser/gltf/GLTFSubParserCamera.ts @@ -10,7 +10,7 @@ export class GLTFSubParserCamera { this.gltf = gltf; } - public parse(cameraId: number) { + public parse(cameraId) { const camera = this.gltf.cameras[cameraId]; if (!camera) diff --git a/src/engine/loader/parser/gltf/GLTFSubParserConverter.ts b/src/loader/parser/gltf/GLTFSubParserConverter.ts similarity index 98% rename from src/engine/loader/parser/gltf/GLTFSubParserConverter.ts rename to src/loader/parser/gltf/GLTFSubParserConverter.ts index 1cc0a4d8..041a2757 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParserConverter.ts +++ b/src/loader/parser/gltf/GLTFSubParserConverter.ts @@ -15,11 +15,11 @@ import { PhysicMaterial } from "../../../materials/PhysicMaterial"; import { Color } from "../../../math/Color"; import { RADIANS_TO_DEGREES } from "../../../math/MathUtil"; import { Quaternion } from "../../../math/Quaternion"; -import { defaultRes } from "../../../textures/DefaultRes"; import { UUID } from "../../../util/Global"; import { GLTF_Info, GLTF_Node } from "./GLTFInfo"; import { GLTFParser } from "./GLTFParser"; import { GLTFSubParser } from "./GLTFSubParser"; +import { GLTFType } from "./GLTFType"; import { KHR_materials_clearcoat } from "./extends/KHR_materials_clearcoat"; import { KHR_materials_emissive_strength } from "./extends/KHR_materials_emissive_strength"; import { KHR_materials_unlit } from "./extends/KHR_materials_unlit"; @@ -38,7 +38,7 @@ export class GLTFSubParserConverter { public async convertNodeToObject3D(nodeInfo: GLTF_Node, parentNode): Promise { const node = new Object3D(); node.name = nodeInfo.name; - node[GLTFParser.GLTF_NODE_INDEX_PROPERTY] = nodeInfo.nodeId; + node[GLTFType.GLTF_NODE_INDEX_PROPERTY] = nodeInfo.nodeId; nodeInfo['nodeObj'] = node; if (nodeInfo.matrix) { @@ -234,8 +234,8 @@ export class GLTFSubParserConverter { if (emissiveFactor && (emissiveFactor[0] > 0 || emissiveFactor[1] > 0 || emissiveFactor[2] > 0)) { if (physicMaterial.emissiveMap) { - if (physicMaterial.emissiveMap == defaultRes.blackTexture) { - physicMaterial.emissiveMap = defaultRes.whiteTexture; + if (physicMaterial.emissiveMap == Engine3D.res.blackTexture) { + physicMaterial.emissiveMap = Engine3D.res.whiteTexture; } } let emissiveFactorA = emissiveFactor[3] ? emissiveFactor[3] : 1.0; diff --git a/src/engine/loader/parser/gltf/GLTFSubParserMaterial.ts b/src/loader/parser/gltf/GLTFSubParserMaterial.ts similarity index 93% rename from src/engine/loader/parser/gltf/GLTFSubParserMaterial.ts rename to src/loader/parser/gltf/GLTFSubParserMaterial.ts index 266596dc..975dc3e8 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParserMaterial.ts +++ b/src/loader/parser/gltf/GLTFSubParserMaterial.ts @@ -1,5 +1,5 @@ +import { Engine3D } from "../../../Engine3D"; import { Vector4 } from "../../../math/Vector4"; -import { defaultRes } from "../../../textures/DefaultRes"; import { GLTF_Info } from "./GLTFInfo"; import { GLTFParser } from "./GLTFParser"; import { GLTFSubParser } from "./GLTFSubParser"; @@ -16,7 +16,7 @@ export class GLTFSubParserMaterial { this.subParser = subParser; } - public async parse(materialId: number) { + public async parse(materialId) { let material; if (materialId == undefined) { material = GLTFParser.defaultMaterial; @@ -76,7 +76,7 @@ export class GLTFSubParserMaterial { if (texture) { dmaterial.baseColorTexture = texture; } else { - dmaterial.baseColorTexture = defaultRes.redTexture; + dmaterial.baseColorTexture = Engine3D.res.redTexture; } } @@ -85,7 +85,7 @@ export class GLTFSubParserMaterial { if (texture) { dmaterial.metallicRoughnessTexture = texture; } else { - dmaterial.metallicRoughnessTexture = defaultRes.blackTexture; + dmaterial.metallicRoughnessTexture = Engine3D.res.blackTexture; } } } else { @@ -117,7 +117,7 @@ export class GLTFSubParserMaterial { if (texture) { dmaterial.normalTexture = texture; } else { - dmaterial.normalTexture = defaultRes.normalTexture; + dmaterial.normalTexture = Engine3D.res.normalTexture; } } @@ -137,7 +137,7 @@ export class GLTFSubParserMaterial { if (texture) { dmaterial.emissiveTexture = texture; } else { - dmaterial.emissiveTexture = defaultRes.blackTexture; + dmaterial.emissiveTexture = Engine3D.res.blackTexture; } } diff --git a/src/engine/loader/parser/gltf/GLTFSubParserMesh.ts b/src/loader/parser/gltf/GLTFSubParserMesh.ts similarity index 94% rename from src/engine/loader/parser/gltf/GLTFSubParserMesh.ts rename to src/loader/parser/gltf/GLTFSubParserMesh.ts index 02f1133b..172be370 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParserMesh.ts +++ b/src/loader/parser/gltf/GLTFSubParserMesh.ts @@ -2,6 +2,7 @@ import { VertexAttributeName } from "../../../core/geometry/VertexAttributeName" import { GLTF_Info } from "./GLTFInfo"; import { GLTFParser } from "./GLTFParser"; import { GLTFSubParser } from "./GLTFSubParser"; +import { GLTFType } from "./GLTFType"; import { KHR_draco_mesh_compression } from "./extends/KHR_draco_mesh_compression"; /** @@ -16,7 +17,7 @@ export class GLTFSubParserMesh { this.subParser = subParser; } - public async parse(meshId: number) { + public async parse(meshId) { const mesh = this.gltf.meshes[meshId]; if (!mesh) @@ -159,15 +160,15 @@ export class GLTFSubParserMesh { let attribName; switch (attribute) { case 'POSITION': - attribName = GLTFParser.MORPH_POSITION_PREFIX + j; + attribName = GLTFType.MORPH_POSITION_PREFIX + j; hasPositions = true; break; case 'NORMAL': - attribName = GLTFParser.MORPH_NORMAL_PREFIX + j; + attribName = GLTFType.MORPH_NORMAL_PREFIX + j; hasNormals = true; break; case 'TANGENT': - attribName = GLTFParser.MORPH_TANGENT_PREFIX + j; + attribName = GLTFType.MORPH_TANGENT_PREFIX + j; hasTangents = true; break; default: @@ -180,9 +181,9 @@ export class GLTFSubParserMesh { }); } - if (hasPositions) dprimitive.defines.push(GLTFParser.getMorphTargetPositionDefine()); - if (hasNormals) dprimitive.defines.push(GLTFParser.getMorphTargetNormalDefine()); - if (hasTangents) dprimitive.defines.push(GLTFParser.getMorphTargetTangentDefine()); + if (hasPositions) dprimitive.defines.push(GLTFParser.getMorphtargetPositionDefine()); + if (hasNormals) dprimitive.defines.push(GLTFParser.getMorphtargetNormalDefine()); + if (hasTangents) dprimitive.defines.push(GLTFParser.getMorphtargetTangentDefine()); dprimitive.weights = mesh.weights || new Array(targets.length).fill(0); } diff --git a/src/engine/loader/parser/gltf/GLTFSubParserSkeleton.ts b/src/loader/parser/gltf/GLTFSubParserSkeleton.ts similarity index 99% rename from src/engine/loader/parser/gltf/GLTFSubParserSkeleton.ts rename to src/loader/parser/gltf/GLTFSubParserSkeleton.ts index e60eb3ac..eb8f0fdc 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParserSkeleton.ts +++ b/src/loader/parser/gltf/GLTFSubParserSkeleton.ts @@ -13,7 +13,7 @@ export class GLTFSubParserSkeleton { this.subParser = subParser; } - public parse(skeletonID: number): Skeleton { + public parse(skeletonID): Skeleton { let skeleton: Skeleton = new Skeleton(); this.buildSkeleton(skeleton, undefined, skeletonID); return skeleton; diff --git a/src/engine/loader/parser/gltf/GLTFSubParserSkin.ts b/src/loader/parser/gltf/GLTFSubParserSkin.ts similarity index 94% rename from src/engine/loader/parser/gltf/GLTFSubParserSkin.ts rename to src/loader/parser/gltf/GLTFSubParserSkin.ts index 0a90e69c..acf171a4 100644 --- a/src/engine/loader/parser/gltf/GLTFSubParserSkin.ts +++ b/src/loader/parser/gltf/GLTFSubParserSkin.ts @@ -1,6 +1,7 @@ import { GLTF_Info } from "./GLTFInfo"; import { GLTFParser } from "./GLTFParser"; import { GLTFSubParser } from "./GLTFSubParser"; +import { GLTFType } from "./GLTFType"; export class GLTFSubParserSkin { protected gltf: GLTF_Info; @@ -11,7 +12,7 @@ export class GLTFSubParserSkin { this.subParser = subParser; } - public parse(skinId: number) { + public parse(skinId) { const skin = this.gltf.skins[skinId]; if (!skin) @@ -53,7 +54,7 @@ export class GLTFSubParserSkin { dskin.skeleton = rootNodeId; } // dskin.skeleton = skeleton === undefined ? GLTFParser.SCENE_ROOT_SKELETON : skeleton; - dskin.inverseBindMatrices = GLTFParser.IDENTITY_INVERSE_BIND_MATRICES; + dskin.inverseBindMatrices = GLTFType.IDENTITY_INVERSE_BIND_MATRICES; if (inverseBindMatrices !== undefined) { const accessor = this.parseAccessor(inverseBindMatrices); diff --git a/src/loader/parser/gltf/GLTFType.ts b/src/loader/parser/gltf/GLTFType.ts new file mode 100644 index 00000000..8ed1aa2c --- /dev/null +++ b/src/loader/parser/gltf/GLTFType.ts @@ -0,0 +1,41 @@ +export class GLTFType { + public static readonly GLTF_NODE_INDEX_PROPERTY: 'GLTF_NODE_INDEX'; + + public static readonly BASE_COLOR_UNIFORM = 'u_baseColorFactor'; + + public static readonly BASE_COLOR_TEXTURE_UNIFORM = 'u_baseColorSampler'; + + public static readonly METALROUGHNESS_UNIFORM = 'u_metallicRoughnessValues'; + + public static readonly METALROUGHNESS_TEXTURE_UNIFORM = 'u_metallicRoughnessSampler'; + + public static readonly NORMAL_TEXTURE_UNIFORM = 'u_normalSampler'; + + public static readonly NORMAL_SCALE_UNIFORM = 'u_normalScale'; + + public static readonly EMISSIVE_TEXTURE_UNIFORM = 'u_emissiveSampler'; + + public static readonly EMISSIVE_FACTOR_UNIFORM = 'u_emissiveFactor'; + + public static readonly OCCLUSION_TEXTURE_UNIFORM = 'u_occlusionSampler'; + + public static readonly OCCLUSION_FACTOR_UNIFORM = 'u_occlusionFactor'; + + public static readonly MAX_MORPH_TARGETS = 8; + + public static readonly MORPH_POSITION_PREFIX = 'a_morphPositions_'; + + public static readonly MORPH_NORMAL_PREFIX = 'a_morphNormals_'; + + public static readonly MORPH_TANGENT_PREFIX = 'a_morphTangents_'; + + public static readonly MORPH_WEIGHT_UNIFORM = 'u_morphWeights'; + + public static readonly SCENE_ROOT_SKELETON = 'SCENE_ROOT'; + + public static readonly IDENTITY_INVERSE_BIND_MATRICES = 'IDENTITY_IBM'; + + public static readonly JOINT_MATRICES_UNIFORM = 'u_jointMatrix'; + + public static readonly ALPHA_CUTOFF_UNIFORM = 'u_alphaCutoff'; +} \ No newline at end of file diff --git a/src/engine/loader/parser/gltf/TypeArray.ts b/src/loader/parser/gltf/TypeArray.ts similarity index 100% rename from src/engine/loader/parser/gltf/TypeArray.ts rename to src/loader/parser/gltf/TypeArray.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_draco_mesh_compression.ts b/src/loader/parser/gltf/extends/KHR_draco_mesh_compression.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_draco_mesh_compression.ts rename to src/loader/parser/gltf/extends/KHR_draco_mesh_compression.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_lights_punctual.ts b/src/loader/parser/gltf/extends/KHR_lights_punctual.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_lights_punctual.ts rename to src/loader/parser/gltf/extends/KHR_lights_punctual.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_clearcoat.ts b/src/loader/parser/gltf/extends/KHR_materials_clearcoat.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_clearcoat.ts rename to src/loader/parser/gltf/extends/KHR_materials_clearcoat.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_emissive_strength.ts b/src/loader/parser/gltf/extends/KHR_materials_emissive_strength.ts similarity index 73% rename from src/engine/loader/parser/gltf/extends/KHR_materials_emissive_strength.ts rename to src/loader/parser/gltf/extends/KHR_materials_emissive_strength.ts index 4964eb3e..e47d6cb9 100644 --- a/src/engine/loader/parser/gltf/extends/KHR_materials_emissive_strength.ts +++ b/src/loader/parser/gltf/extends/KHR_materials_emissive_strength.ts @@ -1,14 +1,14 @@ //https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_emissive_strength -import { defaultRes } from "../../../../textures/DefaultRes"; +import { Engine3D } from "../../../../Engine3D"; export class KHR_materials_emissive_strength { public static apply(gltf: any, dmaterial: any, tMaterial: any) { let extensions = dmaterial.extensions; if (extensions && extensions[`KHR_materials_emissive_strength`]) { tMaterial.emissiveIntensity = extensions[`KHR_materials_emissive_strength`].emissiveStrength * 0.5; - if (tMaterial.emissiveMap == defaultRes.blackTexture) { - tMaterial.emissiveMap = defaultRes.whiteTexture; + if (tMaterial.emissiveMap == Engine3D.res.blackTexture) { + tMaterial.emissiveMap = Engine3D.res.whiteTexture; } } else { tMaterial.emissiveIntensity = 1; diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_ior.ts b/src/loader/parser/gltf/extends/KHR_materials_ior.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_ior.ts rename to src/loader/parser/gltf/extends/KHR_materials_ior.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_sheen.ts b/src/loader/parser/gltf/extends/KHR_materials_sheen.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_sheen.ts rename to src/loader/parser/gltf/extends/KHR_materials_sheen.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_specular.ts b/src/loader/parser/gltf/extends/KHR_materials_specular.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_specular.ts rename to src/loader/parser/gltf/extends/KHR_materials_specular.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_transmission.ts b/src/loader/parser/gltf/extends/KHR_materials_transmission.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_transmission.ts rename to src/loader/parser/gltf/extends/KHR_materials_transmission.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_unlit.ts b/src/loader/parser/gltf/extends/KHR_materials_unlit.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_unlit.ts rename to src/loader/parser/gltf/extends/KHR_materials_unlit.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_variants.ts b/src/loader/parser/gltf/extends/KHR_materials_variants.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_variants.ts rename to src/loader/parser/gltf/extends/KHR_materials_variants.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_materials_volume.ts b/src/loader/parser/gltf/extends/KHR_materials_volume.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_materials_volume.ts rename to src/loader/parser/gltf/extends/KHR_materials_volume.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_mesh_quantization.ts b/src/loader/parser/gltf/extends/KHR_mesh_quantization.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_mesh_quantization.ts rename to src/loader/parser/gltf/extends/KHR_mesh_quantization.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_texture_basisu.ts b/src/loader/parser/gltf/extends/KHR_texture_basisu.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_texture_basisu.ts rename to src/loader/parser/gltf/extends/KHR_texture_basisu.ts diff --git a/src/engine/loader/parser/gltf/extends/KHR_texture_transform.ts b/src/loader/parser/gltf/extends/KHR_texture_transform.ts similarity index 100% rename from src/engine/loader/parser/gltf/extends/KHR_texture_transform.ts rename to src/loader/parser/gltf/extends/KHR_texture_transform.ts diff --git a/src/engine/loader/parser/i3dm/I3DMLoader.ts b/src/loader/parser/i3dm/I3DMLoader.ts similarity index 100% rename from src/engine/loader/parser/i3dm/I3DMLoader.ts rename to src/loader/parser/i3dm/I3DMLoader.ts diff --git a/src/engine/loader/parser/i3dm/I3DMLoaderBase.ts b/src/loader/parser/i3dm/I3DMLoaderBase.ts similarity index 100% rename from src/engine/loader/parser/i3dm/I3DMLoaderBase.ts rename to src/loader/parser/i3dm/I3DMLoaderBase.ts diff --git a/src/engine/loader/parser/tileRenderer/TileSet.ts b/src/loader/parser/tileRenderer/TileSet.ts similarity index 100% rename from src/engine/loader/parser/tileRenderer/TileSet.ts rename to src/loader/parser/tileRenderer/TileSet.ts diff --git a/src/engine/loader/parser/tileRenderer/TilesRenderer.ts b/src/loader/parser/tileRenderer/TilesRenderer.ts similarity index 100% rename from src/engine/loader/parser/tileRenderer/TilesRenderer.ts rename to src/loader/parser/tileRenderer/TilesRenderer.ts diff --git a/src/engine/materials/BlendMode.ts b/src/materials/BlendMode.ts similarity index 100% rename from src/engine/materials/BlendMode.ts rename to src/materials/BlendMode.ts diff --git a/src/engine/materials/ColorLitMaterial.ts b/src/materials/ColorLitMaterial.ts similarity index 87% rename from src/engine/materials/ColorLitMaterial.ts rename to src/materials/ColorLitMaterial.ts index 035432b5..401c393d 100644 --- a/src/engine/materials/ColorLitMaterial.ts +++ b/src/materials/ColorLitMaterial.ts @@ -1,7 +1,8 @@ +import { Engine3D } from '../Engine3D'; import { ShaderLib } from '../assets/shader/ShaderLib'; import { ColorLitShader } from '../assets/shader/materials/ColorLitShader'; import { Color } from '../math/Color'; -import { defaultRes } from '../textures/DefaultRes'; + import { PhysicMaterial } from './PhysicMaterial'; /** * ColorLitMaterial @@ -35,8 +36,8 @@ export class ColorLitMaterial extends PhysicMaterial { shaderState.acceptGI = true; shaderState.useLight = true; - shader.setTexture("normalMap", defaultRes.normalTexture); - shader.setTexture("emissiveMap", defaultRes.blackTexture); + shader.setTexture("normalMap", Engine3D.res.normalTexture); + shader.setTexture("emissiveMap", Engine3D.res.blackTexture); } clone(): this { diff --git a/src/engine/materials/GlassMaterial.ts b/src/materials/GlassMaterial.ts similarity index 93% rename from src/engine/materials/GlassMaterial.ts rename to src/materials/GlassMaterial.ts index fcb0d4a8..d885fe48 100644 --- a/src/engine/materials/GlassMaterial.ts +++ b/src/materials/GlassMaterial.ts @@ -2,7 +2,7 @@ import { ShaderLib } from '../assets/shader/ShaderLib'; import GlassShader from '../assets/shader/materials/GlassShader.wgsl?raw'; import { Engine3D } from '../Engine3D'; import { Vector4 } from '../math/Vector4'; -import { defaultRes } from '../textures/DefaultRes'; + import { PhysicMaterial } from './PhysicMaterial'; import { registerMaterial } from './MaterialRegister'; /** @@ -35,13 +35,13 @@ export class GlassMaterial extends PhysicMaterial { let bdrflutTex = Engine3D.res.getTexture(`BRDFLUT`); this.brdfLUT = bdrflutTex; - this.baseMap = defaultRes.whiteTexture; - this.normalMap = defaultRes.normalTexture; + this.baseMap = Engine3D.res.whiteTexture; + this.normalMap = Engine3D.res.normalTexture; // this.aoMap = defaultTexture.whiteTexture; // this.maskMap = defaultTexture.maskTexture; // this.maskMap = defaultTexture.grayTexture; // shader.setDefine(`USE_ARMC`, false); - this.emissiveMap = defaultRes.blackTexture; + this.emissiveMap = Engine3D.res.blackTexture; } diff --git a/src/engine/materials/LambertMaterial.ts b/src/materials/LambertMaterial.ts similarity index 91% rename from src/engine/materials/LambertMaterial.ts rename to src/materials/LambertMaterial.ts index a663a4a0..6418d8ad 100644 --- a/src/engine/materials/LambertMaterial.ts +++ b/src/materials/LambertMaterial.ts @@ -1,10 +1,11 @@ import { Lambert_shader } from '../assets/shader/materials/Lambert_shader'; import { ShaderLib } from '../assets/shader/ShaderLib'; +import { Engine3D } from '../Engine3D'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { Color } from '../math/Color'; import { Vector4 } from '../math/Vector4'; -import { defaultRes } from '../textures/DefaultRes'; + import { MaterialBase } from './MaterialBase'; import { registerMaterial } from "./MaterialRegister"; @@ -39,9 +40,9 @@ export class LambertMaterial extends MaterialBase { shaderState.useLight = true; // default value - this.baseMap = defaultRes.whiteTexture; - this.emissiveMap = defaultRes.blackTexture; - this.baseMap = defaultRes.grayTexture; + this.baseMap = Engine3D.res.whiteTexture; + this.emissiveMap = Engine3D.res.blackTexture; + this.baseMap = Engine3D.res.grayTexture; } /** diff --git a/src/engine/materials/LitMaterial.ts b/src/materials/LitMaterial.ts similarity index 93% rename from src/engine/materials/LitMaterial.ts rename to src/materials/LitMaterial.ts index be8a37f1..ff4164da 100644 --- a/src/engine/materials/LitMaterial.ts +++ b/src/materials/LitMaterial.ts @@ -1,6 +1,6 @@ import { Engine3D } from '../Engine3D'; import { Vector4 } from '../math/Vector4'; -import { defaultRes } from '../textures/DefaultRes'; + import { registerMaterial } from './MaterialRegister'; import { PhysicMaterial } from './PhysicMaterial'; /** @@ -33,13 +33,13 @@ export class LitMaterial extends PhysicMaterial { let bdrflutTex = Engine3D.res.getTexture(`BRDFLUT`); this.brdfLUT = bdrflutTex; - this.baseMap = defaultRes.whiteTexture; - this.normalMap = defaultRes.normalTexture; + this.baseMap = Engine3D.res.whiteTexture; + this.normalMap = Engine3D.res.normalTexture; // this.aoMap = defaultTexture.whiteTexture; // this.maskMap = defaultTexture.maskTexture; // this.maskMap = defaultTexture.grayTexture; // shader.setDefine(`USE_ARMC`, false); - this.emissiveMap = defaultRes.blackTexture; + this.emissiveMap = Engine3D.res.blackTexture; // this.alphaCutoff = 0.5; diff --git a/src/engine/materials/MaterialBase.ts b/src/materials/MaterialBase.ts similarity index 100% rename from src/engine/materials/MaterialBase.ts rename to src/materials/MaterialBase.ts diff --git a/src/engine/materials/MaterialPass.ts b/src/materials/MaterialPass.ts similarity index 100% rename from src/engine/materials/MaterialPass.ts rename to src/materials/MaterialPass.ts diff --git a/src/engine/materials/MaterialRegister.ts b/src/materials/MaterialRegister.ts similarity index 71% rename from src/engine/materials/MaterialRegister.ts rename to src/materials/MaterialRegister.ts index 858f4e11..4544db69 100644 --- a/src/engine/materials/MaterialRegister.ts +++ b/src/materials/MaterialRegister.ts @@ -31,10 +31,10 @@ export type MaterialClassName = | 'PointMaterial' | 'none'; -export let materialClassToName: Map, MaterialClassName> = new Map, MaterialClassName>(); -export let materialNameToClass: Map> = new Map>(); +// export let materialClassToName: Map, MaterialClassName> = new Map, MaterialClassName>(); +// export let materialNameToClass: Map> = new Map>(); export function registerMaterial(name: MaterialClassName, cls: Ctor): void { - materialClassToName.set(cls, name); - materialNameToClass.set(name, cls); + // materialClassToName.set(cls, name); + // materialNameToClass.set(name, cls); } \ No newline at end of file diff --git a/src/engine/materials/PavementMaterial.ts b/src/materials/PavementMaterial.ts similarity index 88% rename from src/engine/materials/PavementMaterial.ts rename to src/materials/PavementMaterial.ts index 5555dfee..80e4ea7c 100644 --- a/src/engine/materials/PavementMaterial.ts +++ b/src/materials/PavementMaterial.ts @@ -2,9 +2,10 @@ import { ShaderLib } from '../assets/shader/ShaderLib'; import { PavementShader } from '../assets/shader/materials/PavementShader'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { Color } from '../math/Color'; -import { defaultRes } from '../textures/DefaultRes'; + import { PhysicMaterial } from './PhysicMaterial'; import { registerMaterial } from "../materials/MaterialRegister"; +import { Engine3D } from '../Engine3D'; /** * PavementMaterial * @group Material @@ -36,11 +37,11 @@ export class PavementMaterial extends PhysicMaterial { shaderState.receiveEnv = true; shaderState.acceptGI = true; shaderState.useLight = true; - shader.setTexture("normalMap", defaultRes.normalTexture); - shader.setTexture("emissiveMap", defaultRes.blackTexture); + shader.setTexture("normalMap", Engine3D.res.normalTexture); + shader.setTexture("emissiveMap", Engine3D.res.blackTexture); // default value - this.baseMap = defaultRes.whiteTexture; + this.baseMap = Engine3D.res.whiteTexture; this.transparent = true; } diff --git a/src/engine/materials/PhysicMaterial.ts b/src/materials/PhysicMaterial.ts similarity index 98% rename from src/engine/materials/PhysicMaterial.ts rename to src/materials/PhysicMaterial.ts index 89b7fcd5..6aa96a96 100644 --- a/src/engine/materials/PhysicMaterial.ts +++ b/src/materials/PhysicMaterial.ts @@ -1,7 +1,8 @@ +import { Engine3D } from '../Engine3D'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { Color } from '../math/Color'; import { Vector4 } from '../math/Vector4'; -import { defaultRes } from '../textures/DefaultRes'; + import { MaterialBase } from './MaterialBase'; import { registerMaterial } from "./MaterialRegister"; @@ -196,7 +197,7 @@ export class PhysicMaterial extends MaterialBase { public set aoMap(value: Texture) { if (!value) return; this.renderShader.setTexture(`aoMap`, value); - if (value != defaultRes.whiteTexture) { + if (value != Engine3D.res.whiteTexture) { this.renderShader.setDefine(`USE_AOTEX`, true); } } diff --git a/src/engine/materials/PointMaterial.ts b/src/materials/PointMaterial.ts similarity index 94% rename from src/engine/materials/PointMaterial.ts rename to src/materials/PointMaterial.ts index b66c0018..4353148f 100644 --- a/src/engine/materials/PointMaterial.ts +++ b/src/materials/PointMaterial.ts @@ -1,10 +1,11 @@ +import { Engine3D } from '../Engine3D'; import { ShaderLib } from '../assets/shader/ShaderLib'; import { PointShadowDebug } from '../assets/shader/materials/PointShadowDebug'; import UnLit from '../assets/shader/materials/UnLit.wgsl?raw'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { Color } from '../math/Color'; import { Vector4 } from '../math/Vector4'; -import { defaultRes } from '../textures/DefaultRes'; + import { MaterialBase } from './MaterialBase'; import { registerMaterial } from "./MaterialRegister"; @@ -35,7 +36,7 @@ export class PointMaterial extends MaterialBase { shaderState.useLight = false; // default value - this.baseMap = defaultRes.whiteTexture; + this.baseMap = Engine3D.res.whiteTexture; } /** diff --git a/src/engine/materials/SkyMaterial.ts b/src/materials/SkyMaterial.ts similarity index 100% rename from src/engine/materials/SkyMaterial.ts rename to src/materials/SkyMaterial.ts diff --git a/src/engine/materials/UnLitMaterial.ts b/src/materials/UnLitMaterial.ts similarity index 94% rename from src/engine/materials/UnLitMaterial.ts rename to src/materials/UnLitMaterial.ts index 7b99143c..e596040c 100644 --- a/src/engine/materials/UnLitMaterial.ts +++ b/src/materials/UnLitMaterial.ts @@ -1,9 +1,10 @@ +import { Engine3D } from '../Engine3D'; import { ShaderLib } from '../assets/shader/ShaderLib'; import UnLit from '../assets/shader/materials/UnLit.wgsl?raw'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { Color } from '../math/Color'; import { Vector4 } from '../math/Vector4'; -import { defaultRes } from '../textures/DefaultRes'; + import { MaterialBase } from './MaterialBase'; import { registerMaterial } from "./MaterialRegister"; @@ -36,7 +37,7 @@ export class UnLitMaterial extends MaterialBase { shader.setUniformColor("ccc", new Color(1.0, 0.0, 0.0, 1.0)); // default value - this.baseMap = defaultRes.whiteTexture; + this.baseMap = Engine3D.res.whiteTexture; } /** diff --git a/src/engine/materials/effectPass/OutLinePass.ts b/src/materials/effectPass/OutLinePass.ts similarity index 93% rename from src/engine/materials/effectPass/OutLinePass.ts rename to src/materials/effectPass/OutLinePass.ts index 5ff2c8d3..71068e6a 100644 --- a/src/engine/materials/effectPass/OutLinePass.ts +++ b/src/materials/effectPass/OutLinePass.ts @@ -2,9 +2,10 @@ import { MaterialPass } from "../MaterialPass"; import OutlineShaderPass from "../../assets/shader/materials/OutlinePass.wgsl?raw" import { GPUCompareFunction } from "../../gfx/graphics/webGpu/WebGPUConst"; -import { defaultRes } from "../../textures/DefaultRes"; + import { Color } from "../../math/Color"; import { ShaderLib } from "../../assets/shader/ShaderLib"; +import { Engine3D } from "../../Engine3D"; export class OutLinePass extends MaterialPass { constructor(lineWeight: number = 10) { @@ -26,7 +27,7 @@ export class OutLinePass extends MaterialPass { shaderState.depthCompare = GPUCompareFunction.always; // shaderState.blendMode = BlendMode.ADD ; - shader.setTexture("baseMap", defaultRes.whiteTexture); + shader.setTexture("baseMap", Engine3D.res.whiteTexture); } private _lineWeight: number = 0; diff --git a/src/engine/materials/multiPass/CastPointShadowMaterialPass.ts b/src/materials/multiPass/CastPointShadowMaterialPass.ts similarity index 100% rename from src/engine/materials/multiPass/CastPointShadowMaterialPass.ts rename to src/materials/multiPass/CastPointShadowMaterialPass.ts diff --git a/src/engine/materials/multiPass/CastShadowMaterialPass.ts b/src/materials/multiPass/CastShadowMaterialPass.ts similarity index 100% rename from src/engine/materials/multiPass/CastShadowMaterialPass.ts rename to src/materials/multiPass/CastShadowMaterialPass.ts diff --git a/src/engine/materials/multiPass/DepthMaterialPass.ts b/src/materials/multiPass/DepthMaterialPass.ts similarity index 100% rename from src/engine/materials/multiPass/DepthMaterialPass.ts rename to src/materials/multiPass/DepthMaterialPass.ts diff --git a/src/engine/materials/multiPass/GBufferPass.ts b/src/materials/multiPass/GBufferPass.ts similarity index 93% rename from src/engine/materials/multiPass/GBufferPass.ts rename to src/materials/multiPass/GBufferPass.ts index 2c6b43e2..393af896 100644 --- a/src/engine/materials/multiPass/GBufferPass.ts +++ b/src/materials/multiPass/GBufferPass.ts @@ -1,11 +1,12 @@ import { ShaderLib } from '../../assets/shader/ShaderLib'; import { Texture } from '../../gfx/graphics/webGpu/core/texture/Texture'; import { Color } from '../../math/Color'; -import { defaultRes } from '../../textures/DefaultRes'; + import { BlendMode } from '../BlendMode'; import { MaterialBase } from '../MaterialBase'; import { registerMaterial } from "../MaterialRegister"; import GBuffer_shader from '../../assets/shader/core/pass/GBuffer_shader.wgsl?raw'; +import { Engine3D } from '../../Engine3D'; /** * @internal @@ -35,7 +36,7 @@ export class GBufferPass extends MaterialBase { this.renderShader.setUniformFloat(`alphaCutoff`, 1); this.blendMode = BlendMode.NONE; - this.renderShader.setTexture(`normalMap`, defaultRes.normalTexture); + this.renderShader.setTexture(`normalMap`, Engine3D.res.normalTexture); } public set shadowMap(texture: Texture) { } diff --git a/src/engine/materials/multiPass/SkyGBufferPass.ts b/src/materials/multiPass/SkyGBufferPass.ts similarity index 100% rename from src/engine/materials/multiPass/SkyGBufferPass.ts rename to src/materials/multiPass/SkyGBufferPass.ts diff --git a/src/engine/math/AnimationCurve.ts b/src/math/AnimationCurve.ts similarity index 96% rename from src/engine/math/AnimationCurve.ts rename to src/math/AnimationCurve.ts index 95340f51..0d6dac9d 100644 --- a/src/engine/math/AnimationCurve.ts +++ b/src/math/AnimationCurve.ts @@ -1,307 +1,307 @@ -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; -} - -/** - * Animation Cureve - * has frame list data - * @group Math - */ -export class AnimationCurve { - private _totalTime: number = 1; - - private _cache: FrameCache = new FrameCache(); - - private _cacheOut: { lhsIndex: number; rhsIndex: number } = { - lhsIndex: 0, - rhsIndex: 0, - }; - - private _InvalidateCache: boolean = false; - - public curve: Keyframe[] = []; - - public serializedVersion: number; - - public preWarpMode: number; - - public postWarpMode: number; - - public rotationOrder: number; - - constructor(frames?: Keyframe[], preWarpMode: WrapTimeMode = WrapTimeMode.Repeat, postWarpMode: WrapTimeMode = WrapTimeMode.Repeat) { - if (frames) for (let i = 0; i < frames.length; i++) { - const frame = frames[i]; - this.addKeyFrame(frame); - } - this.preWarpMode = preWarpMode; - this.postWarpMode = postWarpMode; - } - - /** - * return this curve use total time - */ - public get totalTime() { - return this._totalTime; - } - - /** - * get curve first keframe time - */ - public get first(): Keyframe { - return this.curve[0]; - } - - /** - * get curve last keyframe time - */ - public get last(): Keyframe { - return this.curve[this.curve.length - 1]; - } - - /** - * add keyFrame to curve keyframe last and calcTotalTime - * @param keyFrame {@link Keyframe} sea: one key frame data - */ - public addKeyFrame(keyFrame: Keyframe) { - if (this.curve.indexOf(keyFrame) == -1) { - this.curve.push(keyFrame); - } - this.calcTotalTime(); - } - - /** - * remove keyframe form this curve - * @param keyFrame {@link Keyframe} - */ - public removeKeyFrame(keyFrame: Keyframe) { - let index = this.curve.indexOf(keyFrame); - if (index != -1) { - this.curve.splice(index, 1); - } - - this.calcTotalTime(); - } - - /** - * calculate keyframe list in to timeline - * @param cache {@link FrameCache} - * @param lhsIndex left frame index - * @param rhsIndex right frame index - * @param timeOffset offset time default 0.0 - */ - public calculateCacheData(cache: FrameCache, lhsIndex: number, rhsIndex: number, timeOffset: number = 0) { - let m_Curve = this.curve; - let lhs = m_Curve[lhsIndex]; - let rhs = m_Curve[rhsIndex]; - // DebugAssertIf (timeOffset < -0.001F || timeOffset - 0.001F > rhs.time - lhs.time); - cache.index = lhsIndex; - cache.time = lhs.time + timeOffset; - cache.timeEnd = rhs.time + timeOffset; - cache.index = lhsIndex; - - let dx, length; - let dy; - let m1, m2, d1, d2; - - dx = rhs.time - lhs.time; - dx = Math.max(dx, 0.0001); - dy = rhs.value - lhs.value; - length = 1.0 / (dx * dx); - - m1 = lhs.outSlope; - m2 = rhs.inSlope; - d1 = m1 * dx; - d2 = m2 * dx; - - cache.coeff[0] = ((d1 + d2 - dy - dy) * length) / dx; - cache.coeff[1] = (dy + dy + dy - d1 - d1 - d2) * length; - cache.coeff[2] = m1; - cache.coeff[3] = lhs.value; - this.setupStepped(cache.coeff, lhs, rhs); - } - - /** - * get caculate frames value - * @param time - * @returns - */ - public getValue(time: number): number { - time = this.wrapTime(time); - - this.findCurve(time, this._cacheOut); - - this.calculateCacheData(this._cache, this._cacheOut.lhsIndex, this._cacheOut.rhsIndex, 0); - - return this.evaluateCache(this._cache, time); - } - - /** - * get has Keyframe list count - * @returns int - */ - public getKeyCount(): number { - return this.curve.length; - } - - /** - * Get a Keyframe Data by Index - * @param index must int - * @returns Keyframe {@link Keyframe} - */ - public getKey(index: number): Keyframe { - return this.curve[index]; - } - - public unSerialized(data: any): this { - this.preWarpMode = data['m_PreInfinity']; - this.postWarpMode = data['m_PostInfinity']; - this.rotationOrder = data['m_RotationOrder']; - - let len = data['m_Curve'].length; - for (let i = 0; i < len; i++) { - this.curve[i] = new Keyframe(); - this.curve[i].unSerialized(data['m_Curve'][i.toString()]); - } - this.calcTotalTime(); - return this; - } - - public unSerialized2(data: Object): this { - this.preWarpMode = data['preWrapMode']; - this.postWarpMode = data['postWrapMode']; - - let keyFrames = data['keyFrames'] || data['keys']; - let len = keyFrames.length; - for (let i = 0; i < len; i++) { - this.curve[i] = new Keyframe(); - this.curve[i].unSerialized2(keyFrames[i.toString()]); - } - this.calcTotalTime(); - return this; - } - - private wrapTime(curveT: number) { - let m_Curve = this.curve; - let begTime = m_Curve[0].time; - let endTime = m_Curve[m_Curve.length - 1].time; - - if (curveT < begTime) { - if (this.preWarpMode == WrapTimeMode.Clamp) curveT = begTime; - else if (this.preWarpMode == WrapTimeMode.PingPong) curveT = PingPong(curveT, begTime, endTime); - else curveT = RepeatSE(curveT, begTime, endTime); - } else if (curveT > endTime) { - if (this.postWarpMode == WrapTimeMode.Clamp) curveT = endTime; - else if (this.postWarpMode == WrapTimeMode.PingPong) curveT = PingPong(curveT, begTime, endTime); - else curveT = RepeatSE(curveT, begTime, endTime); - } - return curveT; - } - - private evaluateCache(cache: FrameCache, curveT: number): number { - let t = curveT - cache.time; - let output = t * (t * (t * cache.coeff[0] + cache.coeff[1]) + cache.coeff[2]) + cache.coeff[3]; - return output; - } - - private findCurve(time: number, out: { lhsIndex: number; rhsIndex: number }) { - let frames = this.curve; - for (let i = 1; i < frames.length; i++) { - let left = frames[i - 1]; - let right = frames[i]; - if (left.time <= time && right.time > time) { - out.lhsIndex = i - 1; - out.rhsIndex = i; - } - } - } - - private setupStepped(coeff: number[], lhs: Keyframe, rhs: Keyframe) { - if (isNaN(lhs.outSlope) || isNaN(rhs.inSlope)) { - coeff[0] = 0.0; - coeff[1] = 0.0; - coeff[2] = 0.0; - coeff[3] = lhs.value; - } - } - - private invalidateCache() { - this._InvalidateCache = true; - } - - private calcTotalTime() { - let maxTime = 0; - for (let curve of this.curve) { - maxTime = Math.max(maxTime, curve.time); - } - this._totalTime = maxTime; - } - - public static scaleCurveValue(curve: AnimationCurve, scale: number) { - if (!curve._InvalidateCache) { - for (let i = 0; i < curve.curve.length; i++) { - let c = curve.curve[i]; - c.value *= scale; - c.inSlope *= scale; - c.outSlope *= scale; - } - } - curve.invalidateCache(); - } -} +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; +} + +/** + * Animation Cureve + * has frame list data + * @group Math + */ +export class AnimationCurve { + private _totalTime: number = 1; + + private _cache: FrameCache = new FrameCache(); + + private _cacheOut: { lhsIndex: number; rhsIndex: number } = { + lhsIndex: 0, + rhsIndex: 0, + }; + + private _InvalidateCache: boolean = false; + + public curve: Keyframe[] = []; + + public serializedVersion: number; + + public preWarpMode: number; + + public postWarpMode: number; + + public rotationOrder: number; + + constructor(frames?: Keyframe[], preWarpMode: WrapTimeMode = WrapTimeMode.Repeat, postWarpMode: WrapTimeMode = WrapTimeMode.Repeat) { + if (frames) for (let i = 0; i < frames.length; i++) { + const frame = frames[i]; + this.addKeyFrame(frame); + } + this.preWarpMode = preWarpMode; + this.postWarpMode = postWarpMode; + } + + /** + * return this curve use total time + */ + public get totalTime() { + return this._totalTime; + } + + /** + * get curve first keframe time + */ + public get first(): Keyframe { + return this.curve[0]; + } + + /** + * get curve last keyframe time + */ + public get last(): Keyframe { + return this.curve[this.curve.length - 1]; + } + + /** + * add keyFrame to curve keyframe last and calcTotalTime + * @param keyFrame {@link Keyframe} sea: one key frame data + */ + public addKeyFrame(keyFrame: Keyframe) { + if (this.curve.indexOf(keyFrame) == -1) { + this.curve.push(keyFrame); + } + this.calcTotalTime(); + } + + /** + * remove keyframe form this curve + * @param keyFrame {@link Keyframe} + */ + public removeKeyFrame(keyFrame: Keyframe) { + let index = this.curve.indexOf(keyFrame); + if (index != -1) { + this.curve.splice(index, 1); + } + + this.calcTotalTime(); + } + + /** + * calculate keyframe list in to timeline + * @param cache {@link FrameCache} + * @param lhsIndex left frame index + * @param rhsIndex right frame index + * @param timeOffset offset time default 0.0 + */ + public calculateCacheData(cache: FrameCache, lhsIndex: number, rhsIndex: number, timeOffset: number = 0) { + let m_Curve = this.curve; + let lhs = m_Curve[lhsIndex]; + let rhs = m_Curve[rhsIndex]; + // DebugAssertIf (timeOffset < -0.001F || timeOffset - 0.001F > rhs.time - lhs.time); + cache.index = lhsIndex; + cache.time = lhs.time + timeOffset; + cache.timeEnd = rhs.time + timeOffset; + cache.index = lhsIndex; + + let dx, length; + let dy; + let m1, m2, d1, d2; + + dx = rhs.time - lhs.time; + dx = Math.max(dx, 0.0001); + dy = rhs.value - lhs.value; + length = 1.0 / (dx * dx); + + m1 = lhs.outSlope; + m2 = rhs.inSlope; + d1 = m1 * dx; + d2 = m2 * dx; + + cache.coeff[0] = ((d1 + d2 - dy - dy) * length) / dx; + cache.coeff[1] = (dy + dy + dy - d1 - d1 - d2) * length; + cache.coeff[2] = m1; + cache.coeff[3] = lhs.value; + this.setupStepped(cache.coeff, lhs, rhs); + } + + /** + * get caculate frames value + * @param time + * @returns + */ + public getValue(time: number): number { + time = this.wrapTime(time); + + this.findCurve(time, this._cacheOut); + + this.calculateCacheData(this._cache, this._cacheOut.lhsIndex, this._cacheOut.rhsIndex, 0); + + return this.evaluateCache(this._cache, time); + } + + /** + * get has Keyframe list count + * @returns int + */ + public getKeyCount(): number { + return this.curve.length; + } + + /** + * Get a Keyframe Data by Index + * @param index must int + * @returns Keyframe {@link Keyframe} + */ + public getKey(index: number): Keyframe { + return this.curve[index]; + } + + public unSerialized(data: any): this { + this.preWarpMode = data['m_PreInfinity']; + this.postWarpMode = data['m_PostInfinity']; + this.rotationOrder = data['m_RotationOrder']; + + let len = data['m_Curve'].length; + for (let i = 0; i < len; i++) { + this.curve[i] = new Keyframe(); + this.curve[i].unSerialized(data['m_Curve'][i.toString()]); + } + this.calcTotalTime(); + return this; + } + + public unSerialized2(data: Object): this { + this.preWarpMode = data['preWrapMode']; + this.postWarpMode = data['postWrapMode']; + + let keyFrames = data['keyFrames'] || data['keys']; + let len = keyFrames.length; + for (let i = 0; i < len; i++) { + this.curve[i] = new Keyframe(); + this.curve[i].unSerialized2(keyFrames[i.toString()]); + } + this.calcTotalTime(); + return this; + } + + private wrapTime(curveT: number) { + let m_Curve = this.curve; + let begTime = m_Curve[0].time; + let endTime = m_Curve[m_Curve.length - 1].time; + + if (curveT < begTime) { + if (this.preWarpMode == WrapTimeMode.Clamp) curveT = begTime; + else if (this.preWarpMode == WrapTimeMode.PingPong) curveT = PingPong(curveT, begTime, endTime); + else curveT = RepeatSE(curveT, begTime, endTime); + } else if (curveT > endTime) { + if (this.postWarpMode == WrapTimeMode.Clamp) curveT = endTime; + else if (this.postWarpMode == WrapTimeMode.PingPong) curveT = PingPong(curveT, begTime, endTime); + else curveT = RepeatSE(curveT, begTime, endTime); + } + return curveT; + } + + private evaluateCache(cache: FrameCache, curveT: number): number { + let t = curveT - cache.time; + let output = t * (t * (t * cache.coeff[0] + cache.coeff[1]) + cache.coeff[2]) + cache.coeff[3]; + return output; + } + + private findCurve(time: number, out: { lhsIndex: number; rhsIndex: number }) { + let frames = this.curve; + for (let i = 1; i < frames.length; i++) { + let left = frames[i - 1]; + let right = frames[i]; + if (left.time <= time && right.time > time) { + out.lhsIndex = i - 1; + out.rhsIndex = i; + } + } + } + + private setupStepped(coeff: number[], lhs: Keyframe, rhs: Keyframe) { + if (isNaN(lhs.outSlope) || isNaN(rhs.inSlope)) { + coeff[0] = 0.0; + coeff[1] = 0.0; + coeff[2] = 0.0; + coeff[3] = lhs.value; + } + } + + private invalidateCache() { + this._InvalidateCache = true; + } + + private calcTotalTime() { + let maxTime = 0; + for (let curve of this.curve) { + maxTime = Math.max(maxTime, curve.time); + } + this._totalTime = maxTime; + } + + public static scaleCurveValue(curve: AnimationCurve, scale: number) { + if (!curve._InvalidateCache) { + for (let i = 0; i < curve.curve.length; i++) { + let c = curve.curve[i]; + c.value *= scale; + c.inSlope *= scale; + c.outSlope *= scale; + } + } + curve.invalidateCache(); + } +} diff --git a/src/engine/math/Bezier2D.ts b/src/math/Bezier2D.ts similarity index 96% rename from src/engine/math/Bezier2D.ts rename to src/math/Bezier2D.ts index ecb3681c..5ce18982 100644 --- a/src/engine/math/Bezier2D.ts +++ b/src/math/Bezier2D.ts @@ -1,95 +1,95 @@ -import { MathUtil } from './MathUtil'; -import { Vector2 } from './Vector2'; -/** - * 2D Bezier Curve - * @group Math - */ -export class Bezier2D { - - private _points: Vector2[]; - - private _cacheValue: Vector2; - - /** - * instance bezier class - */ - constructor(vec2Ds: Vector2[] = []) { - this.points = vec2Ds; - this._cacheValue = new Vector2(); - } - - /** - * get all bezier 2d points - */ - public get points(): Vector2[] { - return this._points; - } - - /** - * set bezier 2d point[x,y] list must great 4 - */ - public set points(value: Vector2[]) { - this._points = value; - } - - /** - * get point2d at curve - * @param v 0.0 ~ 1.0 - * @returns return point2D at curve - */ - public getValue(v: number): Vector2 { - if (v < 0) v = 0; - if (v > 1) v = 1; - - let len = this.points.length - 1; - let ci = Math.floor(len * v); - let ni = ci + 1; - let w = MathUtil.fract((len + 1) * v); - if (ni >= len) { - ni = ci; - w = 0; - } - - this._cacheValue.x = this.points[ci].x + (this.points[ni].x - this.points[ci].x) * w; - this._cacheValue.y = this.points[ci].y + (this.points[ni].y - this.points[ci].y) * w; - return this._cacheValue; - } - - /** - * caclute bezier curve points at line [ 0.0 , 1.0 ] - * @param anchorpoints bezier anchor - * @param pointsAmount point count - * @returns get a bezier curve [Bezier2D] - */ - public static createBezierPoints(anchorpoints: Vector2[], pointsAmount: number): Bezier2D { - var bezier2d: Bezier2D = new Bezier2D(); - for (var i = 0; i < pointsAmount; i++) { - var point = Bezier2D.multiPointBezier(anchorpoints, i / pointsAmount); - bezier2d.points.push(point); - } - return bezier2d; - } - - private static multiPointBezier(points: Vector2[], t: number) { - var len = points.length; - var x = 0, - y = 0; - var erxiangshi = function (start: number, end: number) { - var cs = 1, - bcs = 1; - while (end > 0) { - cs *= start; - bcs *= end; - start--; - end--; - } - return cs / bcs; - }; - for (var i = 0; i < len; i++) { - var point = points[i]; - x += point.x * Math.pow(1 - t, len - 1 - i) * Math.pow(t, i) * erxiangshi(len - 1, i); - y += point.y * Math.pow(1 - t, len - 1 - i) * Math.pow(t, i) * erxiangshi(len - 1, i); - } - return new Vector2(x, y); - } -} +import { MathUtil } from './MathUtil'; +import { Vector2 } from './Vector2'; +/** + * 2D Bezier Curve + * @group Math + */ +export class Bezier2D { + + private _points: Vector2[]; + + private _cacheValue: Vector2; + + /** + * instance bezier class + */ + constructor(vec2Ds: Vector2[] = []) { + this.points = vec2Ds; + this._cacheValue = new Vector2(); + } + + /** + * get all bezier 2d points + */ + public get points(): Vector2[] { + return this._points; + } + + /** + * set bezier 2d point[x,y] list must great 4 + */ + public set points(value: Vector2[]) { + this._points = value; + } + + /** + * get point2d at curve + * @param v 0.0 ~ 1.0 + * @returns return point2D at curve + */ + public getValue(v: number): Vector2 { + if (v < 0) v = 0; + if (v > 1) v = 1; + + let len = this.points.length - 1; + let ci = Math.floor(len * v); + let ni = ci + 1; + let w = MathUtil.fract((len + 1) * v); + if (ni >= len) { + ni = ci; + w = 0; + } + + this._cacheValue.x = this.points[ci].x + (this.points[ni].x - this.points[ci].x) * w; + this._cacheValue.y = this.points[ci].y + (this.points[ni].y - this.points[ci].y) * w; + return this._cacheValue; + } + + /** + * caclute bezier curve points at line [ 0.0 , 1.0 ] + * @param anchorpoints bezier anchor + * @param pointsAmount point count + * @returns get a bezier curve [Bezier2D] + */ + public static createBezierPoints(anchorpoints: Vector2[], pointsAmount: number): Bezier2D { + var bezier2d: Bezier2D = new Bezier2D(); + for (var i = 0; i < pointsAmount; i++) { + var point = Bezier2D.multiPointBezier(anchorpoints, i / pointsAmount); + bezier2d.points.push(point); + } + return bezier2d; + } + + private static multiPointBezier(points: Vector2[], t: number) { + var len = points.length; + var x = 0, + y = 0; + var erxiangshi = function (start: number, end: number) { + var cs = 1, + bcs = 1; + while (end > 0) { + cs *= start; + bcs *= end; + start--; + end--; + } + return cs / bcs; + }; + for (var i = 0; i < len; i++) { + var point = points[i]; + x += point.x * Math.pow(1 - t, len - 1 - i) * Math.pow(t, i) * erxiangshi(len - 1, i); + y += point.y * Math.pow(1 - t, len - 1 - i) * Math.pow(t, i) * erxiangshi(len - 1, i); + } + return new Vector2(x, y); + } +} diff --git a/src/engine/math/Bezier3D.ts b/src/math/Bezier3D.ts similarity index 96% rename from src/engine/math/Bezier3D.ts rename to src/math/Bezier3D.ts index a869392e..c8bf8e0a 100644 --- a/src/engine/math/Bezier3D.ts +++ b/src/math/Bezier3D.ts @@ -1,122 +1,122 @@ -import { Vector3 } from './Vector3'; -/** - * 3D Bezier Curve - * @group Math - */ -export class Bezier3D { - private static tmp_points: Vector3[] = []; - - /** - * get cubic curve point value form t at bezier data - * @param t interval value - * @param p0 start point - * @param c1 left control point - * @param c2 right control point - * @param p3 end point - * @returns cubic curve point - */ - public static calculateCubicBezierPoint(t: number, p0: Vector3, c1: Vector3, c2: Vector3, p3: Vector3): Vector3 { - if (t > 1) t = 1; - if (t < 0) t = 0; - let u = 1 - t; - let uu = u * u; - let uuu = u * u * u; - let tt = t * t; - let ttt = t * t * t; - let p = p0.mul(uuu); - let tp1 = c1.mul(3); - tp1 = tp1.mul(t); - tp1 = tp1.mul(uu); - - let tp2 = c2.mul(3); - tp2 = tp2.mul(tt); - tp2 = tp2.mul(u); - - let tp3 = p3.mul(ttt); - p = p.add(tp1); - p = p.add(tp2); - p = p.add(tp3); - return p; - } - - /** - * get curve point form three point bezier curve - * @param t interval value - * @param p0 start point - * @param c1 contrl point - * @param p1 end point - * @returns get bezier point at curve - */ - public static bezierPoint(t: number, p0: Vector3, c1: Vector3, p1: Vector3): Vector3 { - if (t > 1) t = 1; - if (t < 0) t = 0; - let u = 1 - t; - let uu = u * u; - let tt = t * t; - - let pp0 = p0.mul(uu); - - let cc1 = c1.mul(2); - cc1.scaleBy(u); - cc1.scaleBy(t); - - let pp1 = p1.mul(tt); - - pp0 = pp0.add(cc1); - pp0 = pp0.add(pp1); - - return pp0; - } - - private static calculateCubicBezierPoints(t: number, ps: Vector3[], skip: number): Vector3 { - if (t > 1) t = 1; - if (t < 0) t = 0; - let u = 1 - t; - let uu = u * u; - let uuu = u * u * u; - let tt = t * t; - let ttt = t * t * t; - let p = ps[skip].mul(uuu); - let tp1 = ps[skip + 1].mul(3); - tp1 = tp1.mul(t); - tp1 = tp1.mul(uu); - - let tp2 = ps[skip + 2].mul(3); - tp2 = tp2.mul(tt); - tp2 = tp2.mul(u); - - let tp3 = ps[skip + 3].mul(ttt); - p = p.add(tp1); - p = p.add(tp2); - p = p.add(tp3); - - return p; - } - - private static bezierPathValue(t: number, points: Vector3[]): Vector3 { - if (t > 1) t = 1; - if (t < 0) t = 0; - let count = points.length; - let tmp_points = this.tmp_points; - tmp_points.length = 0; - - for (let i = 1; i < count; ++i) { - for (let j = 0; j < count - i; ++j) { - if (i == 1) { - let v = new Vector3(); - v.x = points[j].x * (1 - t) + points[j + 1].x * t; - v.y = points[j].y * (1 - t) + points[j + 1].y * t; - v.z = points[j].z * (1 - t) + points[j + 1].z * t; - this.tmp_points.push(v); - continue; - } - let v2 = new Vector3(); - v2.x = tmp_points[j].x * (1 - t) + tmp_points[j + 1].x * t; - v2.y = tmp_points[j].y * (1 - t) + tmp_points[j + 1].y * t; - v2.z = tmp_points[j].z * (1 - t) + tmp_points[j + 1].z * t; - tmp_points.push(v2); - } - } - return tmp_points[0]; - } -} +import { Vector3 } from './Vector3'; +/** + * 3D Bezier Curve + * @group Math + */ +export class Bezier3D { + private static tmp_points: Vector3[] = []; + + /** + * get cubic curve point value form t at bezier data + * @param t interval value + * @param p0 start point + * @param c1 left control point + * @param c2 right control point + * @param p3 end point + * @returns cubic curve point + */ + public static calculateCubicBezierPoint(t: number, p0: Vector3, c1: Vector3, c2: Vector3, p3: Vector3): Vector3 { + if (t > 1) t = 1; + if (t < 0) t = 0; + let u = 1 - t; + let uu = u * u; + let uuu = u * u * u; + let tt = t * t; + let ttt = t * t * t; + let p = p0.mul(uuu); + let tp1 = c1.mul(3); + tp1 = tp1.mul(t); + tp1 = tp1.mul(uu); + + let tp2 = c2.mul(3); + tp2 = tp2.mul(tt); + tp2 = tp2.mul(u); + + let tp3 = p3.mul(ttt); + p = p.add(tp1); + p = p.add(tp2); + p = p.add(tp3); + return p; + } + + /** + * get curve point form three point bezier curve + * @param t interval value + * @param p0 start point + * @param c1 contrl point + * @param p1 end point + * @returns get bezier point at curve + */ + public static bezierPoint(t: number, p0: Vector3, c1: Vector3, p1: Vector3): Vector3 { + if (t > 1) t = 1; + if (t < 0) t = 0; + let u = 1 - t; + let uu = u * u; + let tt = t * t; + + let pp0 = p0.mul(uu); + + let cc1 = c1.mul(2); + cc1.scaleBy(u); + cc1.scaleBy(t); + + let pp1 = p1.mul(tt); + + pp0 = pp0.add(cc1); + pp0 = pp0.add(pp1); + + return pp0; + } + + private static calculateCubicBezierPoints(t: number, ps: Vector3[], skip: number): Vector3 { + if (t > 1) t = 1; + if (t < 0) t = 0; + let u = 1 - t; + let uu = u * u; + let uuu = u * u * u; + let tt = t * t; + let ttt = t * t * t; + let p = ps[skip].mul(uuu); + let tp1 = ps[skip + 1].mul(3); + tp1 = tp1.mul(t); + tp1 = tp1.mul(uu); + + let tp2 = ps[skip + 2].mul(3); + tp2 = tp2.mul(tt); + tp2 = tp2.mul(u); + + let tp3 = ps[skip + 3].mul(ttt); + p = p.add(tp1); + p = p.add(tp2); + p = p.add(tp3); + + return p; + } + + private static bezierPathValue(t: number, points: Vector3[]): Vector3 { + if (t > 1) t = 1; + if (t < 0) t = 0; + let count = points.length; + let tmp_points = this.tmp_points; + tmp_points.length = 0; + + for (let i = 1; i < count; ++i) { + for (let j = 0; j < count - i; ++j) { + if (i == 1) { + let v = new Vector3(); + v.x = points[j].x * (1 - t) + points[j + 1].x * t; + v.y = points[j].y * (1 - t) + points[j + 1].y * t; + v.z = points[j].z * (1 - t) + points[j + 1].z * t; + this.tmp_points.push(v); + continue; + } + let v2 = new Vector3(); + v2.x = tmp_points[j].x * (1 - t) + tmp_points[j + 1].x * t; + v2.y = tmp_points[j].y * (1 - t) + tmp_points[j + 1].y * t; + v2.z = tmp_points[j].z * (1 - t) + tmp_points[j + 1].z * t; + tmp_points.push(v2); + } + } + return tmp_points[0]; + } +} diff --git a/src/engine/math/Color.ts b/src/math/Color.ts similarity index 96% rename from src/engine/math/Color.ts rename to src/math/Color.ts index 361763de..5bb72bc8 100644 --- a/src/engine/math/Color.ts +++ b/src/math/Color.ts @@ -1,440 +1,440 @@ -/** - * RGBA Color Object - * @group Math - */ -export class Color { - - /** - * red color - */ - public static COLOR_RED: Color = new Color(1, 0, 0, 1); - - /** - * green color - */ - public static COLOR_GREEN: Color = new Color(0, 1, 0, 1); - - /** - * blue color - */ - public static COLOR_BLUE: Color = new Color(0, 0, 1, 1); - - /** - * white color - */ - public static COLOR_WHITE: Color = new Color(1, 1, 1, 1); - - /** - * cache - * @internal - */ - public static COLOR_0: Color = new Color(); - /** - * cache - * @internal - */ - public static COLOR_1: Color = new Color(); - /** - * cache - * @internal - */ - public static COLOR_2: Color = new Color(); - - /** - * @internal - */ - private static HEX_CHARACTERS = 'a-f\\d'; - - /** - * @internal - */ - private static MATCH_3OR4_HEX = `#?[${Color.HEX_CHARACTERS}]{3}[${Color.HEX_CHARACTERS}]?`; - /** - * @internal - */ - private static MATCH_6OR8_HEX = `#?[${Color.HEX_CHARACTERS}]{6}([${Color.HEX_CHARACTERS}]{2})?`; - /** - * @internal - */ - private static NON_HEX_CHARS = new RegExp(`[^#${Color.HEX_CHARACTERS}]`, 'gi'); - /** - * @internal - */ - private static VALID_HEX_SIZE = new RegExp(`^${Color.MATCH_3OR4_HEX}$|^${Color.MATCH_6OR8_HEX}$`, 'i'); - - /** - * red channel - */ - public r: number = 0; - - /** - * green channel - */ - public g: number = 0; - - /** - * blue channel - */ - public b: number = 0; - - /** - * alpha channel - */ - public a: number = 0; - - /** - * create new color instance - * @param r red channel - * @param g green channel - * @param b blue channel - * @param a alpha channel - */ - constructor(r: number = 1.0, g: number = 1.0, b: number = 1.0, a: number = 1.0) { - this.setTo(r, g, b, a); - } - - /*** - * convert to hdr color , channel a is intensity - */ - convertToHDRRGB(): Color { - this.r = this.r * Math.pow(2.4, this.a); - this.g = this.g * Math.pow(2.4, this.a); - this.b = this.b * Math.pow(2.4, this.a); - return this; - } - - /** - * unSerialized color by data - * @param data - * @returns - */ - public unSerialized(data: any): this { - this.r = data['r']; - this.g = data['g']; - this.b = data['b']; - this.a = data['a']; - return this; - } - - /** - * update this color rgb form hexadecimal no alpha - * @param value - */ - public hexToRGB(value: number) { - //this.a = ((value >> 24) & 0xff ) / 255; - this.r = ((value >> 16) & 0xff) / 255; - this.g = ((value >> 8) & 0xff) / 255; - this.b = (value & 0xff) / 255; - } - - /** - * update this color rgb form hexadecimal has alpha - * @param value - */ - public hexToRGBA(value: number) { - this.a = ((value >> 24) & 0xff) / 255; - this.r = ((value >> 16) & 0xff) / 255; - this.g = ((value >> 8) & 0xff) / 255; - this.b = (value & 0xff) / 255; - } - - /** - * random on color - * @returns - */ - public static random(base: number = 1.0): Color { - let color = new Color(); - color.a = base; - color.r = base * Math.random(); - color.g = base * Math.random(); - color.b = base * Math.random(); - return color; - } - - /** - * set rgba to this color - * @param r red channel - * @param g green channel - * @param b blue channel - * @param a alpha channel - */ - public setTo(r: number, g: number, b: number, a: number) { - this.r = Math.max(r, 0.0); - this.g = Math.max(g, 0.0); - this.b = Math.max(b, 0.0); - this.a = Math.max(a, 0.0); - } - - /** - * update this color rgba form hexadecimal - * @param hex hex string。 - */ - public setHex(hex: string) { - if (typeof hex !== 'string' || Color.NON_HEX_CHARS.test(hex) || !Color.VALID_HEX_SIZE.test(hex)) { - throw new TypeError('Expected a valid hex string'); - } - hex = hex.replace(/^#/, ''); - let alphaFromHex = 1; - - if (hex.length === 8) { - alphaFromHex = Number.parseInt(hex.slice(6, 8), 16) / 255; - hex = hex.slice(0, 6); - } - - if (hex.length === 4) { - alphaFromHex = Number.parseInt(hex.slice(3, 4).repeat(2), 16) / 255; - hex = hex.slice(0, 3); - } - - if (hex.length === 3) { - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; - } - - const number = Number.parseInt(hex, 16); - const red = number >> 16; - const green = (number >> 8) & 255; - const blue = number & 255; - const alpha = alphaFromHex; - this.a = alpha; - this.r = red / 255; - this.g = green / 255; - this.b = blue / 255; - } - - /** - * convert this color to hex string code - * @returns - */ - public getHex(): string { - let getHexStr = (n: number) => { - n *= 255.0; - let str = n.toString(16); - if (str.length === 1) { - str = '0' + str; - } - return str; - }; - let hex = getHexStr(this.r) + getHexStr(this.g) + getHexStr(this.b) + getHexStr(this.a); - return hex; - } - - /** - * get rgb to array - */ - public get rgb(): number[] { - return [(this.r * 255) >>> 0, (this.g * 255) >>> 0, (this.b * 255) >>> 0]; - } - - /** - * set rgb by array - */ - public set rgb(c: number[]) { - this.setTo(c[0] / 255, c[1] / 255, c[2] / 255, this.a); - } - - /** - * get rgba to array - */ - public get rgba(): number[] { - return [(this.r * 255) >>> 0, (this.g * 255) >>> 0, (this.b * 255) >>> 0, (this.a * 255) >>> 0]; - } - - /** - * set rgb by array - */ - public set rgba(c: number[]) { - this.setTo(c[0] / 255, c[1] / 255, c[2] / 255, c[3] / 255); - } - - /** - * clone this color - * @returns - */ - public clone(): Color { - return new Color().copyForm(this); - } - - /** - * copy color form source color - * @returns - */ - public copyForm(src: Color): this { - this.r = src.r; - this.g = src.g; - this.b = src.b; - this.a = src.a; - return this; - } - - /** - * copy color form array - * @param arr [ 255 , 255 , 255 , 255 ] - * @param scalar - * @returns - */ - public copyFormArray(arr: number[], scalar: number = 255) { - this.r = arr[0] / scalar; - this.g = arr[1] / scalar; - this.b = arr[2] / scalar; - this.a = arr[3] / scalar; - return this; - } - - /** - * update this color rgb form hexadecimal no alpha - * @param hexColor rgb color - * @param dst ref out color - */ - public static hexRGBColor(hexColor: number, dst: Color = null): Color { - dst = dst || new Color(); - dst.hexToRGB(hexColor); - return dst; - } - - - - public static PRIMARY = 0x3f51b5; // - public static PRIMARYDARK = 0x303f9f; // - public static ACCENT = 0xff4081; // - - public static WHITE = 0xffffff; - public static IVORY = 0xfffff0; - public static LIGHTYELLOW = 0xffffe0; - public static YELLOW = 0xffff00; - public static SNOW = 0xfffafa; - public static FLORALWHITE = 0xfffaf0; - public static LEMONCHIFFON = 0xfffacd; - public static CORNSILK = 0xfff8dc; - public static SEASHELL = 0xfff5ee; - public static LAVENDERBLUSH = 0xfff0f5; - public static PAPAYAWHIP = 0xffefd5; - public static BLANCHEDALMOND = 0xffebcd; - public static MISTYROSE = 0xffe4e1; - public static BISQUE = 0xffe4c4; - public static MOCCASIN = 0xffe4b5; - public static NAVAJOWHITE = 0xffdead; - public static PEACHPUFF = 0xffdab9; - public static GOLD = 0xffd700; - public static PINK = 0xffc0cb; - public static LIGHTPINK = 0xffb6c1; - public static ORANGE = 0xffa500; - public static LIGHTSALMON = 0xffa07a; - public static DARKORANGE = 0xff8c00; - public static CORAL = 0xff7f50; - public static HOTPINK = 0xff69b4; - public static TOMATO = 0xff6347; - public static ORANGERED = 0xff4500; - public static DEEPPINK = 0xff1493; - public static FUCHSIA = 0xff00ff; - public static MAGENTA = 0xff00ff; - public static RED = 0xff0000; - public static OLDLACE = 0xfdf5e6; - public static LIGHTGOLDENRODYELLOW = 0xfafad2; - public static LINEN = 0xfaf0e6; - public static ANTIQUEWHITE = 0xfaebd7; - public static SALMON = 0xfa8072; - public static GHOSTWHITE = 0xf8f8ff; - public static MINTCREAM = 0xf5fffa; - public static WHITESMOKE = 0xf5f5f5; - public static BEIGE = 0xf5f5dc; - public static WHEAT = 0xf5deb3; - public static SANDYBROWN = 0xf4a460; - public static AZURE = 0xf0ffff; - public static HONEYDEW = 0xf0fff0; - public static ALICEBLUE = 0xf0f8ff; - public static KHAKI = 0xf0e68c; - public static LIGHTCORAL = 0xf08080; - public static PALEGOLDENROD = 0xeee8aa; - public static VIOLET = 0xee82ee; - public static DARKSALMON = 0xe9967a; - public static LAVENDER = 0xe6e6fa; - public static LIGHTCYAN = 0xe0ffff; - public static BURLYWOOD = 0xdeb887; - public static PLUM = 0xdda0dd; - public static GAINSBORO = 0xdcdcdc; - public static CRIMSON = 0xdc143c; - public static PALEVIOLETRED = 0xdb7093; - - public static GOLDENROD = 0xdaa520; - public static ORCHID = 0xda70d6; - public static THISTLE = 0xd8bfd8; - public static LIGHTGREY = 0xd3d3d3; - public static TAN = 0xd2b48c; - public static CHOCOLATE = 0xd2691e; - public static PERU = 0xcd853f; - public static INDIANRED = 0xcd5c5c; - public static MEDIUMVIOLETRED = 0xc71585; - public static SILVER = 0xc0c0c0; - public static DARKKHAKI = 0xbdb76b; - public static ROSYBROWN = 0xbc8f8f; - public static MEDIUMORCHID = 0xba55d3; - public static DARKGOLDENROD = 0xb8860b; - public static FIREBRICK = 0xb22222; - public static POWDERBLUE = 0xb0e0e6; - public static LIGHTSTEELBLUE = 0xb0c4de; - public static PALETURQUOISE = 0xafeeee; - public static GREENYELLOW = 0xadff2f; - public static LIGHTBLUE = 0xadd8e6; - public static DARKGRAY = 0xa9a9a9; - public static BROWN = 0xa52a2a; - public static SIENNA = 0xa0522d; - public static DARKORCHID = 0x9932cc; - public static PALEGREEN = 0x98fb98; - public static DARKVIOLET = 0x9400d3; - public static MEDIUMPURPLE = 0x9370db; - public static LIGHTGREEN = 0x90ee90; - public static DARKSEAGREEN = 0x8fbc8f; - public static SADDLEBROWN = 0x8b4513; - public static DARKMAGENTA = 0x8b008b; - public static DARKRED = 0x8b0000; - public static BLUEVIOLET = 0x8a2be2; - public static LIGHTSKYBLUE = 0x87cefa; - public static SKYBLUE = 0x87ceeb; - public static GRAY = 0x808080; - public static OLIVE = 0x808000; - public static PURPLE = 0x800080; - public static MAROON = 0x800000; - public static AQUAMARINE = 0x7fffd4; - public static CHARTREUSE = 0x7fff00; - public static LAWNGREEN = 0x7cfc00; - public static MEDIUMSLATEBLUE = 0x7b68ee; - public static LIGHTSLATEGRAY = 0x778899; - public static SLATEGRAY = 0x708090; - public static OLIVEDRAB = 0x6b8e23; - public static SLATEBLUE = 0x6a5acd; - public static DIMGRAY = 0x696969; - public static MEDIUMAQUAMARINE = 0x66cdaa; - public static CORNFLOWERBLUE = 0x6495ed; - public static CADETBLUE = 0x5f9ea0; - public static DARKOLIVEGREEN = 0x556b2f; - public static INDIGO = 0x4b0082; - public static MEDIUMTURQUOISE = 0x48d1cc; - public static DARKSLATEBLUE = 0x483d8b; - public static STEELBLUE = 0x4682b4; - public static ROYALBLUE = 0x4169e1; - public static TURQUOISE = 0x40e0d0; - public static MEDIUMSEAGREEN = 0x3cb371; - public static LIMEGREEN = 0x32cd32; - public static DARKSLATEGRAY = 0x2f4f4f; - public static SEAGREEN = 0x2e8b57; - public static FORESTGREEN = 0x228b22; - public static LIGHTSEAGREEN = 0x20b2aa; - public static DODGERBLUE = 0x1e90ff; - public static MIDNIGHTBLUE = 0x191970; - public static AQUA = 0x00ffff; - public static CYAN = 0x00ffff; - public static SPRINGGREEN = 0x00ff7f; - public static LIME = 0x00ff00; - public static MEDIUMSPRINGGREEN = 0x00fa9a; - public static DARKTURQUOISE = 0x00ced1; - public static DEEPSKYBLUE = 0x00bfff; - public static DARKCYAN = 0x008b8b; - public static TEAL = 0x008080; - public static GREEN = 0x008000; - public static DARKGREEN = 0x006400; - public static BLUE = 0x0000ff; - public static MEDIUMBLUE = 0x0000cd; - public static DARKBLUE = 0x00008b; - public static NAVY = 0x000080; - public static BLACK = 0x000000; +/** + * RGBA Color Object + * @group Math + */ +export class Color { + + /** + * red color + */ + public static COLOR_RED: Color = new Color(1, 0, 0, 1); + + /** + * green color + */ + public static COLOR_GREEN: Color = new Color(0, 1, 0, 1); + + /** + * blue color + */ + public static COLOR_BLUE: Color = new Color(0, 0, 1, 1); + + /** + * white color + */ + public static COLOR_WHITE: Color = new Color(1, 1, 1, 1); + + /** + * cache + * @internal + */ + public static COLOR_0: Color = new Color(); + /** + * cache + * @internal + */ + public static COLOR_1: Color = new Color(); + /** + * cache + * @internal + */ + public static COLOR_2: Color = new Color(); + + /** + * @internal + */ + private static HEX_CHARACTERS = 'a-f\\d'; + + /** + * @internal + */ + private static MATCH_3OR4_HEX = `#?[${Color.HEX_CHARACTERS}]{3}[${Color.HEX_CHARACTERS}]?`; + /** + * @internal + */ + private static MATCH_6OR8_HEX = `#?[${Color.HEX_CHARACTERS}]{6}([${Color.HEX_CHARACTERS}]{2})?`; + /** + * @internal + */ + private static NON_HEX_CHARS = new RegExp(`[^#${Color.HEX_CHARACTERS}]`, 'gi'); + /** + * @internal + */ + private static VALID_HEX_SIZE = new RegExp(`^${Color.MATCH_3OR4_HEX}$|^${Color.MATCH_6OR8_HEX}$`, 'i'); + + /** + * red channel + */ + public r: number = 0; + + /** + * green channel + */ + public g: number = 0; + + /** + * blue channel + */ + public b: number = 0; + + /** + * alpha channel + */ + public a: number = 0; + + /** + * create new color instance + * @param r red channel + * @param g green channel + * @param b blue channel + * @param a alpha channel + */ + constructor(r: number = 1.0, g: number = 1.0, b: number = 1.0, a: number = 1.0) { + this.setTo(r, g, b, a); + } + + /*** + * convert to hdr color , channel a is intensity + */ + convertToHDRRGB(): Color { + this.r = this.r * Math.pow(2.4, this.a); + this.g = this.g * Math.pow(2.4, this.a); + this.b = this.b * Math.pow(2.4, this.a); + return this; + } + + /** + * unSerialized color by data + * @param data + * @returns + */ + public unSerialized(data: any): this { + this.r = data['r']; + this.g = data['g']; + this.b = data['b']; + this.a = data['a']; + return this; + } + + /** + * update this color rgb form hexadecimal no alpha + * @param value + */ + public hexToRGB(value: number) { + //this.a = ((value >> 24) & 0xff ) / 255; + this.r = ((value >> 16) & 0xff) / 255; + this.g = ((value >> 8) & 0xff) / 255; + this.b = (value & 0xff) / 255; + } + + /** + * update this color rgb form hexadecimal has alpha + * @param value + */ + public hexToRGBA(value: number) { + this.a = ((value >> 24) & 0xff) / 255; + this.r = ((value >> 16) & 0xff) / 255; + this.g = ((value >> 8) & 0xff) / 255; + this.b = (value & 0xff) / 255; + } + + /** + * random on color + * @returns + */ + public static random(base: number = 1.0): Color { + let color = new Color(); + color.a = base; + color.r = base * Math.random(); + color.g = base * Math.random(); + color.b = base * Math.random(); + return color; + } + + /** + * set rgba to this color + * @param r red channel + * @param g green channel + * @param b blue channel + * @param a alpha channel + */ + public setTo(r: number, g: number, b: number, a: number) { + this.r = Math.max(r, 0.0); + this.g = Math.max(g, 0.0); + this.b = Math.max(b, 0.0); + this.a = Math.max(a, 0.0); + } + + /** + * update this color rgba form hexadecimal + * @param hex hex string. + */ + public setHex(hex: string) { + if (typeof hex !== 'string' || Color.NON_HEX_CHARS.test(hex) || !Color.VALID_HEX_SIZE.test(hex)) { + throw new TypeError('Expected a valid hex string'); + } + hex = hex.replace(/^#/, ''); + let alphaFromHex = 1; + + if (hex.length === 8) { + alphaFromHex = Number.parseInt(hex.slice(6, 8), 16) / 255; + hex = hex.slice(0, 6); + } + + if (hex.length === 4) { + alphaFromHex = Number.parseInt(hex.slice(3, 4).repeat(2), 16) / 255; + hex = hex.slice(0, 3); + } + + if (hex.length === 3) { + hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; + } + + const number = Number.parseInt(hex, 16); + const red = number >> 16; + const green = (number >> 8) & 255; + const blue = number & 255; + const alpha = alphaFromHex; + this.a = alpha; + this.r = red / 255; + this.g = green / 255; + this.b = blue / 255; + } + + /** + * convert this color to hex string code + * @returns + */ + public getHex(): string { + let getHexStr = (n: number) => { + n *= 255.0; + let str = n.toString(16); + if (str.length === 1) { + str = '0' + str; + } + return str; + }; + let hex = getHexStr(this.r) + getHexStr(this.g) + getHexStr(this.b) + getHexStr(this.a); + return hex; + } + + /** + * get rgb to array + */ + public get rgb(): number[] { + return [(this.r * 255) >>> 0, (this.g * 255) >>> 0, (this.b * 255) >>> 0]; + } + + /** + * set rgb by array + */ + public set rgb(c: number[]) { + this.setTo(c[0] / 255, c[1] / 255, c[2] / 255, this.a); + } + + /** + * get rgba to array + */ + public get rgba(): number[] { + return [(this.r * 255) >>> 0, (this.g * 255) >>> 0, (this.b * 255) >>> 0, (this.a * 255) >>> 0]; + } + + /** + * set rgb by array + */ + public set rgba(c: number[]) { + this.setTo(c[0] / 255, c[1] / 255, c[2] / 255, c[3] / 255); + } + + /** + * clone this color + * @returns + */ + public clone(): Color { + return new Color().copyForm(this); + } + + /** + * copy color form source color + * @returns + */ + public copyForm(src: Color): this { + this.r = src.r; + this.g = src.g; + this.b = src.b; + this.a = src.a; + return this; + } + + /** + * copy color form array + * @param arr [ 255 , 255 , 255 , 255 ] + * @param scalar + * @returns + */ + public copyFormArray(arr: number[], scalar: number = 255) { + this.r = arr[0] / scalar; + this.g = arr[1] / scalar; + this.b = arr[2] / scalar; + this.a = arr[3] / scalar; + return this; + } + + /** + * update this color rgb form hexadecimal no alpha + * @param hexColor rgb color + * @param dst ref out color + */ + public static hexRGBColor(hexColor: number, dst: Color = null): Color { + dst = dst || new Color(); + dst.hexToRGB(hexColor); + return dst; + } + + + + public static PRIMARY = 0x3f51b5; // + public static PRIMARYDARK = 0x303f9f; // + public static ACCENT = 0xff4081; // + + public static WHITE = 0xffffff; + public static IVORY = 0xfffff0; + public static LIGHTYELLOW = 0xffffe0; + public static YELLOW = 0xffff00; + public static SNOW = 0xfffafa; + public static FLORALWHITE = 0xfffaf0; + public static LEMONCHIFFON = 0xfffacd; + public static CORNSILK = 0xfff8dc; + public static SEASHELL = 0xfff5ee; + public static LAVENDERBLUSH = 0xfff0f5; + public static PAPAYAWHIP = 0xffefd5; + public static BLANCHEDALMOND = 0xffebcd; + public static MISTYROSE = 0xffe4e1; + public static BISQUE = 0xffe4c4; + public static MOCCASIN = 0xffe4b5; + public static NAVAJOWHITE = 0xffdead; + public static PEACHPUFF = 0xffdab9; + public static GOLD = 0xffd700; + public static PINK = 0xffc0cb; + public static LIGHTPINK = 0xffb6c1; + public static ORANGE = 0xffa500; + public static LIGHTSALMON = 0xffa07a; + public static DARKORANGE = 0xff8c00; + public static CORAL = 0xff7f50; + public static HOTPINK = 0xff69b4; + public static TOMATO = 0xff6347; + public static ORANGERED = 0xff4500; + public static DEEPPINK = 0xff1493; + public static FUCHSIA = 0xff00ff; + public static MAGENTA = 0xff00ff; + public static RED = 0xff0000; + public static OLDLACE = 0xfdf5e6; + public static LIGHTGOLDENRODYELLOW = 0xfafad2; + public static LINEN = 0xfaf0e6; + public static ANTIQUEWHITE = 0xfaebd7; + public static SALMON = 0xfa8072; + public static GHOSTWHITE = 0xf8f8ff; + public static MINTCREAM = 0xf5fffa; + public static WHITESMOKE = 0xf5f5f5; + public static BEIGE = 0xf5f5dc; + public static WHEAT = 0xf5deb3; + public static SANDYBROWN = 0xf4a460; + public static AZURE = 0xf0ffff; + public static HONEYDEW = 0xf0fff0; + public static ALICEBLUE = 0xf0f8ff; + public static KHAKI = 0xf0e68c; + public static LIGHTCORAL = 0xf08080; + public static PALEGOLDENROD = 0xeee8aa; + public static VIOLET = 0xee82ee; + public static DARKSALMON = 0xe9967a; + public static LAVENDER = 0xe6e6fa; + public static LIGHTCYAN = 0xe0ffff; + public static BURLYWOOD = 0xdeb887; + public static PLUM = 0xdda0dd; + public static GAINSBORO = 0xdcdcdc; + public static CRIMSON = 0xdc143c; + public static PALEVIOLETRED = 0xdb7093; + + public static GOLDENROD = 0xdaa520; + public static ORCHID = 0xda70d6; + public static THISTLE = 0xd8bfd8; + public static LIGHTGREY = 0xd3d3d3; + public static TAN = 0xd2b48c; + public static CHOCOLATE = 0xd2691e; + public static PERU = 0xcd853f; + public static INDIANRED = 0xcd5c5c; + public static MEDIUMVIOLETRED = 0xc71585; + public static SILVER = 0xc0c0c0; + public static DARKKHAKI = 0xbdb76b; + public static ROSYBROWN = 0xbc8f8f; + public static MEDIUMORCHID = 0xba55d3; + public static DARKGOLDENROD = 0xb8860b; + public static FIREBRICK = 0xb22222; + public static POWDERBLUE = 0xb0e0e6; + public static LIGHTSTEELBLUE = 0xb0c4de; + public static PALETURQUOISE = 0xafeeee; + public static GREENYELLOW = 0xadff2f; + public static LIGHTBLUE = 0xadd8e6; + public static DARKGRAY = 0xa9a9a9; + public static BROWN = 0xa52a2a; + public static SIENNA = 0xa0522d; + public static DARKORCHID = 0x9932cc; + public static PALEGREEN = 0x98fb98; + public static DARKVIOLET = 0x9400d3; + public static MEDIUMPURPLE = 0x9370db; + public static LIGHTGREEN = 0x90ee90; + public static DARKSEAGREEN = 0x8fbc8f; + public static SADDLEBROWN = 0x8b4513; + public static DARKMAGENTA = 0x8b008b; + public static DARKRED = 0x8b0000; + public static BLUEVIOLET = 0x8a2be2; + public static LIGHTSKYBLUE = 0x87cefa; + public static SKYBLUE = 0x87ceeb; + public static GRAY = 0x808080; + public static OLIVE = 0x808000; + public static PURPLE = 0x800080; + public static MAROON = 0x800000; + public static AQUAMARINE = 0x7fffd4; + public static CHARTREUSE = 0x7fff00; + public static LAWNGREEN = 0x7cfc00; + public static MEDIUMSLATEBLUE = 0x7b68ee; + public static LIGHTSLATEGRAY = 0x778899; + public static SLATEGRAY = 0x708090; + public static OLIVEDRAB = 0x6b8e23; + public static SLATEBLUE = 0x6a5acd; + public static DIMGRAY = 0x696969; + public static MEDIUMAQUAMARINE = 0x66cdaa; + public static CORNFLOWERBLUE = 0x6495ed; + public static CADETBLUE = 0x5f9ea0; + public static DARKOLIVEGREEN = 0x556b2f; + public static INDIGO = 0x4b0082; + public static MEDIUMTURQUOISE = 0x48d1cc; + public static DARKSLATEBLUE = 0x483d8b; + public static STEELBLUE = 0x4682b4; + public static ROYALBLUE = 0x4169e1; + public static TURQUOISE = 0x40e0d0; + public static MEDIUMSEAGREEN = 0x3cb371; + public static LIMEGREEN = 0x32cd32; + public static DARKSLATEGRAY = 0x2f4f4f; + public static SEAGREEN = 0x2e8b57; + public static FORESTGREEN = 0x228b22; + public static LIGHTSEAGREEN = 0x20b2aa; + public static DODGERBLUE = 0x1e90ff; + public static MIDNIGHTBLUE = 0x191970; + public static AQUA = 0x00ffff; + public static CYAN = 0x00ffff; + public static SPRINGGREEN = 0x00ff7f; + public static LIME = 0x00ff00; + public static MEDIUMSPRINGGREEN = 0x00fa9a; + public static DARKTURQUOISE = 0x00ced1; + public static DEEPSKYBLUE = 0x00bfff; + public static DARKCYAN = 0x008b8b; + public static TEAL = 0x008080; + public static GREEN = 0x008000; + public static DARKGREEN = 0x006400; + public static BLUE = 0x0000ff; + public static MEDIUMBLUE = 0x0000cd; + public static DARKBLUE = 0x00008b; + public static NAVY = 0x000080; + public static BLACK = 0x000000; } \ No newline at end of file diff --git a/src/engine/math/HaltonSeq.ts b/src/math/HaltonSeq.ts similarity index 100% rename from src/engine/math/HaltonSeq.ts rename to src/math/HaltonSeq.ts diff --git a/src/engine/math/Line.ts b/src/math/Line.ts similarity index 100% rename from src/engine/math/Line.ts rename to src/math/Line.ts diff --git a/src/engine/math/MathUtil.ts b/src/math/MathUtil.ts similarity index 100% rename from src/engine/math/MathUtil.ts rename to src/math/MathUtil.ts diff --git a/src/engine/math/Matrix3.ts b/src/math/Matrix3.ts similarity index 100% rename from src/engine/math/Matrix3.ts rename to src/math/Matrix3.ts diff --git a/src/engine/math/Matrix4.ts b/src/math/Matrix4.ts similarity index 100% rename from src/engine/math/Matrix4.ts rename to src/math/Matrix4.ts diff --git a/src/engine/math/Orientation3D.ts b/src/math/Orientation3D.ts similarity index 100% rename from src/engine/math/Orientation3D.ts rename to src/math/Orientation3D.ts diff --git a/src/math/ParticleMath.ts b/src/math/ParticleMath.ts new file mode 100644 index 00000000..b8791794 --- /dev/null +++ b/src/math/ParticleMath.ts @@ -0,0 +1,28 @@ +/** + * @internal + */ +export enum ParticleSystemRandomnessIds { + // Curves + kParticleSystemClampVelocityCurveId = 0x13371337, + kParticleSystemForceCurveId = 0x12460f3b, + kParticleSystemRotationCurveId = 0x6aed452e, + kParticleSystemRotationBySpeedCurveId = 0xdec4aea1, + kParticleSystemStartSpeedCurveId = 0x96aa4de3, + kParticleSystemSizeCurveId = 0x8d2c8431, + kParticleSystemSizeBySpeedCurveId = 0xf3857f6f, + kParticleSystemVelocityCurveId = 0xe0fbd834, + kParticleSystemUVCurveId = 0x13740583, + + // Gradient + kParticleSystemColorGradientId = 0x591bc05c, + kParticleSystemColorByVelocityGradientId = 0x40eb95e4, + + // Misc + kParticleSystemMeshSelectionId = 0xbc524e5f, + kParticleSystemUVRowSelectionId = 0xaf502044, +} + +/** + * @internal + */ +export const kPI = 3.1415926535897932384626433832795028841971693993751; diff --git a/src/math/ParticleSystemCurves.ts b/src/math/ParticleSystemCurves.ts new file mode 100644 index 00000000..9978dfaa --- /dev/null +++ b/src/math/ParticleSystemCurves.ts @@ -0,0 +1,235 @@ +import { AnimationCurve, FrameCache } from './AnimationCurve'; +import { lerp } from './MathUtil'; +import { Polynomial, PolynomialCurve } from './PolynomialCurve'; +import { quadraticPolynomialRootsGeneric } from './Polynomials'; +import { Vector2 } from './Vector2'; + +/** + * @internal + */ +export enum ParticleSystemCurveEvalMode { + kEMScalar, + kEMOptimized, + kEMOptimizedMinMax, + kEMSlow, +} + +/** + * @internal + */ +export enum MinMaxCurveState { + kMMCScalar = 0, + kMMCCurve = 1, + kMMCTwoCurves = 2, + kMMCTwoConstants = 3, +} + +// export class MinMaxOptimizedPolyCurves +// { +// public Integrate(){}; +// public DoubleIntegrate(){}; +// public FindMinMaxIntegrated():Vector2{ return null }; +// public FindMinMaxDoubleIntegrated():Vector2{ return null }; + +// public max:OptimizedPolynomialCurve; +// public min:OptimizedPolynomialCurve; +// } +/** + * @internal + * @group Math + */ +export class MinMaxAnimationCurves { + // public SupportsProcedural (); + public max: AnimationCurve; + public min: AnimationCurve; +} + +/** + * @internal + * @group Math + */ +export class MinMaxPolyCurves { + public max: PolynomialCurve; + public min: PolynomialCurve; + + public integrate() { + this.max.integrate(); + this.min.integrate(); + } + + public doubleIntegrate() { + this.max.doubleIntegrate(); + this.min.doubleIntegrate(); + } + + public findMinMaxIntegrated(): Vector2 { + return null; + } + + public findMinMaxDoubleIntegrated(): Vector2 { + return null; + } +} + +/** + * @internal + * @group Math + */ +export class MinMaxCurve { + public minMaxState: MinMaxCurveState; // see enum MinMaxCurveState + public minCurve: AnimationCurve; + public maxCurve: AnimationCurve; + private _scalar = 1; // Since scalar is baked into the optimized curve we use the setter function to modify it. + private _minScalar: number; + constructor(scalarValue: number = 1) { + this._scalar = scalarValue; + this.minMaxState = MinMaxCurveState.kMMCScalar; + this.minCurve = new AnimationCurve(); + this.maxCurve = new AnimationCurve(); + } + + public setScalar(value) { + this._scalar = value; + } + + public getScalar() { + return this._scalar; + } + + public static evaluateSlow(curve: MinMaxCurve, t, factor) { + let v = curve.maxCurve.getValue(t) * curve.getScalar(); + if (curve.minMaxState == MinMaxCurveState.kMMCTwoCurves) { + return lerp(curve.minCurve.getValue(t) * curve.getScalar(), v, factor); + } + else return v; + } + + public static evaluate(curve: MinMaxCurve, t, randomValue = 1.0): number { + if (curve.minMaxState == MinMaxCurveState.kMMCScalar) { + return curve.getScalar(); + } + + let v = curve.maxCurve.getValue(t) * curve.getScalar(); + if (curve.minMaxState == MinMaxCurveState.kMMCCurve) { + return lerp(curve.minCurve.getValue(t) * curve.getScalar(), v, randomValue); + } + if (curve.minMaxState == MinMaxCurveState.kMMCTwoConstants) { + return lerp(curve._minScalar, curve._scalar, randomValue); + } + if (curve.minMaxState == MinMaxCurveState.kMMCTwoCurves) { + return lerp(curve.minCurve.getValue(t) * curve.getScalar(), v, 1 * Math.random()); + } + return this.evaluateSlow(curve, t, 1); + } + + public unSerialized(data: any) { + this.minMaxState = data['minMaxState']; + this._scalar = data['scalar']; + this._minScalar = data['minScalar']; + this.maxCurve.unSerialized(data['maxCurve']); + this.minCurve.unSerialized(data['minCurve']); + } +} + +/** + * @internal + * @group Math + */ +export class ValueSpread { + public value = 0; + public mode: number = 0; + public spread: number = 0; + public speed: MinMaxCurve = new MinMaxCurve(); + + public unSerialized(data: any) { + this.value = data['value']; + this.mode = data['mode']; + this.spread = data['spread']; + this.speed.unSerialized(data['speed']); + } +} + +// export class DualMinMax3DPolyCurves +// { +// public optX:MinMaxOptimizedPolyCurves; +// public optY:MinMaxOptimizedPolyCurves; +// public optZ:MinMaxOptimizedPolyCurves; +// public x:MinMaxPolyCurves; +// public y:MinMaxPolyCurves; +// public z:MinMaxPolyCurves; +// }; +/** + * @internal + */ +export function curvesSupportProcedural(editorCurves: MinMaxAnimationCurves, minMaxState: number): boolean { + let isValid = PolynomialCurve.isValidCurve(editorCurves.max); + if (minMaxState != MinMaxCurveState.kMMCTwoCurves && minMaxState != MinMaxCurveState.kMMCTwoConstants) { + return isValid; + } + else { + return isValid && PolynomialCurve.isValidCurve(editorCurves.min); + } +} + +/** + * @internal + */ +export function buildCurves(polyCurves: MinMaxPolyCurves, editorCurves: MinMaxAnimationCurves, scalar, minMaxState) { + polyCurves.max.buildCurve(editorCurves.max, scalar); + if (minMaxState != MinMaxCurveState.kMMCTwoCurves && minMaxState != MinMaxCurveState.kMMCTwoConstants) { + polyCurves.min.buildCurve(editorCurves.max, scalar); + } + else { + polyCurves.min.buildCurve(editorCurves.min, scalar); + } +} + +/** + * @internal + */ +export function calculateCurveRangesValue(minMaxValue: Vector2, curve: AnimationCurve) { + let keyCount = curve.getKeyCount(); + if (keyCount == 0) { + return; + } + + if (keyCount == 1) { + calculateMinMax(minMaxValue, curve.getKey(0).value); + } else { + let segmentCount = keyCount - 1; + calculateMinMax(minMaxValue, curve.getKey(0).value); + for (let i = 0; i < segmentCount; i++) { + let cache: FrameCache = new FrameCache(); + curve.calculateCacheData(cache, i, i + 1, 0.0); + + // Differentiate polynomial + let a = 3.0 * cache.coeff[0]; + let b = 2.0 * cache.coeff[1]; + let c = 1.0 * cache.coeff[2]; + + let start = curve.getKey(i).time; + let end = curve.getKey(i + 1).time; + + let roots = []; + let numRoots = quadraticPolynomialRootsGeneric(a, b, c, { r0: roots[0], r1: roots[1] }); + for (let r = 0; r < numRoots; r++) { + if (roots[r] >= 0.0 && roots[r] + start < end) { + calculateMinMax(minMaxValue, Polynomial.EvalSegment(roots[r], cache.coeff)); + } + } + calculateMinMax(minMaxValue, Polynomial.EvalSegment(end - start, cache.coeff)); + } + } +} + + + + + +/** + * @internal + */ +export function calculateMinMax(minmax: Vector2, value: number) { + minmax.x = Math.min(minmax.x, value); + minmax.y = Math.max(minmax.y, value); +} diff --git a/src/engine/math/Plane.ts b/src/math/Plane.ts similarity index 100% rename from src/engine/math/Plane.ts rename to src/math/Plane.ts diff --git a/src/engine/math/PolynomialCurve.ts b/src/math/PolynomialCurve.ts similarity index 97% rename from src/engine/math/PolynomialCurve.ts rename to src/math/PolynomialCurve.ts index 47b1730a..458373e3 100644 --- a/src/engine/math/PolynomialCurve.ts +++ b/src/math/PolynomialCurve.ts @@ -1,255 +1,255 @@ -import { AnimationCurve, FrameCache } from './AnimationCurve'; -import { cubicPolynomialRootsGeneric } from './Polynomials'; -import { Vector2 } from './Vector2'; - -/** - * @internal - * @group Math - */ -export class Polynomial { - public coeff: number[] = []; - public static EvalSegment(t: number, coeff: number[]) { - return t * (t * (t * coeff[0] + coeff[1]) + coeff[2]) + coeff[3]; - } -} - -/** - * @internal - * @group Math - */ -export class PolynomialCurve { - private static kMaxNumSegments = 8; - public segments: Polynomial[] = []; - public integrationCache: number[] = []; - public doubleIntegrationCache: number[] = []; - public times: number[] = []; - public segmentCount: number; - - constructor() { - this.segments[PolynomialCurve.kMaxNumSegments] = new Polynomial(); - this.integrationCache[PolynomialCurve.kMaxNumSegments] = 0; - this.doubleIntegrationCache[PolynomialCurve.kMaxNumSegments] = 0; - this.times[PolynomialCurve.kMaxNumSegments] = 0; - } - - public calculateMinMax(minmax: Vector2, value) { - minmax.x = Math.min(minmax.x, value); - minmax.y = Math.max(minmax.y, value); - } - - public findMinMaxDoubleIntegrated(): Vector2 { - let result = Vector2.ZERO.clone(); - let numSteps = 20; - let delta = 1.0 / numSteps; - let acc = delta; - for (let i = 0; i < numSteps; i++) { - this.calculateMinMax(result, this.evaluateDoubleIntegrated(acc)); - acc += delta; - } - return result; - } - - // Find the maximum of the integrated curve (x: min, y: max) - public findMinMaxIntegrated(): Vector2 { - let result = Vector2.ZERO.clone(); - let prevTimeValue = 0.0; - - let start: [] = []; - let end: [] = []; - for (let i = 0; i < this.segmentCount; i++) { - // Differentiate coefficients - let a = 4.0 * this.segments[i].coeff[0]; - let b = 3.0 * this.segments[i].coeff[1]; - let c = 2.0 * this.segments[i].coeff[2]; - let d = 1.0 * this.segments[i].coeff[3]; - - let roots: number[] = []; - let numRoots = cubicPolynomialRootsGeneric(roots, a, b, c, d); - for (let r = 0; r < numRoots; r++) { - let root = roots[r] + start[i]; - if (root >= start[i] && root < end[i]) { - this.calculateMinMax(result, this.evaluateIntegrated(root)); - } - } - - // TODO: Don't use eval integrated, use eval segment (and integrate in loop) - this.calculateMinMax(result, this.evaluateIntegrated(end[i])); - prevTimeValue = this.times[i]; - } - return result; - } - - public generateIntegrationCache(curve: PolynomialCurve) { - curve.integrationCache[0] = 0.0; - let prevTimeValue0 = curve.times[0]; - let prevTimeValue1 = 0.0; - for (let i = 1; i < curve.segmentCount; i++) { - let coeff = curve.segments[i - 1].coeff; - integrateSegment(coeff); - let time = prevTimeValue0 - prevTimeValue1; - curve.integrationCache[i] = curve.integrationCache[i - 1] + Polynomial.EvalSegment(time, coeff) * time; - prevTimeValue1 = prevTimeValue0; - prevTimeValue0 = curve.times[i]; - } - } - - public generateDoubleIntegrationCache(curve: PolynomialCurve) { - let sum = 0.0; - let prevTimeValue = 0.0; - for (let i = 0; i < curve.segmentCount; i++) { - curve.doubleIntegrationCache[i] = sum; - let time = curve.times[i] - prevTimeValue; - time = Math.max(time, 0.0); - sum += Polynomial.EvalSegment(time, curve.segments[i].coeff) * time * time + curve.integrationCache[i] * time; - prevTimeValue = curve.times[i]; - } - } - - // Integrates a velocity curve to be a position curve. - // You have to call EvaluateIntegrated to evaluate the curve - public integrate() { - this.generateIntegrationCache(this); - for (let i = 0; i < this.segmentCount; i++) { - integrateSegment(this.segments[i].coeff); - } - } - - // Integrates a velocity curve to be a position curve. - // You have to call EvaluateDoubleIntegrated to evaluate the curve - public doubleIntegrate() { - this.generateIntegrationCache(this); - for (let i = 0; i < this.segmentCount; i++) { - doubleIntegrateSegment(this.segments[i].coeff); - } - this.generateDoubleIntegrationCache(this); - } - - // Evaluates if it is possible to represent animation curve as PolynomialCurve - static isValidCurve(editorCurve: AnimationCurve): boolean { - let keyCount = editorCurve.getKeyCount(); - let segmentCount = keyCount - 1; - if (editorCurve.getKey(0).time != 0.0) { - segmentCount++; - } - if (editorCurve.getKey(keyCount - 1).time != 1.0) { - segmentCount++; - } - return segmentCount <= PolynomialCurve.kMaxNumSegments; - } - - public evaluateDoubleIntegrated(t) { - let prevTimeValue = 0.0; - for (let i = 0; i < this.segmentCount; i++) { - if (t <= this.times[i]) { - let time = t - prevTimeValue; - return this.doubleIntegrationCache[i] + this.integrationCache[i] * time + Polynomial.EvalSegment(time, this.segments[i].coeff) * time * time; - } - prevTimeValue = this.times[i]; - } - return 1.0; - } - - // Evaluate integrated Polynomial curve. - // Example: position = EvaluateIntegrated (normalizedTime) * startEnergy - // Use Integrate function to for example turn a velocity curve into a position curve. - // Expects that t is in the 0...1 range. - public evaluateIntegrated(t) { - let prevTimeValue = 0.0; - for (let i = 0; i < this.segmentCount; i++) { - if (t <= this.times[i]) { - let time = t - prevTimeValue; - return this.integrationCache[i] + Polynomial.EvalSegment(time, this.segments[i].coeff) * time; - } - prevTimeValue = this.times[i]; - } - return 1.0; - } - - // Evaluate the curve - // extects that t is in the 0...1 range - public evaluate(t): number { - let prevTimeValue = 0.0; - for (let i = 0; i < this.segmentCount; i++) { - if (t <= this.times[i]) { - return Polynomial.EvalSegment(t - prevTimeValue, this.segments[i].coeff); - - } - prevTimeValue = this.times[i]; - } - return 1.0; - } - - public buildCurve(editorCurve: AnimationCurve, scale: number) { - let keyCount = editorCurve.getKeyCount(); - this.segmentCount = 1; - - let kMaxTime = 1.01; - this.segments.length = 0; - this.integrationCache.length = 0; - this.doubleIntegrationCache.length = 0; - this.times.length = 0; - this.times[0] = kMaxTime; - - // Handle corner case 1 & 0 keyframes - if (keyCount == 0) { - } else if (keyCount == 1) { - this.segments[0] = new Polynomial(); - this.segments[0].coeff[3] = editorCurve.getKey(0).value * scale; - } else { - this.segmentCount = keyCount - 1; - let segmentOffset = 0; - - // Add extra key to start if it doesn't match up - if (editorCurve.getKey(0).time != 0.0) { - this.segments[0].coeff[3] = editorCurve.getKey(0).value; - this.times[0] = editorCurve.getKey(0).time; - segmentOffset = 1; - } - - for (let i = 0; i < this.segmentCount; i++) { - let cache: FrameCache; - editorCurve.calculateCacheData(cache, i, i + 1, 0.0); - this.segments[i + segmentOffset].coeff = cache.coeff.concat(); - this.times[i + segmentOffset] = editorCurve.getKey(i + 1).time; - } - this.segmentCount += segmentOffset; - - // Add extra key to start if it doesn't match up - if (editorCurve.getKey(keyCount - 1).time != 1.0) { - this.segments[this.segmentCount].coeff[3] = editorCurve.getKey(keyCount - 1).value; - this.segmentCount++; - } - - // Fixup last key time value - this.times[this.segmentCount - 1] = kMaxTime; - - for (let i = 0; i < this.segmentCount; i++) { - this.segments[i].coeff[0] *= scale; - this.segments[i].coeff[1] *= scale; - this.segments[i].coeff[2] *= scale; - this.segments[i].coeff[3] *= scale; - } - } - return true; - } -} - -/** - * @internal - */ -export function doubleIntegrateSegment(coeff) { - coeff[0] /= 20.0; - coeff[1] /= 12.0; - coeff[2] /= 6.0; - coeff[3] /= 2.0; -} - -/** - * @internal - */ -export function integrateSegment(coeff) { - coeff[0] /= 4.0; - coeff[1] /= 3.0; - coeff[2] /= 2.0; - coeff[3] /= 1.0; -} +import { AnimationCurve, FrameCache } from './AnimationCurve'; +import { cubicPolynomialRootsGeneric } from './Polynomials'; +import { Vector2 } from './Vector2'; + +/** + * @internal + * @group Math + */ +export class Polynomial { + public coeff: number[] = []; + public static EvalSegment(t: number, coeff: number[]) { + return t * (t * (t * coeff[0] + coeff[1]) + coeff[2]) + coeff[3]; + } +} + +/** + * @internal + * @group Math + */ +export class PolynomialCurve { + private static kMaxNumSegments = 8; + public segments: Polynomial[] = []; + public integrationCache: number[] = []; + public doubleIntegrationCache: number[] = []; + public times: number[] = []; + public segmentCount: number; + + constructor() { + this.segments[PolynomialCurve.kMaxNumSegments] = new Polynomial(); + this.integrationCache[PolynomialCurve.kMaxNumSegments] = 0; + this.doubleIntegrationCache[PolynomialCurve.kMaxNumSegments] = 0; + this.times[PolynomialCurve.kMaxNumSegments] = 0; + } + + public calculateMinMax(minmax: Vector2, value) { + minmax.x = Math.min(minmax.x, value); + minmax.y = Math.max(minmax.y, value); + } + + public findMinMaxDoubleIntegrated(): Vector2 { + let result = Vector2.ZERO.clone(); + let numSteps = 20; + let delta = 1.0 / numSteps; + let acc = delta; + for (let i = 0; i < numSteps; i++) { + this.calculateMinMax(result, this.evaluateDoubleIntegrated(acc)); + acc += delta; + } + return result; + } + + // Find the maximum of the integrated curve (x: min, y: max) + public findMinMaxIntegrated(): Vector2 { + let result = Vector2.ZERO.clone(); + let prevTimeValue = 0.0; + + let start: [] = []; + let end: [] = []; + for (let i = 0; i < this.segmentCount; i++) { + // Differentiate coefficients + let a = 4.0 * this.segments[i].coeff[0]; + let b = 3.0 * this.segments[i].coeff[1]; + let c = 2.0 * this.segments[i].coeff[2]; + let d = 1.0 * this.segments[i].coeff[3]; + + let roots: number[] = []; + let numRoots = cubicPolynomialRootsGeneric(roots, a, b, c, d); + for (let r = 0; r < numRoots; r++) { + let root = roots[r] + start[i]; + if (root >= start[i] && root < end[i]) { + this.calculateMinMax(result, this.evaluateIntegrated(root)); + } + } + + // TODO: Don't use eval integrated, use eval segment (and integrate in loop) + this.calculateMinMax(result, this.evaluateIntegrated(end[i])); + prevTimeValue = this.times[i]; + } + return result; + } + + public generateIntegrationCache(curve: PolynomialCurve) { + curve.integrationCache[0] = 0.0; + let prevTimeValue0 = curve.times[0]; + let prevTimeValue1 = 0.0; + for (let i = 1; i < curve.segmentCount; i++) { + let coeff = curve.segments[i - 1].coeff; + integrateSegment(coeff); + let time = prevTimeValue0 - prevTimeValue1; + curve.integrationCache[i] = curve.integrationCache[i - 1] + Polynomial.EvalSegment(time, coeff) * time; + prevTimeValue1 = prevTimeValue0; + prevTimeValue0 = curve.times[i]; + } + } + + public generateDoubleIntegrationCache(curve: PolynomialCurve) { + let sum = 0.0; + let prevTimeValue = 0.0; + for (let i = 0; i < curve.segmentCount; i++) { + curve.doubleIntegrationCache[i] = sum; + let time = curve.times[i] - prevTimeValue; + time = Math.max(time, 0.0); + sum += Polynomial.EvalSegment(time, curve.segments[i].coeff) * time * time + curve.integrationCache[i] * time; + prevTimeValue = curve.times[i]; + } + } + + // Integrates a velocity curve to be a position curve. + // You have to call EvaluateIntegrated to evaluate the curve + public integrate() { + this.generateIntegrationCache(this); + for (let i = 0; i < this.segmentCount; i++) { + integrateSegment(this.segments[i].coeff); + } + } + + // Integrates a velocity curve to be a position curve. + // You have to call EvaluateDoubleIntegrated to evaluate the curve + public doubleIntegrate() { + this.generateIntegrationCache(this); + for (let i = 0; i < this.segmentCount; i++) { + doubleIntegrateSegment(this.segments[i].coeff); + } + this.generateDoubleIntegrationCache(this); + } + + // Evaluates if it is possible to represent animation curve as PolynomialCurve + static isValidCurve(editorCurve: AnimationCurve): boolean { + let keyCount = editorCurve.getKeyCount(); + let segmentCount = keyCount - 1; + if (editorCurve.getKey(0).time != 0.0) { + segmentCount++; + } + if (editorCurve.getKey(keyCount - 1).time != 1.0) { + segmentCount++; + } + return segmentCount <= PolynomialCurve.kMaxNumSegments; + } + + public evaluateDoubleIntegrated(t) { + let prevTimeValue = 0.0; + for (let i = 0; i < this.segmentCount; i++) { + if (t <= this.times[i]) { + let time = t - prevTimeValue; + return this.doubleIntegrationCache[i] + this.integrationCache[i] * time + Polynomial.EvalSegment(time, this.segments[i].coeff) * time * time; + } + prevTimeValue = this.times[i]; + } + return 1.0; + } + + // Evaluate integrated Polynomial curve. + // Example: position = EvaluateIntegrated (normalizedTime) * startEnergy + // Use Integrate function to for example turn a velocity curve into a position curve. + // Expects that t is in the 0...1 range. + public evaluateIntegrated(t) { + let prevTimeValue = 0.0; + for (let i = 0; i < this.segmentCount; i++) { + if (t <= this.times[i]) { + let time = t - prevTimeValue; + return this.integrationCache[i] + Polynomial.EvalSegment(time, this.segments[i].coeff) * time; + } + prevTimeValue = this.times[i]; + } + return 1.0; + } + + // Evaluate the curve + // extects that t is in the 0...1 range + public evaluate(t): number { + let prevTimeValue = 0.0; + for (let i = 0; i < this.segmentCount; i++) { + if (t <= this.times[i]) { + return Polynomial.EvalSegment(t - prevTimeValue, this.segments[i].coeff); + + } + prevTimeValue = this.times[i]; + } + return 1.0; + } + + public buildCurve(editorCurve: AnimationCurve, scale: number) { + let keyCount = editorCurve.getKeyCount(); + this.segmentCount = 1; + + let kMaxTime = 1.01; + this.segments.length = 0; + this.integrationCache.length = 0; + this.doubleIntegrationCache.length = 0; + this.times.length = 0; + this.times[0] = kMaxTime; + + // Handle corner case 1 & 0 keyframes + if (keyCount == 0) { + } else if (keyCount == 1) { + this.segments[0] = new Polynomial(); + this.segments[0].coeff[3] = editorCurve.getKey(0).value * scale; + } else { + this.segmentCount = keyCount - 1; + let segmentOffset = 0; + + // Add extra key to start if it doesn't match up + if (editorCurve.getKey(0).time != 0.0) { + this.segments[0].coeff[3] = editorCurve.getKey(0).value; + this.times[0] = editorCurve.getKey(0).time; + segmentOffset = 1; + } + + for (let i = 0; i < this.segmentCount; i++) { + let cache: FrameCache; + editorCurve.calculateCacheData(cache, i, i + 1, 0.0); + this.segments[i + segmentOffset].coeff = cache.coeff.concat(); + this.times[i + segmentOffset] = editorCurve.getKey(i + 1).time; + } + this.segmentCount += segmentOffset; + + // Add extra key to start if it doesn't match up + if (editorCurve.getKey(keyCount - 1).time != 1.0) { + this.segments[this.segmentCount].coeff[3] = editorCurve.getKey(keyCount - 1).value; + this.segmentCount++; + } + + // Fixup last key time value + this.times[this.segmentCount - 1] = kMaxTime; + + for (let i = 0; i < this.segmentCount; i++) { + this.segments[i].coeff[0] *= scale; + this.segments[i].coeff[1] *= scale; + this.segments[i].coeff[2] *= scale; + this.segments[i].coeff[3] *= scale; + } + } + return true; + } +} + +/** + * @internal + */ +export function doubleIntegrateSegment(coeff) { + coeff[0] /= 20.0; + coeff[1] /= 12.0; + coeff[2] /= 6.0; + coeff[3] /= 2.0; +} + +/** + * @internal + */ +export function integrateSegment(coeff) { + coeff[0] /= 4.0; + coeff[1] /= 3.0; + coeff[2] /= 2.0; + coeff[3] /= 1.0; +} diff --git a/src/engine/math/Polynomials.ts b/src/math/Polynomials.ts similarity index 96% rename from src/engine/math/Polynomials.ts rename to src/math/Polynomials.ts index 4533c869..26622fc8 100644 --- a/src/engine/math/Polynomials.ts +++ b/src/math/Polynomials.ts @@ -1,97 +1,97 @@ -/** - * @internal - * @group Math - */ -export class Polynomials { } - -// Returns the highest root for the cubic x^3 + px^2 + qx + r -/** - * @internal - */ -export function cubicPolynomialRoot(p: number, q: number, r: number) { - let rcp3 = 1.0 / 3.0; - let half = 0.5; - let po3 = p * rcp3; - let po3_2 = po3 * po3; - let po3_3 = po3_2 * po3; - let b = po3_3 - po3 * q * half + r * half; - let a = -po3_2 + q * rcp3; - let a3 = a * a * a; - let det = a3 + b * b; - - if (det >= 0) { - let r0 = Math.sqrt(det) - b; - r0 = r0 > 0 ? Math.pow(r0, rcp3) : -Math.pow(-r0, rcp3); - - return -po3 - a / r0 + r0; - } - - let abs = Math.sqrt(-a3); - let arg = Math.acos(-b / abs); - abs = Math.pow(abs, rcp3); - abs = abs - a / abs; - arg = -po3 + abs * Math.cos(arg * rcp3); - return arg; -} - -// Calculates all real roots of polynomial ax^2 + bx + c (and returns how many) -/** - * @internal - */ -export function quadraticPolynomialRootsGeneric(a, b, c, out: { r0; r1 }) { - let eps = 0.00001; - if (Math.abs(a) < eps) { - if (Math.abs(b) > eps) { - out.r0 = -c / b; - return 1; - } else { - return 0; - } - } - - let disc = b * b - 4 * a * c; - if (disc < 0.0) { - return 0; - } - - let halfRcpA = 0.5 / a; - let sqrtDisc = Math.sqrt(disc); - out.r0 = (sqrtDisc - b) * halfRcpA; - out.r1 = (-sqrtDisc - b) * halfRcpA; - return 2; -} - -// Calculates all the roots for the cubic ax^3 + bx^2 + cx + d. Max num roots is 3. -/** - * @internal - */ -export function cubicPolynomialRootsGeneric(roots: number[], a: number, b: number, c: number, d: number) { - let numRoots = 0; - if (Math.abs(a) >= 0.0001) { - let p = b / a; - let q = c / a; - let r = d / a; - roots[0] = cubicPolynomialRoot(p, q, r); - numRoots++; - - let la = a; - let lb = b + a * roots[0]; - let lc = c + b * roots[0] + a * roots[0] * roots[0]; - numRoots += quadraticPolynomialRootsGeneric(la, lb, lc, { r0: roots[1], r1: roots[2] }); - } else { - numRoots += quadraticPolynomialRootsGeneric(b, c, d, { r0: roots[1], r1: roots[2] }); - } - - return numRoots; -} - -// // Specialized version of QuadraticPolynomialRootsGeneric that returns the largest root -// /** -// * @internal -// */ -// export function quadraticPolynomialRoot(a, b, c) { -// let r0; -// let r1; -// quadraticPolynomialRootsGeneric(a, b, c, { r0: r0, r1: r1 }); -// return r0; -// } +/** + * @internal + * @group Math + */ +export class Polynomials { } + +// Returns the highest root for the cubic x^3 + px^2 + qx + r +/** + * @internal + */ +export function cubicPolynomialRoot(p: number, q: number, r: number) { + let rcp3 = 1.0 / 3.0; + let half = 0.5; + let po3 = p * rcp3; + let po3_2 = po3 * po3; + let po3_3 = po3_2 * po3; + let b = po3_3 - po3 * q * half + r * half; + let a = -po3_2 + q * rcp3; + let a3 = a * a * a; + let det = a3 + b * b; + + if (det >= 0) { + let r0 = Math.sqrt(det) - b; + r0 = r0 > 0 ? Math.pow(r0, rcp3) : -Math.pow(-r0, rcp3); + + return -po3 - a / r0 + r0; + } + + let abs = Math.sqrt(-a3); + let arg = Math.acos(-b / abs); + abs = Math.pow(abs, rcp3); + abs = abs - a / abs; + arg = -po3 + abs * Math.cos(arg * rcp3); + return arg; +} + +// Calculates all real roots of polynomial ax^2 + bx + c (and returns how many) +/** + * @internal + */ +export function quadraticPolynomialRootsGeneric(a, b, c, out: { r0; r1 }) { + let eps = 0.00001; + if (Math.abs(a) < eps) { + if (Math.abs(b) > eps) { + out.r0 = -c / b; + return 1; + } else { + return 0; + } + } + + let disc = b * b - 4 * a * c; + if (disc < 0.0) { + return 0; + } + + let halfRcpA = 0.5 / a; + let sqrtDisc = Math.sqrt(disc); + out.r0 = (sqrtDisc - b) * halfRcpA; + out.r1 = (-sqrtDisc - b) * halfRcpA; + return 2; +} + +// Calculates all the roots for the cubic ax^3 + bx^2 + cx + d. Max num roots is 3. +/** + * @internal + */ +export function cubicPolynomialRootsGeneric(roots: number[], a: number, b: number, c: number, d: number) { + let numRoots = 0; + if (Math.abs(a) >= 0.0001) { + let p = b / a; + let q = c / a; + let r = d / a; + roots[0] = cubicPolynomialRoot(p, q, r); + numRoots++; + + let la = a; + let lb = b + a * roots[0]; + let lc = c + b * roots[0] + a * roots[0] * roots[0]; + numRoots += quadraticPolynomialRootsGeneric(la, lb, lc, { r0: roots[1], r1: roots[2] }); + } else { + numRoots += quadraticPolynomialRootsGeneric(b, c, d, { r0: roots[1], r1: roots[2] }); + } + + return numRoots; +} + +// // Specialized version of QuadraticPolynomialRootsGeneric that returns the largest root +// /** +// * @internal +// */ +// export function quadraticPolynomialRoot(a, b, c) { +// let r0; +// let r1; +// quadraticPolynomialRootsGeneric(a, b, c, { r0: r0, r1: r1 }); +// return r0; +// } diff --git a/src/engine/math/Quaternion.ts b/src/math/Quaternion.ts similarity index 100% rename from src/engine/math/Quaternion.ts rename to src/math/Quaternion.ts diff --git a/src/engine/math/Rand.ts b/src/math/Rand.ts similarity index 100% rename from src/engine/math/Rand.ts rename to src/math/Rand.ts diff --git a/src/engine/math/Random.ts b/src/math/Random.ts similarity index 100% rename from src/engine/math/Random.ts rename to src/math/Random.ts diff --git a/src/engine/math/Ray.ts b/src/math/Ray.ts similarity index 100% rename from src/engine/math/Ray.ts rename to src/math/Ray.ts diff --git a/src/engine/math/Rect.ts b/src/math/Rect.ts similarity index 100% rename from src/engine/math/Rect.ts rename to src/math/Rect.ts diff --git a/src/engine/math/TimeInterpolator.ts b/src/math/TimeInterpolator.ts similarity index 100% rename from src/engine/math/TimeInterpolator.ts rename to src/math/TimeInterpolator.ts diff --git a/src/engine/math/Triangle.ts b/src/math/Triangle.ts similarity index 100% rename from src/engine/math/Triangle.ts rename to src/math/Triangle.ts diff --git a/src/engine/math/UV.ts b/src/math/UV.ts similarity index 100% rename from src/engine/math/UV.ts rename to src/math/UV.ts diff --git a/src/engine/math/Vector2.ts b/src/math/Vector2.ts similarity index 100% rename from src/engine/math/Vector2.ts rename to src/math/Vector2.ts diff --git a/src/engine/math/Vector3.ts b/src/math/Vector3.ts similarity index 99% rename from src/engine/math/Vector3.ts rename to src/math/Vector3.ts index a2f6cc4d..e5bcb71a 100644 --- a/src/engine/math/Vector3.ts +++ b/src/math/Vector3.ts @@ -178,7 +178,7 @@ export class Vector3 { /** - * Creates an instance of a Vector3 object. If you do not specify a。 + * Creates an instance of a Vector3 object. If you do not specify a. * parameter for the constructor, a Vector3 object is created with * the elements (0,0,0,0). * diff --git a/src/engine/math/Vector4.ts b/src/math/Vector4.ts similarity index 100% rename from src/engine/math/Vector4.ts rename to src/math/Vector4.ts diff --git a/src/sample/index.ts b/src/sample/index.ts deleted file mode 100644 index 62bd094f..00000000 --- a/src/sample/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -/******** Load all samples in /src/sample/ ********/ -function Menu() { - // load all modules in /sample - const modules = import.meta.glob(['./*/*.ts', '!./*/_*.ts']) - // create menu - let title = '', list = '' - for (const path in modules) { - const arr = path.split('/') - let _title = arr[1] - let _demo = arr[2].replace(/Sample_|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) => { - let button = e.target as HTMLElement - if (!button.id) - return - // remove prev iframe to clear memory - document.querySelector('iframe')?.remove() - let 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) { - let target = sessionStorage.target - let a = document.querySelector(`[id="${target}"]`) - if (a) { - addIframe() - a.classList.add('active') - menu.scrollTop = sessionStorage.top - } - } else { - document.querySelector('a')?.click() - } - - // create an iframe inside page to load sample - function addIframe() { - const iframe = document.createElement('iframe') as HTMLIFrameElement - iframe.srcdoc = ` - - ` - document.body.appendChild(iframe) - } -} -Menu() - -// auto update index.ts, import all exports from /src/engine/ -const modules = import.meta.glob(['../engine/**/*.ts', '!../engine/**/*-back.ts', '!../engine/**/_*.ts']) -let content = '' -for (let path in modules) - content += `export * from "${path.slice(1, -3)}"\r\n` -import.meta.hot!.send('autoIndex', { content }) \ No newline at end of file diff --git a/src/engine/setting/EngineSetting.ts b/src/setting/EngineSetting.ts similarity index 100% rename from src/engine/setting/EngineSetting.ts rename to src/setting/EngineSetting.ts diff --git a/src/engine/setting/GlobalIlluminationSetting.ts b/src/setting/GlobalIlluminationSetting.ts similarity index 100% rename from src/engine/setting/GlobalIlluminationSetting.ts rename to src/setting/GlobalIlluminationSetting.ts diff --git a/src/engine/setting/LightSetting.ts b/src/setting/LightSetting.ts similarity index 100% rename from src/engine/setting/LightSetting.ts rename to src/setting/LightSetting.ts diff --git a/src/engine/setting/MaterialSetting.ts b/src/setting/MaterialSetting.ts similarity index 100% rename from src/engine/setting/MaterialSetting.ts rename to src/setting/MaterialSetting.ts diff --git a/src/engine/setting/OcclusionQuerySetting.ts b/src/setting/OcclusionQuerySetting.ts similarity index 100% rename from src/engine/setting/OcclusionQuerySetting.ts rename to src/setting/OcclusionQuerySetting.ts diff --git a/src/engine/setting/PickSetting.ts b/src/setting/PickSetting.ts similarity index 100% rename from src/engine/setting/PickSetting.ts rename to src/setting/PickSetting.ts diff --git a/src/engine/setting/RenderSetting.ts b/src/setting/RenderSetting.ts similarity index 100% rename from src/engine/setting/RenderSetting.ts rename to src/setting/RenderSetting.ts diff --git a/src/engine/setting/ShadowSetting.ts b/src/setting/ShadowSetting.ts similarity index 100% rename from src/engine/setting/ShadowSetting.ts rename to src/setting/ShadowSetting.ts diff --git a/src/engine/setting/SkySetting.ts b/src/setting/SkySetting.ts similarity index 100% rename from src/engine/setting/SkySetting.ts rename to src/setting/SkySetting.ts diff --git a/src/engine/setting/post/BloomSetting.ts b/src/setting/post/BloomSetting.ts similarity index 100% rename from src/engine/setting/post/BloomSetting.ts rename to src/setting/post/BloomSetting.ts diff --git a/src/engine/setting/post/DepthOfViewSetting.ts b/src/setting/post/DepthOfViewSetting.ts similarity index 100% rename from src/engine/setting/post/DepthOfViewSetting.ts rename to src/setting/post/DepthOfViewSetting.ts diff --git a/src/engine/setting/post/GTAOSetting.ts b/src/setting/post/GTAOSetting.ts similarity index 88% rename from src/engine/setting/post/GTAOSetting.ts rename to src/setting/post/GTAOSetting.ts index a851ea5e..5af9f1de 100644 --- a/src/engine/setting/post/GTAOSetting.ts +++ b/src/setting/post/GTAOSetting.ts @@ -26,7 +26,7 @@ export type GTAOSetting = { */ multiBounce: boolean; /** - * true:Calculate the position value of GBuffer using f32 to obtain more accurate values (water and other effects may not be supported) + * true: Calculate the position value of GBuffer using f32 to obtain more accurate values (water and other effects may not be supported) * false: We will use the position value of GBuffer in f16 for operations, with a wider coverage */ usePosFloat32: boolean; diff --git a/src/engine/setting/post/GlobalFogSetting.ts b/src/setting/post/GlobalFogSetting.ts similarity index 95% rename from src/engine/setting/post/GlobalFogSetting.ts rename to src/setting/post/GlobalFogSetting.ts index 9031b10a..fbae4be5 100644 --- a/src/engine/setting/post/GlobalFogSetting.ts +++ b/src/setting/post/GlobalFogSetting.ts @@ -12,7 +12,7 @@ export type GlobalFogSetting = { enable: boolean; /** * type of fog: - * 0: linear exponent 2:squar exponent + * 0: linear exponent 2: squar exponent */ fogType: number; /** diff --git a/src/engine/setting/post/OutlineSetting.ts b/src/setting/post/OutlineSetting.ts similarity index 100% rename from src/engine/setting/post/OutlineSetting.ts rename to src/setting/post/OutlineSetting.ts diff --git a/src/engine/setting/post/SSRSetting.ts b/src/setting/post/SSRSetting.ts similarity index 100% rename from src/engine/setting/post/SSRSetting.ts rename to src/setting/post/SSRSetting.ts diff --git a/src/engine/setting/post/TAASetting.ts b/src/setting/post/TAASetting.ts similarity index 100% rename from src/engine/setting/post/TAASetting.ts rename to src/setting/post/TAASetting.ts diff --git a/src/engine/shape/BoxGeometry.ts b/src/shape/BoxGeometry.ts similarity index 100% rename from src/engine/shape/BoxGeometry.ts rename to src/shape/BoxGeometry.ts diff --git a/src/engine/shape/CylinderGeometry.ts b/src/shape/CylinderGeometry.ts similarity index 100% rename from src/engine/shape/CylinderGeometry.ts rename to src/shape/CylinderGeometry.ts diff --git a/src/engine/shape/PlaneGeometry.ts b/src/shape/PlaneGeometry.ts similarity index 100% rename from src/engine/shape/PlaneGeometry.ts rename to src/shape/PlaneGeometry.ts diff --git a/src/engine/shape/SphereGeometry.ts b/src/shape/SphereGeometry.ts similarity index 100% rename from src/engine/shape/SphereGeometry.ts rename to src/shape/SphereGeometry.ts diff --git a/src/engine/shape/TorusGeometry.ts b/src/shape/TorusGeometry.ts similarity index 97% rename from src/engine/shape/TorusGeometry.ts rename to src/shape/TorusGeometry.ts index 77965607..8e516f61 100644 --- a/src/engine/shape/TorusGeometry.ts +++ b/src/shape/TorusGeometry.ts @@ -32,9 +32,9 @@ export class TorusGeometry extends GeometryBase { * * @constructor * @param radius {number} Radius of torus, default value is 0.4 - * @param tube {number} Pipe radius, default value is 0.1。 - * @param radialSegments {number}Number of torus segments, default value is 32。 - * @param tubularSegments {number} Number of pipeline segments, defualt value is 32。 + * @param tube {number} Pipe radius, default value is 0.1. + * @param radialSegments {number}Number of torus segments, default value is 32. + * @param tubularSegments {number} Number of pipeline segments, defualt value is 32. */ constructor(radius: number = 0.4, tube: number = 0.1, radialSegments: number = 32, tubularSegments: number = 32) { super(); diff --git a/src/engine/textures/AtmosphericScatteringSky.ts b/src/textures/AtmosphericScatteringSky.ts similarity index 100% rename from src/engine/textures/AtmosphericScatteringSky.ts rename to src/textures/AtmosphericScatteringSky.ts diff --git a/src/engine/textures/BitmapTexture2D.ts b/src/textures/BitmapTexture2D.ts similarity index 100% rename from src/engine/textures/BitmapTexture2D.ts rename to src/textures/BitmapTexture2D.ts index 93814633..abb0070d 100644 --- a/src/engine/textures/BitmapTexture2D.ts +++ b/src/textures/BitmapTexture2D.ts @@ -1,8 +1,8 @@ -import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { GPUTextureFormat } from '../gfx/graphics/webGpu/WebGPUConst'; import { LoaderBase } from '../loader/LoaderBase'; import { LoaderFunctions } from '../loader/LoaderFunctions'; import { StringUtil } from '../util/StringUtil'; +import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; /** * bitmap texture diff --git a/src/engine/textures/BitmapTexture2DArray.ts b/src/textures/BitmapTexture2DArray.ts similarity index 99% rename from src/engine/textures/BitmapTexture2DArray.ts rename to src/textures/BitmapTexture2DArray.ts index fb9d4773..db0bebfc 100644 --- a/src/engine/textures/BitmapTexture2DArray.ts +++ b/src/textures/BitmapTexture2DArray.ts @@ -1,9 +1,10 @@ import { GPUFilterMode, GPUTextureFormat } from '../gfx/graphics/webGpu/WebGPUConst'; -import { webGPUContext } from '../gfx/graphics/webGpu/Context3D'; -import { ITexture } from '../gfx/graphics/webGpu/core/texture/ITexture'; -import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; + import { BitmapTexture2D } from './BitmapTexture2D'; import { GPUContext } from '../gfx/renderJob/GPUContext'; +import { ITexture } from '../gfx/graphics/webGpu/core/texture/ITexture'; +import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; +import { webGPUContext } from '../gfx/graphics/webGpu/Context3D'; /** * Type BitmapTexture 2D Array , Use in GPU diff --git a/src/engine/textures/BitmapTextureCube.ts b/src/textures/BitmapTextureCube.ts similarity index 100% rename from src/engine/textures/BitmapTextureCube.ts rename to src/textures/BitmapTextureCube.ts diff --git a/src/engine/textures/Depth2DTextureArray.ts b/src/textures/Depth2DTextureArray.ts similarity index 100% rename from src/engine/textures/Depth2DTextureArray.ts rename to src/textures/Depth2DTextureArray.ts diff --git a/src/engine/textures/DepthCubeArrayTexture.ts b/src/textures/DepthCubeArrayTexture.ts similarity index 100% rename from src/engine/textures/DepthCubeArrayTexture.ts rename to src/textures/DepthCubeArrayTexture.ts diff --git a/src/engine/textures/DepthCubeTexture.ts b/src/textures/DepthCubeTexture.ts similarity index 100% rename from src/engine/textures/DepthCubeTexture.ts rename to src/textures/DepthCubeTexture.ts diff --git a/src/engine/textures/Float16ArrayTexture.ts b/src/textures/Float16ArrayTexture.ts similarity index 100% rename from src/engine/textures/Float16ArrayTexture.ts rename to src/textures/Float16ArrayTexture.ts diff --git a/src/engine/textures/Float32ArrayTexture.ts b/src/textures/Float32ArrayTexture.ts similarity index 100% rename from src/engine/textures/Float32ArrayTexture.ts rename to src/textures/Float32ArrayTexture.ts diff --git a/src/engine/textures/HDRTexture.ts b/src/textures/HDRTexture.ts similarity index 100% rename from src/engine/textures/HDRTexture.ts rename to src/textures/HDRTexture.ts diff --git a/src/engine/textures/HDRTextureCube.ts b/src/textures/HDRTextureCube.ts similarity index 100% rename from src/engine/textures/HDRTextureCube.ts rename to src/textures/HDRTextureCube.ts diff --git a/src/engine/textures/LDRTextureCube.ts b/src/textures/LDRTextureCube.ts similarity index 98% rename from src/engine/textures/LDRTextureCube.ts rename to src/textures/LDRTextureCube.ts index 87978e2f..575becb1 100644 --- a/src/engine/textures/LDRTextureCube.ts +++ b/src/textures/LDRTextureCube.ts @@ -8,7 +8,7 @@ import { LoaderFunctions } from "../loader/LoaderFunctions"; import { BitmapTexture2D } from "./BitmapTexture2D"; /** - * LDRTextureCube : create a cube texture, it's low dynamic range texture + * LDRTextureCube: create a cube texture, it's low dynamic range texture * @group Texture */ export class LDRTextureCube extends TextureCube { diff --git a/src/engine/textures/SolidColorSky.ts b/src/textures/SolidColorSky.ts similarity index 81% rename from src/engine/textures/SolidColorSky.ts rename to src/textures/SolidColorSky.ts index bbf4f56e..55db9b36 100644 --- a/src/engine/textures/SolidColorSky.ts +++ b/src/textures/SolidColorSky.ts @@ -1,5 +1,6 @@ +import { Engine3D } from '../Engine3D'; import { Color } from '../math/Color'; -import { defaultRes } from './DefaultRes'; + import { Float16ArrayTexture } from './Float16ArrayTexture'; import { HDRTextureCube } from './HDRTextureCube'; @@ -23,7 +24,7 @@ export class SolidColorSky extends HDRTextureCube { this._skyColor = color; this._internalTexture = new Float16ArrayTexture(); let numbers = []; - defaultRes.fillColor(numbers, this._minSize, this._minSize, this.color.r, this.color.g, this.color.b, this.color.a); + Engine3D.res.fillColor(numbers, this._minSize, this._minSize, this.color.r, this.color.g, this.color.b, this.color.a); this._internalTexture.create(this._minSize, this._minSize, numbers, false); this.createFromTexture(this._minSize, this._internalTexture); return this; @@ -31,7 +32,7 @@ export class SolidColorSky extends HDRTextureCube { private changeColor(color: Color): this { this._skyColor = color; - defaultRes.fillColor(this._internalTexture.floatArray, this._minSize, this._minSize, this.color.r, this.color.g, this.color.b, this.color.a); + Engine3D.res.fillColor(this._internalTexture.floatArray, this._minSize, this._minSize, this.color.r, this.color.g, this.color.b, this.color.a); this._internalTexture.updateTexture(this._minSize, this._minSize, this._internalTexture.floatArray, false); this.uploadTexture(0, this._internalTexture); return this; diff --git a/src/engine/textures/Uint16Texture.ts b/src/textures/Uint16Texture.ts similarity index 100% rename from src/engine/textures/Uint16Texture.ts rename to src/textures/Uint16Texture.ts diff --git a/src/engine/textures/Uint8ArrayTexture.ts b/src/textures/Uint8ArrayTexture.ts similarity index 100% rename from src/engine/textures/Uint8ArrayTexture.ts rename to src/textures/Uint8ArrayTexture.ts diff --git a/src/engine/textures/VirtualTexture.ts b/src/textures/VirtualTexture.ts similarity index 100% rename from src/engine/textures/VirtualTexture.ts rename to src/textures/VirtualTexture.ts diff --git a/src/engine/util/AxisObject.ts b/src/util/AxisObject.ts similarity index 97% rename from src/engine/util/AxisObject.ts rename to src/util/AxisObject.ts index 841a8928..759b87c7 100644 --- a/src/engine/util/AxisObject.ts +++ b/src/util/AxisObject.ts @@ -5,7 +5,7 @@ import { UnLitMaterial } from '../materials/UnLitMaterial'; import { Color } from '../math/Color'; import { Vector3 } from '../math/Vector3'; import { BoxGeometry } from '../shape/BoxGeometry'; -import { defaultRes } from '../textures/DefaultRes'; + /** * @internal diff --git a/src/engine/util/BytesStream.ts b/src/util/BytesStream.ts similarity index 100% rename from src/engine/util/BytesStream.ts rename to src/util/BytesStream.ts diff --git a/src/engine/util/CameraUtil.ts b/src/util/CameraUtil.ts similarity index 100% rename from src/engine/util/CameraUtil.ts rename to src/util/CameraUtil.ts diff --git a/src/engine/util/Convert.ts b/src/util/Convert.ts similarity index 100% rename from src/engine/util/Convert.ts rename to src/util/Convert.ts diff --git a/src/engine/util/GeometryUtil.ts b/src/util/GeometryUtil.ts similarity index 100% rename from src/engine/util/GeometryUtil.ts rename to src/util/GeometryUtil.ts diff --git a/src/engine/util/Global.ts b/src/util/Global.ts similarity index 100% rename from src/engine/util/Global.ts rename to src/util/Global.ts diff --git a/src/engine/util/KelvinUtil.ts b/src/util/KelvinUtil.ts similarity index 100% rename from src/engine/util/KelvinUtil.ts rename to src/util/KelvinUtil.ts diff --git a/src/engine/util/Object3DUtil.ts b/src/util/Object3DUtil.ts similarity index 100% rename from src/engine/util/Object3DUtil.ts rename to src/util/Object3DUtil.ts diff --git a/src/engine/util/ProfilerUtil.ts b/src/util/ProfilerUtil.ts similarity index 100% rename from src/engine/util/ProfilerUtil.ts rename to src/util/ProfilerUtil.ts diff --git a/src/engine/util/StringUtil.ts b/src/util/StringUtil.ts similarity index 100% rename from src/engine/util/StringUtil.ts rename to src/util/StringUtil.ts diff --git a/src/engine/util/Time.ts b/src/util/Time.ts similarity index 100% rename from src/engine/util/Time.ts rename to src/util/Time.ts diff --git a/src/engine/util/Vector3Ex.ts b/src/util/Vector3Ex.ts similarity index 100% rename from src/engine/util/Vector3Ex.ts rename to src/util/Vector3Ex.ts diff --git a/src/engine/util/ZSorterUtil.ts b/src/util/ZSorterUtil.ts similarity index 97% rename from src/engine/util/ZSorterUtil.ts rename to src/util/ZSorterUtil.ts index f57dcb4f..326bf53d 100644 --- a/src/engine/util/ZSorterUtil.ts +++ b/src/util/ZSorterUtil.ts @@ -61,4 +61,4 @@ export class ZSorterUtil { } } -export let zSorterUtil: ZSorterUtil = new ZSorterUtil(); +// export let zSorterUtil: ZSorterUtil = new ZSorterUtil(); diff --git a/src/engine/util/struct/Struct.ts b/src/util/struct/Struct.ts similarity index 100% rename from src/engine/util/struct/Struct.ts rename to src/util/struct/Struct.ts diff --git a/src/engine/util/struct/StructValue.ts b/src/util/struct/StructValue.ts similarity index 100% rename from src/engine/util/struct/StructValue.ts rename to src/util/struct/StructValue.ts diff --git a/src/engine/util/struct/Vector3Struct.ts b/src/util/struct/Vector3Struct.ts similarity index 100% rename from src/engine/util/struct/Vector3Struct.ts rename to src/util/struct/Vector3Struct.ts diff --git a/test/base/base.test.ts b/test/base/base.test.ts index c6596f19..fed99653 100644 --- a/test/base/base.test.ts +++ b/test/base/base.test.ts @@ -1,8 +1,7 @@ -import * as Orillusion from '../../src'; import { test, end } from '../util' await test('Init', async () => { - console.log(Orillusion) + // console.log(Orillusion) }) setTimeout(end, 500) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index f5e65983..38cccccf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "noEmit": true, "rootDir": "./", "baseUrl": "./", + "outDir": "./js", "paths": { "../*": ["src/*"], "@orillusion/*": ["src/libs/*"], @@ -24,6 +25,6 @@ "allowJs": true, "strict": false }, - "include": ["src", "test"], + "include": ["src", "test", "sample"], "exclude": ["node_modules", "dist", "public"] } \ No newline at end of file