From 3a1d326e66981d82415ae6b28a1ba4bd930687d7 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 3 Mar 2023 18:20:16 +0800 Subject: [PATCH 01/62] refactor: opt code --- packages/core/src/Camera.ts | 22 ++++++++++++++ .../core/src/RenderPipeline/RenderPass.ts | 2 +- packages/core/src/shader/SubShader.ts | 30 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/shader/SubShader.ts diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index b82ae00e4a..d166182cce 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -66,6 +66,10 @@ export class Camera extends Component { /** @internal */ @ignoreClone _virtualCamera: VirtualCamera = new VirtualCamera(); + /** @internal */ + _replacementShader: Shader = null; + /** @internal */ + _replacementSubShaderTag: string = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -468,6 +472,24 @@ export class Camera extends Component { this._engine._renderCount++; } + /** + * Set the replacement shader. + * @param shader - Replacement shader + * @param subShaderTag - Replacement sub shader tag + */ + setReplacementShader(shader: Shader, subShaderTag: string): void { + this._replacementShader = shader; + this._replacementSubShaderTag = subShaderTag; + } + + /** + * Reset the replacement shader. + */ + resetReplacementShader(): void { + this._replacementShader = null; + this._replacementSubShaderTag = null; + } + /** * @override * @inheritdoc diff --git a/packages/core/src/RenderPipeline/RenderPass.ts b/packages/core/src/RenderPipeline/RenderPass.ts index 3812843cf8..529028b15b 100644 --- a/packages/core/src/RenderPipeline/RenderPass.ts +++ b/packages/core/src/RenderPipeline/RenderPass.ts @@ -27,7 +27,7 @@ class RenderPass { * @param name - Pass name * @param priority - Priority, less than 0 before the default pass, greater than 0 after the default pass * @param renderTarget - The specified Render Target - * @param replaceMaterial - Replaced material + * @param replaceMaterial - Replaced material * @param mask - Perform bit and operations with Entity.Layer to filter the objects that this Pass needs to render */ constructor( diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts new file mode 100644 index 0000000000..778dc88260 --- /dev/null +++ b/packages/core/src/shader/SubShader.ts @@ -0,0 +1,30 @@ +import { ShaderPass } from "./ShaderPass"; + +/** + * Sub shader. + */ +export class SubShader { + private _tags: Record = {}; + private _passes: ShaderPass[] = []; + + /** + * Shader passes. + */ + get passes(): ReadonlyArray { + return this._passes; + } + + /** + * Add a tag. + * @param name - Name of the tag + * @param value - Value of the tag + */ + addTag(name: string, value: string): void { + const tags = this._tags; + if (tags[name]) { + throw `Tag named "${name}" already exists.`; + } + + tags[name] = value; + } +} From ce6e42373a4adf8ff21b0549e7c6ef2dce4c8895 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sun, 5 Mar 2023 22:36:09 +0800 Subject: [PATCH 02/62] refactor: opt code --- .../src/2d/assembler/SimpleSpriteAssembler.ts | 6 +- .../src/2d/assembler/SlicedSpriteAssembler.ts | 6 +- .../data/{RenderData2D.ts => VertexData2D.ts} | 2 +- packages/core/src/2d/sprite/SpriteMask.ts | 24 +++--- packages/core/src/2d/sprite/SpriteRenderer.ts | 20 ++--- packages/core/src/2d/text/CharRenderData.ts | 6 +- packages/core/src/2d/text/TextRenderer.ts | 31 +++---- packages/core/src/Camera.ts | 6 +- packages/core/src/Engine.ts | 27 +++--- .../core/src/RenderPipeline/Basic2DBatcher.ts | 50 ++++++----- .../src/RenderPipeline/BasicRenderPipeline.ts | 83 +++++++++++++++---- .../core/src/RenderPipeline/MeshRenderData.ts | 23 +++++ .../src/RenderPipeline/MeshRenderElement.ts | 33 -------- .../core/src/RenderPipeline/RenderContext.ts | 4 + .../core/src/RenderPipeline/RenderData.ts | 9 ++ .../core/src/RenderPipeline/RenderElement.ts | 19 +++-- .../core/src/RenderPipeline/RenderQueue.ts | 35 +++----- .../core/src/RenderPipeline/SpriteBatcher.ts | 31 +++---- .../core/src/RenderPipeline/SpriteElement.ts | 36 -------- .../src/RenderPipeline/SpriteMaskBatcher.ts | 27 +++--- .../src/RenderPipeline/SpriteMaskManager.ts | 5 +- ...MaskElement.ts => SpriteMaskRenderData.ts} | 13 +-- .../src/RenderPipeline/SpriteRenderData.ts | 31 +++++++ .../core/src/RenderPipeline/TextRenderData.ts | 11 +++ .../src/RenderPipeline/TextRenderElement.ts | 11 --- packages/core/src/graphic/Mesh.ts | 6 +- packages/core/src/index.ts | 2 - packages/core/src/material/BaseMaterial.ts | 15 +--- packages/core/src/material/Material.ts | 21 ++--- packages/core/src/mesh/MeshRenderer.ts | 15 ++-- packages/core/src/shader/Shader.ts | 55 ++++++------ packages/core/src/shader/ShaderPass.ts | 3 + packages/core/src/shader/SubShader.ts | 35 ++++++-- .../src/shadow/CascadedShadowCasterPass.ts | 5 +- packages/core/src/sky/Sky.ts | 2 +- 35 files changed, 391 insertions(+), 317 deletions(-) rename packages/core/src/2d/data/{RenderData2D.ts => VertexData2D.ts} (90%) create mode 100644 packages/core/src/RenderPipeline/MeshRenderData.ts delete mode 100644 packages/core/src/RenderPipeline/MeshRenderElement.ts create mode 100644 packages/core/src/RenderPipeline/RenderData.ts delete mode 100644 packages/core/src/RenderPipeline/SpriteElement.ts rename packages/core/src/RenderPipeline/{SpriteMaskElement.ts => SpriteMaskRenderData.ts} (51%) create mode 100644 packages/core/src/RenderPipeline/SpriteRenderData.ts create mode 100644 packages/core/src/RenderPipeline/TextRenderData.ts delete mode 100644 packages/core/src/RenderPipeline/TextRenderElement.ts diff --git a/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts b/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts index 468d00c96a..9df7ffa9b3 100644 --- a/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts +++ b/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts @@ -13,7 +13,7 @@ export class SimpleSpriteAssembler { static _worldMatrix: Matrix = new Matrix(); static resetData(renderer: SpriteRenderer | SpriteMask): void { - const { _renderData: renderData } = renderer; + const { _verticesData: renderData } = renderer; const vertexCount = (renderData.vertexCount = 4); const { positions, uvs } = renderData; if (positions.length < vertexCount) { @@ -49,7 +49,7 @@ export class SimpleSpriteAssembler { // --------------- // Update positions. const spritePositions = sprite._getPositions(); - const { positions } = renderer._renderData; + const { positions } = renderer._verticesData; for (let i = 0; i < 4; i++) { const { x, y } = spritePositions[i]; positions[i].set(wE[0] * x + wE[4] * y + wE[12], wE[1] * x + wE[5] * y + wE[13], wE[2] * x + wE[6] * y + wE[14]); @@ -60,7 +60,7 @@ export class SimpleSpriteAssembler { static updateUVs(renderer: SpriteRenderer | SpriteMask): void { const spriteUVs = renderer.sprite._getUVs(); - const renderUVs = renderer._renderData.uvs; + const renderUVs = renderer._verticesData.uvs; const { x: left, y: bottom } = spriteUVs[0]; const { x: right, y: top } = spriteUVs[3]; renderUVs[0].set(left, bottom); diff --git a/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts b/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts index 91f38968a4..e82b84d745 100644 --- a/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts +++ b/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts @@ -10,7 +10,7 @@ import { IAssembler } from "./IAssembler"; export class SlicedSpriteAssembler { static _worldMatrix: Matrix = new Matrix(); static resetData(renderer: SpriteRenderer): void { - const { _renderData: renderData } = renderer; + const { _verticesData: renderData } = renderer; const { positions, uvs } = renderData; if (positions.length < 16) { for (let i = positions.length; i < 16; i++) { @@ -23,7 +23,7 @@ export class SlicedSpriteAssembler { static updatePositions(renderer: SpriteRenderer): void { const { width, height, sprite } = renderer; - const { positions, uvs, triangles } = renderer._renderData; + const { positions, uvs, triangles } = renderer._verticesData; const { border } = sprite; const spriteUVs = sprite._getUVs(); // Update local positions. @@ -131,7 +131,7 @@ export class SlicedSpriteAssembler { triangles[indexOffset++] = start + realJCount; } } - renderer._renderData.vertexCount = realICount * realJCount; + renderer._verticesData.vertexCount = realICount * realJCount; triangles.length = (realICount - 1) * (realJCount - 1) * 6; const { min, max } = renderer._bounds; diff --git a/packages/core/src/2d/data/RenderData2D.ts b/packages/core/src/2d/data/VertexData2D.ts similarity index 90% rename from packages/core/src/2d/data/RenderData2D.ts rename to packages/core/src/2d/data/VertexData2D.ts index 13e3aeb684..c6e3dd891f 100644 --- a/packages/core/src/2d/data/RenderData2D.ts +++ b/packages/core/src/2d/data/VertexData2D.ts @@ -3,7 +3,7 @@ import { Color, Vector2, Vector3 } from "@oasis-engine/math"; /** * @internal */ -export class RenderData2D { +export class VertexData2D { constructor( public vertexCount: number, public positions: Vector3[], diff --git a/packages/core/src/2d/sprite/SpriteMask.ts b/packages/core/src/2d/sprite/SpriteMask.ts index b006d20278..667a4f5883 100644 --- a/packages/core/src/2d/sprite/SpriteMask.ts +++ b/packages/core/src/2d/sprite/SpriteMask.ts @@ -4,11 +4,11 @@ import { ICustomClone } from "../../clone/ComponentCloner"; import { Entity } from "../../Entity"; import { Renderer, RendererUpdateFlags } from "../../Renderer"; import { RenderContext } from "../../RenderPipeline/RenderContext"; -import { SpriteMaskElement } from "../../RenderPipeline/SpriteMaskElement"; +import { RenderElement } from "../../RenderPipeline/RenderElement"; import { Shader } from "../../shader/Shader"; import { ShaderProperty } from "../../shader/ShaderProperty"; import { SimpleSpriteAssembler } from "../assembler/SimpleSpriteAssembler"; -import { RenderData2D } from "../data/RenderData2D"; +import { VertexData2D } from "../data/VertexData2D"; import { SpriteMaskLayer } from "../enums/SpriteMaskLayer"; import { SpriteModifyFlags } from "../enums/SpriteModifyFlags"; import { Sprite } from "./Sprite"; @@ -26,10 +26,10 @@ export class SpriteMask extends Renderer implements ICustomClone { @assignmentClone influenceLayers: number = SpriteMaskLayer.Everything; /** @internal */ - _maskElement: SpriteMaskElement; + _maskElement: RenderElement; /** @internal */ - _renderData: RenderData2D; + _verticesData: VertexData2D; @ignoreClone private _sprite: Sprite = null; @@ -149,7 +149,7 @@ export class SpriteMask extends Renderer implements ICustomClone { */ constructor(entity: Entity) { super(entity); - this._renderData = new RenderData2D(4, [], []); + this._verticesData = new VertexData2D(4, [], []); SimpleSpriteAssembler.resetData(this); this.setMaterial(this._engine._spriteMaskDefaultMaterial); this.shaderData.setFloat(SpriteMask._alphaCutoffProperty, this._alphaCutoff); @@ -163,7 +163,7 @@ export class SpriteMask extends Renderer implements ICustomClone { _onDestroy(): void { this._sprite?._updateFlagManager.removeListener(this._onSpriteChange); this._sprite = null; - this._renderData = null; + this._verticesData = null; super._onDestroy(); } @@ -207,11 +207,15 @@ export class SpriteMask extends Renderer implements ICustomClone { this._dirtyUpdateFlag &= ~SpriteMaskUpdateFlags.UV; } - const spriteMaskElementPool = this._engine._spriteMaskElementPool; - const maskElement = spriteMaskElementPool.getFromPool(); - maskElement.setValue(this, this._renderData, this.getMaterial()); context.camera._renderPipeline._allSpriteMasks.add(this); - this._maskElement = maskElement; + + const renderData = this._engine._spriteMaskRenderDataPool.getFromPool(); + const material = this.getMaterial(); + renderData.setValue(this, material, this._verticesData); + + const renderElement = this._engine._renderElementPool.getFromPool(); + renderElement.set(renderData, material.shader[0].shaderPasses[0], material.renderStates[0]); + this._maskElement = renderElement; } @ignoreClone diff --git a/packages/core/src/2d/sprite/SpriteRenderer.ts b/packages/core/src/2d/sprite/SpriteRenderer.ts index e7b78082ec..1b1ff14182 100644 --- a/packages/core/src/2d/sprite/SpriteRenderer.ts +++ b/packages/core/src/2d/sprite/SpriteRenderer.ts @@ -10,7 +10,7 @@ import { ShaderProperty } from "../../shader/ShaderProperty"; import { IAssembler } from "../assembler/IAssembler"; import { SimpleSpriteAssembler } from "../assembler/SimpleSpriteAssembler"; import { SlicedSpriteAssembler } from "../assembler/SlicedSpriteAssembler"; -import { RenderData2D } from "../data/RenderData2D"; +import { VertexData2D } from "../data/VertexData2D"; import { SpriteDrawMode } from "../enums/SpriteDrawMode"; import { SpriteMaskInteraction } from "../enums/SpriteMaskInteraction"; import { SpriteMaskLayer } from "../enums/SpriteMaskLayer"; @@ -26,7 +26,7 @@ export class SpriteRenderer extends Renderer implements ICustomClone { /** @internal */ @ignoreClone - _renderData: RenderData2D; + _verticesData: VertexData2D; @ignoreClone private _drawMode: SpriteDrawMode; @@ -205,7 +205,7 @@ export class SpriteRenderer extends Renderer implements ICustomClone { */ constructor(entity: Entity) { super(entity); - this._renderData = new RenderData2D(4, [], [], null, this._color); + this._verticesData = new VertexData2D(4, [], [], null, this._color); this.drawMode = SpriteDrawMode.Simple; this.setMaterial(this._engine._spriteDefaultMaterial); this._onSpriteChange = this._onSpriteChange.bind(this); @@ -226,7 +226,7 @@ export class SpriteRenderer extends Renderer implements ICustomClone { this._color = null; this._sprite = null; this._assembler = null; - this._renderData = null; + this._verticesData = null; super._onDestroy(); } @@ -262,16 +262,12 @@ export class SpriteRenderer extends Renderer implements ICustomClone { this._dirtyUpdateFlag &= ~SpriteRendererUpdateFlags.UV; } - // Push primitive. + // Push render data const material = this.getMaterial(); - const passes = material.shader.passes; - const renderStates = material.renderStates; const texture = this.sprite.texture; - for (let i = 0, n = passes.length; i < n; i++) { - const spriteElement = this._engine._spriteElementPool.getFromPool(); - spriteElement.setValue(this, this._renderData, material, texture, renderStates[i], passes[i]); - context.camera._renderPipeline.pushPrimitive(spriteElement); - } + const renderData = this._engine._spriteRenderDataPool.getFromPool(); + renderData.set(this, material, this._verticesData, texture); + context.camera._renderPipeline.pushRenderData(context, renderData); } private _updateStencilState(): void { diff --git a/packages/core/src/2d/text/CharRenderData.ts b/packages/core/src/2d/text/CharRenderData.ts index 884550ae12..3ae4d17a47 100644 --- a/packages/core/src/2d/text/CharRenderData.ts +++ b/packages/core/src/2d/text/CharRenderData.ts @@ -1,6 +1,6 @@ import { Vector3, Vector4 } from "@oasis-engine/math"; import { Texture2D } from "../../texture"; -import { RenderData2D } from "../data/RenderData2D"; +import { VertexData2D } from "../data/VertexData2D"; /** * @internal @@ -11,10 +11,10 @@ export class CharRenderData { texture: Texture2D; /** x:Top y:Left z:Bottom w:Right */ localPositions: Vector4 = new Vector4(); - renderData: RenderData2D; + renderData: VertexData2D; constructor() { const positions = [new Vector3(), new Vector3(), new Vector3(), new Vector3()]; - this.renderData = new RenderData2D(4, positions, null, CharRenderData.triangles, null); + this.renderData = new VertexData2D(4, positions, null, CharRenderData.triangles, null); } } diff --git a/packages/core/src/2d/text/TextRenderer.ts b/packages/core/src/2d/text/TextRenderer.ts index faa40c9d7f..3ceaa2b72e 100644 --- a/packages/core/src/2d/text/TextRenderer.ts +++ b/packages/core/src/2d/text/TextRenderer.ts @@ -5,6 +5,7 @@ import { Engine } from "../../Engine"; import { Entity } from "../../Entity"; import { Renderer } from "../../Renderer"; import { RenderContext } from "../../RenderPipeline/RenderContext"; +import { SpriteRenderData } from "../../RenderPipeline/SpriteRenderData"; import { CompareFunction } from "../../shader/enums/CompareFunction"; import { TransformModifyFlags } from "../../Transform"; import { FontStyle } from "../enums/FontStyle"; @@ -66,6 +67,9 @@ export class TextRenderer extends Renderer implements ICustomClone { @assignmentClone private _maskLayer: number = SpriteMaskLayer.Layer0; + @ignoreClone + private _charsRenderData: SpriteRenderData[] = []; + /** * Rendering color for the Text. */ @@ -379,35 +383,24 @@ export class TextRenderer extends Renderer implements ICustomClone { this._setDirtyFlagFalse(DirtyFlag.WorldPosition); } - const spriteElementPool = this._engine._spriteElementPool; - const textElement = this._engine._textElementPool.getFromPool(); - const charElements = textElement.charElements; + const spriteRenderDataPool = this._engine._spriteRenderDataPool; + const textElement = this._engine._textRenderDataPool.getFromPool(); + const charsData = textElement.charsData; const material = this.getMaterial(); const charRenderDatas = this._charRenderDatas; const charCount = charRenderDatas.length; - const passes = material.shader.passes; - const renderStates = material.renderStates; textElement.component = this; textElement.material = material; - charElements.length = charCount; - textElement.renderState = renderStates[0]; + charsData.length = charCount; for (let i = 0; i < charCount; ++i) { const charRenderData = charRenderDatas[i]; - const spriteElement = spriteElementPool.getFromPool(); - spriteElement.setValue( - this, - charRenderData.renderData, - material, - charRenderData.texture, - renderStates[0], - passes[0], - i - ); - charElements[i] = spriteElement; + const spriteRenderData = spriteRenderDataPool.getFromPool(); + spriteRenderData.set(this, material, charRenderData.renderData, charRenderData.texture, i); + charsData[i] = spriteRenderData; } - context.camera._renderPipeline.pushPrimitive(textElement); + context.camera._renderPipeline.pushRenderData(context, textElement); } private _updateStencilState(): void { diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index d166182cce..e52ef233f5 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -475,11 +475,11 @@ export class Camera extends Component { /** * Set the replacement shader. * @param shader - Replacement shader - * @param subShaderTag - Replacement sub shader tag + * @param replacementTag - Replacement sub shader tag */ - setReplacementShader(shader: Shader, subShaderTag: string): void { + setReplacementShader(shader: Shader, replacementTag: string): void { this._replacementShader = shader; - this._replacementSubShaderTag = subShaderTag; + this._replacementSubShaderTag = replacementTag; } /** diff --git a/packages/core/src/Engine.ts b/packages/core/src/Engine.ts index 01808337a9..039834f0fb 100644 --- a/packages/core/src/Engine.ts +++ b/packages/core/src/Engine.ts @@ -14,12 +14,13 @@ import { Material } from "./material/Material"; import { PhysicsManager } from "./physics"; import { IHardwareRenderer } from "./renderingHardwareInterface"; import { ClassPool } from "./RenderPipeline/ClassPool"; -import { MeshRenderElement } from "./RenderPipeline/MeshRenderElement"; +import { MeshRenderData } from "./RenderPipeline/MeshRenderData"; import { RenderContext } from "./RenderPipeline/RenderContext"; -import { SpriteElement } from "./RenderPipeline/SpriteElement"; -import { SpriteMaskElement } from "./RenderPipeline/SpriteMaskElement"; +import { RenderElement } from "./RenderPipeline/RenderElement"; import { SpriteMaskManager } from "./RenderPipeline/SpriteMaskManager"; -import { TextRenderElement } from "./RenderPipeline/TextRenderElement"; +import { SpriteMaskRenderData } from "./RenderPipeline/SpriteMaskRenderData"; +import { SpriteRenderData } from "./RenderPipeline/SpriteRenderData"; +import { TextRenderData } from "./RenderPipeline/TextRenderData"; import { Scene } from "./Scene"; import { SceneManager } from "./SceneManager"; import { BlendFactor } from "./shader/enums/BlendFactor"; @@ -58,10 +59,13 @@ export class Engine extends EventDispatcher { _componentsManager: ComponentsManager = new ComponentsManager(); _hardwareRenderer: IHardwareRenderer; _lastRenderState: RenderState = new RenderState(); - _renderElementPool: ClassPool = new ClassPool(MeshRenderElement); - _spriteElementPool: ClassPool = new ClassPool(SpriteElement); - _spriteMaskElementPool: ClassPool = new ClassPool(SpriteMaskElement); - _textElementPool: ClassPool = new ClassPool(TextRenderElement); + + _renderElementPool: ClassPool = new ClassPool(RenderElement); + _meshRenderDataPool: ClassPool = new ClassPool(MeshRenderData); + _spriteRenderDataPool: ClassPool = new ClassPool(SpriteRenderData); + _spriteMaskRenderDataPool: ClassPool = new ClassPool(SpriteMaskRenderData); + _textRenderDataPool: ClassPool = new ClassPool(TextRenderData); + _spriteDefaultMaterial: Material; _spriteMaskDefaultMaterial: Material; _textDefaultFont: Font; @@ -288,9 +292,10 @@ export class Engine extends EventDispatcher { this._frameInProcess = true; this._renderElementPool.resetPool(); - this._spriteElementPool.resetPool(); - this._spriteMaskElementPool.resetPool(); - this._textElementPool.resetPool(); + this._meshRenderDataPool.resetPool(); + this._spriteRenderDataPool.resetPool(); + this._spriteMaskRenderDataPool.resetPool(); + this._textRenderDataPool.resetPool(); const scene = this._sceneManager._activeScene; const componentsManager = this._componentsManager; diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 692364403e..6025d62f06 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -4,11 +4,12 @@ import { Buffer, BufferBindFlag, BufferUsage, IndexFormat, MeshTopology, SubMesh import { Material } from "../material"; import { BufferMesh } from "../mesh"; import { ClassPool } from "./ClassPool"; -import { SpriteElement } from "./SpriteElement"; -import { SpriteMaskElement } from "./SpriteMaskElement"; -import { TextRenderElement } from "./TextRenderElement"; +import { RenderElement } from "./RenderElement"; +import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; +import { SpriteRenderData } from "./SpriteRenderData"; +import { TextRenderData } from "./TextRenderData"; -type Element = SpriteElement | SpriteMaskElement; +type SpriteData = SpriteRenderData | SpriteMaskRenderData; export abstract class Basic2DBatcher { /** The maximum number of vertex. */ @@ -20,7 +21,7 @@ export abstract class Basic2DBatcher { /** @internal */ _subMeshPool: ClassPool = new ClassPool(SubMesh); /** @internal */ - _batchedQueue: Element[] = []; + _batchedQueue: RenderElement[] = []; /** @internal */ _meshes: BufferMesh[] = []; /** @internal */ @@ -45,18 +46,20 @@ export abstract class Basic2DBatcher { this._initMeshes(engine); } - drawElement( - element: SpriteMaskElement | SpriteElement | TextRenderElement, - camera: Camera, - replaceMaterial: Material - ): void { - if (element.multiRenderData) { - const elements = (element).charElements; - for (let i = 0, n = elements.length; i < n; ++i) { - this._drawSubElement(elements[i], camera, replaceMaterial); + drawElement(element: RenderElement, camera: Camera, replaceMaterial: Material): void { + const data = element.data; + + if (data.multiRenderData) { + const charsData = (data).charsData; + const pool = camera.engine._renderElementPool; + + for (let i = 0, n = charsData.length; i < n; ++i) { + const charRenderElement = pool.getFromPool(); + charRenderElement.set(charsData[i], element.shaderPass, element.renderState); + this._drawSubElement(charRenderElement, camera, replaceMaterial); } } else { - this._drawSubElement(element, camera, replaceMaterial); + this._drawSubElement(element, camera, replaceMaterial); } } @@ -75,8 +78,8 @@ export abstract class Basic2DBatcher { } } - private _drawSubElement(element: SpriteMaskElement | SpriteElement, camera: Camera, replaceMaterial: Material) { - const len = element.renderData.vertexCount; + private _drawSubElement(element: RenderElement, camera: Camera, replaceMaterial: Material) { + const len = (element.data).renderData.vertexCount; if (this._vertexCount + len > Basic2DBatcher.MAX_VERTEX_COUNT) { this.flush(camera, replaceMaterial); } @@ -178,21 +181,22 @@ export abstract class Basic2DBatcher { let vertexCount = 0; let curIndiceStartIndex = 0; let curMeshIndex = 0; - let preElement: Element = null; + let preElement: RenderElement = null; for (let i = 0, len = batchedQueue.length; i < len; i++) { const curElement = batchedQueue[i]; + const curData= curElement.data; // Batch vertex - vertexIndex = this.updateVertices(curElement, vertices, vertexIndex); + vertexIndex = this.updateVertices(curData, vertices, vertexIndex); // Batch indice - const { triangles } = curElement.renderData; + const { triangles } = curData.renderData; const triangleNum = triangles.length; for (let j = 0; j < triangleNum; j++) { indices[indiceIndex++] = triangles[j] + curIndiceStartIndex; } - curIndiceStartIndex += curElement.renderData.vertexCount; + curIndiceStartIndex += curData.renderData.vertexCount; if (preElement === null) { vertexCount += triangleNum; @@ -233,12 +237,12 @@ export abstract class Basic2DBatcher { /** * @internal */ - abstract canBatch(preElement: Element, curElement: Element): boolean; + abstract canBatch(preElement: RenderElement, curElement: RenderElement): boolean; /** * @internal */ - abstract updateVertices(element: Element, vertices: Float32Array, vertexIndex: number): number; + abstract updateVertices(element: SpriteData, vertices: Float32Array, vertexIndex: number): number; /** * @internal diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index fc64322a10..8fdc1aa8e2 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -11,10 +11,14 @@ import { Layer } from "../Layer"; import { Material } from "../material"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Shader } from "../shader/Shader"; +import { ShaderPass } from "../shader/ShaderPass"; +import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; import { RenderTarget, TextureCubeFace } from "../texture"; +import { ClassPool } from "./ClassPool"; import { RenderContext } from "./RenderContext"; +import { RenderData } from "./RenderData"; import { RenderElement } from "./RenderElement"; import { RenderPass } from "./RenderPass"; import { RenderQueue } from "./RenderQueue"; @@ -146,6 +150,8 @@ export class BasicRenderPipeline { const transparentQueue = this._transparentQueue; camera.engine._spriteMaskManager.clear(); + + context.pipelineStage = "ShadowCaster"; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -156,6 +162,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); + context.pipelineStage = "Forward"; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); @@ -191,8 +198,8 @@ export class BasicRenderPipeline { if (pass.renderOverride) { pass.render(camera, this._opaqueQueue, this._alphaTestQueue, this._transparentQueue); } else { - this._opaqueQueue.render(camera, pass.replaceMaterial, pass.mask, null); - this._alphaTestQueue.render(camera, pass.replaceMaterial, pass.mask, null); + this._opaqueQueue.render(camera, pass.replaceMaterial, pass.mask); + this._alphaTestQueue.render(camera, pass.replaceMaterial, pass.mask); if (camera.clearFlags & CameraClearFlags.Color) { if (background.mode === BackgroundMode.Sky) { background.sky._render(context); @@ -200,7 +207,7 @@ export class BasicRenderPipeline { this._drawBackgroundTexture(engine, background); } } - this._transparentQueue.render(camera, pass.replaceMaterial, pass.mask, null); + this._transparentQueue.render(camera, pass.replaceMaterial, pass.mask); } renderTarget?._blitRenderTarget(); @@ -211,20 +218,59 @@ export class BasicRenderPipeline { } /** - * Push a render element to the render queue. - * @param element - Render element + * Push render data to render queue. + * @param context - Render context + * @param data - Render data */ - pushPrimitive(element: RenderElement): void { - switch (element.renderState.renderQueueType) { - case RenderQueueType.Transparent: - this._transparentQueue.pushPrimitive(element); - break; - case RenderQueueType.AlphaTest: - this._alphaTestQueue.pushPrimitive(element); - break; - case RenderQueueType.Opaque: - this._opaqueQueue.pushPrimitive(element); - break; + pushRenderData(context: RenderContext, data: RenderData): void { + const material = data.material; + const pool = context.camera.engine._renderElementPool; + const renderStates = material.renderStates; + const materialShader = material.shader.subShaders[0]; + const replacementShader = context.replacementShader; + + if (replacementShader) { + const replacementSubShaders = replacementShader.subShaders; + const { replacementTag } = context; + if (replacementTag) { + for (let i = 0, n = replacementSubShaders.length; i < n; i++) { + const replacementSubShader = replacementSubShaders[i]; + if (replacementSubShader.replacementTags[replacementTag] === materialShader.replacementTags[replacementTag]) { + this.pushShaderPrimitive(context.pipelineStage, pool, data, replacementSubShader.passes, renderStates); + } + } + } else { + this.pushShaderPrimitive(context.pipelineStage, pool, data, replacementSubShaders[0].passes, renderStates); + } + } else { + this.pushShaderPrimitive(context.pipelineStage, pool, data, materialShader.passes, renderStates); + } + } + + private pushShaderPrimitive( + pipelineStage: string, + shaderRenderElementPool: ClassPool, + element: RenderData, + shaderPasses: ReadonlyArray, + renderStates: ReadonlyArray + ) { + for (let i = 0, n = shaderPasses.length; i < n; i++) { + const shaderPass = shaderPasses[i]; + if (shaderPass.pipelineStage === pipelineStage) { + const shaderElement = shaderRenderElementPool.getFromPool(); + shaderElement.set(element, shaderPass, renderStates[i]); + switch (shaderElement.renderState.renderQueueType) { + case RenderQueueType.Transparent: + this._transparentQueue.pushPrimitive(shaderElement); + break; + case RenderQueueType.AlphaTest: + this._alphaTestQueue.pushPrimitive(shaderElement); + break; + case RenderQueueType.Opaque: + this._opaqueQueue.pushPrimitive(shaderElement); + break; + } + } } } @@ -241,7 +287,10 @@ export class BasicRenderPipeline { background._resizeBackgroundTexture(); } - const program = _backgroundTextureMaterial.shader.passes[0]._getShaderProgram(engine, Shader._compileMacros); + const program = _backgroundTextureMaterial.shader.subShaders[0].passes[0]._getShaderProgram( + engine, + Shader._compileMacros + ); program.bind(); program.uploadAll(program.materialUniformBlock, _backgroundTextureMaterial.shaderData); program.uploadUnGroupTextures(); diff --git a/packages/core/src/RenderPipeline/MeshRenderData.ts b/packages/core/src/RenderPipeline/MeshRenderData.ts new file mode 100644 index 0000000000..7737428f08 --- /dev/null +++ b/packages/core/src/RenderPipeline/MeshRenderData.ts @@ -0,0 +1,23 @@ +import { Mesh } from "../graphic/Mesh"; +import { SubMesh } from "../graphic/SubMesh"; +import { Material } from "../material/Material"; +import { Renderer } from "../Renderer"; +import { RenderData } from "./RenderData"; + +/** + * Render element. + */ +export class MeshRenderData extends RenderData { + /** Mesh. */ + mesh: Mesh; + /** Sub mesh. */ + subMesh: SubMesh; + + set(component: Renderer, material: Material, mesh: Mesh, subMesh: SubMesh): void { + this.component = component; + this.material = material; + + this.mesh = mesh; + this.subMesh = subMesh; + } +} diff --git a/packages/core/src/RenderPipeline/MeshRenderElement.ts b/packages/core/src/RenderPipeline/MeshRenderElement.ts deleted file mode 100644 index fbf87d8473..0000000000 --- a/packages/core/src/RenderPipeline/MeshRenderElement.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Mesh } from "../graphic/Mesh"; -import { SubMesh } from "../graphic/SubMesh"; -import { Material } from "../material/Material"; -import { Renderer } from "../Renderer"; -import { ShaderPass } from "../shader/ShaderPass"; -import { RenderState } from "../shader/state/RenderState"; -import { RenderElement } from "./RenderElement"; - -/** - * Render element. - */ -export class MeshRenderElement extends RenderElement { - /** Mesh. */ - mesh: Mesh; - /** Sub mesh. */ - subMesh: SubMesh; - - setValue( - component: Renderer, - mesh: Mesh, - subMesh: SubMesh, - material: Material, - renderState: RenderState, - shaderPass: ShaderPass - ): void { - this.component = component; - this.mesh = mesh; - this.subMesh = subMesh; - this.material = material; - this.renderState = renderState; - this.shaderPass = shaderPass; - } -} diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index 21f0059972..fe4dbd79cd 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -16,6 +16,10 @@ export class RenderContext { camera: Camera; virtualCamera: VirtualCamera; + replacementShader: Shader; + replacementTag: string; + pipelineStage: string; + applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; const shaderData = this.camera.shaderData; diff --git a/packages/core/src/RenderPipeline/RenderData.ts b/packages/core/src/RenderPipeline/RenderData.ts new file mode 100644 index 0000000000..f5bcca0ce1 --- /dev/null +++ b/packages/core/src/RenderPipeline/RenderData.ts @@ -0,0 +1,9 @@ +import { Material } from "../material"; +import { Renderer } from "../Renderer"; + +export class RenderData { + component: Renderer; + material: Material; + + multiRenderData: boolean; +} diff --git a/packages/core/src/RenderPipeline/RenderElement.ts b/packages/core/src/RenderPipeline/RenderElement.ts index 4ad4ef89d3..9f0bfadc2d 100644 --- a/packages/core/src/RenderPipeline/RenderElement.ts +++ b/packages/core/src/RenderPipeline/RenderElement.ts @@ -1,12 +1,17 @@ -import { Material } from "../material/Material"; -import { Renderer } from "../Renderer"; -import { ShaderPass } from "../shader"; +import { ShaderPass } from "../shader/ShaderPass"; import { RenderState } from "../shader/state/RenderState"; +import { RenderData } from "./RenderData"; export class RenderElement { - component: Renderer; - material: Material; - multiRenderData: boolean; - renderState: RenderState; + data: RenderData; shaderPass: ShaderPass; + renderState: RenderState; + + multiRenderData: boolean; + + set(data: RenderData, shaderPass: ShaderPass, renderState: RenderState): void { + this.data = data; + this.shaderPass = shaderPass; + this.renderState = renderState; + } } diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index 664e040557..395243411f 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -4,10 +4,10 @@ import { Layer } from "../Layer"; import { Material } from "../material/Material"; import { Shader } from "../shader"; import { ShaderMacroCollection } from "../shader/ShaderMacroCollection"; -import { MeshRenderElement } from "./MeshRenderElement"; +import { MeshRenderData } from "./MeshRenderData"; +import { RenderData } from "./RenderData"; import { RenderElement } from "./RenderElement"; import { SpriteBatcher } from "./SpriteBatcher"; -import { SpriteElement } from "./SpriteElement"; /** * Render queue. @@ -16,14 +16,14 @@ export class RenderQueue { /** * @internal */ - static _compareFromNearToFar(a: RenderElement, b: RenderElement): number { + static _compareFromNearToFar(a: RenderData, b: RenderData): number { return a.component.priority - b.component.priority || a.component._distanceForSort - b.component._distanceForSort; } /** * @internal */ - static _compareFromFarToNear(a: RenderElement, b: RenderElement): number { + static _compareFromFarToNear(a: RenderData, b: RenderData): number { return a.component.priority - b.component.priority || b.component._distanceForSort - a.component._distanceForSort; } @@ -41,7 +41,7 @@ export class RenderQueue { this.items.push(element); } - render(camera: Camera, replaceMaterial: Material, mask: Layer, customShader: Shader): void { + render(camera: Camera, replaceMaterial: Material, mask: Layer): void { const items = this.items; if (items.length === 0) { return; @@ -54,26 +54,24 @@ export class RenderQueue { const cameraData = camera.shaderData; for (let i = 0, n = items.length; i < n; i++) { - const item = items[i]; - const renderPassFlag = item.component.entity.layer; + const renderItem = items[i]; + const data = renderItem.data; + const renderPassFlag = data.component.entity.layer; if (!(renderPassFlag & mask)) { continue; } - if (!!(item as MeshRenderElement).mesh) { + if (!!(data as MeshRenderData).mesh) { this._spriteBatcher.flush(camera, replaceMaterial); const compileMacros = Shader._compileMacros; - const element = item; + const element = data; const renderer = element.component; const material = element.material.destroyed ? engine._magentaMaterial : element.material; const rendererData = renderer.shaderData; const materialData = material.shaderData; - // @todo: temporary solution - (replaceMaterial || material)._preRender(element); - // union render global macro and material self macro. ShaderMacroCollection.unionCollection( renderer._globalShaderMacro, @@ -81,13 +79,7 @@ export class RenderQueue { compileMacros ); - // @todo: temporary solution - const program = ( - customShader?.passes[0] || - replaceMaterial?.shader.passes[0] || - element.shaderPass - )._getShaderProgram(engine, compileMacros); - + const program = renderItem.shaderPass._getShaderProgram(engine, compileMacros); if (!program.isValid) { continue; } @@ -142,12 +134,11 @@ export class RenderQueue { program.uploadUnGroupTextures(); } } - element.renderState._apply(engine, renderer.entity.transform._isFrontFaceInvert()); + renderItem.renderState._apply(engine, renderer.entity.transform._isFrontFaceInvert()); rhi.drawPrimitive(element.mesh, element.subMesh, program); } else { - const spriteElement = item; - this._spriteBatcher.drawElement(spriteElement, camera, replaceMaterial); + this._spriteBatcher.drawElement(renderItem, camera, replaceMaterial); } } diff --git a/packages/core/src/RenderPipeline/SpriteBatcher.ts b/packages/core/src/RenderPipeline/SpriteBatcher.ts index 807e3a3ebf..625695dbdf 100644 --- a/packages/core/src/RenderPipeline/SpriteBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteBatcher.ts @@ -3,12 +3,12 @@ import { SpriteRenderer } from "../2d/sprite/SpriteRenderer"; import { Camera } from "../Camera"; import { VertexElementFormat } from "../graphic/enums/VertexElementFormat"; import { VertexElement } from "../graphic/VertexElement"; -import { Material } from "../material"; import { Shader } from "../shader/Shader"; import { ShaderMacroCollection } from "../shader/ShaderMacroCollection"; import { ShaderProperty } from "../shader/ShaderProperty"; import { Basic2DBatcher } from "./Basic2DBatcher"; -import { SpriteElement } from "./SpriteElement"; +import { RenderElement } from "./RenderElement"; +import { SpriteRenderData } from "./SpriteRenderData"; /** * @internal @@ -23,13 +23,15 @@ export class SpriteBatcher extends Basic2DBatcher { return 36; } - canBatch(preElement: SpriteElement, curElement: SpriteElement): boolean { + canBatch(preElement: RenderElement, curElement: RenderElement): boolean { if (!this._engine._canSpriteBatch) { return false; } - const preRenderer = preElement.component; - const curRenderer = curElement.component; + const preSpriteData = preElement.data; + const curSpriteData = curElement.data; + const preRenderer = preSpriteData.component; + const curRenderer = curSpriteData.component; // Compare mask if (!this.checkBatchWithMask(preRenderer, curRenderer)) { @@ -37,12 +39,12 @@ export class SpriteBatcher extends Basic2DBatcher { } // Compare texture - if (preElement.texture !== curElement.texture) { + if (preSpriteData.texture !== curSpriteData.texture) { return false; } // Compare material - return preElement.material === curElement.material; + return preSpriteData.material === curSpriteData.material; } checkBatchWithMask(left: SpriteRenderer, right: SpriteRenderer): boolean { @@ -57,7 +59,7 @@ export class SpriteBatcher extends Basic2DBatcher { return left.maskLayer === right.maskLayer; } - updateVertices(element: SpriteElement, vertices: Float32Array, vertexIndex: number): number { + updateVertices(element: SpriteRenderData, vertices: Float32Array, vertexIndex: number): number { const { positions, uvs, color, vertexCount } = element.renderData; for (let i = 0; i < vertexCount; i++) { const curPos = positions[i]; @@ -76,7 +78,7 @@ export class SpriteBatcher extends Basic2DBatcher { return vertexIndex; } - drawBatches(camera: Camera, replaceMaterial: Material): void { + drawBatches(camera: Camera): void { const { _engine: engine, _batchedQueue: batchedQueue } = this; const mesh = this._meshes[this._flushId]; const subMeshes = mesh.subMeshes; @@ -86,14 +88,15 @@ export class SpriteBatcher extends Basic2DBatcher { for (let i = 0, len = subMeshes.length; i < len; i++) { const subMesh = subMeshes[i]; - const spriteElement = batchedQueue[i]; + const spriteElement = batchedQueue[i]; + const spriteData = spriteElement.data; if (!subMesh || !spriteElement) { return; } - const renderer = spriteElement.component; - const material = spriteElement.material; + const renderer = spriteData.component; + const material = spriteData.material; maskManager.preRender(camera, renderer); const compileMacros = Shader._compileMacros; @@ -104,14 +107,12 @@ export class SpriteBatcher extends Basic2DBatcher { compileMacros ); - // @todo: temporary solution - (replaceMaterial || material)._preRender(spriteElement); const program = spriteElement.shaderPass._getShaderProgram(engine, compileMacros); if (!program.isValid) { return; } - renderer.shaderData.setTexture(SpriteBatcher._textureProperty, spriteElement.texture); + renderer.shaderData.setTexture(SpriteBatcher._textureProperty, spriteData.texture); program.bind(); program.groupingOtherUniformBlock(); diff --git a/packages/core/src/RenderPipeline/SpriteElement.ts b/packages/core/src/RenderPipeline/SpriteElement.ts deleted file mode 100644 index 48b77ec12a..0000000000 --- a/packages/core/src/RenderPipeline/SpriteElement.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { RenderData2D } from "../2d/data/RenderData2D"; -import { Material } from "../material/Material"; -import { Renderer } from "../Renderer"; -import { ShaderPass } from "../shader"; -import { RenderState } from "../shader/state/RenderState"; -import { Texture2D } from "../texture"; -import { RenderElement } from "./RenderElement"; - -export class SpriteElement extends RenderElement { - renderData: RenderData2D; - texture: Texture2D; - dataIndex: number;// Add for CanvasRenderer plugin. - - constructor() { - super(); - this.multiRenderData = false; - } - - setValue( - component: Renderer, - renderDate: RenderData2D, - material: Material, - texture: Texture2D, - renderState: RenderState, - shaderPass: ShaderPass, - dataIndex: number = 0 - ): void { - this.component = component; - this.renderData = renderDate; - this.material = material; - this.texture = texture; - this.renderState = renderState; - this.shaderPass = shaderPass; - this.dataIndex = dataIndex; - } -} diff --git a/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts b/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts index 7e18723c7f..ca76d8aa34 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts @@ -6,7 +6,8 @@ import { StencilOperation } from "../shader/enums/StencilOperation"; import { Shader } from "../shader/Shader"; import { ShaderMacroCollection } from "../shader/ShaderMacroCollection"; import { Basic2DBatcher } from "./Basic2DBatcher"; -import { SpriteMaskElement } from "./SpriteMaskElement"; +import { RenderElement } from "./RenderElement"; +import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; export class SpriteMaskBatcher extends Basic2DBatcher { createVertexElements(vertexElements: VertexElement[]): number { @@ -15,14 +16,17 @@ export class SpriteMaskBatcher extends Basic2DBatcher { return 20; } - canBatch(preElement: SpriteMaskElement, curElement: SpriteMaskElement): boolean { - if (preElement.isAdd !== curElement.isAdd) { + canBatch(preElement: RenderElement, curElement: RenderElement): boolean { + const preSpriteData = preElement.data; + const curSpriteData = curElement.data; + + if (preSpriteData.isAdd !== curSpriteData.isAdd) { return false; } // Compare renderer property - const preShaderData = (preElement.component).shaderData; - const curShaderData = (curElement.component).shaderData; + const preShaderData = (preSpriteData.component).shaderData; + const curShaderData = (curSpriteData.component).shaderData; const textureProperty = SpriteMask._textureProperty; const alphaCutoffProperty = SpriteMask._alphaCutoffProperty; @@ -32,7 +36,7 @@ export class SpriteMaskBatcher extends Basic2DBatcher { ); } - updateVertices(element: SpriteMaskElement, vertices: Float32Array, vertexIndex: number): number { + updateVertices(element: SpriteMaskRenderData, vertices: Float32Array, vertexIndex: number): number { const { positions, uvs, vertexCount } = element.renderData; for (let i = 0; i < vertexCount; i++) { const curPos = positions[i]; @@ -56,14 +60,15 @@ export class SpriteMaskBatcher extends Basic2DBatcher { for (let i = 0, len = subMeshes.length; i < len; i++) { const subMesh = subMeshes[i]; - const spriteMaskElement = batchedQueue[i]; + const spriteMaskElement = batchedQueue[i]; + const spritMaskData = spriteMaskElement.data; if (!subMesh || !spriteMaskElement) { return; } - const renderer = spriteMaskElement.component; - const material = spriteMaskElement.material; + const renderer = spritMaskData.component; + const material = spritMaskData.material; const compileMacros = Shader._compileMacros; // union render global macro and material self macro. @@ -75,11 +80,11 @@ export class SpriteMaskBatcher extends Basic2DBatcher { // Update stencil state const stencilState = material.renderState.stencilState; - const op = spriteMaskElement.isAdd ? StencilOperation.IncrementSaturate : StencilOperation.DecrementSaturate; + const op = spritMaskData.isAdd ? StencilOperation.IncrementSaturate : StencilOperation.DecrementSaturate; stencilState.passOperationFront = op; stencilState.passOperationBack = op; - const program = material.shader.passes[0]._getShaderProgram(engine, compileMacros); + const program = material.shader.subShaders[0].passes[0]._getShaderProgram(engine, compileMacros); if (!program.isValid) { return; } diff --git a/packages/core/src/RenderPipeline/SpriteMaskManager.ts b/packages/core/src/RenderPipeline/SpriteMaskManager.ts index 6c7d1f1373..48d096362a 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskManager.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskManager.ts @@ -3,6 +3,7 @@ import { SpriteRenderer } from "../2d/sprite/SpriteRenderer"; import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { SpriteMaskBatcher } from "./SpriteMaskBatcher"; +import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; /** * @internal @@ -64,14 +65,14 @@ export class SpriteMaskManager { if (influenceLayers & addLayer) { const maskRenderElement = mask._maskElement; - maskRenderElement.isAdd = true; + (maskRenderElement.data).isAdd = true; this._batcher.drawElement(maskRenderElement, camera, null); continue; } if (influenceLayers & reduceLayer) { const maskRenderElement = mask._maskElement; - maskRenderElement.isAdd = false; + (maskRenderElement.data).isAdd = false; this._batcher.drawElement(maskRenderElement, camera, null); } } diff --git a/packages/core/src/RenderPipeline/SpriteMaskElement.ts b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts similarity index 51% rename from packages/core/src/RenderPipeline/SpriteMaskElement.ts rename to packages/core/src/RenderPipeline/SpriteMaskRenderData.ts index 8ce38754ca..52efe8f127 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskElement.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts @@ -1,20 +1,21 @@ -import { RenderData2D } from "../2d/data/RenderData2D"; +import { VertexData2D } from "../2d/data/VertexData2D"; import { Material } from "../material/Material"; import { Renderer } from "../Renderer"; -import { RenderElement } from "./RenderElement"; +import { RenderData } from "./RenderData"; -export class SpriteMaskElement extends RenderElement { - renderData: RenderData2D; +export class SpriteMaskRenderData extends RenderData { isAdd: boolean = true; + renderData: VertexData2D; constructor() { super(); this.multiRenderData = false; } - setValue(component: Renderer, renderData: RenderData2D, material: Material): void { + setValue(component: Renderer, material: Material, renderData: VertexData2D): void { this.component = component; - this.renderData = renderData; this.material = material; + + this.renderData = renderData; } } diff --git a/packages/core/src/RenderPipeline/SpriteRenderData.ts b/packages/core/src/RenderPipeline/SpriteRenderData.ts new file mode 100644 index 0000000000..80718440d7 --- /dev/null +++ b/packages/core/src/RenderPipeline/SpriteRenderData.ts @@ -0,0 +1,31 @@ +import { VertexData2D } from "../2d/data/VertexData2D"; +import { Material } from "../material/Material"; +import { Renderer } from "../Renderer"; +import { Texture2D } from "../texture"; +import { RenderData } from "./RenderData"; + +export class SpriteRenderData extends RenderData { + renderData: VertexData2D; + texture: Texture2D; + dataIndex: number; // Add for CanvasRenderer plugin. + + constructor() { + super(); + this.multiRenderData = false; + } + + set( + component: Renderer, + material: Material, + renderDate: VertexData2D, + texture: Texture2D, + dataIndex: number = 0 + ): void { + this.component = component; + this.material = material; + + this.renderData = renderDate; + this.texture = texture; + this.dataIndex = dataIndex; + } +} diff --git a/packages/core/src/RenderPipeline/TextRenderData.ts b/packages/core/src/RenderPipeline/TextRenderData.ts new file mode 100644 index 0000000000..1bb74d8fc7 --- /dev/null +++ b/packages/core/src/RenderPipeline/TextRenderData.ts @@ -0,0 +1,11 @@ +import { RenderData } from "./RenderData"; +import { SpriteRenderData } from "./SpriteRenderData"; + +export class TextRenderData extends RenderData { + charsData: SpriteRenderData[] = []; + + constructor() { + super(); + this.multiRenderData = true; + } +} diff --git a/packages/core/src/RenderPipeline/TextRenderElement.ts b/packages/core/src/RenderPipeline/TextRenderElement.ts deleted file mode 100644 index 730173d99b..0000000000 --- a/packages/core/src/RenderPipeline/TextRenderElement.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { RenderElement } from "./RenderElement"; -import { SpriteElement } from "./SpriteElement"; - -export class TextRenderElement extends RenderElement { - charElements: SpriteElement[] = []; - - constructor() { - super(); - this.multiRenderData = true; - } -} diff --git a/packages/core/src/graphic/Mesh.ts b/packages/core/src/graphic/Mesh.ts index 58b06ba1d9..f48b0485e4 100644 --- a/packages/core/src/graphic/Mesh.ts +++ b/packages/core/src/graphic/Mesh.ts @@ -113,6 +113,7 @@ export abstract class Mesh extends RefObject { startOrSubMesh = new SubMesh(startOrSubMesh, count, topology); } this._subMeshes.push(startOrSubMesh); + this._updateFlagManager.dispatch(MeshModifyFlags.SubMesh); return startOrSubMesh; } @@ -126,6 +127,7 @@ export abstract class Mesh extends RefObject { if (index !== -1) { subMeshes.splice(index, 1); } + this._updateFlagManager.dispatch(MeshModifyFlags.SubMesh); } /** @@ -133,6 +135,7 @@ export abstract class Mesh extends RefObject { */ clearSubMesh(): void { this._subMeshes.length = 0; + this._updateFlagManager.dispatch(MeshModifyFlags.SubMesh); } /** @@ -236,5 +239,6 @@ export abstract class Mesh extends RefObject { */ export enum MeshModifyFlags { Bounds = 0x1, - VertexElements = 0x2 + VertexElements = 0x2, + SubMesh = 0x4 } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 554be279ab..f186509205 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -27,8 +27,6 @@ export { RefObject } from "./asset/RefObject"; export { BasicRenderPipeline } from "./RenderPipeline/BasicRenderPipeline"; export { RenderQueue } from "./RenderPipeline/RenderQueue"; export { RenderPass } from "./RenderPipeline/RenderPass"; -export { MeshRenderElement } from "./RenderPipeline/MeshRenderElement"; -export { SpriteElement } from "./RenderPipeline/SpriteElement"; export * from "./base"; export { Background } from "./Background"; diff --git a/packages/core/src/material/BaseMaterial.ts b/packages/core/src/material/BaseMaterial.ts index 155e967224..e194d123c4 100644 --- a/packages/core/src/material/BaseMaterial.ts +++ b/packages/core/src/material/BaseMaterial.ts @@ -2,7 +2,6 @@ import { Engine } from "../Engine"; import { BlendFactor, BlendOperation, CullMode, Shader } from "../shader"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { ShaderMacro } from "../shader/ShaderMacro"; -import { RenderState } from "../shader/state/RenderState"; import { BlendMode } from "./enums/BlendMode"; import { RenderFace } from "./enums/RenderFace"; import { Material } from "./Material"; @@ -35,19 +34,13 @@ export class BaseMaterial extends Material { } set shader(value: Shader) { - this._shader = value; - const renderStates = this._renderStates; const lastStatesCount = renderStates.length; - const passCount = value.passes.length; + super.shader = value; + const newStatesCount = renderStates.length; - if (lastStatesCount < passCount) { - for (let i = lastStatesCount; i < passCount; i++) { - renderStates.push(new RenderState()); - this.setBlendMode(i, BlendMode.Normal); - } - } else { - renderStates.length = passCount; + for (let i = lastStatesCount; i < newStatesCount; i++) { + this.setBlendMode(i, BlendMode.Normal); } } diff --git a/packages/core/src/material/Material.ts b/packages/core/src/material/Material.ts index 78f55671be..d776e1e916 100644 --- a/packages/core/src/material/Material.ts +++ b/packages/core/src/material/Material.ts @@ -2,8 +2,6 @@ import { IClone } from "@oasis-engine/design"; import { RefObject } from "../asset/RefObject"; import { CloneManager } from "../clone/CloneManager"; import { Engine } from "../Engine"; -import { MeshRenderElement } from "../RenderPipeline/MeshRenderElement"; -import { SpriteElement } from "../RenderPipeline/SpriteElement"; import { ShaderDataGroup } from "../shader/enums/ShaderDataGroup"; import { Shader } from "../shader/Shader"; import { ShaderData } from "../shader/ShaderData"; @@ -35,14 +33,19 @@ export class Material extends RefObject implements IClone { const renderStates = this._renderStates; const lastStatesCount = renderStates.length; - const passCount = value.passes.length; - if (lastStatesCount < passCount) { - for (let i = lastStatesCount; i < passCount; i++) { + let maxPassCount = 0; + const subShaders = value.subShaders; + for (let i = 0; i < subShaders.length; i++) { + maxPassCount = Math.max(subShaders[i].passes.length, maxPassCount); + } + + if (lastStatesCount < maxPassCount) { + for (let i = lastStatesCount; i < maxPassCount; i++) { renderStates.push(new RenderState()); } } else { - renderStates.length = passCount; + renderStates.length = maxPassCount; } } @@ -97,12 +100,6 @@ export class Material extends RefObject implements IClone { this.shaderData._addRefCount(value); } - /** - * @internal - * @todo:temporary solution - */ - _preRender(renderElement: MeshRenderElement | SpriteElement) {} - /** * @override */ diff --git a/packages/core/src/mesh/MeshRenderer.ts b/packages/core/src/mesh/MeshRenderer.ts index 72ff340054..a32ad306d4 100644 --- a/packages/core/src/mesh/MeshRenderer.ts +++ b/packages/core/src/mesh/MeshRenderer.ts @@ -116,19 +116,16 @@ export class MeshRenderer extends Renderer implements ICustomClone { this._dirtyUpdateFlag &= ~MeshRendererUpdateFlags.VertexElementMacro; } + const materials = this._materials; const subMeshes = mesh.subMeshes; const renderPipeline = context.camera._renderPipeline; - const renderElementPool = this._engine._renderElementPool; + const meshRenderDataPool = this._engine._meshRenderDataPool; for (let i = 0, n = subMeshes.length; i < n; i++) { - const material = this._materials[i]; + const material = materials[i]; if (material) { - const renderStates = material.renderStates; - const shaderPasses = material.shader.passes; - for (let j = 0, m = shaderPasses.length; j < m; j++) { - const element = renderElementPool.getFromPool(); - element.setValue(this, mesh, subMeshes[i], material, renderStates[j], shaderPasses[j]); - renderPipeline.pushPrimitive(element); - } + const renderData = meshRenderDataPool.getFromPool(); + renderData.set(this, material, mesh, subMeshes[i]); + renderPipeline.pushRenderData(context, renderData); } } } else { diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index 756c201542..eb641a9d39 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -4,6 +4,7 @@ import { ShaderMacro } from "./ShaderMacro"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderPass } from "./ShaderPass"; import { ShaderProperty } from "./ShaderProperty"; +import { SubShader } from "./SubShader"; /** * Shader for rendering. @@ -38,17 +39,25 @@ export class Shader { /** * Create a shader. * @param name - Name of the shader - * @param shaderPasses - Shader passes + * @param SubShader - Sub shader * @returns Shader */ - static create(name: string, shaderPasses: ShaderPass[]): Shader; + static create(name: string, shaderPasses: SubShader[]): Shader; - static create(name: string, vertexSourceOrShaderPasses: string | ShaderPass[], fragmentSource?: string): Shader { + static create(name: string, vertexSourceOrSubShaders: string | SubShader[], fragmentSource?: string): Shader { const shaderMap = Shader._shaderMap; if (shaderMap[name]) { throw `Shader named "${name}" already exists.`; } - return (shaderMap[name] = new Shader(name, vertexSourceOrShaderPasses, fragmentSource)); + let shader: Shader; + if (typeof vertexSourceOrSubShaders === "string") { + const shaderPass = new ShaderPass(vertexSourceOrSubShaders, fragmentSource); + shader = new Shader(name, [new SubShader("DefaultPass", [shaderPass])]); + } else { + shader = new Shader(name, vertexSourceOrSubShaders); + } + shaderMap[name] = shader; + return shader; } /** @@ -139,31 +148,24 @@ export class Shader { } } - /** The name of shader. */ - readonly name: string; + private _subShaders: SubShader[] = []; /** - * Shader passes. + * Sub shaders of the shader. */ - get passes(): ReadonlyArray { - return this._passes; + get subShaders(): ReadonlyArray { + return this._subShaders; } - private _passes: ShaderPass[] = []; - - private constructor(name: string, vertexSourceOrShaderPasses: string | ShaderPass[], fragmentSource?: string) { + private constructor(public readonly name: string, subShaders: SubShader[]) { this.name = name; - if (typeof vertexSourceOrShaderPasses === "string") { - this._passes.push(new ShaderPass(vertexSourceOrShaderPasses, fragmentSource)); - } else { - const passCount = vertexSourceOrShaderPasses.length; - if (passCount < 1) { - throw "Shader pass count must large than 0."; - } - for (let i = 0; i < passCount; i++) { - this._passes.push(vertexSourceOrShaderPasses[i]); - } + const passCount = subShaders.length; + if (passCount < 1) { + throw "SubShader count must large than 0."; + } + for (let i = 0; i < passCount; i++) { + this._subShaders.push(subShaders[i]); } } @@ -185,9 +187,12 @@ export class Shader { } let isValid = true; - const passes = this._passes; - for (let i = 0, n = passes.length; i < n; i++) { - isValid &&= passes[i]._getShaderProgram(engine, compileMacros).isValid; + const subShaders = this._subShaders; + for (let i = 0, n = subShaders.length; i < n; i++) { + const { passes } = subShaders[i]; + for (let j = 0, m = passes.length; j < m; j++) { + isValid &&= passes[j]._getShaderProgram(engine, compileMacros).isValid; + } } return isValid; } diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 082c49e11a..526eff3cae 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -11,6 +11,9 @@ import { ShaderProgram } from "./ShaderProgram"; export class ShaderPass { private static _shaderPassCounter: number = 0; + /** */ + pipelineStage: string; + /** @internal */ _shaderPassId: number = 0; diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 778dc88260..341482d6b8 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -4,23 +4,48 @@ import { ShaderPass } from "./ShaderPass"; * Sub shader. */ export class SubShader { - private _tags: Record = {}; + /** Disable batch. */ + disableBatch: boolean = false; + + private _replacementTags: Record; private _passes: ShaderPass[] = []; /** - * Shader passes. + * replacement tags. + */ + get replacementTags(): Readonly> { + return this._replacementTags; + } + + /** + * Sub shader passes. */ get passes(): ReadonlyArray { return this._passes; } /** - * Add a tag. + * Create a sub shader. + * @param name - Name of the sub shader + * @param passes - Sub shader passes + */ + constructor(public readonly name: string, passes: ShaderPass[]) { + const passCount = passes.length; + if (passCount < 1) { + throw " count must large than 0."; + } + for (let i = 0; i < passCount; i++) { + this._passes.push(passes[i]); + } + } + + /** + * Add a replacement tag. * @param name - Name of the tag * @param value - Value of the tag */ - addTag(name: string, value: string): void { - const tags = this._tags; + addReplacementTag(name: string, value: string): void { + const tags = this._replacementTags; if (tags[name]) { throw `Tag named "${name}" already exists.`; } diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index 9a4845b78d..178b34e97b 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -88,7 +88,6 @@ export class CascadedShadowCasterPass { const { _engine: engine, _camera: camera, - _shadowCasterShader: shadowCasterShader, _viewportOffsets: viewports, _shadowSliceData: shadowSliceData, _splitBoundSpheres: splitBoundSpheres, @@ -209,8 +208,8 @@ export class CascadedShadowCasterPass { rhi.scissor(x + 1, y + 1, shadowTileResolution - 2, shadowTileResolution - 2); engine._renderCount++; - opaqueQueue.render(camera, null, Layer.Everything, shadowCasterShader); - alphaTestQueue.render(camera, null, Layer.Everything, shadowCasterShader); + opaqueQueue.render(camera, null, Layer.Everything); + alphaTestQueue.render(camera, null, Layer.Everything); rhi.setGlobalDepthBias(0, 0); } } diff --git a/packages/core/src/sky/Sky.ts b/packages/core/src/sky/Sky.ts index 0a4e0ce272..fa73c58cc2 100644 --- a/packages/core/src/sky/Sky.ts +++ b/packages/core/src/sky/Sky.ts @@ -59,7 +59,7 @@ export class Sky { materialShaderData._macroCollection, compileMacros ); - const program = shader.passes[0]._getShaderProgram(engine, compileMacros); + const program = shader.subShaders[0].passes[0]._getShaderProgram(engine, compileMacros); program.bind(); program.groupingOtherUniformBlock(); program.uploadAll(program.cameraUniformBlock, cameraShaderData); From 4a3448504fee94cd5fad9e879fd67b99d156712a Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sun, 5 Mar 2023 22:46:39 +0800 Subject: [PATCH 03/62] refactor: opt code --- .../src/RenderPipeline/BasicRenderPipeline.ts | 35 ++++++++++--------- .../core/src/RenderPipeline/RenderQueue.ts | 2 +- packages/core/src/mesh/MeshRenderer.ts | 9 +++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 8fdc1aa8e2..c6cdceb5b8 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -16,10 +16,8 @@ import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; import { RenderTarget, TextureCubeFace } from "../texture"; -import { ClassPool } from "./ClassPool"; import { RenderContext } from "./RenderContext"; import { RenderData } from "./RenderData"; -import { RenderElement } from "./RenderElement"; import { RenderPass } from "./RenderPass"; import { RenderQueue } from "./RenderQueue"; @@ -224,9 +222,8 @@ export class BasicRenderPipeline { */ pushRenderData(context: RenderContext, data: RenderData): void { const material = data.material; - const pool = context.camera.engine._renderElementPool; const renderStates = material.renderStates; - const materialShader = material.shader.subShaders[0]; + const materialSubShader = material.shader.subShaders[0]; const replacementShader = context.replacementShader; if (replacementShader) { @@ -235,39 +232,43 @@ export class BasicRenderPipeline { if (replacementTag) { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { const replacementSubShader = replacementSubShaders[i]; - if (replacementSubShader.replacementTags[replacementTag] === materialShader.replacementTags[replacementTag]) { - this.pushShaderPrimitive(context.pipelineStage, pool, data, replacementSubShader.passes, renderStates); + if ( + replacementSubShader.replacementTags[replacementTag] === materialSubShader.replacementTags[replacementTag] + ) { + this.pushRenderDataWihShader(context, data, replacementSubShader.passes, renderStates); } } } else { - this.pushShaderPrimitive(context.pipelineStage, pool, data, replacementSubShaders[0].passes, renderStates); + this.pushRenderDataWihShader(context, data, replacementSubShaders[0].passes, renderStates); } } else { - this.pushShaderPrimitive(context.pipelineStage, pool, data, materialShader.passes, renderStates); + this.pushRenderDataWihShader(context, data, materialSubShader.passes, renderStates); } } - private pushShaderPrimitive( - pipelineStage: string, - shaderRenderElementPool: ClassPool, + private pushRenderDataWihShader( + context: RenderContext, element: RenderData, shaderPasses: ReadonlyArray, renderStates: ReadonlyArray ) { + const pipelineStage = context.pipelineStage; + const renderElementPool = context.camera.engine._renderElementPool; for (let i = 0, n = shaderPasses.length; i < n; i++) { const shaderPass = shaderPasses[i]; if (shaderPass.pipelineStage === pipelineStage) { - const shaderElement = shaderRenderElementPool.getFromPool(); - shaderElement.set(element, shaderPass, renderStates[i]); - switch (shaderElement.renderState.renderQueueType) { + const renderElement = renderElementPool.getFromPool(); + + renderElement.set(element, shaderPass, renderStates[i]); + switch (renderElement.renderState.renderQueueType) { case RenderQueueType.Transparent: - this._transparentQueue.pushPrimitive(shaderElement); + this._transparentQueue.pushRenderElement(renderElement); break; case RenderQueueType.AlphaTest: - this._alphaTestQueue.pushPrimitive(shaderElement); + this._alphaTestQueue.pushRenderElement(renderElement); break; case RenderQueueType.Opaque: - this._opaqueQueue.pushPrimitive(shaderElement); + this._opaqueQueue.pushRenderElement(renderElement); break; } } diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index 395243411f..bcad1ccacf 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -37,7 +37,7 @@ export class RenderQueue { /** * Push a render element. */ - pushPrimitive(element: RenderElement): void { + pushRenderElement(element: RenderElement): void { this.items.push(element); } diff --git a/packages/core/src/mesh/MeshRenderer.ts b/packages/core/src/mesh/MeshRenderer.ts index a32ad306d4..1aa35573f0 100644 --- a/packages/core/src/mesh/MeshRenderer.ts +++ b/packages/core/src/mesh/MeshRenderer.ts @@ -122,11 +122,10 @@ export class MeshRenderer extends Renderer implements ICustomClone { const meshRenderDataPool = this._engine._meshRenderDataPool; for (let i = 0, n = subMeshes.length; i < n; i++) { const material = materials[i]; - if (material) { - const renderData = meshRenderDataPool.getFromPool(); - renderData.set(this, material, mesh, subMeshes[i]); - renderPipeline.pushRenderData(context, renderData); - } + if (!material) continue; + const renderData = meshRenderDataPool.getFromPool(); + renderData.set(this, material, mesh, subMeshes[i]); + renderPipeline.pushRenderData(context, renderData); } } else { Logger.error("mesh is null."); From fb9209d9202946df48f006a04e49999120ad6e05 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sun, 5 Mar 2023 23:02:07 +0800 Subject: [PATCH 04/62] refactor: opt code --- .../core/src/RenderPipeline/RenderQueue.ts | 8 ++++---- packages/core/src/material/BaseMaterial.ts | 20 +++++++++++++++---- packages/core/src/shader/Shader.ts | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index bcad1ccacf..6d781862fb 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -16,15 +16,15 @@ export class RenderQueue { /** * @internal */ - static _compareFromNearToFar(a: RenderData, b: RenderData): number { - return a.component.priority - b.component.priority || a.component._distanceForSort - b.component._distanceForSort; + static _compareFromNearToFar(a: RenderElement, b: RenderElement): number { + return a.data.component.priority - b.data.component.priority || a.data.component._distanceForSort - b.data.component._distanceForSort; } /** * @internal */ - static _compareFromFarToNear(a: RenderData, b: RenderData): number { - return a.component.priority - b.component.priority || b.component._distanceForSort - a.component._distanceForSort; + static _compareFromFarToNear(a: RenderElement, b: RenderElement): number { + return a.data.component.priority - b.data.component.priority || b.data.component._distanceForSort - a.data.component._distanceForSort; } readonly items: RenderElement[] = []; diff --git a/packages/core/src/material/BaseMaterial.ts b/packages/core/src/material/BaseMaterial.ts index e194d123c4..a6238ae7d5 100644 --- a/packages/core/src/material/BaseMaterial.ts +++ b/packages/core/src/material/BaseMaterial.ts @@ -2,6 +2,7 @@ import { Engine } from "../Engine"; import { BlendFactor, BlendOperation, CullMode, Shader } from "../shader"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { ShaderMacro } from "../shader/ShaderMacro"; +import { RenderState } from "../shader/state/RenderState"; import { BlendMode } from "./enums/BlendMode"; import { RenderFace } from "./enums/RenderFace"; import { Material } from "./Material"; @@ -34,13 +35,24 @@ export class BaseMaterial extends Material { } set shader(value: Shader) { + this._shader = value; + const renderStates = this._renderStates; const lastStatesCount = renderStates.length; - super.shader = value; - const newStatesCount = renderStates.length; - for (let i = lastStatesCount; i < newStatesCount; i++) { - this.setBlendMode(i, BlendMode.Normal); + let maxPassCount = 0; + const subShaders = value.subShaders; + for (let i = 0; i < subShaders.length; i++) { + maxPassCount = Math.max(subShaders[i].passes.length, maxPassCount); + } + + if (lastStatesCount < maxPassCount) { + for (let i = lastStatesCount; i < maxPassCount; i++) { + renderStates.push(new RenderState()); + this.setBlendMode(i, BlendMode.Normal); + } + } else { + renderStates.length = maxPassCount; } } diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index eb641a9d39..da38d2052b 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -52,6 +52,7 @@ export class Shader { let shader: Shader; if (typeof vertexSourceOrSubShaders === "string") { const shaderPass = new ShaderPass(vertexSourceOrSubShaders, fragmentSource); + shaderPass.pipelineStage = "Forward"; shader = new Shader(name, [new SubShader("DefaultPass", [shaderPass])]); } else { shader = new Shader(name, vertexSourceOrSubShaders); From 044f6449ca77eb0dbc8151160ab4c878cf494e1f Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 00:30:30 +0800 Subject: [PATCH 05/62] refactor: opt code --- packages/core/src/Camera.ts | 11 +++--- .../src/RenderPipeline/BasicRenderPipeline.ts | 14 ++++---- .../core/src/RenderPipeline/RenderContext.ts | 5 +-- packages/core/src/shader/Shader.ts | 3 +- packages/core/src/shader/ShaderPass.ts | 5 +-- packages/core/src/shader/ShaderString.ts | 36 +++++++++++++++++++ packages/core/src/shader/SubShader.ts | 31 ++++++++-------- 7 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 packages/core/src/shader/ShaderString.ts diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index e52ef233f5..d56a2f3bb0 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -12,6 +12,7 @@ import { ShaderDataGroup } from "./shader/enums/ShaderDataGroup"; import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; +import { ShaderString } from "./shader/ShaderString"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; import { Transform } from "./Transform"; @@ -69,7 +70,7 @@ export class Camera extends Component { /** @internal */ _replacementShader: Shader = null; /** @internal */ - _replacementSubShaderTag: string = null; + _replacementSubShaderTagKey: ShaderString = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -475,11 +476,11 @@ export class Camera extends Component { /** * Set the replacement shader. * @param shader - Replacement shader - * @param replacementTag - Replacement sub shader tag + * @param replacementTagKey - Replacement tag key */ - setReplacementShader(shader: Shader, replacementTag: string): void { + setReplacementShader(shader: Shader, replacementTagKey: ShaderString): void { this._replacementShader = shader; - this._replacementSubShaderTag = replacementTag; + this._replacementSubShaderTagKey = replacementTagKey; } /** @@ -487,7 +488,7 @@ export class Camera extends Component { */ resetReplacementShader(): void { this._replacementShader = null; - this._replacementSubShaderTag = null; + this._replacementSubShaderTagKey = null; } /** diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index c6cdceb5b8..af8aec4f2e 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -1,4 +1,4 @@ -import { Vector2, Vector3 } from "@oasis-engine/math"; +import { Vector2 } from "@oasis-engine/math"; import { SpriteMask } from "../2d"; import { Background } from "../Background"; import { Camera } from "../Camera"; @@ -12,6 +12,7 @@ import { Material } from "../material"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Shader } from "../shader/Shader"; import { ShaderPass } from "../shader/ShaderPass"; +import { ShaderString } from "../shader/ShaderString"; import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; @@ -25,8 +26,8 @@ import { RenderQueue } from "./RenderQueue"; * Basic render pipeline. */ export class BasicRenderPipeline { - private static _tempVector0 = new Vector3(); - private static _tempVector1 = new Vector3(); + private static _shadowCasterPipelineStage = ShaderString.getByName("ShadowCaster"); + private static _forwardPipelineStage = ShaderString.getByName("Forward"); /** @internal */ _opaqueQueue: RenderQueue; @@ -149,7 +150,7 @@ export class BasicRenderPipeline { camera.engine._spriteMaskManager.clear(); - context.pipelineStage = "ShadowCaster"; + context.pipelineStage = BasicRenderPipeline._shadowCasterPipelineStage; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -160,7 +161,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); - context.pipelineStage = "Forward"; + context.pipelineStage = BasicRenderPipeline._forwardPipelineStage; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); @@ -233,7 +234,8 @@ export class BasicRenderPipeline { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { const replacementSubShader = replacementSubShaders[i]; if ( - replacementSubShader.replacementTags[replacementTag] === materialSubShader.replacementTags[replacementTag] + replacementSubShader.getReplacementTag(replacementTag) === + materialSubShader.getReplacementTag(replacementTag) ) { this.pushRenderDataWihShader(context, data, replacementSubShader.passes, renderStates); } diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index fe4dbd79cd..cfc3dcd3bf 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,5 +1,6 @@ import { Camera } from "../Camera"; import { Shader } from "../shader"; +import { ShaderString } from "../shader/ShaderString"; import { VirtualCamera } from "../VirtualCamera"; /** @@ -17,8 +18,8 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTag: string; - pipelineStage: string; + replacementTag: ShaderString; + pipelineStage: ShaderString; applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index da38d2052b..e758205d15 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -4,6 +4,7 @@ import { ShaderMacro } from "./ShaderMacro"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderPass } from "./ShaderPass"; import { ShaderProperty } from "./ShaderProperty"; +import { ShaderString } from "./ShaderString"; import { SubShader } from "./SubShader"; /** @@ -52,7 +53,7 @@ export class Shader { let shader: Shader; if (typeof vertexSourceOrSubShaders === "string") { const shaderPass = new ShaderPass(vertexSourceOrSubShaders, fragmentSource); - shaderPass.pipelineStage = "Forward"; + shaderPass.pipelineStage = ShaderString.getByName("Forward"); shader = new Shader(name, [new SubShader("DefaultPass", [shaderPass])]); } else { shader = new Shader(name, vertexSourceOrSubShaders); diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 526eff3cae..ea80875579 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -4,6 +4,7 @@ import { ShaderFactory } from "../shaderlib/ShaderFactory"; import { Shader } from "./Shader"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderProgram } from "./ShaderProgram"; +import { ShaderString } from "./ShaderString"; /** * Shader pass containing vertex and fragment source. @@ -11,8 +12,8 @@ import { ShaderProgram } from "./ShaderProgram"; export class ShaderPass { private static _shaderPassCounter: number = 0; - /** */ - pipelineStage: string; + /** Pipeline stage. */ + pipelineStage: ShaderString; /** @internal */ _shaderPassId: number = 0; diff --git a/packages/core/src/shader/ShaderString.ts b/packages/core/src/shader/ShaderString.ts new file mode 100644 index 0000000000..e11036c647 --- /dev/null +++ b/packages/core/src/shader/ShaderString.ts @@ -0,0 +1,36 @@ +/** + * ShaderString is a class that represents a shader string. + */ +export class ShaderString { + private static _nameCounter: number = 0; + private static _nameMap: Record = Object.create(null); + private static _idMap: Record = Object.create(null); + + /** + * Get shader property by name. + * @param name - Name of the shader property + * @returns Shader property + */ + static getByName(name: string): ShaderString { + const propertyNameMap = ShaderString._nameMap; + if (propertyNameMap[name] != null) { + return propertyNameMap[name]; + } else { + const property = new ShaderString(name); + propertyNameMap[name] = property; + ShaderString._idMap[property._uniqueId] = property; + return property; + } + } + + /** Shader property name. */ + readonly name: string; + + /** @internal */ + _uniqueId: number; + + private constructor(name: string) { + this.name = name; + this._uniqueId = ShaderString._nameCounter++; + } +} diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 341482d6b8..42bbf2bb26 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -1,4 +1,5 @@ import { ShaderPass } from "./ShaderPass"; +import { ShaderString } from "./ShaderString"; /** * Sub shader. @@ -7,16 +8,9 @@ export class SubShader { /** Disable batch. */ disableBatch: boolean = false; - private _replacementTags: Record; + private _replacementTagsMap: Record; private _passes: ShaderPass[] = []; - /** - * replacement tags. - */ - get replacementTags(): Readonly> { - return this._replacementTags; - } - /** * Sub shader passes. */ @@ -41,15 +35,24 @@ export class SubShader { /** * Add a replacement tag. - * @param name - Name of the tag + * @param key - Key of the tag * @param value - Value of the tag */ - addReplacementTag(name: string, value: string): void { - const tags = this._replacementTags; - if (tags[name]) { - throw `Tag named "${name}" already exists.`; + addReplacementTag(key: ShaderString, value: ShaderString): void { + const tags = this._replacementTagsMap; + if (tags[key._uniqueId]) { + throw `Tag named "${key}" already exists.`; } - tags[name] = value; + tags[key._uniqueId] = value; + } + + /** + * Get a replacement tag. + * @param key - Key of the tag + * @returns Value of the tag + */ + getReplacementTag(key: ShaderString): ShaderString { + return this._replacementTagsMap[key._uniqueId]; } } From c606f95fa423ce3a1284ce924bc7969f6b11dbff Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 00:46:26 +0800 Subject: [PATCH 06/62] refactor: opt code --- packages/core/src/shader/Shader.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index e758205d15..1fcf0ff04a 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -45,18 +45,32 @@ export class Shader { */ static create(name: string, shaderPasses: SubShader[]): Shader; - static create(name: string, vertexSourceOrSubShaders: string | SubShader[], fragmentSource?: string): Shader { + static create( + name: string, + vertexSourceOrShaderPassesOrSubShaders: SubShader[] | ShaderPass[] | string, + fragmentSource?: string + ): Shader { const shaderMap = Shader._shaderMap; if (shaderMap[name]) { throw `Shader named "${name}" already exists.`; } let shader: Shader; - if (typeof vertexSourceOrSubShaders === "string") { - const shaderPass = new ShaderPass(vertexSourceOrSubShaders, fragmentSource); + if (typeof vertexSourceOrShaderPassesOrSubShaders === "string") { + const shaderPass = new ShaderPass(vertexSourceOrShaderPassesOrSubShaders, fragmentSource); shaderPass.pipelineStage = ShaderString.getByName("Forward"); shader = new Shader(name, [new SubShader("DefaultPass", [shaderPass])]); } else { - shader = new Shader(name, vertexSourceOrSubShaders); + if (vertexSourceOrShaderPassesOrSubShaders.length > 0) { + if (vertexSourceOrShaderPassesOrSubShaders[0].constructor === ShaderPass) { + shader = new Shader(name, [ + new SubShader("DefaultPass", vertexSourceOrShaderPassesOrSubShaders) + ]); + } else { + shader = new Shader(name, vertexSourceOrShaderPassesOrSubShaders); + } + } else { + throw "SubShader or ShaderPass count must large than 0."; + } } shaderMap[name] = shader; return shader; From 9e49d312fcd533e3aca932844c38770cb5ea0d5d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 00:57:06 +0800 Subject: [PATCH 07/62] refactor: opt code --- packages/core/src/shader/Shader.ts | 13 +++++++--- packages/core/src/shader/ShaderPass.ts | 5 ++-- packages/core/src/shader/ShaderPool.ts | 33 ++++++++++++++++---------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index 1fcf0ff04a..e9344775a0 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -40,10 +40,18 @@ export class Shader { /** * Create a shader. * @param name - Name of the shader - * @param SubShader - Sub shader + * @param shaderPasses - Shader passes * @returns Shader */ - static create(name: string, shaderPasses: SubShader[]): Shader; + static create(name: string, shaderPasses: ShaderPass[]): Shader; + + /** + * Create a shader. + * @param name - Name of the shader + * @param SubShaders - Sub shaders + * @returns Shader + */ + static create(name: string, SubShaders: SubShader[]): Shader; static create( name: string, @@ -57,7 +65,6 @@ export class Shader { let shader: Shader; if (typeof vertexSourceOrShaderPassesOrSubShaders === "string") { const shaderPass = new ShaderPass(vertexSourceOrShaderPassesOrSubShaders, fragmentSource); - shaderPass.pipelineStage = ShaderString.getByName("Forward"); shader = new Shader(name, [new SubShader("DefaultPass", [shaderPass])]); } else { if (vertexSourceOrShaderPassesOrSubShaders.length > 0) { diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index ea80875579..2e0fd76c35 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -13,7 +13,7 @@ export class ShaderPass { private static _shaderPassCounter: number = 0; /** Pipeline stage. */ - pipelineStage: ShaderString; + readonly pipelineStage: ShaderString; /** @internal */ _shaderPassId: number = 0; @@ -21,11 +21,12 @@ export class ShaderPass { private _vertexSource: string; private _fragmentSource: string; - constructor(vertexSource: string, fragmentSource: string) { + constructor(vertexSource: string, fragmentSource: string, pipelineStage?: ShaderString) { this._shaderPassId = ShaderPass._shaderPassCounter++; this._vertexSource = vertexSource; this._fragmentSource = fragmentSource; + this.pipelineStage = pipelineStage || ShaderString.getByName("Forward"); } /** diff --git a/packages/core/src/shader/ShaderPool.ts b/packages/core/src/shader/ShaderPool.ts index cb15b5cee1..60f55bf5a7 100644 --- a/packages/core/src/shader/ShaderPool.ts +++ b/packages/core/src/shader/ShaderPool.ts @@ -1,9 +1,11 @@ +import backgroundTextureFs from "../shaderlib/extra/background-texture.fs.glsl"; +import backgroundTextureVs from "../shaderlib/extra/background-texture.vs.glsl"; import blinnPhongFs from "../shaderlib/extra/blinn-phong.fs.glsl"; import blinnPhongVs from "../shaderlib/extra/blinn-phong.vs.glsl"; import particleFs from "../shaderlib/extra/particle.fs.glsl"; import particleVs from "../shaderlib/extra/particle.vs.glsl"; -import pbrFs from "../shaderlib/extra/pbr.fs.glsl"; import pbrSpecularFs from "../shaderlib/extra/pbr-specular.fs.glsl"; +import pbrFs from "../shaderlib/extra/pbr.fs.glsl"; import pbrVs from "../shaderlib/extra/pbr.vs.glsl"; import shadowMapFs from "../shaderlib/extra/shadow-map.fs.glsl"; import shadowMapVs from "../shaderlib/extra/shadow-map.vs.glsl"; @@ -15,9 +17,9 @@ import spriteFs from "../shaderlib/extra/sprite.fs.glsl"; import spriteVs from "../shaderlib/extra/sprite.vs.glsl"; import unlitFs from "../shaderlib/extra/unlit.fs.glsl"; import unlitVs from "../shaderlib/extra/unlit.vs.glsl"; -import backgroundTextureVs from "../shaderlib/extra/background-texture.vs.glsl"; -import backgroundTextureFs from "../shaderlib/extra/background-texture.fs.glsl"; import { Shader } from "./Shader"; +import { ShaderPass } from "./ShaderPass"; +import { ShaderString } from "./ShaderString"; /** * Internal shader pool. @@ -25,15 +27,20 @@ import { Shader } from "./Shader"; */ export class ShaderPool { static init(): void { - Shader.create("blinn-phong", blinnPhongVs, blinnPhongFs); - Shader.create("pbr", pbrVs, pbrFs); - Shader.create("pbr-specular", pbrVs, pbrSpecularFs); - Shader.create("unlit", unlitVs, unlitFs); - Shader.create("shadow-map", shadowMapVs, shadowMapFs); - Shader.create("skybox", skyboxVs, skyboxFs); - Shader.create("particle-shader", particleVs, particleFs); - Shader.create("SpriteMask", spriteMaskVs, spriteMaskFs); - Shader.create("Sprite", spriteVs, spriteFs); - Shader.create("background-texture", backgroundTextureVs, backgroundTextureFs); + const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, ShaderString.getByName("ShadowCaster")); + const forwardPipelineStage = ShaderString.getByName("Forward"); + + Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, forwardPipelineStage), shadowCasterPass]); + Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, forwardPipelineStage), shadowCasterPass]); + Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, forwardPipelineStage), shadowCasterPass]); + Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, forwardPipelineStage), shadowCasterPass]); + + Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, forwardPipelineStage)]); + Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, forwardPipelineStage)]); + Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, forwardPipelineStage)]); + Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, forwardPipelineStage)]); + Shader.create("background-texture", [ + new ShaderPass(backgroundTextureVs, backgroundTextureFs, forwardPipelineStage) + ]); } } From 81172ec4641635978f5a053d3917297f3a50452b Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 13:39:11 +0800 Subject: [PATCH 08/62] =?UTF-8?q?refactor=EF=BC=9A=20opt=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/2d/assembler/SimpleSpriteAssembler.ts | 8 ++++---- packages/core/src/2d/assembler/SlicedSpriteAssembler.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts b/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts index 9df7ffa9b3..546e89bc6a 100644 --- a/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts +++ b/packages/core/src/2d/assembler/SimpleSpriteAssembler.ts @@ -13,16 +13,16 @@ export class SimpleSpriteAssembler { static _worldMatrix: Matrix = new Matrix(); static resetData(renderer: SpriteRenderer | SpriteMask): void { - const { _verticesData: renderData } = renderer; - const vertexCount = (renderData.vertexCount = 4); - const { positions, uvs } = renderData; + const { _verticesData: verticesData } = renderer; + const vertexCount = (verticesData.vertexCount = 4); + const { positions, uvs } = verticesData; if (positions.length < vertexCount) { for (let i = positions.length; i < vertexCount; i++) { positions.push(new Vector3()); uvs.push(new Vector2()); } } - renderData.triangles = SimpleSpriteAssembler._rectangleTriangles; + verticesData.triangles = SimpleSpriteAssembler._rectangleTriangles; } static updatePositions(renderer: SpriteRenderer | SpriteMask): void { diff --git a/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts b/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts index e82b84d745..45248e2f90 100644 --- a/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts +++ b/packages/core/src/2d/assembler/SlicedSpriteAssembler.ts @@ -10,15 +10,15 @@ import { IAssembler } from "./IAssembler"; export class SlicedSpriteAssembler { static _worldMatrix: Matrix = new Matrix(); static resetData(renderer: SpriteRenderer): void { - const { _verticesData: renderData } = renderer; - const { positions, uvs } = renderData; + const { _verticesData: verticesData } = renderer; + const { positions, uvs } = verticesData; if (positions.length < 16) { for (let i = positions.length; i < 16; i++) { positions.push(new Vector3()); uvs.push(new Vector2()); } } - renderData.triangles = []; + verticesData.triangles = []; } static updatePositions(renderer: SpriteRenderer): void { From f8d3254ddde57b698cfe1c2c50a00d795c596b28 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:14:43 +0800 Subject: [PATCH 09/62] refactor: opt code --- packages/core/src/2d/sprite/SpriteMask.ts | 2 +- packages/core/src/2d/text/TextRenderer.ts | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/core/src/2d/sprite/SpriteMask.ts b/packages/core/src/2d/sprite/SpriteMask.ts index 667a4f5883..c980604608 100644 --- a/packages/core/src/2d/sprite/SpriteMask.ts +++ b/packages/core/src/2d/sprite/SpriteMask.ts @@ -212,7 +212,7 @@ export class SpriteMask extends Renderer implements ICustomClone { const renderData = this._engine._spriteMaskRenderDataPool.getFromPool(); const material = this.getMaterial(); renderData.setValue(this, material, this._verticesData); - + const renderElement = this._engine._renderElementPool.getFromPool(); renderElement.set(renderData, material.shader[0].shaderPasses[0], material.renderStates[0]); this._maskElement = renderElement; diff --git a/packages/core/src/2d/text/TextRenderer.ts b/packages/core/src/2d/text/TextRenderer.ts index 3ceaa2b72e..c94f7f6488 100644 --- a/packages/core/src/2d/text/TextRenderer.ts +++ b/packages/core/src/2d/text/TextRenderer.ts @@ -5,7 +5,6 @@ import { Engine } from "../../Engine"; import { Entity } from "../../Entity"; import { Renderer } from "../../Renderer"; import { RenderContext } from "../../RenderPipeline/RenderContext"; -import { SpriteRenderData } from "../../RenderPipeline/SpriteRenderData"; import { CompareFunction } from "../../shader/enums/CompareFunction"; import { TransformModifyFlags } from "../../Transform"; import { FontStyle } from "../enums/FontStyle"; @@ -67,9 +66,6 @@ export class TextRenderer extends Renderer implements ICustomClone { @assignmentClone private _maskLayer: number = SpriteMaskLayer.Layer0; - @ignoreClone - private _charsRenderData: SpriteRenderData[] = []; - /** * Rendering color for the Text. */ @@ -384,14 +380,14 @@ export class TextRenderer extends Renderer implements ICustomClone { } const spriteRenderDataPool = this._engine._spriteRenderDataPool; - const textElement = this._engine._textRenderDataPool.getFromPool(); - const charsData = textElement.charsData; + const textData = this._engine._textRenderDataPool.getFromPool(); + const charsData = textData.charsData; const material = this.getMaterial(); const charRenderDatas = this._charRenderDatas; const charCount = charRenderDatas.length; - textElement.component = this; - textElement.material = material; + textData.component = this; + textData.material = material; charsData.length = charCount; for (let i = 0; i < charCount; ++i) { @@ -400,7 +396,7 @@ export class TextRenderer extends Renderer implements ICustomClone { spriteRenderData.set(this, material, charRenderData.renderData, charRenderData.texture, i); charsData[i] = spriteRenderData; } - context.camera._renderPipeline.pushRenderData(context, textElement); + context.camera._renderPipeline.pushRenderData(context, textData); } private _updateStencilState(): void { From a091ab13eb6ac5b83fd8bc9d8b44fc18fd63df69 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:26:48 +0800 Subject: [PATCH 10/62] refactor: opt code --- packages/core/src/Camera.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index d56a2f3bb0..2979cb822a 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -476,15 +476,19 @@ export class Camera extends Component { /** * Set the replacement shader. * @param shader - Replacement shader - * @param replacementTagKey - Replacement tag key + * @param replacementTagKey - Sub shader tag key + * + * @remarks + * If replacementTagKey is not specified, the first sub shader will be replaced. + * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same replacement tag value get by replacementTagKey. */ - setReplacementShader(shader: Shader, replacementTagKey: ShaderString): void { + setReplacementShader(shader: Shader, replacementTagKey?: ShaderString): void { this._replacementShader = shader; this._replacementSubShaderTagKey = replacementTagKey; } /** - * Reset the replacement shader. + * Reset and clear the replacement shader. */ resetReplacementShader(): void { this._replacementShader = null; From b28ac21c0fda51463c428372725a4d8f9d013ae3 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:35:35 +0800 Subject: [PATCH 11/62] refactor: opt code --- .../core/src/RenderPipeline/Basic2DBatcher.ts | 19 +++++++++---------- .../src/RenderPipeline/BasicRenderPipeline.ts | 6 +++--- .../core/src/RenderPipeline/RenderQueue.ts | 8 ++++---- .../src/RenderPipeline/SpriteMaskManager.ts | 6 +++--- .../src/shadow/CascadedShadowCasterPass.ts | 4 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 6025d62f06..47b7c170c2 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -1,7 +1,6 @@ import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { Buffer, BufferBindFlag, BufferUsage, IndexFormat, MeshTopology, SubMesh, VertexElement } from "../graphic"; -import { Material } from "../material"; import { BufferMesh } from "../mesh"; import { ClassPool } from "./ClassPool"; import { RenderElement } from "./RenderElement"; @@ -46,7 +45,7 @@ export abstract class Basic2DBatcher { this._initMeshes(engine); } - drawElement(element: RenderElement, camera: Camera, replaceMaterial: Material): void { + drawElement(element: RenderElement, camera: Camera): void { const data = element.data; if (data.multiRenderData) { @@ -56,10 +55,10 @@ export abstract class Basic2DBatcher { for (let i = 0, n = charsData.length; i < n; ++i) { const charRenderElement = pool.getFromPool(); charRenderElement.set(charsData[i], element.shaderPass, element.renderState); - this._drawSubElement(charRenderElement, camera, replaceMaterial); + this._drawSubElement(charRenderElement, camera); } } else { - this._drawSubElement(element, camera, replaceMaterial); + this._drawSubElement(element, camera); } } @@ -78,24 +77,24 @@ export abstract class Basic2DBatcher { } } - private _drawSubElement(element: RenderElement, camera: Camera, replaceMaterial: Material) { + private _drawSubElement(element: RenderElement, camera: Camera): void { const len = (element.data).renderData.vertexCount; if (this._vertexCount + len > Basic2DBatcher.MAX_VERTEX_COUNT) { - this.flush(camera, replaceMaterial); + this.flush(camera); } this._vertexCount += len; this._batchedQueue[this._elementCount++] = element; } - flush(camera: Camera, replaceMaterial: Material): void { + flush(camera: Camera): void { const batchedQueue = this._batchedQueue; if (batchedQueue.length === 0) { return; } this._updateData(this._engine); - this.drawBatches(camera, replaceMaterial); + this.drawBatches(camera); if (!Basic2DBatcher._canUploadSameBuffer) { this._flushId++; @@ -184,7 +183,7 @@ export abstract class Basic2DBatcher { let preElement: RenderElement = null; for (let i = 0, len = batchedQueue.length; i < len; i++) { const curElement = batchedQueue[i]; - const curData= curElement.data; + const curData = curElement.data; // Batch vertex vertexIndex = this.updateVertices(curData, vertices, vertexIndex); @@ -247,5 +246,5 @@ export abstract class Basic2DBatcher { /** * @internal */ - abstract drawBatches(camera: Camera, replaceMaterial: Material): void; + abstract drawBatches(camera: Camera): void; } diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index af8aec4f2e..6197c54abf 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -197,8 +197,8 @@ export class BasicRenderPipeline { if (pass.renderOverride) { pass.render(camera, this._opaqueQueue, this._alphaTestQueue, this._transparentQueue); } else { - this._opaqueQueue.render(camera, pass.replaceMaterial, pass.mask); - this._alphaTestQueue.render(camera, pass.replaceMaterial, pass.mask); + this._opaqueQueue.render(camera, pass.mask); + this._alphaTestQueue.render(camera, pass.mask); if (camera.clearFlags & CameraClearFlags.Color) { if (background.mode === BackgroundMode.Sky) { background.sky._render(context); @@ -206,7 +206,7 @@ export class BasicRenderPipeline { this._drawBackgroundTexture(engine, background); } } - this._transparentQueue.render(camera, pass.replaceMaterial, pass.mask); + this._transparentQueue.render(camera, pass.mask); } renderTarget?._blitRenderTarget(); diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index 6d781862fb..fd418f559f 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -41,7 +41,7 @@ export class RenderQueue { this.items.push(element); } - render(camera: Camera, replaceMaterial: Material, mask: Layer): void { + render(camera: Camera, mask: Layer): void { const items = this.items; if (items.length === 0) { return; @@ -63,7 +63,7 @@ export class RenderQueue { } if (!!(data as MeshRenderData).mesh) { - this._spriteBatcher.flush(camera, replaceMaterial); + this._spriteBatcher.flush(camera); const compileMacros = Shader._compileMacros; const element = data; @@ -138,11 +138,11 @@ export class RenderQueue { rhi.drawPrimitive(element.mesh, element.subMesh, program); } else { - this._spriteBatcher.drawElement(renderItem, camera, replaceMaterial); + this._spriteBatcher.drawElement(renderItem, camera); } } - this._spriteBatcher.flush(camera, replaceMaterial); + this._spriteBatcher.flush(camera); } /** diff --git a/packages/core/src/RenderPipeline/SpriteMaskManager.ts b/packages/core/src/RenderPipeline/SpriteMaskManager.ts index 48d096362a..f224255171 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskManager.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskManager.ts @@ -29,7 +29,7 @@ export class SpriteMaskManager { this._batcher.clear(); this._processMasksDiff(camera, renderer); - this._batcher.flush(camera, null); + this._batcher.flush(camera); } postRender(renderer: SpriteRenderer): void { @@ -66,14 +66,14 @@ export class SpriteMaskManager { if (influenceLayers & addLayer) { const maskRenderElement = mask._maskElement; (maskRenderElement.data).isAdd = true; - this._batcher.drawElement(maskRenderElement, camera, null); + this._batcher.drawElement(maskRenderElement, camera); continue; } if (influenceLayers & reduceLayer) { const maskRenderElement = mask._maskElement; (maskRenderElement.data).isAdd = false; - this._batcher.drawElement(maskRenderElement, camera, null); + this._batcher.drawElement(maskRenderElement, camera); } } } diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index 178b34e97b..b2cc94c7d0 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -208,8 +208,8 @@ export class CascadedShadowCasterPass { rhi.scissor(x + 1, y + 1, shadowTileResolution - 2, shadowTileResolution - 2); engine._renderCount++; - opaqueQueue.render(camera, null, Layer.Everything); - alphaTestQueue.render(camera, null, Layer.Everything); + opaqueQueue.render(camera, Layer.Everything); + alphaTestQueue.render(camera, Layer.Everything); rhi.setGlobalDepthBias(0, 0); } } From d92dc82d1149e53fc74f5bef3e39a19bbfc390f5 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:36:54 +0800 Subject: [PATCH 12/62] refactor: opt code --- .../core/src/RenderPipeline/Basic2DBatcher.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 47b7c170c2..a8c3045a5a 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -77,16 +77,6 @@ export abstract class Basic2DBatcher { } } - private _drawSubElement(element: RenderElement, camera: Camera): void { - const len = (element.data).renderData.vertexCount; - if (this._vertexCount + len > Basic2DBatcher.MAX_VERTEX_COUNT) { - this.flush(camera); - } - - this._vertexCount += len; - this._batchedQueue[this._elementCount++] = element; - } - flush(camera: Camera): void { const batchedQueue = this._batchedQueue; @@ -134,6 +124,16 @@ export abstract class Basic2DBatcher { this._indiceBuffers = null; } + private _drawSubElement(element: RenderElement, camera: Camera): void { + const len = (element.data).renderData.vertexCount; + if (this._vertexCount + len > Basic2DBatcher.MAX_VERTEX_COUNT) { + this.flush(camera); + } + + this._vertexCount += len; + this._batchedQueue[this._elementCount++] = element; + } + private _createMesh(engine: Engine, index: number): BufferMesh { const { MAX_VERTEX_COUNT } = Basic2DBatcher; const mesh = new BufferMesh(engine, `BufferMesh${index}`); From 0b45014d1a219be823afed8a8a01f26cde129a53 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:47:25 +0800 Subject: [PATCH 13/62] refactor: opt code --- .../core/src/RenderPipeline/Basic2DBatcher.ts | 6 +++--- .../src/RenderPipeline/BasicRenderPipeline.ts | 15 +++++++-------- packages/core/src/RenderPipeline/RenderContext.ts | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index a8c3045a5a..0a0393ef66 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -125,12 +125,12 @@ export abstract class Basic2DBatcher { } private _drawSubElement(element: RenderElement, camera: Camera): void { - const len = (element.data).renderData.vertexCount; - if (this._vertexCount + len > Basic2DBatcher.MAX_VERTEX_COUNT) { + const vertexCount = (element.data).renderData.vertexCount; + if (this._vertexCount + vertexCount > Basic2DBatcher.MAX_VERTEX_COUNT) { this.flush(camera); } - this._vertexCount += len; + this._vertexCount += vertexCount; this._batchedQueue[this._elementCount++] = element; } diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 6197c54abf..2e12961a5e 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -222,22 +222,21 @@ export class BasicRenderPipeline { * @param data - Render data */ pushRenderData(context: RenderContext, data: RenderData): void { - const material = data.material; - const renderStates = material.renderStates; + const { material } = data; + const { renderStates } = material; const materialSubShader = material.shader.subShaders[0]; const replacementShader = context.replacementShader; if (replacementShader) { const replacementSubShaders = replacementShader.subShaders; - const { replacementTag } = context; - if (replacementTag) { + const { replacementTagKey } = context; + if (replacementTagKey) { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { - const replacementSubShader = replacementSubShaders[i]; + const subShader = replacementSubShaders[i]; if ( - replacementSubShader.getReplacementTag(replacementTag) === - materialSubShader.getReplacementTag(replacementTag) + subShader.getReplacementTag(replacementTagKey) === materialSubShader.getReplacementTag(replacementTagKey) ) { - this.pushRenderDataWihShader(context, data, replacementSubShader.passes, renderStates); + this.pushRenderDataWihShader(context, data, subShader.passes, renderStates); } } } else { diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index cfc3dcd3bf..d1257b4338 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -18,7 +18,7 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTag: ShaderString; + replacementTagKey: ShaderString; pipelineStage: ShaderString; applyVirtualCamera(virtualCamera: VirtualCamera): void { From d20abbab3d543a7f7f70ae2593aad4f69963d53d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:52:44 +0800 Subject: [PATCH 14/62] refactor: opt code --- packages/core/src/RenderPipeline/RenderElement.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/src/RenderPipeline/RenderElement.ts b/packages/core/src/RenderPipeline/RenderElement.ts index 9f0bfadc2d..4af61ab184 100644 --- a/packages/core/src/RenderPipeline/RenderElement.ts +++ b/packages/core/src/RenderPipeline/RenderElement.ts @@ -7,8 +7,6 @@ export class RenderElement { shaderPass: ShaderPass; renderState: RenderState; - multiRenderData: boolean; - set(data: RenderData, shaderPass: ShaderPass, renderState: RenderState): void { this.data = data; this.shaderPass = shaderPass; From 75610a14e95adb04628f5fa12a40cb1c80a77ca5 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:56:03 +0800 Subject: [PATCH 15/62] refactor: opt code --- .../core/src/RenderPipeline/RenderQueue.ts | 28 +++++++++++-------- .../src/shadow/CascadedShadowCasterPass.ts | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index fd418f559f..887bb54412 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -1,11 +1,9 @@ import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { Layer } from "../Layer"; -import { Material } from "../material/Material"; import { Shader } from "../shader"; import { ShaderMacroCollection } from "../shader/ShaderMacroCollection"; import { MeshRenderData } from "./MeshRenderData"; -import { RenderData } from "./RenderData"; import { RenderElement } from "./RenderElement"; import { SpriteBatcher } from "./SpriteBatcher"; @@ -17,17 +15,23 @@ export class RenderQueue { * @internal */ static _compareFromNearToFar(a: RenderElement, b: RenderElement): number { - return a.data.component.priority - b.data.component.priority || a.data.component._distanceForSort - b.data.component._distanceForSort; + return ( + a.data.component.priority - b.data.component.priority || + a.data.component._distanceForSort - b.data.component._distanceForSort + ); } /** * @internal */ static _compareFromFarToNear(a: RenderElement, b: RenderElement): number { - return a.data.component.priority - b.data.component.priority || b.data.component._distanceForSort - a.data.component._distanceForSort; + return ( + a.data.component.priority - b.data.component.priority || + b.data.component._distanceForSort - a.data.component._distanceForSort + ); } - readonly items: RenderElement[] = []; + readonly elements: RenderElement[] = []; private _spriteBatcher: SpriteBatcher; constructor(engine: Engine) { @@ -38,12 +42,12 @@ export class RenderQueue { * Push a render element. */ pushRenderElement(element: RenderElement): void { - this.items.push(element); + this.elements.push(element); } render(camera: Camera, mask: Layer): void { - const items = this.items; - if (items.length === 0) { + const elements = this.elements; + if (elements.length === 0) { return; } @@ -53,8 +57,8 @@ export class RenderQueue { const sceneData = scene.shaderData; const cameraData = camera.shaderData; - for (let i = 0, n = items.length; i < n; i++) { - const renderItem = items[i]; + for (let i = 0, n = elements.length; i < n; i++) { + const renderItem = elements[i]; const data = renderItem.data; const renderPassFlag = data.component.entity.layer; @@ -149,7 +153,7 @@ export class RenderQueue { * Clear collection. */ clear(): void { - this.items.length = 0; + this.elements.length = 0; this._spriteBatcher.clear(); } @@ -165,7 +169,7 @@ export class RenderQueue { * Sort the elements. */ sort(compareFunc: Function): void { - this._quickSort(this.items, 0, this.items.length, compareFunc); + this._quickSort(this.elements, 0, this.elements.length, compareFunc); } /** diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index b2cc94c7d0..6cd7965651 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -195,7 +195,7 @@ export class CascadedShadowCasterPass { ShadowUtils.shadowCullFrustum(context, light, elements[k], shadowSliceData); } - if (opaqueQueue.items.length || alphaTestQueue.items.length) { + if (opaqueQueue.elements.length || alphaTestQueue.elements.length) { opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); From 8a40bd1f17905689483360cd2b2bc1caf9feea39 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 14:58:27 +0800 Subject: [PATCH 16/62] refactor: opt code --- .../core/src/RenderPipeline/RenderQueue.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/core/src/RenderPipeline/RenderQueue.ts b/packages/core/src/RenderPipeline/RenderQueue.ts index 887bb54412..66cd907637 100644 --- a/packages/core/src/RenderPipeline/RenderQueue.ts +++ b/packages/core/src/RenderPipeline/RenderQueue.ts @@ -58,8 +58,8 @@ export class RenderQueue { const cameraData = camera.shaderData; for (let i = 0, n = elements.length; i < n; i++) { - const renderItem = elements[i]; - const data = renderItem.data; + const element = elements[i]; + const data = element.data; const renderPassFlag = data.component.entity.layer; if (!(renderPassFlag & mask)) { @@ -70,9 +70,9 @@ export class RenderQueue { this._spriteBatcher.flush(camera); const compileMacros = Shader._compileMacros; - const element = data; - const renderer = element.component; - const material = element.material.destroyed ? engine._magentaMaterial : element.material; + const meshData = data; + const renderer = meshData.component; + const material = meshData.material.destroyed ? engine._magentaMaterial : meshData.material; const rendererData = renderer.shaderData; const materialData = material.shaderData; @@ -83,7 +83,7 @@ export class RenderQueue { compileMacros ); - const program = renderItem.shaderPass._getShaderProgram(engine, compileMacros); + const program = element.shaderPass._getShaderProgram(engine, compileMacros); if (!program.isValid) { continue; } @@ -138,11 +138,11 @@ export class RenderQueue { program.uploadUnGroupTextures(); } } - renderItem.renderState._apply(engine, renderer.entity.transform._isFrontFaceInvert()); + element.renderState._apply(engine, renderer.entity.transform._isFrontFaceInvert()); - rhi.drawPrimitive(element.mesh, element.subMesh, program); + rhi.drawPrimitive(meshData.mesh, meshData.subMesh, program); } else { - this._spriteBatcher.drawElement(renderItem, camera); + this._spriteBatcher.drawElement(element, camera); } } From 647f6aaf0b9af79d74d6a8cff83b27e79481f7a8 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:02:04 +0800 Subject: [PATCH 17/62] refactor: opt code --- packages/core/src/RenderPipeline/Basic2DBatcher.ts | 6 +++--- packages/core/src/RenderPipeline/SpriteBatcher.ts | 2 +- packages/core/src/RenderPipeline/SpriteMaskBatcher.ts | 2 +- packages/core/src/RenderPipeline/SpriteMaskRenderData.ts | 6 +++--- packages/core/src/RenderPipeline/SpriteRenderData.ts | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 0a0393ef66..9b705e9871 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -125,7 +125,7 @@ export abstract class Basic2DBatcher { } private _drawSubElement(element: RenderElement, camera: Camera): void { - const vertexCount = (element.data).renderData.vertexCount; + const vertexCount = (element.data).verticesData.vertexCount; if (this._vertexCount + vertexCount > Basic2DBatcher.MAX_VERTEX_COUNT) { this.flush(camera); } @@ -189,13 +189,13 @@ export abstract class Basic2DBatcher { vertexIndex = this.updateVertices(curData, vertices, vertexIndex); // Batch indice - const { triangles } = curData.renderData; + const { triangles } = curData.verticesData; const triangleNum = triangles.length; for (let j = 0; j < triangleNum; j++) { indices[indiceIndex++] = triangles[j] + curIndiceStartIndex; } - curIndiceStartIndex += curData.renderData.vertexCount; + curIndiceStartIndex += curData.verticesData.vertexCount; if (preElement === null) { vertexCount += triangleNum; diff --git a/packages/core/src/RenderPipeline/SpriteBatcher.ts b/packages/core/src/RenderPipeline/SpriteBatcher.ts index 625695dbdf..b93cf3c052 100644 --- a/packages/core/src/RenderPipeline/SpriteBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteBatcher.ts @@ -60,7 +60,7 @@ export class SpriteBatcher extends Basic2DBatcher { } updateVertices(element: SpriteRenderData, vertices: Float32Array, vertexIndex: number): number { - const { positions, uvs, color, vertexCount } = element.renderData; + const { positions, uvs, color, vertexCount } = element.verticesData; for (let i = 0; i < vertexCount; i++) { const curPos = positions[i]; const curUV = uvs[i]; diff --git a/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts b/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts index ca76d8aa34..1a0cca0544 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskBatcher.ts @@ -37,7 +37,7 @@ export class SpriteMaskBatcher extends Basic2DBatcher { } updateVertices(element: SpriteMaskRenderData, vertices: Float32Array, vertexIndex: number): number { - const { positions, uvs, vertexCount } = element.renderData; + const { positions, uvs, vertexCount } = element.verticesData; for (let i = 0; i < vertexCount; i++) { const curPos = positions[i]; const curUV = uvs[i]; diff --git a/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts index 52efe8f127..cd19c619c3 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts @@ -5,17 +5,17 @@ import { RenderData } from "./RenderData"; export class SpriteMaskRenderData extends RenderData { isAdd: boolean = true; - renderData: VertexData2D; + verticesData: VertexData2D; constructor() { super(); this.multiRenderData = false; } - setValue(component: Renderer, material: Material, renderData: VertexData2D): void { + setValue(component: Renderer, material: Material, verticesData: VertexData2D): void { this.component = component; this.material = material; - this.renderData = renderData; + this.verticesData = verticesData; } } diff --git a/packages/core/src/RenderPipeline/SpriteRenderData.ts b/packages/core/src/RenderPipeline/SpriteRenderData.ts index 80718440d7..50f3541285 100644 --- a/packages/core/src/RenderPipeline/SpriteRenderData.ts +++ b/packages/core/src/RenderPipeline/SpriteRenderData.ts @@ -5,7 +5,7 @@ import { Texture2D } from "../texture"; import { RenderData } from "./RenderData"; export class SpriteRenderData extends RenderData { - renderData: VertexData2D; + verticesData: VertexData2D; texture: Texture2D; dataIndex: number; // Add for CanvasRenderer plugin. @@ -17,14 +17,14 @@ export class SpriteRenderData extends RenderData { set( component: Renderer, material: Material, - renderDate: VertexData2D, + verticesData: VertexData2D, texture: Texture2D, dataIndex: number = 0 ): void { this.component = component; this.material = material; - this.renderData = renderDate; + this.verticesData = verticesData; this.texture = texture; this.dataIndex = dataIndex; } From c9b783c96aaec768eb4db8bc16f9eba1582d0f50 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:05:51 +0800 Subject: [PATCH 18/62] refactor: opt code --- packages/core/src/2d/sprite/SpriteMask.ts | 2 +- packages/core/src/RenderPipeline/SpriteMaskRenderData.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/core/src/2d/sprite/SpriteMask.ts b/packages/core/src/2d/sprite/SpriteMask.ts index c980604608..59b6ed4766 100644 --- a/packages/core/src/2d/sprite/SpriteMask.ts +++ b/packages/core/src/2d/sprite/SpriteMask.ts @@ -211,7 +211,7 @@ export class SpriteMask extends Renderer implements ICustomClone { const renderData = this._engine._spriteMaskRenderDataPool.getFromPool(); const material = this.getMaterial(); - renderData.setValue(this, material, this._verticesData); + renderData.set(this, material, this._verticesData); const renderElement = this._engine._renderElementPool.getFromPool(); renderElement.set(renderData, material.shader[0].shaderPasses[0], material.renderStates[0]); diff --git a/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts index cd19c619c3..fb01c2ff50 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts @@ -12,10 +12,9 @@ export class SpriteMaskRenderData extends RenderData { this.multiRenderData = false; } - setValue(component: Renderer, material: Material, verticesData: VertexData2D): void { + set(component: Renderer, material: Material, verticesData: VertexData2D): void { this.component = component; this.material = material; - this.verticesData = verticesData; } } From 79c9b767927aaaa1aa73491e1a70f57453edf65c Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:08:38 +0800 Subject: [PATCH 19/62] refactor: opt code --- packages/core/src/graphic/Mesh.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/core/src/graphic/Mesh.ts b/packages/core/src/graphic/Mesh.ts index f48b0485e4..58b06ba1d9 100644 --- a/packages/core/src/graphic/Mesh.ts +++ b/packages/core/src/graphic/Mesh.ts @@ -113,7 +113,6 @@ export abstract class Mesh extends RefObject { startOrSubMesh = new SubMesh(startOrSubMesh, count, topology); } this._subMeshes.push(startOrSubMesh); - this._updateFlagManager.dispatch(MeshModifyFlags.SubMesh); return startOrSubMesh; } @@ -127,7 +126,6 @@ export abstract class Mesh extends RefObject { if (index !== -1) { subMeshes.splice(index, 1); } - this._updateFlagManager.dispatch(MeshModifyFlags.SubMesh); } /** @@ -135,7 +133,6 @@ export abstract class Mesh extends RefObject { */ clearSubMesh(): void { this._subMeshes.length = 0; - this._updateFlagManager.dispatch(MeshModifyFlags.SubMesh); } /** @@ -239,6 +236,5 @@ export abstract class Mesh extends RefObject { */ export enum MeshModifyFlags { Bounds = 0x1, - VertexElements = 0x2, - SubMesh = 0x4 + VertexElements = 0x2 } From c99e72307952c669bf083cf27a66fc810ef7e5e2 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:16:25 +0800 Subject: [PATCH 20/62] refactor: opt code --- packages/core/src/shader/ShaderPool.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/src/shader/ShaderPool.ts b/packages/core/src/shader/ShaderPool.ts index 60f55bf5a7..2a0d3e4182 100644 --- a/packages/core/src/shader/ShaderPool.ts +++ b/packages/core/src/shader/ShaderPool.ts @@ -28,19 +28,19 @@ import { ShaderString } from "./ShaderString"; export class ShaderPool { static init(): void { const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, ShaderString.getByName("ShadowCaster")); - const forwardPipelineStage = ShaderString.getByName("Forward"); + const pipelineForward = ShaderString.getByName("Forward"); - Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, forwardPipelineStage), shadowCasterPass]); - Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, forwardPipelineStage), shadowCasterPass]); - Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, forwardPipelineStage), shadowCasterPass]); - Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, forwardPipelineStage), shadowCasterPass]); + Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, pipelineForward), shadowCasterPass]); + Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, pipelineForward), shadowCasterPass]); + Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, pipelineForward), shadowCasterPass]); + Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, pipelineForward), shadowCasterPass]); - Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, forwardPipelineStage)]); - Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, forwardPipelineStage)]); - Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, forwardPipelineStage)]); - Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, forwardPipelineStage)]); + Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, pipelineForward)]); + Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, pipelineForward)]); + Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, pipelineForward)]); + Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, pipelineForward)]); Shader.create("background-texture", [ - new ShaderPass(backgroundTextureVs, backgroundTextureFs, forwardPipelineStage) + new ShaderPass(backgroundTextureVs, backgroundTextureFs, pipelineForward) ]); } } From 95a257fc42866be58f7e9b8c2a40e3a53ea68b29 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:19:28 +0800 Subject: [PATCH 21/62] refactor: opt code --- packages/core/src/RenderPipeline/BasicRenderPipeline.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 2e12961a5e..1f34eb4699 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -237,6 +237,7 @@ export class BasicRenderPipeline { subShader.getReplacementTag(replacementTagKey) === materialSubShader.getReplacementTag(replacementTagKey) ) { this.pushRenderDataWihShader(context, data, subShader.passes, renderStates); + break; } } } else { From f3513cb5e5d5eb1ff81901171db67d9c6ecf630a Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:25:51 +0800 Subject: [PATCH 22/62] refactor: opt code --- packages/core/src/shader/ShaderString.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/core/src/shader/ShaderString.ts b/packages/core/src/shader/ShaderString.ts index e11036c647..9505f04301 100644 --- a/packages/core/src/shader/ShaderString.ts +++ b/packages/core/src/shader/ShaderString.ts @@ -4,7 +4,6 @@ export class ShaderString { private static _nameCounter: number = 0; private static _nameMap: Record = Object.create(null); - private static _idMap: Record = Object.create(null); /** * Get shader property by name. @@ -12,15 +11,8 @@ export class ShaderString { * @returns Shader property */ static getByName(name: string): ShaderString { - const propertyNameMap = ShaderString._nameMap; - if (propertyNameMap[name] != null) { - return propertyNameMap[name]; - } else { - const property = new ShaderString(name); - propertyNameMap[name] = property; - ShaderString._idMap[property._uniqueId] = property; - return property; - } + const nameMap = ShaderString._nameMap; + return (nameMap[name] ||= new ShaderString(name)); } /** Shader property name. */ From 9fa31f643105b5bd4cb5cee6df606c5b954221b2 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:29:18 +0800 Subject: [PATCH 23/62] refactor: opt code --- packages/core/src/shader/Shader.ts | 7 ++----- packages/core/src/shader/SubShader.ts | 9 ++------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index e9344775a0..7cf568004f 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -4,7 +4,6 @@ import { ShaderMacro } from "./ShaderMacro"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderPass } from "./ShaderPass"; import { ShaderProperty } from "./ShaderProperty"; -import { ShaderString } from "./ShaderString"; import { SubShader } from "./SubShader"; /** @@ -171,7 +170,7 @@ export class Shader { } } - private _subShaders: SubShader[] = []; + private _subShaders: SubShader[]; /** * Sub shaders of the shader. @@ -187,9 +186,7 @@ export class Shader { if (passCount < 1) { throw "SubShader count must large than 0."; } - for (let i = 0; i < passCount; i++) { - this._subShaders.push(subShaders[i]); - } + this._subShaders = subShaders.slice(); } /** diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 42bbf2bb26..263ed4679e 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -5,11 +5,8 @@ import { ShaderString } from "./ShaderString"; * Sub shader. */ export class SubShader { - /** Disable batch. */ - disableBatch: boolean = false; - private _replacementTagsMap: Record; - private _passes: ShaderPass[] = []; + private _passes: ShaderPass[]; /** * Sub shader passes. @@ -28,9 +25,7 @@ export class SubShader { if (passCount < 1) { throw " count must large than 0."; } - for (let i = 0; i < passCount; i++) { - this._passes.push(passes[i]); - } + this._passes = passes.slice(); } /** From 5c179a66a099ad4f69a69f73e9eeff2faac43a56 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 15:31:48 +0800 Subject: [PATCH 24/62] refactor: opt code --- packages/core/src/RenderPipeline/BasicRenderPipeline.ts | 2 +- packages/core/src/shader/SubShader.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 1f34eb4699..06ee2fb7a4 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -234,7 +234,7 @@ export class BasicRenderPipeline { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { const subShader = replacementSubShaders[i]; if ( - subShader.getReplacementTag(replacementTagKey) === materialSubShader.getReplacementTag(replacementTagKey) + subShader.getReplacementTagValue(replacementTagKey) === materialSubShader.getReplacementTagValue(replacementTagKey) ) { this.pushRenderDataWihShader(context, data, subShader.passes, renderStates); break; diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 263ed4679e..263eab7586 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -43,11 +43,11 @@ export class SubShader { } /** - * Get a replacement tag. + * Get a replacement tag value. * @param key - Key of the tag * @returns Value of the tag */ - getReplacementTag(key: ShaderString): ShaderString { + getReplacementTagValue(key: ShaderString): ShaderString { return this._replacementTagsMap[key._uniqueId]; } } From 470354ca2fd6ba1d9d1d6d9fbfa852a11d90e9da Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 16:27:48 +0800 Subject: [PATCH 25/62] refactor: fix unit test --- packages/core/src/asset/RefObject.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/asset/RefObject.ts b/packages/core/src/asset/RefObject.ts index 4d370930cf..038dd47418 100644 --- a/packages/core/src/asset/RefObject.ts +++ b/packages/core/src/asset/RefObject.ts @@ -43,8 +43,9 @@ export abstract class RefObject extends EngineObject implements IRefObject { if (refCount > 0) { this._addRefCount(-refCount); } - this._engine = null; + this._onDestroy(); + this._engine = null; return true; } From 38e40003f49845d917cc87fda9c6a0a7e4a91287 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 17:24:33 +0800 Subject: [PATCH 26/62] fix: sprite mask error --- packages/core/src/2d/sprite/SpriteMask.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/2d/sprite/SpriteMask.ts b/packages/core/src/2d/sprite/SpriteMask.ts index 59b6ed4766..f9292d4dc1 100644 --- a/packages/core/src/2d/sprite/SpriteMask.ts +++ b/packages/core/src/2d/sprite/SpriteMask.ts @@ -214,7 +214,7 @@ export class SpriteMask extends Renderer implements ICustomClone { renderData.set(this, material, this._verticesData); const renderElement = this._engine._renderElementPool.getFromPool(); - renderElement.set(renderData, material.shader[0].shaderPasses[0], material.renderStates[0]); + renderElement.set(renderData, material.shader.subShaders[0].passes[0], material.renderStates[0]); this._maskElement = renderElement; } From 2cd9289545e477bb58925d186ddb9c6fb7b142ac Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 18:29:48 +0800 Subject: [PATCH 27/62] refactor: opt code --- packages/core/src/shader/ShaderPass.ts | 26 +++++++++++++++++-- packages/core/src/shader/ShaderPool.ts | 24 +++++++---------- packages/core/src/shader/index.ts | 2 +- .../src/shadow/CascadedShadowCasterPass.ts | 2 -- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 2e0fd76c35..dee4652480 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -21,12 +21,34 @@ export class ShaderPass { private _vertexSource: string; private _fragmentSource: string; - constructor(vertexSource: string, fragmentSource: string, pipelineStage?: ShaderString) { + /** + * Create a shader pass. + * @param vertexSource - Vertex shader source + * @param fragmentSource - Fragment shader source + * @param pipelineStageName - Pipeline stage name + */ + constructor(vertexSource: string, fragmentSource: string, pipelineStageName?: string); + + /** + * Create a shader pass. + * @param vertexSource - Vertex shader source + * @param fragmentSource - Fragment shader source + * @param pipelineStage - Pipeline stage + */ + constructor(vertexSource: string, fragmentSource: string, pipelineStage?: ShaderString); + + constructor(vertexSource: string, fragmentSource: string, pipelineStageOrName?: string | ShaderString) { this._shaderPassId = ShaderPass._shaderPassCounter++; this._vertexSource = vertexSource; this._fragmentSource = fragmentSource; - this.pipelineStage = pipelineStage || ShaderString.getByName("Forward"); + + if (pipelineStageOrName) { + this.pipelineStage = + typeof pipelineStageOrName === "string" ? ShaderString.getByName(pipelineStageOrName) : pipelineStageOrName; + } else { + this.pipelineStage = ShaderString.getByName("Forward"); + } } /** diff --git a/packages/core/src/shader/ShaderPool.ts b/packages/core/src/shader/ShaderPool.ts index 2a0d3e4182..c76a48987b 100644 --- a/packages/core/src/shader/ShaderPool.ts +++ b/packages/core/src/shader/ShaderPool.ts @@ -19,7 +19,6 @@ import unlitFs from "../shaderlib/extra/unlit.fs.glsl"; import unlitVs from "../shaderlib/extra/unlit.vs.glsl"; import { Shader } from "./Shader"; import { ShaderPass } from "./ShaderPass"; -import { ShaderString } from "./ShaderString"; /** * Internal shader pool. @@ -27,20 +26,17 @@ import { ShaderString } from "./ShaderString"; */ export class ShaderPool { static init(): void { - const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, ShaderString.getByName("ShadowCaster")); - const pipelineForward = ShaderString.getByName("Forward"); + const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, "ShadowCaster"); - Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, pipelineForward), shadowCasterPass]); - Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, pipelineForward), shadowCasterPass]); - Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, pipelineForward), shadowCasterPass]); - Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, pipelineForward), shadowCasterPass]); + Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, "Forward"), shadowCasterPass]); + Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, "Forward"), shadowCasterPass]); + Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, "Forward"), shadowCasterPass]); + Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, "Forward"), shadowCasterPass]); - Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, pipelineForward)]); - Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, pipelineForward)]); - Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, pipelineForward)]); - Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, pipelineForward)]); - Shader.create("background-texture", [ - new ShaderPass(backgroundTextureVs, backgroundTextureFs, pipelineForward) - ]); + Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, "Forward")]); + Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, "Forward")]); + Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, "Forward")]); + Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, "Forward")]); + Shader.create("background-texture", [new ShaderPass(backgroundTextureVs, backgroundTextureFs, "Forward")]); } } diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index 4ba9d0bf57..d5a97ab9af 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -9,6 +9,6 @@ export { StencilOperation } from "./enums/StencilOperation"; export { Shader } from "./Shader"; export { ShaderData } from "./ShaderData"; export { ShaderPass } from "./ShaderPass"; - +export { ShaderString } from "./ShaderString"; export { ShaderProperty } from "./ShaderProperty"; diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index 6cd7965651..67f1cb2edd 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -39,7 +39,6 @@ export class CascadedShadowCasterPass { private readonly _camera: Camera; private readonly _engine: Engine; - private readonly _shadowCasterShader: Shader; private readonly _supportDepthTexture: boolean; private _shadowMapResolution: number; @@ -67,7 +66,6 @@ export class CascadedShadowCasterPass { this._engine = camera.engine; this._supportDepthTexture = camera.engine._hardwareRenderer.canIUse(GLCapabilityType.depthTexture); - this._shadowCasterShader = Shader.find("shadow-map"); this._shadowSliceData.virtualCamera.isOrthographic = true; } From ed5027c38c1d08918c5e60330986d4f88aa3f433 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 22:38:17 +0800 Subject: [PATCH 28/62] refactor: opt code --- packages/core/src/Camera.ts | 2 +- .../src/RenderPipeline/BasicRenderPipeline.ts | 2 +- packages/core/src/shader/SubShader.ts | 30 ++++++++++++------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index 2979cb822a..a8c75b97ab 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -480,7 +480,7 @@ export class Camera extends Component { * * @remarks * If replacementTagKey is not specified, the first sub shader will be replaced. - * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same replacement tag value get by replacementTagKey. + * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. */ setReplacementShader(shader: Shader, replacementTagKey?: ShaderString): void { this._replacementShader = shader; diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 06ee2fb7a4..26203ef81a 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -234,7 +234,7 @@ export class BasicRenderPipeline { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { const subShader = replacementSubShaders[i]; if ( - subShader.getReplacementTagValue(replacementTagKey) === materialSubShader.getReplacementTagValue(replacementTagKey) + subShader.getTagValue(replacementTagKey) === materialSubShader.getTagValue(replacementTagKey) ) { this.pushRenderDataWihShader(context, data, subShader.passes, renderStates); break; diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 263eab7586..7ab999c45d 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -5,7 +5,7 @@ import { ShaderString } from "./ShaderString"; * Sub shader. */ export class SubShader { - private _replacementTagsMap: Record; + private _tagsMap: Record; private _passes: ShaderPass[]; /** @@ -29,25 +29,35 @@ export class SubShader { } /** - * Add a replacement tag. + * Add a tag. + * @param keyName - Name of the tag key + * @param valueName - Name of the tag value + */ + addTag(keyName: string, valueName: string): void; + /** + * Add a tag. * @param key - Key of the tag * @param value - Value of the tag */ - addReplacementTag(key: ShaderString, value: ShaderString): void { - const tags = this._replacementTagsMap; + addTag(key: ShaderString, value: ShaderString): void; + + addTag(keyOrKeyName: ShaderString | string, valueOrValueName: ShaderString | string): void { + const key = typeof keyOrKeyName === "string" ? ShaderString.getByName(keyOrKeyName) : keyOrKeyName; + const value = typeof valueOrValueName === "string" ? ShaderString.getByName(valueOrValueName) : valueOrValueName; + const tags = this._tagsMap; + if (tags[key._uniqueId]) { - throw `Tag named "${key}" already exists.`; + throw `Tag named "${key.name}" already exists.`; } - - tags[key._uniqueId] = value; + tags[value._uniqueId] = value; } /** - * Get a replacement tag value. + * Get a tag value. * @param key - Key of the tag * @returns Value of the tag */ - getReplacementTagValue(key: ShaderString): ShaderString { - return this._replacementTagsMap[key._uniqueId]; + getTagValue(key: ShaderString): ShaderString { + return this._tagsMap[key._uniqueId]; } } From 72c1536192ea68ffcdedb1c7f4623d26b146a4a7 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 22:48:47 +0800 Subject: [PATCH 29/62] refactor: opt code --- packages/core/src/Camera.ts | 6 +++--- .../core/src/RenderPipeline/BasicRenderPipeline.ts | 6 +++--- packages/core/src/RenderPipeline/RenderContext.ts | 6 +++--- packages/core/src/shader/ShaderPass.ts | 12 ++++++------ packages/core/src/shader/ShaderString.ts | 14 +++++++------- packages/core/src/shader/SubShader.ts | 14 +++++++------- packages/core/src/shader/index.ts | 2 +- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index a8c75b97ab..cb693b6a4b 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -12,7 +12,7 @@ import { ShaderDataGroup } from "./shader/enums/ShaderDataGroup"; import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; -import { ShaderString } from "./shader/ShaderString"; +import { ShaderTag } from "./shader/ShaderString"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; import { Transform } from "./Transform"; @@ -70,7 +70,7 @@ export class Camera extends Component { /** @internal */ _replacementShader: Shader = null; /** @internal */ - _replacementSubShaderTagKey: ShaderString = null; + _replacementSubShaderTagKey: ShaderTag = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -482,7 +482,7 @@ export class Camera extends Component { * If replacementTagKey is not specified, the first sub shader will be replaced. * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. */ - setReplacementShader(shader: Shader, replacementTagKey?: ShaderString): void { + setReplacementShader(shader: Shader, replacementTagKey?: ShaderTag): void { this._replacementShader = shader; this._replacementSubShaderTagKey = replacementTagKey; } diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 26203ef81a..ef6922b553 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -12,7 +12,7 @@ import { Material } from "../material"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Shader } from "../shader/Shader"; import { ShaderPass } from "../shader/ShaderPass"; -import { ShaderString } from "../shader/ShaderString"; +import { ShaderTag } from "../shader/ShaderString"; import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; @@ -26,8 +26,8 @@ import { RenderQueue } from "./RenderQueue"; * Basic render pipeline. */ export class BasicRenderPipeline { - private static _shadowCasterPipelineStage = ShaderString.getByName("ShadowCaster"); - private static _forwardPipelineStage = ShaderString.getByName("Forward"); + private static _shadowCasterPipelineStage = ShaderTag.getByName("ShadowCaster"); + private static _forwardPipelineStage = ShaderTag.getByName("Forward"); /** @internal */ _opaqueQueue: RenderQueue; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index d1257b4338..4d1575a67c 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,6 +1,6 @@ import { Camera } from "../Camera"; import { Shader } from "../shader"; -import { ShaderString } from "../shader/ShaderString"; +import { ShaderTag } from "../shader/ShaderString"; import { VirtualCamera } from "../VirtualCamera"; /** @@ -18,8 +18,8 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTagKey: ShaderString; - pipelineStage: ShaderString; + replacementTagKey: ShaderTag; + pipelineStage: ShaderTag; applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index dee4652480..5029dfbd64 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -4,7 +4,7 @@ import { ShaderFactory } from "../shaderlib/ShaderFactory"; import { Shader } from "./Shader"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderProgram } from "./ShaderProgram"; -import { ShaderString } from "./ShaderString"; +import { ShaderTag } from "./ShaderString"; /** * Shader pass containing vertex and fragment source. @@ -13,7 +13,7 @@ export class ShaderPass { private static _shaderPassCounter: number = 0; /** Pipeline stage. */ - readonly pipelineStage: ShaderString; + readonly pipelineStage: ShaderTag; /** @internal */ _shaderPassId: number = 0; @@ -35,9 +35,9 @@ export class ShaderPass { * @param fragmentSource - Fragment shader source * @param pipelineStage - Pipeline stage */ - constructor(vertexSource: string, fragmentSource: string, pipelineStage?: ShaderString); + constructor(vertexSource: string, fragmentSource: string, pipelineStage?: ShaderTag); - constructor(vertexSource: string, fragmentSource: string, pipelineStageOrName?: string | ShaderString) { + constructor(vertexSource: string, fragmentSource: string, pipelineStageOrName?: string | ShaderTag) { this._shaderPassId = ShaderPass._shaderPassCounter++; this._vertexSource = vertexSource; @@ -45,9 +45,9 @@ export class ShaderPass { if (pipelineStageOrName) { this.pipelineStage = - typeof pipelineStageOrName === "string" ? ShaderString.getByName(pipelineStageOrName) : pipelineStageOrName; + typeof pipelineStageOrName === "string" ? ShaderTag.getByName(pipelineStageOrName) : pipelineStageOrName; } else { - this.pipelineStage = ShaderString.getByName("Forward"); + this.pipelineStage = ShaderTag.getByName("Forward"); } } diff --git a/packages/core/src/shader/ShaderString.ts b/packages/core/src/shader/ShaderString.ts index 9505f04301..10573335a8 100644 --- a/packages/core/src/shader/ShaderString.ts +++ b/packages/core/src/shader/ShaderString.ts @@ -1,18 +1,18 @@ /** - * ShaderString is a class that represents a shader string. + * Shader tag. */ -export class ShaderString { +export class ShaderTag { private static _nameCounter: number = 0; - private static _nameMap: Record = Object.create(null); + private static _nameMap: Record = Object.create(null); /** * Get shader property by name. * @param name - Name of the shader property * @returns Shader property */ - static getByName(name: string): ShaderString { - const nameMap = ShaderString._nameMap; - return (nameMap[name] ||= new ShaderString(name)); + static getByName(name: string): ShaderTag { + const nameMap = ShaderTag._nameMap; + return (nameMap[name] ||= new ShaderTag(name)); } /** Shader property name. */ @@ -23,6 +23,6 @@ export class ShaderString { private constructor(name: string) { this.name = name; - this._uniqueId = ShaderString._nameCounter++; + this._uniqueId = ShaderTag._nameCounter++; } } diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 7ab999c45d..df5998c795 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -1,11 +1,11 @@ import { ShaderPass } from "./ShaderPass"; -import { ShaderString } from "./ShaderString"; +import { ShaderTag } from "./ShaderString"; /** * Sub shader. */ export class SubShader { - private _tagsMap: Record; + private _tagsMap: Record; private _passes: ShaderPass[]; /** @@ -39,11 +39,11 @@ export class SubShader { * @param key - Key of the tag * @param value - Value of the tag */ - addTag(key: ShaderString, value: ShaderString): void; + addTag(key: ShaderTag, value: ShaderTag): void; - addTag(keyOrKeyName: ShaderString | string, valueOrValueName: ShaderString | string): void { - const key = typeof keyOrKeyName === "string" ? ShaderString.getByName(keyOrKeyName) : keyOrKeyName; - const value = typeof valueOrValueName === "string" ? ShaderString.getByName(valueOrValueName) : valueOrValueName; + addTag(keyOrKeyName: ShaderTag | string, valueOrValueName: ShaderTag | string): void { + const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; + const value = typeof valueOrValueName === "string" ? ShaderTag.getByName(valueOrValueName) : valueOrValueName; const tags = this._tagsMap; if (tags[key._uniqueId]) { @@ -57,7 +57,7 @@ export class SubShader { * @param key - Key of the tag * @returns Value of the tag */ - getTagValue(key: ShaderString): ShaderString { + getTagValue(key: ShaderTag): ShaderTag { return this._tagsMap[key._uniqueId]; } } diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index d5a97ab9af..786398bcec 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -9,6 +9,6 @@ export { StencilOperation } from "./enums/StencilOperation"; export { Shader } from "./Shader"; export { ShaderData } from "./ShaderData"; export { ShaderPass } from "./ShaderPass"; -export { ShaderString } from "./ShaderString"; +export { ShaderTag as ShaderString } from "./ShaderString"; export { ShaderProperty } from "./ShaderProperty"; From 8f09a8ca96b23e8c24081b73be34e1295dd0e4b9 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 6 Mar 2023 22:52:11 +0800 Subject: [PATCH 30/62] refactor: opt code --- packages/core/src/Camera.ts | 2 +- packages/core/src/RenderPipeline/BasicRenderPipeline.ts | 2 +- packages/core/src/RenderPipeline/RenderContext.ts | 2 +- packages/core/src/shader/ShaderPass.ts | 2 +- packages/core/src/shader/{ShaderString.ts => ShaderTag.ts} | 0 packages/core/src/shader/SubShader.ts | 2 +- packages/core/src/shader/index.ts | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) rename packages/core/src/shader/{ShaderString.ts => ShaderTag.ts} (100%) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index cb693b6a4b..473ed6fada 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -12,7 +12,7 @@ import { ShaderDataGroup } from "./shader/enums/ShaderDataGroup"; import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; -import { ShaderTag } from "./shader/ShaderString"; +import { ShaderTag } from "./shader/ShaderTag"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; import { Transform } from "./Transform"; diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index ef6922b553..ab701917a7 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -12,7 +12,7 @@ import { Material } from "../material"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Shader } from "../shader/Shader"; import { ShaderPass } from "../shader/ShaderPass"; -import { ShaderTag } from "../shader/ShaderString"; +import { ShaderTag } from "../shader/ShaderTag"; import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index 4d1575a67c..e1bef6708f 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,6 +1,6 @@ import { Camera } from "../Camera"; import { Shader } from "../shader"; -import { ShaderTag } from "../shader/ShaderString"; +import { ShaderTag } from "../shader/ShaderTag"; import { VirtualCamera } from "../VirtualCamera"; /** diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 5029dfbd64..d87f9643ac 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -4,7 +4,7 @@ import { ShaderFactory } from "../shaderlib/ShaderFactory"; import { Shader } from "./Shader"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderProgram } from "./ShaderProgram"; -import { ShaderTag } from "./ShaderString"; +import { ShaderTag } from "./ShaderTag"; /** * Shader pass containing vertex and fragment source. diff --git a/packages/core/src/shader/ShaderString.ts b/packages/core/src/shader/ShaderTag.ts similarity index 100% rename from packages/core/src/shader/ShaderString.ts rename to packages/core/src/shader/ShaderTag.ts diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index df5998c795..7b92a8e9a2 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -1,5 +1,5 @@ import { ShaderPass } from "./ShaderPass"; -import { ShaderTag } from "./ShaderString"; +import { ShaderTag } from "./ShaderTag"; /** * Sub shader. diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index 786398bcec..ab684e9516 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -9,6 +9,6 @@ export { StencilOperation } from "./enums/StencilOperation"; export { Shader } from "./Shader"; export { ShaderData } from "./ShaderData"; export { ShaderPass } from "./ShaderPass"; -export { ShaderTag as ShaderString } from "./ShaderString"; +export { ShaderTag } from "./ShaderTag"; export { ShaderProperty } from "./ShaderProperty"; From 451e5276941cc8380ac524c55b46c3e9fba9042d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 7 Mar 2023 11:38:49 +0800 Subject: [PATCH 31/62] fix: replacement bug --- packages/core/src/Camera.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index 473ed6fada..2db48628af 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -448,6 +448,8 @@ export class Camera extends Component { context.camera = this; context.virtualCamera = virtualCamera; + context.replacementShader = this._replacementShader; + context.replacementTagKey = this._replacementSubShaderTagKey; // compute cull frustum. if (this.enableFrustumCulling && (this._frustumViewChangeFlag.flag || this._isFrustumProjectDirty)) { From af7763cb6229aee4121691be238db411a91d8dd8 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 7 Mar 2023 13:59:20 +0800 Subject: [PATCH 32/62] refactor: opt code --- .../src/RenderPipeline/BasicRenderPipeline.ts | 13 ++--- .../core/src/RenderPipeline/RenderContext.ts | 8 +-- packages/core/src/shader/ShaderPass.ts | 56 +++++++++++++++---- packages/core/src/shader/ShaderPool.ts | 27 +++++---- packages/core/src/shader/SubShader.ts | 2 +- packages/core/src/sky/Sky.ts | 6 +- 6 files changed, 75 insertions(+), 37 deletions(-) diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index ab701917a7..389d0a615c 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -150,7 +150,7 @@ export class BasicRenderPipeline { camera.engine._spriteMaskManager.clear(); - context.pipelineStage = BasicRenderPipeline._shadowCasterPipelineStage; + context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStage; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -161,7 +161,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); - context.pipelineStage = BasicRenderPipeline._forwardPipelineStage; + context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStage; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); @@ -233,9 +233,7 @@ export class BasicRenderPipeline { if (replacementTagKey) { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { const subShader = replacementSubShaders[i]; - if ( - subShader.getTagValue(replacementTagKey) === materialSubShader.getTagValue(replacementTagKey) - ) { + if (subShader.getTagValue(replacementTagKey) === materialSubShader.getTagValue(replacementTagKey)) { this.pushRenderDataWihShader(context, data, subShader.passes, renderStates); break; } @@ -254,11 +252,12 @@ export class BasicRenderPipeline { shaderPasses: ReadonlyArray, renderStates: ReadonlyArray ) { - const pipelineStage = context.pipelineStage; + const pipelineStage = context.pipelineStageValue; const renderElementPool = context.camera.engine._renderElementPool; for (let i = 0, n = shaderPasses.length; i < n; i++) { const shaderPass = shaderPasses[i]; - if (shaderPass.pipelineStage === pipelineStage) { + debugger; + if (shaderPass.getTagValue(RenderContext.pipelineStageKey) === pipelineStage) { const renderElement = renderElementPool.getFromPool(); renderElement.set(element, shaderPass, renderStates[i]); diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index e1bef6708f..5e76db5b54 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -8,8 +8,8 @@ import { VirtualCamera } from "../VirtualCamera"; * Rendering context. */ export class RenderContext { - /** @internal */ - static _vpMatrixProperty = Shader.getPropertyByName("u_VPMat"); + static vpMatrixProperty = Shader.getPropertyByName("u_VPMat"); + static pipelineStageKey: ShaderTag = ShaderTag.getByName("PipelineStage"); private static _viewMatrixProperty = Shader.getPropertyByName("u_viewMat"); private static _projectionMatrixProperty = Shader.getPropertyByName("u_projMat"); @@ -19,13 +19,13 @@ export class RenderContext { replacementShader: Shader; replacementTagKey: ShaderTag; - pipelineStage: ShaderTag; + pipelineStageValue: ShaderTag; applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; const shaderData = this.camera.shaderData; shaderData.setMatrix(RenderContext._viewMatrixProperty, virtualCamera.viewMatrix); shaderData.setMatrix(RenderContext._projectionMatrixProperty, virtualCamera.projectionMatrix); - shaderData.setMatrix(RenderContext._vpMatrixProperty, virtualCamera.viewProjectionMatrix); + shaderData.setMatrix(RenderContext.vpMatrixProperty, virtualCamera.viewProjectionMatrix); } } diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index d87f9643ac..e7775c3de9 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -12,43 +12,75 @@ import { ShaderTag } from "./ShaderTag"; export class ShaderPass { private static _shaderPassCounter: number = 0; - /** Pipeline stage. */ - readonly pipelineStage: ShaderTag; - /** @internal */ _shaderPassId: number = 0; private _vertexSource: string; private _fragmentSource: string; + private _tagsMap: Record = Object.create(null); /** * Create a shader pass. * @param vertexSource - Vertex shader source * @param fragmentSource - Fragment shader source - * @param pipelineStageName - Pipeline stage name + * @param tags - Tags */ - constructor(vertexSource: string, fragmentSource: string, pipelineStageName?: string); + constructor(vertexSource: string, fragmentSource: string, tags?: Record); /** * Create a shader pass. * @param vertexSource - Vertex shader source * @param fragmentSource - Fragment shader source - * @param pipelineStage - Pipeline stage + * @param tags - Tags */ - constructor(vertexSource: string, fragmentSource: string, pipelineStage?: ShaderTag); + constructor(vertexSource: string, fragmentSource: string, tags?: Record); - constructor(vertexSource: string, fragmentSource: string, pipelineStageOrName?: string | ShaderTag) { + constructor(vertexSource: string, fragmentSource: string, tags?: Record) { this._shaderPassId = ShaderPass._shaderPassCounter++; this._vertexSource = vertexSource; this._fragmentSource = fragmentSource; - if (pipelineStageOrName) { - this.pipelineStage = - typeof pipelineStageOrName === "string" ? ShaderTag.getByName(pipelineStageOrName) : pipelineStageOrName; + if (tags) { + for (const key in tags) { + this.addTag(key, tags[key]); + } } else { - this.pipelineStage = ShaderTag.getByName("Forward"); + this.addTag("PipelineStage", "Forward"); + } + } + + /** + * Add a tag. + * @param keyName - Name of the tag key + * @param valueName - Name of the tag value + */ + addTag(keyName: string, valueName: string): void; + /** + * Add a tag. + * @param key - Key of the tag + * @param value - Value of the tag + */ + addTag(key: ShaderTag, value: ShaderTag): void; + + addTag(keyOrKeyName: ShaderTag | string, valueOrValueName: ShaderTag | string): void { + const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; + const value = typeof valueOrValueName === "string" ? ShaderTag.getByName(valueOrValueName) : valueOrValueName; + const tags = this._tagsMap; + + if (tags[key._uniqueId]) { + throw `Tag named "${key.name}" already exists.`; } + tags[key._uniqueId] = value; + } + + /** + * Get a tag value. + * @param key - Key of the tag + * @returns Value of the tag + */ + getTagValue(key: ShaderTag): ShaderTag { + return this._tagsMap[key._uniqueId]; } /** diff --git a/packages/core/src/shader/ShaderPool.ts b/packages/core/src/shader/ShaderPool.ts index c76a48987b..a3d1000323 100644 --- a/packages/core/src/shader/ShaderPool.ts +++ b/packages/core/src/shader/ShaderPool.ts @@ -26,17 +26,24 @@ import { ShaderPass } from "./ShaderPass"; */ export class ShaderPool { static init(): void { - const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, "ShadowCaster"); + const shadowCasterPassTags = { + PipelineStage: "ShadowCaster" + }; + const forwardPassTags = { + PipelineStage: "Forward" + }; - Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, "Forward"), shadowCasterPass]); - Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, "Forward"), shadowCasterPass]); - Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, "Forward"), shadowCasterPass]); - Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, "Forward"), shadowCasterPass]); + const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, shadowCasterPassTags); - Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, "Forward")]); - Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, "Forward")]); - Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, "Forward")]); - Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, "Forward")]); - Shader.create("background-texture", [new ShaderPass(backgroundTextureVs, backgroundTextureFs, "Forward")]); + Shader.create("blinn-phong", [new ShaderPass(blinnPhongVs, blinnPhongFs, forwardPassTags), shadowCasterPass]); + Shader.create("pbr", [new ShaderPass(pbrVs, pbrFs, forwardPassTags), shadowCasterPass]); + Shader.create("pbr-specular", [new ShaderPass(pbrVs, pbrSpecularFs, forwardPassTags), shadowCasterPass]); + Shader.create("unlit", [new ShaderPass(unlitVs, unlitFs, forwardPassTags), shadowCasterPass]); + + Shader.create("skybox", [new ShaderPass(skyboxVs, skyboxFs, forwardPassTags)]); + Shader.create("particle-shader", [new ShaderPass(particleVs, particleFs, forwardPassTags)]); + Shader.create("SpriteMask", [new ShaderPass(spriteMaskVs, spriteMaskFs, forwardPassTags)]); + Shader.create("Sprite", [new ShaderPass(spriteVs, spriteFs, forwardPassTags)]); + Shader.create("background-texture", [new ShaderPass(backgroundTextureVs, backgroundTextureFs, forwardPassTags)]); } } diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 7b92a8e9a2..09e9acc2b8 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -49,7 +49,7 @@ export class SubShader { if (tags[key._uniqueId]) { throw `Tag named "${key.name}" already exists.`; } - tags[value._uniqueId] = value; + tags[key._uniqueId] = value; } /** diff --git a/packages/core/src/sky/Sky.ts b/packages/core/src/sky/Sky.ts index fa73c58cc2..18403e4730 100644 --- a/packages/core/src/sky/Sky.ts +++ b/packages/core/src/sky/Sky.ts @@ -50,8 +50,8 @@ export class Sky { // view-proj matrix Matrix.multiply(projectionMatrix, viewProjMatrix, viewProjMatrix); - const originViewProjMatrix = cameraShaderData.getMatrix(RenderContext._vpMatrixProperty); - cameraShaderData.setMatrix(RenderContext._vpMatrixProperty, viewProjMatrix); + const originViewProjMatrix = cameraShaderData.getMatrix(RenderContext.vpMatrixProperty); + cameraShaderData.setMatrix(RenderContext.vpMatrixProperty, viewProjMatrix); const compileMacros = Shader._compileMacros; ShaderMacroCollection.unionCollection( @@ -68,6 +68,6 @@ export class Sky { renderState._apply(engine, false); rhi.drawPrimitive(mesh, mesh.subMesh, program); - cameraShaderData.setMatrix(RenderContext._vpMatrixProperty, originViewProjMatrix); + cameraShaderData.setMatrix(RenderContext.vpMatrixProperty, originViewProjMatrix); } } From 68e91a6d02a02dbef31a737a79db4035980b2f4a Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 7 Mar 2023 15:41:18 +0800 Subject: [PATCH 33/62] refactor: opt code --- packages/core/src/shader/ShaderPart.ts | 58 ++++++++++++++++++++++++++ packages/core/src/shader/ShaderPass.ts | 53 +++-------------------- packages/core/src/shader/SubShader.ts | 41 +++--------------- 3 files changed, 69 insertions(+), 83 deletions(-) create mode 100644 packages/core/src/shader/ShaderPart.ts diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts new file mode 100644 index 0000000000..1ed1e191db --- /dev/null +++ b/packages/core/src/shader/ShaderPart.ts @@ -0,0 +1,58 @@ +import { ShaderTag } from "./ShaderTag"; + +export class ShaderPart { + private _tagsMap: Record; + + /** + * Add a tag. + * @param keyName - Name of the tag key + * @param valueName - Name of the tag value + */ + setTag(keyName: string, valueName: string): void; + /** + * Add a tag. + * @param key - Key of the tag + * @param value - Value of the tag + */ + setTag(key: ShaderTag, value: ShaderTag): void; + + setTag(keyOrKeyName: ShaderTag | string, valueOrValueName: ShaderTag | string): void { + const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; + const value = typeof valueOrValueName === "string" ? ShaderTag.getByName(valueOrValueName) : valueOrValueName; + const tags = this._tagsMap; + + if (tags[key._uniqueId]) { + throw `Tag named "${key.name}" already exists.`; + } + tags[key._uniqueId] = value; + } + + /** + * Delete a tag by key name. + * @param KeyName - Key name of the tag + * @returns Value of the tag + */ + deleteTag(KeyName: string); + + /** + * Delete a tag. + * @param key - Key of the tag + * @returns Value of the tag + */ + deleteTag(key: ShaderTag); + + deleteTag(keyOrKeyName: ShaderTag | string): void { + delete this._tagsMap[ + typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + ]; + } + + /** + * Get a tag value. + * @param key - Key of the tag + * @returns Value of the tag + */ + getTagValue(key: ShaderTag): ShaderTag { + return this._tagsMap[key._uniqueId]; + } +} diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index e7775c3de9..986841a24c 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -3,13 +3,13 @@ import { Engine } from "../Engine"; import { ShaderFactory } from "../shaderlib/ShaderFactory"; import { Shader } from "./Shader"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; +import { ShaderPart } from "./ShaderPart"; import { ShaderProgram } from "./ShaderProgram"; -import { ShaderTag } from "./ShaderTag"; /** * Shader pass containing vertex and fragment source. */ -export class ShaderPass { +export class ShaderPass extends ShaderPart { private static _shaderPassCounter: number = 0; /** @internal */ @@ -17,7 +17,6 @@ export class ShaderPass { private _vertexSource: string; private _fragmentSource: string; - private _tagsMap: Record = Object.create(null); /** * Create a shader pass. @@ -25,17 +24,8 @@ export class ShaderPass { * @param fragmentSource - Fragment shader source * @param tags - Tags */ - constructor(vertexSource: string, fragmentSource: string, tags?: Record); - - /** - * Create a shader pass. - * @param vertexSource - Vertex shader source - * @param fragmentSource - Fragment shader source - * @param tags - Tags - */ - constructor(vertexSource: string, fragmentSource: string, tags?: Record); - constructor(vertexSource: string, fragmentSource: string, tags?: Record) { + super(); this._shaderPassId = ShaderPass._shaderPassCounter++; this._vertexSource = vertexSource; @@ -43,46 +33,13 @@ export class ShaderPass { if (tags) { for (const key in tags) { - this.addTag(key, tags[key]); + this.setTag(key, tags[key]); } } else { - this.addTag("PipelineStage", "Forward"); + this.setTag("PipelineStage", "Forward"); } } - /** - * Add a tag. - * @param keyName - Name of the tag key - * @param valueName - Name of the tag value - */ - addTag(keyName: string, valueName: string): void; - /** - * Add a tag. - * @param key - Key of the tag - * @param value - Value of the tag - */ - addTag(key: ShaderTag, value: ShaderTag): void; - - addTag(keyOrKeyName: ShaderTag | string, valueOrValueName: ShaderTag | string): void { - const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; - const value = typeof valueOrValueName === "string" ? ShaderTag.getByName(valueOrValueName) : valueOrValueName; - const tags = this._tagsMap; - - if (tags[key._uniqueId]) { - throw `Tag named "${key.name}" already exists.`; - } - tags[key._uniqueId] = value; - } - - /** - * Get a tag value. - * @param key - Key of the tag - * @returns Value of the tag - */ - getTagValue(key: ShaderTag): ShaderTag { - return this._tagsMap[key._uniqueId]; - } - /** * @internal */ diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 09e9acc2b8..38f401c7cc 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -1,11 +1,10 @@ +import { ShaderPart } from "./ShaderPart"; import { ShaderPass } from "./ShaderPass"; -import { ShaderTag } from "./ShaderTag"; /** * Sub shader. */ -export class SubShader { - private _tagsMap: Record; +export class SubShader extends ShaderPart { private _passes: ShaderPass[]; /** @@ -20,44 +19,16 @@ export class SubShader { * @param name - Name of the sub shader * @param passes - Sub shader passes */ - constructor(public readonly name: string, passes: ShaderPass[]) { + constructor(public readonly name: string, passes: ShaderPass[], tags?: Record) { + super(); const passCount = passes.length; if (passCount < 1) { throw " count must large than 0."; } this._passes = passes.slice(); - } - - /** - * Add a tag. - * @param keyName - Name of the tag key - * @param valueName - Name of the tag value - */ - addTag(keyName: string, valueName: string): void; - /** - * Add a tag. - * @param key - Key of the tag - * @param value - Value of the tag - */ - addTag(key: ShaderTag, value: ShaderTag): void; - addTag(keyOrKeyName: ShaderTag | string, valueOrValueName: ShaderTag | string): void { - const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; - const value = typeof valueOrValueName === "string" ? ShaderTag.getByName(valueOrValueName) : valueOrValueName; - const tags = this._tagsMap; - - if (tags[key._uniqueId]) { - throw `Tag named "${key.name}" already exists.`; + for (const key in tags) { + this.setTag(key, tags[key]); } - tags[key._uniqueId] = value; - } - - /** - * Get a tag value. - * @param key - Key of the tag - * @returns Value of the tag - */ - getTagValue(key: ShaderTag): ShaderTag { - return this._tagsMap[key._uniqueId]; } } From 59ec9da9238745dfbec70c4dcc6a0cf93f7e9b07 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 7 Mar 2023 15:48:24 +0800 Subject: [PATCH 34/62] refactor: opt code --- .../src/RenderPipeline/BasicRenderPipeline.ts | 1 - packages/core/src/shader/ShaderPart.ts | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 389d0a615c..a4e547db52 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -256,7 +256,6 @@ export class BasicRenderPipeline { const renderElementPool = context.camera.engine._renderElementPool; for (let i = 0, n = shaderPasses.length; i < n; i++) { const shaderPass = shaderPasses[i]; - debugger; if (shaderPass.getTagValue(RenderContext.pipelineStageKey) === pipelineStage) { const renderElement = renderElementPool.getFromPool(); diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 1ed1e191db..ebe171baac 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -1,16 +1,16 @@ import { ShaderTag } from "./ShaderTag"; export class ShaderPart { - private _tagsMap: Record; + private _tagsMap: Record = Object.create(null); /** - * Add a tag. + * Set tag by name. * @param keyName - Name of the tag key * @param valueName - Name of the tag value */ setTag(keyName: string, valueName: string): void; /** - * Add a tag. + * Set tag. * @param key - Key of the tag * @param value - Value of the tag */ @@ -30,16 +30,14 @@ export class ShaderPart { /** * Delete a tag by key name. * @param KeyName - Key name of the tag - * @returns Value of the tag */ - deleteTag(KeyName: string); + deleteTag(KeyName: string): void; /** - * Delete a tag. + * Delete a tag by key. * @param key - Key of the tag - * @returns Value of the tag */ - deleteTag(key: ShaderTag); + deleteTag(key: ShaderTag): void; deleteTag(keyOrKeyName: ShaderTag | string): void { delete this._tagsMap[ @@ -48,11 +46,22 @@ export class ShaderPart { } /** - * Get a tag value. + * Get tag value by key name. + * @param keyName - Key name of the tag + * @returns Value of the tag + */ + getTagValue(keyName: ShaderTag | string): ShaderTag; + + /** + * Get tag value by key. * @param key - Key of the tag * @returns Value of the tag */ - getTagValue(key: ShaderTag): ShaderTag { - return this._tagsMap[key._uniqueId]; + getTagValue(key: ShaderTag | string): ShaderTag; + + getTagValue(keyOrKeyName: ShaderTag | string): ShaderTag { + return this._tagsMap[ + typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + ]; } } From d41ccc4d5155fabd5c1eff1828074ac07f703368 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 7 Mar 2023 17:02:28 +0800 Subject: [PATCH 35/62] refactor: opt code --- packages/core/src/Camera.ts | 6 +- packages/core/src/ComponentsDependencies.ts | 86 ++++++++++++++------- packages/core/src/Renderer.ts | 6 +- packages/core/src/index.ts | 2 +- packages/core/src/physics/Collider.ts | 4 +- packages/core/src/physics/joint/Joint.ts | 10 +-- 6 files changed, 74 insertions(+), 40 deletions(-) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index 2db48628af..e11f42fdda 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -3,7 +3,7 @@ import { Logger } from "./base"; import { BoolUpdateFlag } from "./BoolUpdateFlag"; import { deepClone, ignoreClone } from "./clone/CloneManager"; import { Component } from "./Component"; -import { dependentComponents } from "./ComponentsDependencies"; +import { dependentComponents, DependentMode } from "./ComponentsDependencies"; import { Entity } from "./Entity"; import { CameraClearFlags } from "./enums/CameraClearFlags"; import { Layer } from "./Layer"; @@ -26,9 +26,9 @@ class MathTemp { /** * Camera component, as the entrance to the three-dimensional world. - * @decorator `@dependentComponents(Transform)` + * @decorator `@dependentComponents(DependentMode.CheckOnly, Transform)` */ -@dependentComponents(Transform) +@dependentComponents(DependentMode.CheckOnly, Transform) export class Camera extends Component { /** @internal */ private static _inverseViewMatrixProperty = Shader.getPropertyByName("u_viewInvMat"); diff --git a/packages/core/src/ComponentsDependencies.ts b/packages/core/src/ComponentsDependencies.ts index 3cb1054eff..09b552cba3 100644 --- a/packages/core/src/ComponentsDependencies.ts +++ b/packages/core/src/ComponentsDependencies.ts @@ -4,34 +4,29 @@ import { Entity } from "./Entity"; type ComponentConstructor = new (entity: Entity) => Component; /** + * @internal * Used for component dependency registration. */ export class ComponentsDependencies { - /** - * @internal - */ - private static _dependenciesMap = new Map(); private static _invDependenciesMap = new Map(); - /** - * @internal - */ - static _register(currentComponent: ComponentConstructor, dependentComponent: ComponentConstructor): void { - this._addDependency(currentComponent, dependentComponent, this._dependenciesMap); - this._addDependency(dependentComponent, currentComponent, this._invDependenciesMap); - } + static _dependenciesMap = new Map(); /** * @internal */ - static _addCheck(entity: Entity, type: ComponentConstructor): void { - // Check if there are dependent components. - const dependentComponents = ComponentsDependencies._dependenciesMap.get(type); - if (dependentComponents) { - for (let i = 0, n = dependentComponents.length; i < n; i++) { - const dependentComponent = dependentComponents[i]; + static _addCheck(entity: Entity, target: ComponentConstructor): void { + const dependentInfo = ComponentsDependencies._dependenciesMap.get(target); + if (dependentInfo) { + const { components, mode } = dependentInfo; + for (let i = 0, n = components.length; i < n; i++) { + const dependentComponent = components[i]; if (!entity.getComponent(dependentComponent)) { - entity.addComponent(dependentComponent); + if (mode === DependentMode.AutoAdd) { + entity.addComponent(dependentComponent); + } else { + throw `Should add ${dependentComponent.name} before adding ${target.name}`; + } } } } @@ -45,17 +40,35 @@ export class ComponentsDependencies { if (invDependencies) { for (let i = 0, len = invDependencies.length; i < len; i++) { if (entity.getComponent(invDependencies[i])) { - throw `you should remove ${invDependencies[i]} before adding ${type}`; + throw `Should remove ${invDependencies[i].name} before adding ${type.name}`; } } } } - private static _addDependency( - currentComponent: ComponentConstructor, + /** + * @internal + */ + static _addDependency( + targetInfo: DependentInfo, dependentComponent: ComponentConstructor, - map: Map + map: Map ): void { + let components = map.get(targetInfo); + if (!components) { + components = []; + map.set(targetInfo, components); + } + if (components.indexOf(dependentComponent) === -1) { + components.push(dependentComponent); + } + } + + /** + * @internal + */ + static _addInvDependency(currentComponent: ComponentConstructor, dependentComponent: ComponentConstructor): void { + const map = this._invDependenciesMap; let components = map.get(currentComponent); if (!components) { components = []; @@ -70,11 +83,32 @@ export class ComponentsDependencies { } /** - * Dependent components, automatically added if they do not exist. - * @param components - Dependent components + * Declare dependent components. + * @param dependentMode - Dependent mode + * @param components - Dependent components */ -export function dependentComponents(...components: ComponentConstructor[]) { +export function dependentComponents(dependentMode: DependentMode, ...components: ComponentConstructor[]) { return function (target: T): void { - components.forEach((component) => ComponentsDependencies._register(target, component)); + const dependentInfo = { mode: dependentMode, components }; + ComponentsDependencies._dependenciesMap.set(target, dependentInfo); + components.forEach((component) => ComponentsDependencies._addInvDependency(component, target)); }; } + +/** + * Dependent mode. + */ +export enum DependentMode { + /** Check only, throw error if dependent components do not exist. */ + CheckOnly, + /** Auto add if dependent components do not exist. */ + AutoAdd +} + +/** + * @internal + */ +interface DependentInfo { + mode: DependentMode; + components: ComponentConstructor[]; +} diff --git a/packages/core/src/Renderer.ts b/packages/core/src/Renderer.ts index fc341112bd..0d9f704ba9 100644 --- a/packages/core/src/Renderer.ts +++ b/packages/core/src/Renderer.ts @@ -1,7 +1,7 @@ import { BoundingBox, Matrix, Vector3 } from "@oasis-engine/math"; import { assignmentClone, deepClone, ignoreClone, shallowClone } from "./clone/CloneManager"; import { Component } from "./Component"; -import { dependentComponents } from "./ComponentsDependencies"; +import { dependentComponents, DependentMode } from "./ComponentsDependencies"; import { Entity } from "./Entity"; import { Material } from "./material/Material"; import { RenderContext } from "./RenderPipeline/RenderContext"; @@ -13,9 +13,9 @@ import { Transform, TransformModifyFlags } from "./Transform"; /** * Basis for all renderers. - * @decorator `@dependentComponents(Transform)` + * @decorator `@dependentComponents(DependentMode.CheckOnly, Transform)` */ -@dependentComponents(Transform) +@dependentComponents(DependentMode.CheckOnly, Transform) export class Renderer extends Component { private static _tempVector0 = new Vector3(); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f186509205..3506635516 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -10,7 +10,7 @@ export { Entity } from "./Entity"; export { Component } from "./Component"; export { Script } from "./Script"; export { Renderer } from "./Renderer"; -export { dependentComponents } from "./ComponentsDependencies"; +export { dependentComponents, DependentMode } from "./ComponentsDependencies"; export { Camera } from "./Camera"; export { Transform } from "./Transform"; export { BoolUpdateFlag } from "./BoolUpdateFlag"; diff --git a/packages/core/src/physics/Collider.ts b/packages/core/src/physics/Collider.ts index f853ac52ee..85ba784e6d 100644 --- a/packages/core/src/physics/Collider.ts +++ b/packages/core/src/physics/Collider.ts @@ -2,7 +2,7 @@ import { ICollider, IStaticCollider } from "@oasis-engine/design"; import { BoolUpdateFlag } from "../BoolUpdateFlag"; import { ignoreClone } from "../clone/CloneManager"; import { Component } from "../Component"; -import { dependentComponents } from "../ComponentsDependencies"; +import { dependentComponents, DependentMode } from "../ComponentsDependencies"; import { Entity } from "../Entity"; import { Transform } from "../Transform"; import { ColliderShape } from "./shape/ColliderShape"; @@ -11,7 +11,7 @@ import { ColliderShape } from "./shape/ColliderShape"; * Base class for all colliders. * @decorator `@dependentComponents(Transform)` */ -@dependentComponents(Transform) +@dependentComponents(DependentMode.CheckOnly, Transform) export class Collider extends Component { /** @internal */ @ignoreClone diff --git a/packages/core/src/physics/joint/Joint.ts b/packages/core/src/physics/joint/Joint.ts index cf79bc45bd..5ad9f1743e 100644 --- a/packages/core/src/physics/joint/Joint.ts +++ b/packages/core/src/physics/joint/Joint.ts @@ -1,15 +1,15 @@ import { IJoint } from "@oasis-engine/design"; -import { Vector3, Quaternion } from "@oasis-engine/math"; +import { Quaternion, Vector3 } from "@oasis-engine/math"; import { Component } from "../../Component"; -import { Collider } from "../Collider"; -import { dependentComponents } from "../../ComponentsDependencies"; +import { dependentComponents, DependentMode } from "../../ComponentsDependencies"; import { Entity } from "../../Entity"; +import { Collider } from "../Collider"; /** * A base class providing common functionality for joints. - * @decorator `@dependentComponents(Collider)` + * @decorator `@dependentComponents(DependentMode.CheckOnly,Collider)` */ -@dependentComponents(Collider) +@dependentComponents(DependentMode.CheckOnly, Collider) export class Joint extends Component { protected _connectedCollider = new JointCollider(); protected _collider = new JointCollider(); From dc1de594a4b9cc653aa7c89c7458c12a3329d58a Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 7 Mar 2023 17:33:38 +0800 Subject: [PATCH 36/62] refactor: opt code --- packages/core/src/shader/Shader.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index 7cf568004f..c8fad885de 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -64,12 +64,12 @@ export class Shader { let shader: Shader; if (typeof vertexSourceOrShaderPassesOrSubShaders === "string") { const shaderPass = new ShaderPass(vertexSourceOrShaderPassesOrSubShaders, fragmentSource); - shader = new Shader(name, [new SubShader("DefaultPass", [shaderPass])]); + shader = new Shader(name, [new SubShader("Default", [shaderPass])]); } else { if (vertexSourceOrShaderPassesOrSubShaders.length > 0) { if (vertexSourceOrShaderPassesOrSubShaders[0].constructor === ShaderPass) { shader = new Shader(name, [ - new SubShader("DefaultPass", vertexSourceOrShaderPassesOrSubShaders) + new SubShader("Default", vertexSourceOrShaderPassesOrSubShaders) ]); } else { shader = new Shader(name, vertexSourceOrShaderPassesOrSubShaders); From 1f1327b911596ffa997382bb9e2c458539c091dc Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 11:32:18 +0800 Subject: [PATCH 37/62] test(Script): add dependentComponents decorator test --- tests/src/core/Script.test.ts | 25 ++++++++++++++++++++++++- tsconfig.tests.json | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/src/core/Script.test.ts b/tests/src/core/Script.test.ts index 02062e0b0d..00401fa6c2 100644 --- a/tests/src/core/Script.test.ts +++ b/tests/src/core/Script.test.ts @@ -1,4 +1,4 @@ -import { Entity, Script } from "@oasis-engine/core"; +import { Camera, dependentComponents, DependentMode, Entity, Script } from "@oasis-engine/core"; import { WebGLEngine } from "@oasis-engine/rhi-webgl"; import chai, { expect } from "chai"; import spies from "chai-spies"; @@ -250,5 +250,28 @@ describe("Script", () => { expect(script.onDestroy).to.have.been.called.exactly(1); }, 1000); }); + + it("Dependent components", () => { + @dependentComponents(DependentMode.CheckOnly, Camera) + class CheckScript extends Script {} + + @dependentComponents(DependentMode.AutoAdd, Camera) + class AutoAddScript extends Script {} + + const engine = new WebGLEngine(document.createElement("canvas")); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity("root"); + engine.run(); + + const entity1 = rootEntity.createChild("entity"); + expect(() => { + entity1.addComponent(CheckScript); + }).throw(`Should add Camera1 before adding CheckScript`); + + const entity2 = rootEntity.createChild("entity"); + entity2.addComponent(AutoAddScript); + const camera = entity2.getComponent(Camera); + expect(camera).to.not.null; + }); }); }); diff --git a/tsconfig.tests.json b/tsconfig.tests.json index b0d71a1c54..8c4e1ecea9 100644 --- a/tsconfig.tests.json +++ b/tsconfig.tests.json @@ -3,6 +3,7 @@ "target": "ES2017", "module": "CommonJS", "moduleResolution": "node", + "experimentalDecorators": true, "esModuleInterop": true, "strict": false, "lib": [ From 6cf6cc0c0bd04fea1e7315132408d0020f177adb Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 14:42:59 +0800 Subject: [PATCH 38/62] fix: shader compileVariant bug --- packages/core/src/shader/Shader.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index c8fad885de..0eb40114ad 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -68,9 +68,7 @@ export class Shader { } else { if (vertexSourceOrShaderPassesOrSubShaders.length > 0) { if (vertexSourceOrShaderPassesOrSubShaders[0].constructor === ShaderPass) { - shader = new Shader(name, [ - new SubShader("Default", vertexSourceOrShaderPassesOrSubShaders) - ]); + shader = new Shader(name, [new SubShader("Default", vertexSourceOrShaderPassesOrSubShaders)]); } else { shader = new Shader(name, vertexSourceOrShaderPassesOrSubShaders); } @@ -206,14 +204,19 @@ export class Shader { compileMacros.enable(Shader.getMacroByName(macros[i])); } - let isValid = true; const subShaders = this._subShaders; for (let i = 0, n = subShaders.length; i < n; i++) { + let isValid: boolean; const { passes } = subShaders[i]; for (let j = 0, m = passes.length; j < m; j++) { - isValid &&= passes[j]._getShaderProgram(engine, compileMacros).isValid; + if (isValid === undefined) { + isValid = passes[j]._getShaderProgram(engine, compileMacros).isValid; + } else { + isValid &&= passes[j]._getShaderProgram(engine, compileMacros).isValid; + } } + if (isValid) return true; } - return isValid; + return false; } } From 0691d4e69af96bdef2be9de87c517a0d2826a59d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 14:43:40 +0800 Subject: [PATCH 39/62] test(Shader): add shader unit test --- tests/src/core/Shader.test.ts | 141 ++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 tests/src/core/Shader.test.ts diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts new file mode 100644 index 0000000000..d997f8951f --- /dev/null +++ b/tests/src/core/Shader.test.ts @@ -0,0 +1,141 @@ +import { Shader, ShaderTag } from "@oasis-engine/core"; +import chai, { expect } from "chai"; +import spies from "chai-spies"; + +chai.use(spies); + +describe("Shader", () => { + describe("Custom Shader", () => { + it("Shader", () => { + const customShader = Shader.create("custom", customVS, customFS); + // Base struct created by Shader.create + expect(customShader.subShaders).length(1); + expect(customShader.subShaders[0].passes).length(1); + + // Shader find + expect(customShader).equal(Shader.find("custom")); + + // Shader property + const customProperty = Shader.getPropertyByName("customProperty"); + expect(customProperty.name).to.equal("customProperty"); + + // Shader macro + const customMacro = Shader.getMacroByName("CUSTOM_MACRO"); + expect(customMacro.name).to.equal("CUSTOM_MACRO"); + + // Compile variant + }); + + it("SubShader", () => { + const customShader = Shader.find("custom"); + const subShader = customShader.subShaders[0]; + + // Add tag by name + subShader.setTag("customTagKey", "customTagValue"); + let getTag = subShader.getTagValue("customTagKey"); + expect(getTag.name).to.equal("customTagValue"); + + // Delete tag by name + subShader.deleteTag("customTagKey"); + getTag = subShader.getTagValue("customTagKey"); + expect(getTag).to.undefined; + + // Add tag + subShader.setTag(ShaderTag.getByName("customTagKey"), ShaderTag.getByName("customTagValue")); + getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); + + // Delete tag + subShader.deleteTag(ShaderTag.getByName("customTagKey")); + getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); + expect(getTag).to.undefined; + }); + + it("PassShader", () => { + const customShader = Shader.find("custom"); + const shaderPass = customShader.subShaders[0].passes[0]; + + // Add tag by name + shaderPass.setTag("customTagKey", "customTagValue"); + let getTag = shaderPass.getTagValue("customTagKey"); + expect(getTag.name).to.equal("customTagValue"); + + // Delete tag by name + shaderPass.deleteTag("customTagKey"); + getTag = shaderPass.getTagValue("customTagKey"); + expect(getTag).to.undefined; + + // Add tag + shaderPass.setTag(ShaderTag.getByName("customTagKey"), ShaderTag.getByName("customTagValue")); + getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); + + // Delete tag + shaderPass.deleteTag(ShaderTag.getByName("customTagKey")); + getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); + expect(getTag).to.undefined; + }); + }); +}); + +const customVS = ` +#include +#include +#include +#include +#include + +void main() { + + #include + #include + #include + #include + #include + + #include +} +`; + +const customFS = ` +#include +#include +#include + +uniform vec4 u_baseColor; +uniform float u_alphaCutoff; + +#ifdef BASETEXTURE + uniform sampler2D u_baseTexture; +#endif + +void main() { + vec4 baseColor = u_baseColor; + + #ifdef BASETEXTURE + vec4 textureColor = texture2D(u_baseTexture, v_uv); + #ifndef OASIS_COLORSPACE_GAMMA + textureColor = gammaToLinear(textureColor); + #endif + baseColor *= textureColor; + #endif + + #ifdef ALPHA_CUTOFF + if( baseColor.a < u_alphaCutoff ) { + discard; + } + #endif + + gl_FragColor = baseColor; + + #ifndef OASIS_TRANSPARENT + gl_FragColor.a = 1.0; + #endif + + #include + + #ifndef OASIS_COLORSPACE_GAMMA + gl_FragColor = linearToGamma(gl_FragColor); + #endif +} +`; From 6f196a90ed5fcd7659041461d3ab547707d1fc2a Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 15:08:54 +0800 Subject: [PATCH 40/62] refactor: opt code --- packages/core/src/shader/Shader.ts | 121 ++++++--------------- packages/core/src/shader/ShaderData.ts | 2 +- packages/core/src/shader/ShaderMacro.ts | 66 ++++++++++- packages/core/src/shader/ShaderPass.ts | 3 +- packages/core/src/shader/ShaderProgram.ts | 5 +- packages/core/src/shader/ShaderProperty.ts | 29 +++++ tests/src/core/Shader.test.ts | 6 +- 7 files changed, 135 insertions(+), 97 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index 0eb40114ad..49ae69b941 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -1,5 +1,4 @@ import { Engine } from "../Engine"; -import { ShaderDataGroup } from "./enums/ShaderDataGroup"; import { ShaderMacro } from "./ShaderMacro"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderPass } from "./ShaderPass"; @@ -18,14 +17,8 @@ export class Shader { "GL_OES_standard_derivatives", "GL_EXT_draw_buffers" ]; - /** @internal */ - static _propertyIdMap: Record = Object.create(null); private static _shaderMap: Record = Object.create(null); - private static _propertyNameMap: Record = Object.create(null); - private static _macroMaskMap: string[][] = []; - private static _macroCounter: number = 0; - private static _macroMap: Record = Object.create(null); /** * Create a shader. @@ -88,86 +81,6 @@ export class Shader { return Shader._shaderMap[name]; } - /** - * Get shader macro by name. - * @param name - Name of the shader macro - * @returns Shader macro - */ - static getMacroByName(name: string): ShaderMacro; - - /** - * Get shader macro by name. - * @param name - Name of the shader macro - * @param value - Value of the shader macro - * @returns Shader macro - */ - static getMacroByName(name: string, value: string): ShaderMacro; - - static getMacroByName(name: string, value?: string): ShaderMacro { - const key = value ? name + ` ` + value : name; - let macro = Shader._macroMap[key]; - if (!macro) { - const maskMap = Shader._macroMaskMap; - const counter = Shader._macroCounter; - const index = Math.floor(counter / 32); - const bit = counter % 32; - - macro = new ShaderMacro(name, value, index, 1 << bit); - Shader._macroMap[key] = macro; - if (index == maskMap.length) { - maskMap.length++; - maskMap[index] = new Array(32); - } - maskMap[index][bit] = key; - Shader._macroCounter++; - } - return macro; - } - - /** - * Get shader property by name. - * @param name - Name of the shader property - * @returns Shader property - */ - static getPropertyByName(name: string): ShaderProperty { - const propertyNameMap = Shader._propertyNameMap; - if (propertyNameMap[name] != null) { - return propertyNameMap[name]; - } else { - const property = new ShaderProperty(name); - propertyNameMap[name] = property; - Shader._propertyIdMap[property._uniqueId] = property; - return property; - } - } - - /** - * @internal - */ - static _getShaderPropertyGroup(propertyName: string): ShaderDataGroup | null { - const shaderProperty = Shader._propertyNameMap[propertyName]; - return shaderProperty?._group; - } - - /** - * @internal - */ - static _getNamesByMacros(macros: ShaderMacroCollection, out: string[]): void { - const maskMap = Shader._macroMaskMap; - const mask = macros._mask; - out.length = 0; - for (let i = 0, n = macros._length; i < n; i++) { - const subMaskMap = maskMap[i]; - const subMask = mask[i]; - const m = subMask < 0 ? 32 : Math.floor(Math.log2(subMask)) + 1; // if is negative must contain 1 << 31. - for (let j = 0; j < m; j++) { - if (subMask & (1 << j)) { - out.push(subMaskMap[j]); - } - } - } - } - private _subShaders: SubShader[]; /** @@ -219,4 +132,38 @@ export class Shader { } return false; } + + /** + * @deprecated Please use `ShaderMacro.getByName` instead + * + * Get shader macro by name. + * @param name - Name of the shader macro + * @returns Shader macro + */ + static getMacroByName(name: string): ShaderMacro; + + /** + * @deprecated Please use `ShaderMacro.getByName` instead + * + * Get shader macro by name. + * @param name - Name of the shader macro + * @param value - Value of the shader macro + * @returns Shader macro + */ + static getMacroByName(name: string, value: string): ShaderMacro; + + static getMacroByName(name: string, value?: string): ShaderMacro { + return ShaderMacro.getByName(name, value); + } + + /** + * @deprecated Please use `ShaderProperty.getByName` instead + * + * Get shader property by name. + * @param name - Name of the shader property + * @returns Shader property + */ + static getPropertyByName(name: string): ShaderProperty { + return ShaderProperty.getByName(name); + } } diff --git a/packages/core/src/shader/ShaderData.ts b/packages/core/src/shader/ShaderData.ts index 3d86e84885..1174dd8015 100644 --- a/packages/core/src/shader/ShaderData.ts +++ b/packages/core/src/shader/ShaderData.ts @@ -583,7 +583,7 @@ export class ShaderData implements IRefObject, IClone { } const propertyValueMap = this._propertyValueMap; - const propertyIdMap = Shader._propertyIdMap; + const propertyIdMap = ShaderProperty._propertyIdMap; for (let key in propertyValueMap) { properties.push(propertyIdMap[key]); } diff --git a/packages/core/src/shader/ShaderMacro.ts b/packages/core/src/shader/ShaderMacro.ts index 57b1fda8b4..737a714ae8 100644 --- a/packages/core/src/shader/ShaderMacro.ts +++ b/packages/core/src/shader/ShaderMacro.ts @@ -1,11 +1,72 @@ +import { ShaderMacroCollection } from "./ShaderMacroCollection"; + /** * Shader macro。 */ export class ShaderMacro { + /** @internal */ + static _macroMaskMap: string[][] = []; /** @internal */ static _macroNameIdMap: Record = Object.create(null); private static _macroNameCounter: number = 0; + private static _macroCounter: number = 0; + private static _macroMap: Record = Object.create(null); + + /** + * Get shader macro by name. + * @param name - Name of the shader macro + * @returns Shader macro + */ + static getByName(name: string): ShaderMacro; + + /** + * Get shader macro by name. + * @param name - Name of the shader macro + * @param value - Value of the shader macro + * @returns Shader macro + */ + static getByName(name: string, value: string): ShaderMacro; + + static getByName(name: string, value?: string): ShaderMacro { + const key = value ? name + ` ` + value : name; + let macro = ShaderMacro._macroMap[key]; + if (!macro) { + const maskMap = ShaderMacro._macroMaskMap; + const counter = ShaderMacro._macroCounter; + const index = Math.floor(counter / 32); + const bit = counter % 32; + + macro = new ShaderMacro(name, value, index, 1 << bit); + ShaderMacro._macroMap[key] = macro; + if (index == maskMap.length) { + maskMap.length++; + maskMap[index] = new Array(32); + } + maskMap[index][bit] = key; + ShaderMacro._macroCounter++; + } + return macro; + } + + /** + * @internal + */ + static _getNamesByMacros(macros: ShaderMacroCollection, out: string[]): void { + const maskMap = ShaderMacro._macroMaskMap; + const mask = macros._mask; + out.length = 0; + for (let i = 0, n = macros._length; i < n; i++) { + const subMaskMap = maskMap[i]; + const subMask = mask[i]; + const m = subMask < 0 ? 32 : Math.floor(Math.log2(subMask)) + 1; // if is negative must contain 1 << 31. + for (let j = 0; j < m; j++) { + if (subMask & (1 << j)) { + out.push(subMaskMap[j]); + } + } + } + } /** Name. */ readonly name: string; @@ -19,10 +80,7 @@ export class ShaderMacro { /** @internal */ _maskValue: number; - /** - * @internal - */ - constructor(name: string, value: string, maskIndex: number, maskValue: number) { + private constructor(name: string, value: string, maskIndex: number, maskValue: number) { this.name = name; this._maskIndex = maskIndex; this._maskValue = maskValue; diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 986841a24c..07e7cb2402 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -2,6 +2,7 @@ import { GLCapabilityType } from "../base/Constant"; import { Engine } from "../Engine"; import { ShaderFactory } from "../shaderlib/ShaderFactory"; import { Shader } from "./Shader"; +import { ShaderMacro } from "./ShaderMacro"; import { ShaderMacroCollection } from "./ShaderMacroCollection"; import { ShaderPart } from "./ShaderPart"; import { ShaderProgram } from "./ShaderProgram"; @@ -52,7 +53,7 @@ export class ShaderPass extends ShaderPart { const isWebGL2: boolean = engine._hardwareRenderer.isWebGL2; const macroNameList = []; - Shader._getNamesByMacros(macroCollection, macroNameList); + ShaderMacro._getNamesByMacros(macroCollection, macroNameList); const macroNameStr = ShaderFactory.parseCustomMacros(macroNameList); const versionStr = isWebGL2 ? "#version 300 es" : "#version 100"; const graphicAPI = isWebGL2 ? "#define GRAPHICS_API_WEBGL2" : "#define GRAPHICS_API_WEBGL1"; diff --git a/packages/core/src/shader/ShaderProgram.ts b/packages/core/src/shader/ShaderProgram.ts index 87515fd626..94d154a5a9 100644 --- a/packages/core/src/shader/ShaderProgram.ts +++ b/packages/core/src/shader/ShaderProgram.ts @@ -10,6 +10,7 @@ import { Texture } from "../texture"; import { ShaderDataGroup } from "./enums/ShaderDataGroup"; import { Shader } from "./Shader"; import { ShaderData } from "./ShaderData"; +import { ShaderProperty } from "./ShaderProperty"; import { ShaderUniform } from "./ShaderUniform"; import { ShaderUniformBlock } from "./ShaderUniformBlock"; @@ -187,7 +188,7 @@ export class ShaderProgram { private _groupingSubOtherUniforms(uniforms: ShaderUniform[], isTexture: boolean): void { for (let i = uniforms.length - 1; i >= 0; i--) { const uniform = uniforms[i]; - const group = Shader._getShaderPropertyGroup(uniform.name); + const group = ShaderProperty._getShaderPropertyGroup(uniform.name); if (group !== undefined) { uniforms.splice(uniforms.indexOf(uniform), 1); this._groupingUniform(uniform, group, isTexture); @@ -449,7 +450,7 @@ export class ShaderProgram { break; } - const group = Shader._getShaderPropertyGroup(name); + const group = ShaderProperty._getShaderPropertyGroup(name); this._groupingUniform(shaderUniform, group, isTexture); }); diff --git a/packages/core/src/shader/ShaderProperty.ts b/packages/core/src/shader/ShaderProperty.ts index f4de346b2e..3a1d7e308b 100644 --- a/packages/core/src/shader/ShaderProperty.ts +++ b/packages/core/src/shader/ShaderProperty.ts @@ -5,7 +5,36 @@ import { ShaderPropertyType } from "./enums/ShaderPropertyType"; * Shader property. */ export class ShaderProperty { + /** @internal */ + static _propertyIdMap: Record = Object.create(null); + private static _propertyNameCounter: number = 0; + private static _propertyNameMap: Record = Object.create(null); + + /** + * Get shader property by name. + * @param name - Name of the shader property + * @returns Shader property + */ + static getByName(name: string): ShaderProperty { + const propertyNameMap = ShaderProperty._propertyNameMap; + if (propertyNameMap[name] != null) { + return propertyNameMap[name]; + } else { + const property = new ShaderProperty(name); + propertyNameMap[name] = property; + ShaderProperty._propertyIdMap[property._uniqueId] = property; + return property; + } + } + + /** + * @internal + */ + static _getShaderPropertyGroup(propertyName: string): ShaderDataGroup | null { + const shaderProperty = ShaderProperty._propertyNameMap[propertyName]; + return shaderProperty?._group; + } /** @internal */ _uniqueId: number; diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index d997f8951f..e7a0f412e2 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -1,6 +1,8 @@ import { Shader, ShaderTag } from "@oasis-engine/core"; import chai, { expect } from "chai"; import spies from "chai-spies"; +import { ShaderProperty } from "packages/core/src"; +import { ShaderMacro } from "packages/core/src/shader/ShaderMacro"; chai.use(spies); @@ -16,11 +18,11 @@ describe("Shader", () => { expect(customShader).equal(Shader.find("custom")); // Shader property - const customProperty = Shader.getPropertyByName("customProperty"); + const customProperty = ShaderProperty.getByName("customProperty"); expect(customProperty.name).to.equal("customProperty"); // Shader macro - const customMacro = Shader.getMacroByName("CUSTOM_MACRO"); + const customMacro = ShaderMacro.getByName("CUSTOM_MACRO"); expect(customMacro.name).to.equal("CUSTOM_MACRO"); // Compile variant From 2f1935474eae4e4acb44872e9a8838a9eb601f1b Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 15:17:00 +0800 Subject: [PATCH 41/62] refactor: opt code --- packages/core/src/2d/sprite/SpriteMask.ts | 4 +- packages/core/src/2d/sprite/SpriteRenderer.ts | 2 +- packages/core/src/Camera.ts | 5 +- packages/core/src/Engine.ts | 4 +- .../core/src/RenderPipeline/RenderContext.ts | 8 +-- .../core/src/RenderPipeline/SpriteBatcher.ts | 2 +- packages/core/src/Renderer.ts | 17 ++++--- packages/core/src/Scene.ts | 6 +-- packages/core/src/lighting/AmbientLight.ts | 20 ++++---- packages/core/src/lighting/DirectLight.ts | 4 +- packages/core/src/lighting/PointLight.ts | 6 +-- packages/core/src/lighting/SpotLight.ts | 12 ++--- packages/core/src/material/BaseMaterial.ts | 30 +++++------ .../core/src/material/BlinnPhongMaterial.ts | 7 +-- packages/core/src/material/PBRBaseMaterial.ts | 20 ++++---- packages/core/src/material/PBRMaterial.ts | 7 +-- .../core/src/material/PBRSpecularMaterial.ts | 9 ++-- packages/core/src/mesh/BlendShapeManager.ts | 18 ++++--- packages/core/src/mesh/MeshRenderer.ts | 11 ++-- packages/core/src/mesh/SkinnedMeshRenderer.ts | 8 +-- packages/core/src/shader/Shader.ts | 2 +- packages/core/src/shader/ShaderData.ts | 50 +++++++++---------- packages/core/src/shader/ShaderProgram.ts | 2 +- .../src/shadow/CascadedShadowCasterPass.ts | 18 +++---- 24 files changed, 140 insertions(+), 132 deletions(-) diff --git a/packages/core/src/2d/sprite/SpriteMask.ts b/packages/core/src/2d/sprite/SpriteMask.ts index f9292d4dc1..001053b208 100644 --- a/packages/core/src/2d/sprite/SpriteMask.ts +++ b/packages/core/src/2d/sprite/SpriteMask.ts @@ -18,9 +18,9 @@ import { Sprite } from "./Sprite"; */ export class SpriteMask extends Renderer implements ICustomClone { /** @internal */ - static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_maskTexture"); + static _textureProperty: ShaderProperty = ShaderProperty.getByName("u_maskTexture"); /** @internal */ - static _alphaCutoffProperty: ShaderProperty = Shader.getPropertyByName("u_maskAlphaCutoff"); + static _alphaCutoffProperty: ShaderProperty = ShaderProperty.getByName("u_maskAlphaCutoff"); /** The mask layers the sprite mask influence to. */ @assignmentClone diff --git a/packages/core/src/2d/sprite/SpriteRenderer.ts b/packages/core/src/2d/sprite/SpriteRenderer.ts index 1b1ff14182..24afdbefa8 100644 --- a/packages/core/src/2d/sprite/SpriteRenderer.ts +++ b/packages/core/src/2d/sprite/SpriteRenderer.ts @@ -22,7 +22,7 @@ import { Sprite } from "./Sprite"; */ export class SpriteRenderer extends Renderer implements ICustomClone { /** @internal */ - static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_spriteTexture"); + static _textureProperty: ShaderProperty = ShaderProperty.getByName("u_spriteTexture"); /** @internal */ @ignoreClone diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index e11f42fdda..ea07f9c8d9 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -12,6 +12,7 @@ import { ShaderDataGroup } from "./shader/enums/ShaderDataGroup"; import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; +import { ShaderProperty } from "./shader/ShaderProperty"; import { ShaderTag } from "./shader/ShaderTag"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; @@ -31,9 +32,9 @@ class MathTemp { @dependentComponents(DependentMode.CheckOnly, Transform) export class Camera extends Component { /** @internal */ - private static _inverseViewMatrixProperty = Shader.getPropertyByName("u_viewInvMat"); + private static _inverseViewMatrixProperty = ShaderProperty.getByName("u_viewInvMat"); /** @internal */ - private static _cameraPositionProperty = Shader.getPropertyByName("u_cameraPos"); + private static _cameraPositionProperty = ShaderProperty.getByName("u_cameraPos"); /** Shader data. */ readonly shaderData: ShaderData = new ShaderData(ShaderDataGroup.Camera); diff --git a/packages/core/src/Engine.ts b/packages/core/src/Engine.ts index 039834f0fb..b6747284ca 100644 --- a/packages/core/src/Engine.ts +++ b/packages/core/src/Engine.ts @@ -45,9 +45,9 @@ ShaderPool.init(); */ export class Engine extends EventDispatcher { /** @internal */ - static _gammaMacro: ShaderMacro = Shader.getMacroByName("OASIS_COLORSPACE_GAMMA"); + static _gammaMacro: ShaderMacro = ShaderMacro.getByName("OASIS_COLORSPACE_GAMMA"); /** @internal */ - static _noDepthTextureMacro: ShaderMacro = Shader.getMacroByName("OASIS_NO_DEPTH_TEXTURE"); + static _noDepthTextureMacro: ShaderMacro = ShaderMacro.getByName("OASIS_NO_DEPTH_TEXTURE"); /** @internal Conversion of space units to pixel units for 2D. */ static _pixelsPerUnit: number = 100; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index 5e76db5b54..586cec0fa2 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,5 +1,5 @@ import { Camera } from "../Camera"; -import { Shader } from "../shader"; +import { Shader, ShaderProperty } from "../shader"; import { ShaderTag } from "../shader/ShaderTag"; import { VirtualCamera } from "../VirtualCamera"; @@ -8,11 +8,11 @@ import { VirtualCamera } from "../VirtualCamera"; * Rendering context. */ export class RenderContext { - static vpMatrixProperty = Shader.getPropertyByName("u_VPMat"); + static vpMatrixProperty = ShaderProperty.getByName("u_VPMat"); static pipelineStageKey: ShaderTag = ShaderTag.getByName("PipelineStage"); - private static _viewMatrixProperty = Shader.getPropertyByName("u_viewMat"); - private static _projectionMatrixProperty = Shader.getPropertyByName("u_projMat"); + private static _viewMatrixProperty = ShaderProperty.getByName("u_viewMat"); + private static _projectionMatrixProperty = ShaderProperty.getByName("u_projMat"); camera: Camera; virtualCamera: VirtualCamera; diff --git a/packages/core/src/RenderPipeline/SpriteBatcher.ts b/packages/core/src/RenderPipeline/SpriteBatcher.ts index b93cf3c052..2a0f16ba70 100644 --- a/packages/core/src/RenderPipeline/SpriteBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteBatcher.ts @@ -14,7 +14,7 @@ import { SpriteRenderData } from "./SpriteRenderData"; * @internal */ export class SpriteBatcher extends Basic2DBatcher { - private static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_spriteTexture"); + private static _textureProperty: ShaderProperty = ShaderProperty.getByName("u_spriteTexture"); createVertexElements(vertexElements: VertexElement[]): number { vertexElements[0] = new VertexElement("POSITION", 0, VertexElementFormat.Vector3, 0); diff --git a/packages/core/src/Renderer.ts b/packages/core/src/Renderer.ts index 0d9f704ba9..67271a65c3 100644 --- a/packages/core/src/Renderer.ts +++ b/packages/core/src/Renderer.ts @@ -5,9 +5,10 @@ import { dependentComponents, DependentMode } from "./ComponentsDependencies"; import { Entity } from "./Entity"; import { Material } from "./material/Material"; import { RenderContext } from "./RenderPipeline/RenderContext"; -import { Shader } from "./shader"; +import { Shader, ShaderProperty } from "./shader"; import { ShaderDataGroup } from "./shader/enums/ShaderDataGroup"; import { ShaderData } from "./shader/ShaderData"; +import { ShaderMacro } from "./shader/ShaderMacro"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; import { Transform, TransformModifyFlags } from "./Transform"; @@ -19,13 +20,13 @@ import { Transform, TransformModifyFlags } from "./Transform"; export class Renderer extends Component { private static _tempVector0 = new Vector3(); - private static _receiveShadowMacro = Shader.getMacroByName("OASIS_RECEIVE_SHADOWS"); - private static _localMatrixProperty = Shader.getPropertyByName("u_localMat"); - private static _worldMatrixProperty = Shader.getPropertyByName("u_modelMat"); - private static _mvMatrixProperty = Shader.getPropertyByName("u_MVMat"); - private static _mvpMatrixProperty = Shader.getPropertyByName("u_MVPMat"); - private static _mvInvMatrixProperty = Shader.getPropertyByName("u_MVInvMat"); - private static _normalMatrixProperty = Shader.getPropertyByName("u_normalMat"); + private static _receiveShadowMacro = ShaderMacro.getByName("OASIS_RECEIVE_SHADOWS"); + private static _localMatrixProperty = ShaderProperty.getByName("u_localMat"); + private static _worldMatrixProperty = ShaderProperty.getByName("u_modelMat"); + private static _mvMatrixProperty = ShaderProperty.getByName("u_MVMat"); + private static _mvpMatrixProperty = ShaderProperty.getByName("u_MVPMat"); + private static _mvInvMatrixProperty = ShaderProperty.getByName("u_MVInvMat"); + private static _normalMatrixProperty = ShaderProperty.getByName("u_normalMat"); /** ShaderData related to renderer. */ @deepClone diff --git a/packages/core/src/Scene.ts b/packages/core/src/Scene.ts index 123e447b9f..e95d2e0e46 100644 --- a/packages/core/src/Scene.ts +++ b/packages/core/src/Scene.ts @@ -7,7 +7,7 @@ import { Entity } from "./Entity"; import { FogMode } from "./enums/FogMode"; import { Light } from "./lighting"; import { AmbientLight } from "./lighting/AmbientLight"; -import { Shader } from "./shader"; +import { ShaderProperty } from "./shader"; import { ShaderDataGroup } from "./shader/enums/ShaderDataGroup"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; @@ -19,8 +19,8 @@ import { ShadowType } from "./shadow/enum/ShadowType"; * Scene. */ export class Scene extends EngineObject { - private static _fogColorProperty = Shader.getPropertyByName("oasis_FogColor"); - private static _fogParamsProperty = Shader.getPropertyByName("oasis_FogParams"); + private static _fogColorProperty = ShaderProperty.getByName("oasis_FogColor"); + private static _fogParamsProperty = ShaderProperty.getByName("oasis_FogParams"); /** Scene name. */ name: string; diff --git a/packages/core/src/lighting/AmbientLight.ts b/packages/core/src/lighting/AmbientLight.ts index 5dbcb7aa3c..2debc917f9 100644 --- a/packages/core/src/lighting/AmbientLight.ts +++ b/packages/core/src/lighting/AmbientLight.ts @@ -10,18 +10,18 @@ import { DiffuseMode } from "./enums/DiffuseMode"; * Ambient light. */ export class AmbientLight { - private static _shMacro: ShaderMacro = Shader.getMacroByName("O3_USE_SH"); - private static _specularMacro: ShaderMacro = Shader.getMacroByName("O3_USE_SPECULAR_ENV"); - private static _decodeRGBMMacro: ShaderMacro = Shader.getMacroByName("O3_DECODE_ENV_RGBM"); - - private static _diffuseColorProperty: ShaderProperty = Shader.getPropertyByName("u_envMapLight.diffuse"); - private static _diffuseSHProperty: ShaderProperty = Shader.getPropertyByName("u_env_sh"); - private static _diffuseIntensityProperty: ShaderProperty = Shader.getPropertyByName("u_envMapLight.diffuseIntensity"); - private static _specularTextureProperty: ShaderProperty = Shader.getPropertyByName("u_env_specularSampler"); - private static _specularIntensityProperty: ShaderProperty = Shader.getPropertyByName( + private static _shMacro: ShaderMacro = ShaderMacro.getByName("O3_USE_SH"); + private static _specularMacro: ShaderMacro = ShaderMacro.getByName("O3_USE_SPECULAR_ENV"); + private static _decodeRGBMMacro: ShaderMacro = ShaderMacro.getByName("O3_DECODE_ENV_RGBM"); + + private static _diffuseColorProperty: ShaderProperty = ShaderProperty.getByName("u_envMapLight.diffuse"); + private static _diffuseSHProperty: ShaderProperty = ShaderProperty.getByName("u_env_sh"); + private static _diffuseIntensityProperty: ShaderProperty = ShaderProperty.getByName("u_envMapLight.diffuseIntensity"); + private static _specularTextureProperty: ShaderProperty = ShaderProperty.getByName("u_env_specularSampler"); + private static _specularIntensityProperty: ShaderProperty = ShaderProperty.getByName( "u_envMapLight.specularIntensity" ); - private static _mipLevelProperty: ShaderProperty = Shader.getPropertyByName("u_envMapLight.mipMapLevel"); + private static _mipLevelProperty: ShaderProperty = ShaderProperty.getByName("u_envMapLight.mipMapLevel"); private _diffuseSphericalHarmonics: SphericalHarmonics3; private _diffuseSolidColor: Color = new Color(0.212, 0.227, 0.259); diff --git a/packages/core/src/lighting/DirectLight.ts b/packages/core/src/lighting/DirectLight.ts index 4ad99bdb04..dd1377b066 100644 --- a/packages/core/src/lighting/DirectLight.ts +++ b/packages/core/src/lighting/DirectLight.ts @@ -7,8 +7,8 @@ import { Light } from "./Light"; * Directional light. */ export class DirectLight extends Light { - private static _colorProperty: ShaderProperty = Shader.getPropertyByName("u_directLightColor"); - private static _directionProperty: ShaderProperty = Shader.getPropertyByName("u_directLightDirection"); + private static _colorProperty: ShaderProperty = ShaderProperty.getByName("u_directLightColor"); + private static _directionProperty: ShaderProperty = ShaderProperty.getByName("u_directLightDirection"); private static _combinedData = { color: new Float32Array(3 * Light._maxLight), diff --git a/packages/core/src/lighting/PointLight.ts b/packages/core/src/lighting/PointLight.ts index 6469f5a9e8..eafb993bae 100644 --- a/packages/core/src/lighting/PointLight.ts +++ b/packages/core/src/lighting/PointLight.ts @@ -7,9 +7,9 @@ import { Light } from "./Light"; * Point light. */ export class PointLight extends Light { - private static _colorProperty: ShaderProperty = Shader.getPropertyByName("u_pointLightColor"); - private static _positionProperty: ShaderProperty = Shader.getPropertyByName("u_pointLightPosition"); - private static _distanceProperty: ShaderProperty = Shader.getPropertyByName("u_pointLightDistance"); + private static _colorProperty: ShaderProperty = ShaderProperty.getByName("u_pointLightColor"); + private static _positionProperty: ShaderProperty = ShaderProperty.getByName("u_pointLightPosition"); + private static _distanceProperty: ShaderProperty = ShaderProperty.getByName("u_pointLightDistance"); private static _combinedData = { color: new Float32Array(3 * Light._maxLight), diff --git a/packages/core/src/lighting/SpotLight.ts b/packages/core/src/lighting/SpotLight.ts index 0aee9ea1e8..fbbe9bf70a 100644 --- a/packages/core/src/lighting/SpotLight.ts +++ b/packages/core/src/lighting/SpotLight.ts @@ -7,12 +7,12 @@ import { Light } from "./Light"; * Spot light. */ export class SpotLight extends Light { - private static _colorProperty: ShaderProperty = Shader.getPropertyByName("u_spotLightColor"); - private static _positionProperty: ShaderProperty = Shader.getPropertyByName("u_spotLightPosition"); - private static _directionProperty: ShaderProperty = Shader.getPropertyByName("u_spotLightDirection"); - private static _distanceProperty: ShaderProperty = Shader.getPropertyByName("u_spotLightDistance"); - private static _angleCosProperty: ShaderProperty = Shader.getPropertyByName("u_spotLightAngleCos"); - private static _penumbraCosProperty: ShaderProperty = Shader.getPropertyByName("u_spotLightPenumbraCos"); + private static _colorProperty: ShaderProperty = ShaderProperty.getByName("u_spotLightColor"); + private static _positionProperty: ShaderProperty = ShaderProperty.getByName("u_spotLightPosition"); + private static _directionProperty: ShaderProperty = ShaderProperty.getByName("u_spotLightDirection"); + private static _distanceProperty: ShaderProperty = ShaderProperty.getByName("u_spotLightDistance"); + private static _angleCosProperty: ShaderProperty = ShaderProperty.getByName("u_spotLightAngleCos"); + private static _penumbraCosProperty: ShaderProperty = ShaderProperty.getByName("u_spotLightPenumbraCos"); private static _combinedData = { color: new Float32Array(3 * Light._maxLight), diff --git a/packages/core/src/material/BaseMaterial.ts b/packages/core/src/material/BaseMaterial.ts index a6238ae7d5..f3bca386dc 100644 --- a/packages/core/src/material/BaseMaterial.ts +++ b/packages/core/src/material/BaseMaterial.ts @@ -1,5 +1,5 @@ import { Engine } from "../Engine"; -import { BlendFactor, BlendOperation, CullMode, Shader } from "../shader"; +import { BlendFactor, BlendOperation, CullMode, Shader, ShaderProperty } from "../shader"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { ShaderMacro } from "../shader/ShaderMacro"; import { RenderState } from "../shader/state/RenderState"; @@ -8,20 +8,20 @@ import { RenderFace } from "./enums/RenderFace"; import { Material } from "./Material"; export class BaseMaterial extends Material { - protected static _baseColorProp = Shader.getPropertyByName("u_baseColor"); - protected static _baseTextureProp = Shader.getPropertyByName("u_baseTexture"); - protected static _baseTextureMacro: ShaderMacro = Shader.getMacroByName("BASETEXTURE"); - protected static _tilingOffsetProp = Shader.getPropertyByName("u_tilingOffset"); - protected static _normalTextureProp = Shader.getPropertyByName("u_normalTexture"); - protected static _normalIntensityProp = Shader.getPropertyByName("u_normalIntensity"); - protected static _normalTextureMacro: ShaderMacro = Shader.getMacroByName("NORMALTEXTURE"); - protected static _emissiveColorProp = Shader.getPropertyByName("u_emissiveColor"); - protected static _emissiveTextureProp = Shader.getPropertyByName("u_emissiveTexture"); - protected static _emissiveTextureMacro: ShaderMacro = Shader.getMacroByName("EMISSIVETEXTURE"); - protected static _transparentMacro: ShaderMacro = Shader.getMacroByName("OASIS_TRANSPARENT"); - - private static _alphaCutoffProp = Shader.getPropertyByName("u_alphaCutoff"); - private static _alphaCutoffMacro: ShaderMacro = Shader.getMacroByName("ALPHA_CUTOFF"); + protected static _baseColorProp: ShaderProperty = ShaderProperty.getByName("u_baseColor"); + protected static _baseTextureProp: ShaderProperty = ShaderProperty.getByName("u_baseTexture"); + protected static _baseTextureMacro: ShaderMacro = ShaderMacro.getByName("BASETEXTURE"); + protected static _tilingOffsetProp: ShaderProperty = ShaderProperty.getByName("u_tilingOffset"); + protected static _normalTextureProp: ShaderProperty = ShaderProperty.getByName("u_normalTexture"); + protected static _normalIntensityProp: ShaderProperty = ShaderProperty.getByName("u_normalIntensity"); + protected static _normalTextureMacro: ShaderMacro = ShaderMacro.getByName("NORMALTEXTURE"); + protected static _emissiveColorProp: ShaderProperty = ShaderProperty.getByName("u_emissiveColor"); + protected static _emissiveTextureProp: ShaderProperty = ShaderProperty.getByName("u_emissiveTexture"); + protected static _emissiveTextureMacro: ShaderMacro = ShaderMacro.getByName("EMISSIVETEXTURE"); + protected static _transparentMacro: ShaderMacro = ShaderMacro.getByName("OASIS_TRANSPARENT"); + + private static _alphaCutoffProp = ShaderProperty.getByName("u_alphaCutoff"); + private static _alphaCutoffMacro: ShaderMacro = ShaderMacro.getByName("ALPHA_CUTOFF"); private _renderFace: RenderFace = RenderFace.Front; private _isTransparent: boolean = false; diff --git a/packages/core/src/material/BlinnPhongMaterial.ts b/packages/core/src/material/BlinnPhongMaterial.ts index b4278b32c8..ce094f8fca 100644 --- a/packages/core/src/material/BlinnPhongMaterial.ts +++ b/packages/core/src/material/BlinnPhongMaterial.ts @@ -1,6 +1,7 @@ import { Color, Vector4 } from "@oasis-engine/math"; import { Engine } from "../Engine"; import { Shader } from "../shader/Shader"; +import { ShaderProperty } from "../shader/ShaderProperty"; import { Texture2D } from "../texture/Texture2D"; import { BaseMaterial } from "./BaseMaterial"; @@ -8,9 +9,9 @@ import { BaseMaterial } from "./BaseMaterial"; * Blinn-phong Material. */ export class BlinnPhongMaterial extends BaseMaterial { - private static _specularColorProp = Shader.getPropertyByName("u_specularColor"); - private static _shininessProp = Shader.getPropertyByName("u_shininess"); - private static _specularTextureProp = Shader.getPropertyByName("u_specularTexture"); + private static _specularColorProp = ShaderProperty.getByName("u_specularColor"); + private static _shininessProp = ShaderProperty.getByName("u_shininess"); + private static _specularTextureProp = ShaderProperty.getByName("u_specularTexture"); /** * Base color. diff --git a/packages/core/src/material/PBRBaseMaterial.ts b/packages/core/src/material/PBRBaseMaterial.ts index 7888cf012e..f3de652a6e 100644 --- a/packages/core/src/material/PBRBaseMaterial.ts +++ b/packages/core/src/material/PBRBaseMaterial.ts @@ -1,5 +1,5 @@ import { Color, Vector4 } from "@oasis-engine/math"; -import { Logger } from ".."; +import { Logger, ShaderProperty } from ".."; import { Engine } from "../Engine"; import { Shader } from "../shader/Shader"; import { Texture2D } from "../texture/Texture2D"; @@ -10,15 +10,15 @@ import { TextureCoordinate } from "./enums/TextureCoordinate"; * PBR (Physically-Based Rendering) Material. */ export abstract class PBRBaseMaterial extends BaseMaterial { - private static _occlusionTextureIntensityProp = Shader.getPropertyByName("u_occlusionIntensity"); - private static _occlusionTextureCoordProp = Shader.getPropertyByName("u_occlusionTextureCoord"); - private static _occlusionTextureProp = Shader.getPropertyByName("u_occlusionTexture"); - - private static _clearCoatProp = Shader.getPropertyByName("u_clearCoat"); - private static _clearCoatTextureProp = Shader.getPropertyByName("u_clearCoatTexture"); - private static _clearCoatRoughnessProp = Shader.getPropertyByName("u_clearCoatRoughness"); - private static _clearCoatRoughnessTextureProp = Shader.getPropertyByName("u_clearCoatRoughnessTexture"); - private static _clearCoatNormalTextureProp = Shader.getPropertyByName("u_clearCoatNormalTexture"); + private static _occlusionTextureIntensityProp = ShaderProperty.getByName("u_occlusionIntensity"); + private static _occlusionTextureCoordProp = ShaderProperty.getByName("u_occlusionTextureCoord"); + private static _occlusionTextureProp = ShaderProperty.getByName("u_occlusionTexture"); + + private static _clearCoatProp = ShaderProperty.getByName("u_clearCoat"); + private static _clearCoatTextureProp = ShaderProperty.getByName("u_clearCoatTexture"); + private static _clearCoatRoughnessProp = ShaderProperty.getByName("u_clearCoatRoughness"); + private static _clearCoatRoughnessTextureProp = ShaderProperty.getByName("u_clearCoatRoughnessTexture"); + private static _clearCoatNormalTextureProp = ShaderProperty.getByName("u_clearCoatNormalTexture"); /** * Base color. diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 8ebe15762c..15cb70b644 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -1,4 +1,5 @@ import { Engine } from "../Engine"; +import { ShaderProperty } from "../shader"; import { Shader } from "../shader/Shader"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; @@ -7,9 +8,9 @@ import { PBRBaseMaterial } from "./PBRBaseMaterial"; * PBR (Metallic-Roughness Workflow) Material. */ export class PBRMaterial extends PBRBaseMaterial { - private static _metallicProp = Shader.getPropertyByName("u_metal"); - private static _roughnessProp = Shader.getPropertyByName("u_roughness"); - private static _roughnessMetallicTextureProp = Shader.getPropertyByName("u_roughnessMetallicTexture"); + private static _metallicProp = ShaderProperty.getByName("u_metal"); + private static _roughnessProp = ShaderProperty.getByName("u_roughness"); + private static _roughnessMetallicTextureProp = ShaderProperty.getByName("u_roughnessMetallicTexture"); /** * Metallic, default 1.0. diff --git a/packages/core/src/material/PBRSpecularMaterial.ts b/packages/core/src/material/PBRSpecularMaterial.ts index 16790a3e87..788b40584e 100644 --- a/packages/core/src/material/PBRSpecularMaterial.ts +++ b/packages/core/src/material/PBRSpecularMaterial.ts @@ -2,6 +2,7 @@ import { Color } from "@oasis-engine/math"; import { Engine } from "../Engine"; import { Shader } from "../shader/Shader"; import { ShaderMacro } from "../shader/ShaderMacro"; +import { ShaderProperty } from "../shader/ShaderProperty"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; @@ -9,10 +10,10 @@ import { PBRBaseMaterial } from "./PBRBaseMaterial"; * PBR (Specular-Glossiness Workflow) Material. */ export class PBRSpecularMaterial extends PBRBaseMaterial { - private static _specularColorProp = Shader.getPropertyByName("u_PBRSpecularColor"); - private static _glossinessProp = Shader.getPropertyByName("u_glossiness"); - private static _specularGlossinessTextureProp = Shader.getPropertyByName("u_specularGlossinessTexture"); - private static _specularGlossinessTextureMacro: ShaderMacro = Shader.getMacroByName("SPECULARGLOSSINESSTEXTURE"); + private static _specularColorProp = ShaderProperty.getByName("u_PBRSpecularColor"); + private static _glossinessProp = ShaderProperty.getByName("u_glossiness"); + private static _specularGlossinessTextureProp = ShaderProperty.getByName("u_specularGlossinessTexture"); + private static _specularGlossinessTextureMacro: ShaderMacro = ShaderMacro.getByName("SPECULARGLOSSINESSTEXTURE"); /** * Specular color. diff --git a/packages/core/src/mesh/BlendShapeManager.ts b/packages/core/src/mesh/BlendShapeManager.ts index bfcf0991bd..894c64c852 100644 --- a/packages/core/src/mesh/BlendShapeManager.ts +++ b/packages/core/src/mesh/BlendShapeManager.ts @@ -9,6 +9,8 @@ import { VertexBufferBinding } from "../graphic/VertexBufferBinding"; import { VertexElement } from "../graphic/VertexElement"; import { Shader } from "../shader/Shader"; import { ShaderData } from "../shader/ShaderData"; +import { ShaderMacro } from "../shader/ShaderMacro"; +import { ShaderProperty } from "../shader/ShaderProperty"; import { Texture2DArray, TextureFilterMode, TextureFormat } from "../texture"; import { BlendShape } from "./BlendShape"; import { ModelMesh } from "./ModelMesh"; @@ -18,14 +20,14 @@ import { SkinnedMeshRenderer } from "./SkinnedMeshRenderer"; * @internal */ export class BlendShapeManager { - private static _blendShapeMacro = Shader.getMacroByName("OASIS_BLENDSHAPE"); - private static _blendShapeTextureMacro = Shader.getMacroByName("OASIS_BLENDSHAPE_TEXTURE"); - private static _blendShapeNormalMacro = Shader.getMacroByName("OASIS_BLENDSHAPE_NORMAL"); - private static _blendShapeTangentMacro = Shader.getMacroByName("OASIS_BLENDSHAPE_TANGENT"); - - private static _blendShapeWeightsProperty = Shader.getPropertyByName("u_blendShapeWeights"); - private static _blendShapeTextureProperty = Shader.getPropertyByName("u_blendShapeTexture"); - private static _blendShapeTextureInfoProperty = Shader.getPropertyByName("u_blendShapeTextureInfo"); + private static _blendShapeMacro = ShaderMacro.getByName("OASIS_BLENDSHAPE"); + private static _blendShapeTextureMacro = ShaderMacro.getByName("OASIS_BLENDSHAPE_TEXTURE"); + private static _blendShapeNormalMacro = ShaderMacro.getByName("OASIS_BLENDSHAPE_NORMAL"); + private static _blendShapeTangentMacro = ShaderMacro.getByName("OASIS_BLENDSHAPE_TANGENT"); + + private static _blendShapeWeightsProperty = ShaderProperty.getByName("u_blendShapeWeights"); + private static _blendShapeTextureProperty = ShaderProperty.getByName("u_blendShapeTexture"); + private static _blendShapeTextureInfoProperty = ShaderProperty.getByName("u_blendShapeTextureInfo"); /** @internal */ _blendShapeCount: number = 0; diff --git a/packages/core/src/mesh/MeshRenderer.ts b/packages/core/src/mesh/MeshRenderer.ts index 1aa35573f0..47e087c33b 100644 --- a/packages/core/src/mesh/MeshRenderer.ts +++ b/packages/core/src/mesh/MeshRenderer.ts @@ -7,16 +7,17 @@ import { Mesh, MeshModifyFlags } from "../graphic/Mesh"; import { Renderer, RendererUpdateFlags } from "../Renderer"; import { RenderContext } from "../RenderPipeline/RenderContext"; import { Shader } from "../shader/Shader"; +import { ShaderMacro } from "../shader/ShaderMacro"; /** * MeshRenderer Component. */ export class MeshRenderer extends Renderer implements ICustomClone { - private static _uvMacro = Shader.getMacroByName("O3_HAS_UV"); - private static _uv1Macro = Shader.getMacroByName("O3_HAS_UV1"); - private static _normalMacro = Shader.getMacroByName("O3_HAS_NORMAL"); - private static _tangentMacro = Shader.getMacroByName("O3_HAS_TANGENT"); - private static _vertexColorMacro = Shader.getMacroByName("O3_HAS_VERTEXCOLOR"); + private static _uvMacro = ShaderMacro.getByName("O3_HAS_UV"); + private static _uv1Macro = ShaderMacro.getByName("O3_HAS_UV1"); + private static _normalMacro = ShaderMacro.getByName("O3_HAS_NORMAL"); + private static _tangentMacro = ShaderMacro.getByName("O3_HAS_TANGENT"); + private static _vertexColorMacro = ShaderMacro.getByName("O3_HAS_VERTEXCOLOR"); /** @internal */ @ignoreClone diff --git a/packages/core/src/mesh/SkinnedMeshRenderer.ts b/packages/core/src/mesh/SkinnedMeshRenderer.ts index 5b63e2debc..88ec734ea5 100644 --- a/packages/core/src/mesh/SkinnedMeshRenderer.ts +++ b/packages/core/src/mesh/SkinnedMeshRenderer.ts @@ -4,7 +4,7 @@ import { ignoreClone } from "../clone/CloneManager"; import { Entity } from "../Entity"; import { RendererUpdateFlags } from "../Renderer"; import { RenderContext } from "../RenderPipeline/RenderContext"; -import { Shader } from "../shader"; +import { Shader, ShaderProperty } from "../shader"; import { TextureFilterMode } from "../texture/enums/TextureFilterMode"; import { TextureFormat } from "../texture/enums/TextureFormat"; import { Texture2D } from "../texture/Texture2D"; @@ -18,9 +18,9 @@ import { Skin } from "./Skin"; */ export class SkinnedMeshRenderer extends MeshRenderer { private static _tempMatrix = new Matrix(); - private static _jointCountProperty = Shader.getPropertyByName("u_jointCount"); - private static _jointSamplerProperty = Shader.getPropertyByName("u_jointSampler"); - private static _jointMatrixProperty = Shader.getPropertyByName("u_jointMatrix"); + private static _jointCountProperty = ShaderProperty.getByName("u_jointCount"); + private static _jointSamplerProperty = ShaderProperty.getByName("u_jointSampler"); + private static _jointMatrixProperty = ShaderProperty.getByName("u_jointMatrix"); @ignoreClone private _hasInitSkin: boolean = false; diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index 49ae69b941..eec8f8b218 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -114,7 +114,7 @@ export class Shader { const compileMacros = Shader._compileMacros; compileMacros.clear(); for (let i = 0, n = macros.length; i < n; i++) { - compileMacros.enable(Shader.getMacroByName(macros[i])); + compileMacros.enable(ShaderMacro.getByName(macros[i])); } const subShaders = this._subShaders; diff --git a/packages/core/src/shader/ShaderData.ts b/packages/core/src/shader/ShaderData.ts index 1174dd8015..a52400cd64 100644 --- a/packages/core/src/shader/ShaderData.ts +++ b/packages/core/src/shader/ShaderData.ts @@ -40,7 +40,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get float by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Float */ getFloat(property: ShaderProperty): number; @@ -60,7 +60,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set float by shader property. * @remarks Corresponding float shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Float */ setFloat(property: ShaderProperty, value: number): void; @@ -78,7 +78,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get int by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Int */ getInt(property: ShaderProperty): number; @@ -98,7 +98,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set int by shader property. * @remarks Correspondence includes int and bool shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Int */ setInt(property: ShaderProperty, value: number): void; @@ -116,7 +116,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get float array by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Float array */ getFloatArray(property: ShaderProperty): Float32Array; @@ -136,7 +136,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set float array by shader property. * @remarks Correspondence includes float array、vec2 array、vec3 array、vec4 array and matrix array shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Float array */ setFloatArray(property: ShaderProperty, value: Float32Array): void; @@ -154,7 +154,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get int array by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Int Array */ getIntArray(property: ShaderProperty): Int32Array; @@ -174,7 +174,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set int array by shader property. * @remarks Correspondence includes bool array、int array、bvec2 array、bvec3 array、bvec4 array、ivec2 array、ivec3 array and ivec4 array shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Int Array */ setIntArray(property: ShaderProperty, value: Int32Array): void; @@ -192,7 +192,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get two-dimensional from shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Two-dimensional vector */ getVector2(property: ShaderProperty): Vector2; @@ -212,7 +212,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set two-dimensional vector from shader property. * @remarks Correspondence includes vec2、ivec2 and bvec2 shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Two-dimensional vector */ setVector2(property: ShaderProperty, value: Vector2): void; @@ -230,7 +230,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get vector3 by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Three-dimensional vector */ getVector3(property: ShaderProperty): Vector3; @@ -250,7 +250,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set three dimensional vector by shader property. * @remarks Correspondence includes vec3、ivec3 and bvec3 shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Three-dimensional vector */ setVector3(property: ShaderProperty, value: Vector3): void; @@ -268,7 +268,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get vector4 by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Four-dimensional vector */ getVector4(property: ShaderProperty): Vector4; @@ -288,7 +288,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set four-dimensional vector by shader property. * @remarks Correspondence includes vec4、ivec4 and bvec4 shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Four-dimensional vector */ setVector4(property: ShaderProperty, value: Vector4): void; @@ -306,7 +306,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get matrix by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Matrix */ getMatrix(property: ShaderProperty): Matrix; @@ -326,7 +326,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set matrix by shader property. * @remarks Correspondence includes matrix shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Matrix */ setMatrix(property: ShaderProperty, value: Matrix); @@ -344,7 +344,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get color by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Color */ getColor(property: ShaderProperty): Color; @@ -364,7 +364,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set color by shader property. * @remarks Correspondence includes vec4 shader property type. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Color */ setColor(property: ShaderProperty, value: Color): void; @@ -382,7 +382,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get texture by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Texture */ getTexture(property: ShaderProperty): Texture; @@ -400,7 +400,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set texture by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Texture */ setTexture(property: ShaderProperty, value: Texture): void; @@ -423,7 +423,7 @@ export class ShaderData implements IRefObject, IClone { /** * Get texture array by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @returns Texture array */ getTextureArray(property: ShaderProperty): Texture[]; @@ -441,7 +441,7 @@ export class ShaderData implements IRefObject, IClone { /** * Set texture array by shader property. - * @param property - Shader property, use `Shader.getPropertyByName` to get + * @param property - Shader property, use `ShaderProperty.getByName` to get * @param value - Texture array */ setTextureArray(property: ShaderProperty, value: Texture[]): void; @@ -470,7 +470,7 @@ export class ShaderData implements IRefObject, IClone { */ getPropertyValue(property: string | ShaderProperty): T { if (typeof property === "string") { - property = Shader.getPropertyByName(property); + property = ShaderProperty.getByName(property); } return this._propertyValueMap[property._uniqueId] as T; } @@ -497,7 +497,7 @@ export class ShaderData implements IRefObject, IClone { enableMacro(macro: string | ShaderMacro, value?: string): void { if (typeof macro === "string") { - macro = Shader.getMacroByName(macro, value); + macro = ShaderMacro.getByName(macro, value); } const nameID = macro._nameId; const lastMacro = this._macroMap[nameID]; @@ -639,7 +639,7 @@ export class ShaderData implements IRefObject, IClone { value: T ): void { if (typeof property === "string") { - property = Shader.getPropertyByName(property); + property = ShaderProperty.getByName(property); } if (property._group !== this._group) { diff --git a/packages/core/src/shader/ShaderProgram.ts b/packages/core/src/shader/ShaderProgram.ts index 94d154a5a9..a1b01b7d7d 100644 --- a/packages/core/src/shader/ShaderProgram.ts +++ b/packages/core/src/shader/ShaderProgram.ts @@ -328,7 +328,7 @@ export class ShaderProgram { const location = gl.getUniformLocation(program, name); shaderUniform.name = name; - shaderUniform.propertyId = Shader.getPropertyByName(name)._uniqueId; + shaderUniform.propertyId = ShaderProperty.getByName(name)._uniqueId; shaderUniform.location = location; switch (type) { diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index 67f1cb2edd..d3f5f08e4d 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -7,7 +7,7 @@ import { Layer } from "../Layer"; import { DirectLight } from "../lighting"; import { RenderContext } from "../RenderPipeline/RenderContext"; import { RenderQueue } from "../RenderPipeline/RenderQueue"; -import { Shader } from "../shader"; +import { Shader, ShaderProperty } from "../shader"; import { TextureDepthCompareFunction } from "../texture/enums/TextureDepthCompareFunction"; import { TextureFormat } from "../texture/enums/TextureFormat"; import { TextureWrapMode } from "../texture/enums/TextureWrapMode"; @@ -21,14 +21,14 @@ import { ShadowUtils } from "./ShadowUtils"; * Cascade shadow caster. */ export class CascadedShadowCasterPass { - private static _lightShadowBiasProperty = Shader.getPropertyByName("u_shadowBias"); - private static _lightDirectionProperty = Shader.getPropertyByName("u_lightDirection"); - - private static _shadowMatricesProperty = Shader.getPropertyByName("u_shadowMatrices"); - private static _shadowMapSize = Shader.getPropertyByName("u_shadowMapSize"); - private static _shadowInfosProperty = Shader.getPropertyByName("u_shadowInfo"); - private static _shadowMapsProperty = Shader.getPropertyByName("u_shadowMap"); - private static _shadowSplitSpheresProperty = Shader.getPropertyByName("u_shadowSplitSpheres"); + private static _lightShadowBiasProperty = ShaderProperty.getByName("u_shadowBias"); + private static _lightDirectionProperty = ShaderProperty.getByName("u_lightDirection"); + + private static _shadowMatricesProperty = ShaderProperty.getByName("u_shadowMatrices"); + private static _shadowMapSize = ShaderProperty.getByName("u_shadowMapSize"); + private static _shadowInfosProperty = ShaderProperty.getByName("u_shadowInfo"); + private static _shadowMapsProperty = ShaderProperty.getByName("u_shadowMap"); + private static _shadowSplitSpheresProperty = ShaderProperty.getByName("u_shadowSplitSpheres"); private static _maxCascades: number = 4; private static _cascadesSplitDistance: number[] = new Array(CascadedShadowCasterPass._maxCascades + 1); From 8add4fb1725ad2c6d7e45f516ec1420a2542898c Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 15:30:00 +0800 Subject: [PATCH 42/62] test(Shader): improve shader unit test --- packages/core/src/shader/index.ts | 6 ++++-- tests/src/core/Shader.test.ts | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index ab684e9516..f57096ce10 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -1,14 +1,16 @@ -export { RenderQueueType } from "./enums/RenderQueueType"; export { BlendFactor } from "./enums/BlendFactor"; export { BlendOperation } from "./enums/BlendOperation"; export { ColorWriteMask } from "./enums/ColorWriteMask"; export { CompareFunction } from "./enums/CompareFunction"; export { CullMode } from "./enums/CullMode"; +export { RenderQueueType } from "./enums/RenderQueueType"; export { ShaderPropertyType } from "./enums/ShaderPropertyType"; export { StencilOperation } from "./enums/StencilOperation"; export { Shader } from "./Shader"; export { ShaderData } from "./ShaderData"; +export { ShaderMacro } from "./ShaderMacro"; export { ShaderPass } from "./ShaderPass"; -export { ShaderTag } from "./ShaderTag"; export { ShaderProperty } from "./ShaderProperty"; +export { ShaderTag } from "./ShaderTag"; +export { SubShader } from "./SubShader"; diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index e7a0f412e2..0f36b54505 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -1,15 +1,17 @@ -import { Shader, ShaderTag } from "@oasis-engine/core"; +import { Shader, ShaderMacro, ShaderPass, ShaderProperty, ShaderTag, SubShader } from "@oasis-engine/core"; import chai, { expect } from "chai"; import spies from "chai-spies"; -import { ShaderProperty } from "packages/core/src"; -import { ShaderMacro } from "packages/core/src/shader/ShaderMacro"; chai.use(spies); describe("Shader", () => { describe("Custom Shader", () => { it("Shader", () => { - const customShader = Shader.create("custom", customVS, customFS); + // Create shader + let customShader = Shader.create("customByStringCreate", customVS, customFS); + customShader = Shader.create("customByPassCreate", [new ShaderPass(customVS, customFS)]); + customShader = Shader.create("custom", [new SubShader("Default", [new ShaderPass(customVS, customFS)])]); + // Base struct created by Shader.create expect(customShader.subShaders).length(1); expect(customShader.subShaders[0].passes).length(1); From adfc9cb51080f36b21079cb24834077e22c522c4 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 16:25:53 +0800 Subject: [PATCH 43/62] test(Shader): improve unit test --- tests/src/core/Shader.test.ts | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index 0f36b54505..8373698537 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -1,4 +1,13 @@ -import { Shader, ShaderMacro, ShaderPass, ShaderProperty, ShaderTag, SubShader } from "@oasis-engine/core"; +import { + BlinnPhongMaterial, Camera, DirectLight, MeshRenderer, + PrimitiveMesh, Shader, + ShaderMacro, + ShaderPass, + ShaderProperty, + ShaderTag, + SubShader +} from "@oasis-engine/core"; +import { WebGLEngine } from "@oasis-engine/rhi-webgl"; import chai, { expect } from "chai"; import spies from "chai-spies"; @@ -25,7 +34,12 @@ describe("Shader", () => { // Shader macro const customMacro = ShaderMacro.getByName("CUSTOM_MACRO"); + + // Shader macro with value + const customMacroValue = ShaderMacro.getByName("CUSTOM_MACRO", "Value"); expect(customMacro.name).to.equal("CUSTOM_MACRO"); + expect(customMacroValue.name).to.equal("CUSTOM_MACRO"); + expect(customMacroValue.value).to.equal("Value"); // Compile variant }); @@ -79,6 +93,34 @@ describe("Shader", () => { getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.undefined; }); + + it("Render and compile", () => { + const engine = new WebGLEngine(document.createElement("canvas")); + // Get scene and create root entity + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity("Root"); + + // Create light + const lightEntity = rootEntity.createChild("Light"); + const directLight = lightEntity.addComponent(DirectLight); + lightEntity.transform.setRotation(-45, -45, 0); + directLight.intensity = 0.4; + + // Create camera + const cameraEntity = rootEntity.createChild("Camera"); + cameraEntity.addComponent(Camera); + cameraEntity.transform.setPosition(0, 0, 12); + + // Create sphere + const meshEntity = rootEntity.createChild("Sphere"); + const meshRenderer = meshEntity.addComponent(MeshRenderer); + const material = new BlinnPhongMaterial(engine); + meshRenderer.setMaterial(material); + meshRenderer.mesh = PrimitiveMesh.createSphere(engine, 1); + + // Call update will compile shader internally + engine.update(); + }); }); }); From b2af4efb726ffd66b9d5518f4ad08e5f28876289 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Wed, 8 Mar 2023 17:20:59 +0800 Subject: [PATCH 44/62] doc(Shader): fix spell --- packages/core/src/shader/Shader.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index eec8f8b218..f786db2fcf 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -40,10 +40,10 @@ export class Shader { /** * Create a shader. * @param name - Name of the shader - * @param SubShaders - Sub shaders + * @param subShaders - Sub shaders * @returns Shader */ - static create(name: string, SubShaders: SubShader[]): Shader; + static create(name: string, subShaders: SubShader[]): Shader; static create( name: string, From 05e42c9ff734c8bd9c166b780551dd9e9b80dd92 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Thu, 9 Mar 2023 01:11:35 +0800 Subject: [PATCH 45/62] refactor: opt ShaderPass construct --- packages/core/src/shader/ShaderPass.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 07e7cb2402..7e1e1b3002 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -25,19 +25,19 @@ export class ShaderPass extends ShaderPart { * @param fragmentSource - Fragment shader source * @param tags - Tags */ - constructor(vertexSource: string, fragmentSource: string, tags?: Record) { + constructor( + vertexSource: string, + fragmentSource: string, + tags: Record = { PipelineStage: "Forward" } + ) { super(); this._shaderPassId = ShaderPass._shaderPassCounter++; this._vertexSource = vertexSource; this._fragmentSource = fragmentSource; - if (tags) { - for (const key in tags) { - this.setTag(key, tags[key]); - } - } else { - this.setTag("PipelineStage", "Forward"); + for (const key in tags) { + this.setTag(key, tags[key]); } } From 9ce7aa7ca14013237baa8179b11daf13b184f1fe Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Thu, 9 Mar 2023 11:15:48 +0800 Subject: [PATCH 46/62] refactor: opt shader part --- packages/core/src/shader/ShaderPart.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index ebe171baac..4c0db3f0b2 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -1,6 +1,9 @@ import { ShaderTag } from "./ShaderTag"; -export class ShaderPart { +/** + * Base class for shader structure. + */ +export abstract class ShaderPart { private _tagsMap: Record = Object.create(null); /** @@ -50,14 +53,14 @@ export class ShaderPart { * @param keyName - Key name of the tag * @returns Value of the tag */ - getTagValue(keyName: ShaderTag | string): ShaderTag; + getTagValue(keyName: string): ShaderTag; /** * Get tag value by key. * @param key - Key of the tag * @returns Value of the tag */ - getTagValue(key: ShaderTag | string): ShaderTag; + getTagValue(key: ShaderTag): ShaderTag; getTagValue(keyOrKeyName: ShaderTag | string): ShaderTag { return this._tagsMap[ From f7cb7e3f10f7dcf6f8a61fd28d21d376482e725c Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Thu, 9 Mar 2023 13:27:50 +0800 Subject: [PATCH 47/62] refactor: opt pipelineStage by enum --- packages/core/src/RenderPipeline/BasicRenderPipeline.ts | 9 +++++---- packages/core/src/RenderPipeline/Index.ts | 4 ++++ packages/core/src/RenderPipeline/RenderContext.ts | 2 +- packages/core/src/RenderPipeline/enums/PipelineStage.ts | 9 +++++++++ packages/core/src/index.ts | 4 +--- packages/core/src/shader/ShaderPart.ts | 1 + packages/core/src/shader/ShaderPass.ts | 3 ++- packages/core/src/shader/ShaderPool.ts | 5 +++-- 8 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 packages/core/src/RenderPipeline/Index.ts create mode 100644 packages/core/src/RenderPipeline/enums/PipelineStage.ts diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index a4e547db52..e9a72d17a2 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -17,6 +17,7 @@ import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; import { RenderTarget, TextureCubeFace } from "../texture"; +import { PipelineStage } from "./enums/PipelineStage"; import { RenderContext } from "./RenderContext"; import { RenderData } from "./RenderData"; import { RenderPass } from "./RenderPass"; @@ -26,8 +27,8 @@ import { RenderQueue } from "./RenderQueue"; * Basic render pipeline. */ export class BasicRenderPipeline { - private static _shadowCasterPipelineStage = ShaderTag.getByName("ShadowCaster"); - private static _forwardPipelineStage = ShaderTag.getByName("Forward"); + private static _shadowCasterPipelineStageValue = ShaderTag.getByName(PipelineStage.ShadowCaster); + private static _forwardPipelineStageValue = ShaderTag.getByName(PipelineStage.Forward); /** @internal */ _opaqueQueue: RenderQueue; @@ -150,7 +151,7 @@ export class BasicRenderPipeline { camera.engine._spriteMaskManager.clear(); - context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStage; + context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStageValue; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -161,7 +162,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); - context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStage; + context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStageValue; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); diff --git a/packages/core/src/RenderPipeline/Index.ts b/packages/core/src/RenderPipeline/Index.ts new file mode 100644 index 0000000000..dd7aa20cd5 --- /dev/null +++ b/packages/core/src/RenderPipeline/Index.ts @@ -0,0 +1,4 @@ +export { BasicRenderPipeline } from "./BasicRenderPipeline"; +export { PipelineStage } from "./enums/PipelineStage"; +export { RenderPass } from "./RenderPass"; +export { RenderQueue } from "./RenderQueue"; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index 586cec0fa2..5c4e441be9 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -9,7 +9,7 @@ import { VirtualCamera } from "../VirtualCamera"; */ export class RenderContext { static vpMatrixProperty = ShaderProperty.getByName("u_VPMat"); - static pipelineStageKey: ShaderTag = ShaderTag.getByName("PipelineStage"); + static pipelineStageKey: ShaderTag = ShaderTag.getByName("pipelineStage"); private static _viewMatrixProperty = ShaderProperty.getByName("u_viewMat"); private static _projectionMatrixProperty = ShaderProperty.getByName("u_projMat"); diff --git a/packages/core/src/RenderPipeline/enums/PipelineStage.ts b/packages/core/src/RenderPipeline/enums/PipelineStage.ts new file mode 100644 index 0000000000..61612071f3 --- /dev/null +++ b/packages/core/src/RenderPipeline/enums/PipelineStage.ts @@ -0,0 +1,9 @@ +/** + * Pipeline stage. + */ +export enum PipelineStage { + /** Shadow caster stage. */ + ShadowCaster = "ShadowCaster", + /** Forward shading stage. */ + Forward = "Forward" +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 3506635516..933c519cf6 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -24,9 +24,7 @@ export type { LoadItem } from "./asset/LoadItem"; export { AssetType } from "./asset/AssetType"; export { RefObject } from "./asset/RefObject"; -export { BasicRenderPipeline } from "./RenderPipeline/BasicRenderPipeline"; -export { RenderQueue } from "./RenderPipeline/RenderQueue"; -export { RenderPass } from "./RenderPipeline/RenderPass"; +export * from "./RenderPipeline"; export * from "./base"; export { Background } from "./Background"; diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 4c0db3f0b2..2c8e0c6f9f 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -12,6 +12,7 @@ export abstract class ShaderPart { * @param valueName - Name of the tag value */ setTag(keyName: string, valueName: string): void; + /** * Set tag. * @param key - Key of the tag diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 7e1e1b3002..568ff6c3e0 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -1,5 +1,6 @@ import { GLCapabilityType } from "../base/Constant"; import { Engine } from "../Engine"; +import { PipelineStage } from "../RenderPipeline/enums/PipelineStage"; import { ShaderFactory } from "../shaderlib/ShaderFactory"; import { Shader } from "./Shader"; import { ShaderMacro } from "./ShaderMacro"; @@ -28,7 +29,7 @@ export class ShaderPass extends ShaderPart { constructor( vertexSource: string, fragmentSource: string, - tags: Record = { PipelineStage: "Forward" } + tags: Record = { pipelineStage: PipelineStage.Forward } ) { super(); this._shaderPassId = ShaderPass._shaderPassCounter++; diff --git a/packages/core/src/shader/ShaderPool.ts b/packages/core/src/shader/ShaderPool.ts index a3d1000323..61473002c6 100644 --- a/packages/core/src/shader/ShaderPool.ts +++ b/packages/core/src/shader/ShaderPool.ts @@ -1,3 +1,4 @@ +import { PipelineStage } from "../RenderPipeline/enums/PipelineStage"; import backgroundTextureFs from "../shaderlib/extra/background-texture.fs.glsl"; import backgroundTextureVs from "../shaderlib/extra/background-texture.vs.glsl"; import blinnPhongFs from "../shaderlib/extra/blinn-phong.fs.glsl"; @@ -27,10 +28,10 @@ import { ShaderPass } from "./ShaderPass"; export class ShaderPool { static init(): void { const shadowCasterPassTags = { - PipelineStage: "ShadowCaster" + pipelineStage: PipelineStage.ShadowCaster }; const forwardPassTags = { - PipelineStage: "Forward" + pipelineStage: PipelineStage.Forward }; const shadowCasterPass = new ShaderPass(shadowMapVs, shadowMapFs, shadowCasterPassTags); From 87687ef2084477d35fb039a470c66eef55c9b2ef Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Thu, 9 Mar 2023 13:30:26 +0800 Subject: [PATCH 48/62] refactor: opt code --- packages/core/src/RenderPipeline/BasicRenderPipeline.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index e9a72d17a2..efdde12dd9 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -27,8 +27,8 @@ import { RenderQueue } from "./RenderQueue"; * Basic render pipeline. */ export class BasicRenderPipeline { - private static _shadowCasterPipelineStageValue = ShaderTag.getByName(PipelineStage.ShadowCaster); - private static _forwardPipelineStageValue = ShaderTag.getByName(PipelineStage.Forward); + private static _shadowCasterPipelineStageTag = ShaderTag.getByName(PipelineStage.ShadowCaster); + private static _forwardPipelineStageTag = ShaderTag.getByName(PipelineStage.Forward); /** @internal */ _opaqueQueue: RenderQueue; @@ -151,7 +151,7 @@ export class BasicRenderPipeline { camera.engine._spriteMaskManager.clear(); - context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStageValue; + context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStageTag; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -162,7 +162,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); - context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStageValue; + context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStageTag; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); From b74727713325e7a79497239db434ae7f7af4690f Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Thu, 9 Mar 2023 23:46:12 +0800 Subject: [PATCH 49/62] refactor: opt code --- packages/core/src/Camera.ts | 6 ++-- .../src/RenderPipeline/BasicRenderPipeline.ts | 6 ++-- .../core/src/RenderPipeline/RenderContext.ts | 8 +++--- packages/core/src/shader/ShaderPart.ts | 26 ++++++++--------- packages/core/src/shader/ShaderTag.ts | 28 ------------------- packages/core/src/shader/ShaderTagProperty.ts | 28 +++++++++++++++++++ packages/core/src/shader/index.ts | 2 +- 7 files changed, 52 insertions(+), 52 deletions(-) delete mode 100644 packages/core/src/shader/ShaderTag.ts create mode 100644 packages/core/src/shader/ShaderTagProperty.ts diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index ea07f9c8d9..f66c3290f3 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -13,7 +13,7 @@ import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; import { ShaderProperty } from "./shader/ShaderProperty"; -import { ShaderTag } from "./shader/ShaderTag"; +import { ShaderTagProperty } from "./shader/ShaderTagProperty"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; import { Transform } from "./Transform"; @@ -71,7 +71,7 @@ export class Camera extends Component { /** @internal */ _replacementShader: Shader = null; /** @internal */ - _replacementSubShaderTagKey: ShaderTag = null; + _replacementSubShaderTagKey: ShaderTagProperty = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -485,7 +485,7 @@ export class Camera extends Component { * If replacementTagKey is not specified, the first sub shader will be replaced. * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. */ - setReplacementShader(shader: Shader, replacementTagKey?: ShaderTag): void { + setReplacementShader(shader: Shader, replacementTagKey?: ShaderTagProperty): void { this._replacementShader = shader; this._replacementSubShaderTagKey = replacementTagKey; } diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index efdde12dd9..6396d90e7b 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -12,7 +12,7 @@ import { Material } from "../material"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Shader } from "../shader/Shader"; import { ShaderPass } from "../shader/ShaderPass"; -import { ShaderTag } from "../shader/ShaderTag"; +import { ShaderTagProperty } from "../shader/ShaderTagProperty"; import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; @@ -27,8 +27,8 @@ import { RenderQueue } from "./RenderQueue"; * Basic render pipeline. */ export class BasicRenderPipeline { - private static _shadowCasterPipelineStageTag = ShaderTag.getByName(PipelineStage.ShadowCaster); - private static _forwardPipelineStageTag = ShaderTag.getByName(PipelineStage.Forward); + private static _shadowCasterPipelineStageTag = ShaderTagProperty.getByName(PipelineStage.ShadowCaster); + private static _forwardPipelineStageTag = ShaderTagProperty.getByName(PipelineStage.Forward); /** @internal */ _opaqueQueue: RenderQueue; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index 5c4e441be9..a43f7dfd89 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,6 +1,6 @@ import { Camera } from "../Camera"; import { Shader, ShaderProperty } from "../shader"; -import { ShaderTag } from "../shader/ShaderTag"; +import { ShaderTagProperty } from "../shader/ShaderTagProperty"; import { VirtualCamera } from "../VirtualCamera"; /** @@ -9,7 +9,7 @@ import { VirtualCamera } from "../VirtualCamera"; */ export class RenderContext { static vpMatrixProperty = ShaderProperty.getByName("u_VPMat"); - static pipelineStageKey: ShaderTag = ShaderTag.getByName("pipelineStage"); + static pipelineStageKey: ShaderTagProperty = ShaderTagProperty.getByName("pipelineStage"); private static _viewMatrixProperty = ShaderProperty.getByName("u_viewMat"); private static _projectionMatrixProperty = ShaderProperty.getByName("u_projMat"); @@ -18,8 +18,8 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTagKey: ShaderTag; - pipelineStageValue: ShaderTag; + replacementTagKey: ShaderTagProperty; + pipelineStageValue: ShaderTagProperty; applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 2c8e0c6f9f..7d706ad1fb 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -1,10 +1,10 @@ -import { ShaderTag } from "./ShaderTag"; +import { ShaderTagProperty } from "./ShaderTagProperty"; /** * Base class for shader structure. */ export abstract class ShaderPart { - private _tagsMap: Record = Object.create(null); + private _tagsMap: Record = Object.create(null); /** * Set tag by name. @@ -18,11 +18,11 @@ export abstract class ShaderPart { * @param key - Key of the tag * @param value - Value of the tag */ - setTag(key: ShaderTag, value: ShaderTag): void; + setTag(key: ShaderTagProperty, value: ShaderTagProperty): void; - setTag(keyOrKeyName: ShaderTag | string, valueOrValueName: ShaderTag | string): void { - const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; - const value = typeof valueOrValueName === "string" ? ShaderTag.getByName(valueOrValueName) : valueOrValueName; + setTag(keyOrKeyName: ShaderTagProperty | string, valueOrValueName: ShaderTagProperty | string): void { + const key = typeof keyOrKeyName === "string" ? ShaderTagProperty.getByName(keyOrKeyName) : keyOrKeyName; + const value = typeof valueOrValueName === "string" ? ShaderTagProperty.getByName(valueOrValueName) : valueOrValueName; const tags = this._tagsMap; if (tags[key._uniqueId]) { @@ -41,11 +41,11 @@ export abstract class ShaderPart { * Delete a tag by key. * @param key - Key of the tag */ - deleteTag(key: ShaderTag): void; + deleteTag(key: ShaderTagProperty): void; - deleteTag(keyOrKeyName: ShaderTag | string): void { + deleteTag(keyOrKeyName: ShaderTagProperty | string): void { delete this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + typeof keyOrKeyName == "string" ? ShaderTagProperty.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId ]; } @@ -54,18 +54,18 @@ export abstract class ShaderPart { * @param keyName - Key name of the tag * @returns Value of the tag */ - getTagValue(keyName: string): ShaderTag; + getTagValue(keyName: string): ShaderTagProperty; /** * Get tag value by key. * @param key - Key of the tag * @returns Value of the tag */ - getTagValue(key: ShaderTag): ShaderTag; + getTagValue(key: ShaderTagProperty): ShaderTagProperty; - getTagValue(keyOrKeyName: ShaderTag | string): ShaderTag { + getTagValue(keyOrKeyName: ShaderTagProperty | string): ShaderTagProperty { return this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + typeof keyOrKeyName == "string" ? ShaderTagProperty.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId ]; } } diff --git a/packages/core/src/shader/ShaderTag.ts b/packages/core/src/shader/ShaderTag.ts deleted file mode 100644 index 10573335a8..0000000000 --- a/packages/core/src/shader/ShaderTag.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Shader tag. - */ -export class ShaderTag { - private static _nameCounter: number = 0; - private static _nameMap: Record = Object.create(null); - - /** - * Get shader property by name. - * @param name - Name of the shader property - * @returns Shader property - */ - static getByName(name: string): ShaderTag { - const nameMap = ShaderTag._nameMap; - return (nameMap[name] ||= new ShaderTag(name)); - } - - /** Shader property name. */ - readonly name: string; - - /** @internal */ - _uniqueId: number; - - private constructor(name: string) { - this.name = name; - this._uniqueId = ShaderTag._nameCounter++; - } -} diff --git a/packages/core/src/shader/ShaderTagProperty.ts b/packages/core/src/shader/ShaderTagProperty.ts new file mode 100644 index 0000000000..4d77167823 --- /dev/null +++ b/packages/core/src/shader/ShaderTagProperty.ts @@ -0,0 +1,28 @@ +/** + * Shader tag property. + */ +export class ShaderTagProperty { + private static _nameCounter: number = 0; + private static _nameMap: Record = Object.create(null); + + /** + * Get shader property by name. + * @param name - Name of the shader property + * @returns Shader property + */ + static getByName(name: string): ShaderTagProperty { + const nameMap = ShaderTagProperty._nameMap; + return (nameMap[name] ||= new ShaderTagProperty(name)); + } + + /** Shader tag property name. */ + readonly name: string; + + /** @internal */ + _uniqueId: number; + + private constructor(name: string) { + this.name = name; + this._uniqueId = ShaderTagProperty._nameCounter++; + } +} diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index f57096ce10..1e05884bc6 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -11,6 +11,6 @@ export { ShaderData } from "./ShaderData"; export { ShaderMacro } from "./ShaderMacro"; export { ShaderPass } from "./ShaderPass"; export { ShaderProperty } from "./ShaderProperty"; -export { ShaderTag } from "./ShaderTag"; +export { ShaderTagProperty } from "./ShaderTagProperty"; export { SubShader } from "./SubShader"; From 661c02da601f2bbcb1be2224ab45bd1d0dc27ece Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 00:03:38 +0800 Subject: [PATCH 50/62] test(Shader): fix shader unit test --- tests/src/core/Shader.test.ts | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index 8373698537..b44d7794fa 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -1,10 +1,14 @@ import { - BlinnPhongMaterial, Camera, DirectLight, MeshRenderer, - PrimitiveMesh, Shader, + BlinnPhongMaterial, + Camera, + DirectLight, + MeshRenderer, + PrimitiveMesh, + Shader, ShaderMacro, ShaderPass, ShaderProperty, - ShaderTag, + ShaderTagProperty, SubShader } from "@oasis-engine/core"; import { WebGLEngine } from "@oasis-engine/rhi-webgl"; @@ -59,13 +63,13 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - subShader.setTag(ShaderTag.getByName("customTagKey"), ShaderTag.getByName("customTagValue")); - getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); + subShader.setTag(ShaderTagProperty.getByName("customTagKey"), ShaderTagProperty.getByName("customTagValue")); + getTag = subShader.getTagValue(ShaderTagProperty.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTagProperty.getByName("customTagValue")); // Delete tag - subShader.deleteTag(ShaderTag.getByName("customTagKey")); - getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); + subShader.deleteTag(ShaderTagProperty.getByName("customTagKey")); + getTag = subShader.getTagValue(ShaderTagProperty.getByName("customTagKey")); expect(getTag).to.undefined; }); @@ -84,13 +88,13 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - shaderPass.setTag(ShaderTag.getByName("customTagKey"), ShaderTag.getByName("customTagValue")); - getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); + shaderPass.setTag(ShaderTagProperty.getByName("customTagKey"), ShaderTagProperty.getByName("customTagValue")); + getTag = shaderPass.getTagValue(ShaderTagProperty.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTagProperty.getByName("customTagValue")); // Delete tag - shaderPass.deleteTag(ShaderTag.getByName("customTagKey")); - getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); + shaderPass.deleteTag(ShaderTagProperty.getByName("customTagKey")); + getTag = shaderPass.getTagValue(ShaderTagProperty.getByName("customTagKey")); expect(getTag).to.undefined; }); From a979350c073d3519598695710542dbda79b6d5cf Mon Sep 17 00:00:00 2001 From: singlecoder Date: Fri, 10 Mar 2023 11:24:09 +0800 Subject: [PATCH 51/62] Add can batch check in shader pass for 2d (#10) * feat(replace-shader): 2d add can batch check in shader pass --- packages/core/src/RenderPipeline/Basic2DBatcher.ts | 3 +++ packages/core/src/RenderPipeline/SpriteBatcher.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 9b705e9871..56376d835d 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -2,6 +2,7 @@ import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { Buffer, BufferBindFlag, BufferUsage, IndexFormat, MeshTopology, SubMesh, VertexElement } from "../graphic"; import { BufferMesh } from "../mesh"; +import { ShaderTag } from "../shader"; import { ClassPool } from "./ClassPool"; import { RenderElement } from "./RenderElement"; import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; @@ -39,6 +40,8 @@ export abstract class Basic2DBatcher { _vertexCount: number = 0; /** @internal */ _elementCount: number = 0; + /** @internal */ + _disableBatchTagKey: ShaderTag = ShaderTag.getByName("SpriteDisableBatch"); constructor(engine: Engine) { this._engine = engine; diff --git a/packages/core/src/RenderPipeline/SpriteBatcher.ts b/packages/core/src/RenderPipeline/SpriteBatcher.ts index 2a0f16ba70..bdd39b6980 100644 --- a/packages/core/src/RenderPipeline/SpriteBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteBatcher.ts @@ -24,7 +24,7 @@ export class SpriteBatcher extends Basic2DBatcher { } canBatch(preElement: RenderElement, curElement: RenderElement): boolean { - if (!this._engine._canSpriteBatch) { + if (!this._engine._canSpriteBatch || curElement.shaderPass.getTagValue(this._disableBatchTagKey)) { return false; } From bb02b8e07961ecf8f80150948bf29f509e669b0d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 11:32:49 +0800 Subject: [PATCH 52/62] refactor: opt code --- packages/core/src/RenderPipeline/Basic2DBatcher.ts | 7 ++++--- packages/core/src/RenderPipeline/SpriteBatcher.ts | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 56376d835d..a1f73375cc 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -2,7 +2,7 @@ import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { Buffer, BufferBindFlag, BufferUsage, IndexFormat, MeshTopology, SubMesh, VertexElement } from "../graphic"; import { BufferMesh } from "../mesh"; -import { ShaderTag } from "../shader"; +import { ShaderTagProperty } from "../shader"; import { ClassPool } from "./ClassPool"; import { RenderElement } from "./RenderElement"; import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; @@ -12,6 +12,9 @@ import { TextRenderData } from "./TextRenderData"; type SpriteData = SpriteRenderData | SpriteMaskRenderData; export abstract class Basic2DBatcher { + protected static _disableBatchTagKey: ShaderTagProperty = ShaderTagProperty.getByName("spriteDisableBatching"); + protected static _disableBatchTagValue: ShaderTagProperty = ShaderTagProperty.getByName("true"); + /** The maximum number of vertex. */ static MAX_VERTEX_COUNT: number = 4096; static _canUploadSameBuffer: boolean = true; @@ -40,8 +43,6 @@ export abstract class Basic2DBatcher { _vertexCount: number = 0; /** @internal */ _elementCount: number = 0; - /** @internal */ - _disableBatchTagKey: ShaderTag = ShaderTag.getByName("SpriteDisableBatch"); constructor(engine: Engine) { this._engine = engine; diff --git a/packages/core/src/RenderPipeline/SpriteBatcher.ts b/packages/core/src/RenderPipeline/SpriteBatcher.ts index bdd39b6980..eb78e38204 100644 --- a/packages/core/src/RenderPipeline/SpriteBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteBatcher.ts @@ -24,7 +24,10 @@ export class SpriteBatcher extends Basic2DBatcher { } canBatch(preElement: RenderElement, curElement: RenderElement): boolean { - if (!this._engine._canSpriteBatch || curElement.shaderPass.getTagValue(this._disableBatchTagKey)) { + if ( + !this._engine._canSpriteBatch || + curElement.shaderPass.getTagValue(Basic2DBatcher._disableBatchTagKey) === Basic2DBatcher._disableBatchTagValue + ) { return false; } From b5c176ff28ccbc77d7be5efe786b15fee5e22dc4 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 15:06:51 +0800 Subject: [PATCH 53/62] refactor: opt code --- packages/core/src/Camera.ts | 6 +-- .../core/src/RenderPipeline/Basic2DBatcher.ts | 5 +-- .../src/RenderPipeline/BasicRenderPipeline.ts | 9 ++-- .../core/src/RenderPipeline/RenderContext.ts | 8 ++-- .../core/src/RenderPipeline/SpriteBatcher.ts | 2 +- packages/core/src/mesh/MeshRenderer.ts | 1 - packages/core/src/shader/ShaderPart.ts | 43 +++++++++---------- packages/core/src/shader/ShaderTag.ts | 28 ++++++++++++ packages/core/src/shader/ShaderTagProperty.ts | 28 ------------ packages/core/src/shader/index.ts | 2 +- tests/src/core/Shader.test.ts | 24 +++++------ 11 files changed, 76 insertions(+), 80 deletions(-) create mode 100644 packages/core/src/shader/ShaderTag.ts delete mode 100644 packages/core/src/shader/ShaderTagProperty.ts diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index f66c3290f3..ea07f9c8d9 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -13,7 +13,7 @@ import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; import { ShaderProperty } from "./shader/ShaderProperty"; -import { ShaderTagProperty } from "./shader/ShaderTagProperty"; +import { ShaderTag } from "./shader/ShaderTag"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; import { Transform } from "./Transform"; @@ -71,7 +71,7 @@ export class Camera extends Component { /** @internal */ _replacementShader: Shader = null; /** @internal */ - _replacementSubShaderTagKey: ShaderTagProperty = null; + _replacementSubShaderTagKey: ShaderTag = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -485,7 +485,7 @@ export class Camera extends Component { * If replacementTagKey is not specified, the first sub shader will be replaced. * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. */ - setReplacementShader(shader: Shader, replacementTagKey?: ShaderTagProperty): void { + setReplacementShader(shader: Shader, replacementTagKey?: ShaderTag): void { this._replacementShader = shader; this._replacementSubShaderTagKey = replacementTagKey; } diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index a1f73375cc..ad136ca70e 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -2,7 +2,7 @@ import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { Buffer, BufferBindFlag, BufferUsage, IndexFormat, MeshTopology, SubMesh, VertexElement } from "../graphic"; import { BufferMesh } from "../mesh"; -import { ShaderTagProperty } from "../shader"; +import { ShaderTag } from "../shader/ShaderTag"; import { ClassPool } from "./ClassPool"; import { RenderElement } from "./RenderElement"; import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; @@ -12,8 +12,7 @@ import { TextRenderData } from "./TextRenderData"; type SpriteData = SpriteRenderData | SpriteMaskRenderData; export abstract class Basic2DBatcher { - protected static _disableBatchTagKey: ShaderTagProperty = ShaderTagProperty.getByName("spriteDisableBatching"); - protected static _disableBatchTagValue: ShaderTagProperty = ShaderTagProperty.getByName("true"); + protected static _disableBatchTag: ShaderTag = ShaderTag.getByName("spriteDisableBatching"); /** The maximum number of vertex. */ static MAX_VERTEX_COUNT: number = 4096; diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 6396d90e7b..2d0c0c5132 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -12,7 +12,6 @@ import { Material } from "../material"; import { RenderQueueType } from "../shader/enums/RenderQueueType"; import { Shader } from "../shader/Shader"; import { ShaderPass } from "../shader/ShaderPass"; -import { ShaderTagProperty } from "../shader/ShaderTagProperty"; import { RenderState } from "../shader/state/RenderState"; import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass"; import { ShadowType } from "../shadow/enum/ShadowType"; @@ -27,8 +26,8 @@ import { RenderQueue } from "./RenderQueue"; * Basic render pipeline. */ export class BasicRenderPipeline { - private static _shadowCasterPipelineStageTag = ShaderTagProperty.getByName(PipelineStage.ShadowCaster); - private static _forwardPipelineStageTag = ShaderTagProperty.getByName(PipelineStage.Forward); + private static _shadowCasterPipelineStageTagValue = PipelineStage.ShadowCaster; + private static _forwardPipelineStageValue = PipelineStage.Forward; /** @internal */ _opaqueQueue: RenderQueue; @@ -151,7 +150,7 @@ export class BasicRenderPipeline { camera.engine._spriteMaskManager.clear(); - context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStageTag; + context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStageTagValue; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -162,7 +161,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); - context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStageTag; + context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStageValue; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index a43f7dfd89..4fee0f4afc 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,6 +1,6 @@ import { Camera } from "../Camera"; import { Shader, ShaderProperty } from "../shader"; -import { ShaderTagProperty } from "../shader/ShaderTagProperty"; +import { ShaderTag } from "../shader/ShaderTag"; import { VirtualCamera } from "../VirtualCamera"; /** @@ -9,7 +9,7 @@ import { VirtualCamera } from "../VirtualCamera"; */ export class RenderContext { static vpMatrixProperty = ShaderProperty.getByName("u_VPMat"); - static pipelineStageKey: ShaderTagProperty = ShaderTagProperty.getByName("pipelineStage"); + static pipelineStageKey: ShaderTag = ShaderTag.getByName("pipelineStage"); private static _viewMatrixProperty = ShaderProperty.getByName("u_viewMat"); private static _projectionMatrixProperty = ShaderProperty.getByName("u_projMat"); @@ -18,8 +18,8 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTagKey: ShaderTagProperty; - pipelineStageValue: ShaderTagProperty; + replacementTagKey: ShaderTag; + pipelineStageValue: string; applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; diff --git a/packages/core/src/RenderPipeline/SpriteBatcher.ts b/packages/core/src/RenderPipeline/SpriteBatcher.ts index eb78e38204..d16fcd37d0 100644 --- a/packages/core/src/RenderPipeline/SpriteBatcher.ts +++ b/packages/core/src/RenderPipeline/SpriteBatcher.ts @@ -26,7 +26,7 @@ export class SpriteBatcher extends Basic2DBatcher { canBatch(preElement: RenderElement, curElement: RenderElement): boolean { if ( !this._engine._canSpriteBatch || - curElement.shaderPass.getTagValue(Basic2DBatcher._disableBatchTagKey) === Basic2DBatcher._disableBatchTagValue + curElement.shaderPass.getTagValue(Basic2DBatcher._disableBatchTag) === true ) { return false; } diff --git a/packages/core/src/mesh/MeshRenderer.ts b/packages/core/src/mesh/MeshRenderer.ts index 47e087c33b..c92c655c82 100644 --- a/packages/core/src/mesh/MeshRenderer.ts +++ b/packages/core/src/mesh/MeshRenderer.ts @@ -6,7 +6,6 @@ import { Entity } from "../Entity"; import { Mesh, MeshModifyFlags } from "../graphic/Mesh"; import { Renderer, RendererUpdateFlags } from "../Renderer"; import { RenderContext } from "../RenderPipeline/RenderContext"; -import { Shader } from "../shader/Shader"; import { ShaderMacro } from "../shader/ShaderMacro"; /** diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 7d706ad1fb..753396911b 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -1,28 +1,27 @@ -import { ShaderTagProperty } from "./ShaderTagProperty"; +import { ShaderTag } from "./ShaderTag"; /** * Base class for shader structure. */ export abstract class ShaderPart { - private _tagsMap: Record = Object.create(null); + private _tagsMap: Record = Object.create(null); /** - * Set tag by name. - * @param keyName - Name of the tag key - * @param valueName - Name of the tag value + * Set tag by key name. + * @param keyName - Key name of the tag + * @param value - Tag value */ - setTag(keyName: string, valueName: string): void; - + setTag(keyName: string, value: number | string | boolean): void; + /** * Set tag. * @param key - Key of the tag - * @param value - Value of the tag + * @param value - Tag value */ - setTag(key: ShaderTagProperty, value: ShaderTagProperty): void; + setTag(key: ShaderTag, value: number | string | boolean): void; - setTag(keyOrKeyName: ShaderTagProperty | string, valueOrValueName: ShaderTagProperty | string): void { - const key = typeof keyOrKeyName === "string" ? ShaderTagProperty.getByName(keyOrKeyName) : keyOrKeyName; - const value = typeof valueOrValueName === "string" ? ShaderTagProperty.getByName(valueOrValueName) : valueOrValueName; + setTag(keyOrKeyName: ShaderTag | string, value: number | string | boolean): void { + const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; const tags = this._tagsMap; if (tags[key._uniqueId]) { @@ -41,31 +40,31 @@ export abstract class ShaderPart { * Delete a tag by key. * @param key - Key of the tag */ - deleteTag(key: ShaderTagProperty): void; + deleteTag(key: ShaderTag): void; - deleteTag(keyOrKeyName: ShaderTagProperty | string): void { + deleteTag(keyOrKeyName: ShaderTag | string): void { delete this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTagProperty.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId ]; } /** - * Get tag value by key name. + * Get tag by key name. * @param keyName - Key name of the tag - * @returns Value of the tag + * @returns Tag value */ - getTagValue(keyName: string): ShaderTagProperty; + getTagValue(keyName: string): number | string | boolean; /** * Get tag value by key. * @param key - Key of the tag - * @returns Value of the tag + * @returns Tag value */ - getTagValue(key: ShaderTagProperty): ShaderTagProperty; + getTagValue(key: ShaderTag): number | string | boolean; - getTagValue(keyOrKeyName: ShaderTagProperty | string): ShaderTagProperty { + getTagValue(keyOrKeyName: ShaderTag | string): number | string | boolean { return this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTagProperty.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId ]; } } diff --git a/packages/core/src/shader/ShaderTag.ts b/packages/core/src/shader/ShaderTag.ts new file mode 100644 index 0000000000..88f5b04972 --- /dev/null +++ b/packages/core/src/shader/ShaderTag.ts @@ -0,0 +1,28 @@ +/** + * Shader tag. + */ +export class ShaderTag { + private static _nameCounter: number = 0; + private static _nameMap: Record = Object.create(null); + + /** + * Get shader property by name. + * @param name - Name of the shader property + * @returns Shader property + */ + static getByName(name: string): ShaderTag { + const nameMap = ShaderTag._nameMap; + return (nameMap[name] ||= new ShaderTag(name)); + } + + /** Shader tag property name. */ + readonly name: string; + + /** @internal */ + _uniqueId: number; + + private constructor(name: string) { + this.name = name; + this._uniqueId = ShaderTag._nameCounter++; + } +} diff --git a/packages/core/src/shader/ShaderTagProperty.ts b/packages/core/src/shader/ShaderTagProperty.ts deleted file mode 100644 index 4d77167823..0000000000 --- a/packages/core/src/shader/ShaderTagProperty.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Shader tag property. - */ -export class ShaderTagProperty { - private static _nameCounter: number = 0; - private static _nameMap: Record = Object.create(null); - - /** - * Get shader property by name. - * @param name - Name of the shader property - * @returns Shader property - */ - static getByName(name: string): ShaderTagProperty { - const nameMap = ShaderTagProperty._nameMap; - return (nameMap[name] ||= new ShaderTagProperty(name)); - } - - /** Shader tag property name. */ - readonly name: string; - - /** @internal */ - _uniqueId: number; - - private constructor(name: string) { - this.name = name; - this._uniqueId = ShaderTagProperty._nameCounter++; - } -} diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index 1e05884bc6..f57096ce10 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -11,6 +11,6 @@ export { ShaderData } from "./ShaderData"; export { ShaderMacro } from "./ShaderMacro"; export { ShaderPass } from "./ShaderPass"; export { ShaderProperty } from "./ShaderProperty"; -export { ShaderTagProperty } from "./ShaderTagProperty"; +export { ShaderTag } from "./ShaderTag"; export { SubShader } from "./SubShader"; diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index b44d7794fa..b303d8f5a8 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -8,7 +8,7 @@ import { ShaderMacro, ShaderPass, ShaderProperty, - ShaderTagProperty, + ShaderTag, SubShader } from "@oasis-engine/core"; import { WebGLEngine } from "@oasis-engine/rhi-webgl"; @@ -63,13 +63,13 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - subShader.setTag(ShaderTagProperty.getByName("customTagKey"), ShaderTagProperty.getByName("customTagValue")); - getTag = subShader.getTagValue(ShaderTagProperty.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTagProperty.getByName("customTagValue")); + subShader.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); + getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); // Delete tag - subShader.deleteTag(ShaderTagProperty.getByName("customTagKey")); - getTag = subShader.getTagValue(ShaderTagProperty.getByName("customTagKey")); + subShader.deleteTag(ShaderTag.getByName("customTagKey")); + getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.undefined; }); @@ -80,7 +80,7 @@ describe("Shader", () => { // Add tag by name shaderPass.setTag("customTagKey", "customTagValue"); let getTag = shaderPass.getTagValue("customTagKey"); - expect(getTag.name).to.equal("customTagValue"); + expect(getTag).to.equal("customTagValue"); // Delete tag by name shaderPass.deleteTag("customTagKey"); @@ -88,13 +88,13 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - shaderPass.setTag(ShaderTagProperty.getByName("customTagKey"), ShaderTagProperty.getByName("customTagValue")); - getTag = shaderPass.getTagValue(ShaderTagProperty.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTagProperty.getByName("customTagValue")); + shaderPass.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); + getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); // Delete tag - shaderPass.deleteTag(ShaderTagProperty.getByName("customTagKey")); - getTag = shaderPass.getTagValue(ShaderTagProperty.getByName("customTagKey")); + shaderPass.deleteTag(ShaderTag.getByName("customTagKey")); + getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.undefined; }); From 569942f0993cbeb53905db39c1582b23d3a9702d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 15:23:06 +0800 Subject: [PATCH 54/62] refactor: opt code --- packages/core/src/Camera.ts | 8 ++-- .../src/RenderPipeline/BasicRenderPipeline.ts | 10 ++--- .../core/src/RenderPipeline/RenderContext.ts | 4 +- packages/core/src/shader/ShaderPart.ts | 44 ++++++++++--------- packages/core/src/shader/ShaderPass.ts | 2 +- packages/core/src/shader/SubShader.ts | 2 +- 6 files changed, 36 insertions(+), 34 deletions(-) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index ea07f9c8d9..f59bac9251 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -71,7 +71,7 @@ export class Camera extends Component { /** @internal */ _replacementShader: Shader = null; /** @internal */ - _replacementSubShaderTagKey: ShaderTag = null; + _replacementSubShaderTag: ShaderTag = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -450,7 +450,7 @@ export class Camera extends Component { context.camera = this; context.virtualCamera = virtualCamera; context.replacementShader = this._replacementShader; - context.replacementTagKey = this._replacementSubShaderTagKey; + context.replacementTag = this._replacementSubShaderTag; // compute cull frustum. if (this.enableFrustumCulling && (this._frustumViewChangeFlag.flag || this._isFrustumProjectDirty)) { @@ -487,7 +487,7 @@ export class Camera extends Component { */ setReplacementShader(shader: Shader, replacementTagKey?: ShaderTag): void { this._replacementShader = shader; - this._replacementSubShaderTagKey = replacementTagKey; + this._replacementSubShaderTag = replacementTagKey; } /** @@ -495,7 +495,7 @@ export class Camera extends Component { */ resetReplacementShader(): void { this._replacementShader = null; - this._replacementSubShaderTagKey = null; + this._replacementSubShaderTag = null; } /** diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 2d0c0c5132..c81fc45a21 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -27,7 +27,7 @@ import { RenderQueue } from "./RenderQueue"; */ export class BasicRenderPipeline { private static _shadowCasterPipelineStageTagValue = PipelineStage.ShadowCaster; - private static _forwardPipelineStageValue = PipelineStage.Forward; + private static _forwardPipelineStageTagValue = PipelineStage.Forward; /** @internal */ _opaqueQueue: RenderQueue; @@ -150,7 +150,7 @@ export class BasicRenderPipeline { camera.engine._spriteMaskManager.clear(); - context.pipelineStageValue = BasicRenderPipeline._shadowCasterPipelineStageTagValue; + context.pipelineStageTagValue = BasicRenderPipeline._shadowCasterPipelineStageTagValue; if (scene.castShadows && scene._sunLight?.shadowType !== ShadowType.None) { this._cascadedShadowCaster._render(context); } @@ -161,7 +161,7 @@ export class BasicRenderPipeline { context.applyVirtualCamera(camera._virtualCamera); - context.pipelineStageValue = BasicRenderPipeline._forwardPipelineStageValue; + context.pipelineStageTagValue = BasicRenderPipeline._forwardPipelineStageTagValue; this._callRender(context); opaqueQueue.sort(RenderQueue._compareFromNearToFar); alphaTestQueue.sort(RenderQueue._compareFromNearToFar); @@ -229,7 +229,7 @@ export class BasicRenderPipeline { if (replacementShader) { const replacementSubShaders = replacementShader.subShaders; - const { replacementTagKey } = context; + const { replacementTag: replacementTagKey } = context; if (replacementTagKey) { for (let i = 0, n = replacementSubShaders.length; i < n; i++) { const subShader = replacementSubShaders[i]; @@ -252,7 +252,7 @@ export class BasicRenderPipeline { shaderPasses: ReadonlyArray, renderStates: ReadonlyArray ) { - const pipelineStage = context.pipelineStageValue; + const pipelineStage = context.pipelineStageTagValue; const renderElementPool = context.camera.engine._renderElementPool; for (let i = 0, n = shaderPasses.length; i < n; i++) { const shaderPass = shaderPasses[i]; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index 4fee0f4afc..cabc943328 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -18,8 +18,8 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTagKey: ShaderTag; - pipelineStageValue: string; + replacementTag: ShaderTag; + pipelineStageTagValue: string; applyVirtualCamera(virtualCamera: VirtualCamera): void { this.virtualCamera = virtualCamera; diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 753396911b..1ed0c250da 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -11,16 +11,16 @@ export abstract class ShaderPart { * @param keyName - Key name of the tag * @param value - Tag value */ - setTag(keyName: string, value: number | string | boolean): void; + setTagValue(keyName: string, value: T): void; /** * Set tag. * @param key - Key of the tag * @param value - Tag value */ - setTag(key: ShaderTag, value: number | string | boolean): void; + setTagValue(key: ShaderTag, value: T): void; - setTag(keyOrKeyName: ShaderTag | string, value: number | string | boolean): void { + setTagValue(keyOrKeyName: ShaderTag | string, value: T): void { const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; const tags = this._tagsMap; @@ -31,39 +31,41 @@ export abstract class ShaderPart { } /** - * Delete a tag by key name. - * @param KeyName - Key name of the tag + * Get tag by key name. + * @param keyName - Key name of the tag + * @returns Tag value */ - deleteTag(KeyName: string): void; + getTagValue(keyName: string): T; /** - * Delete a tag by key. + * Get tag value by key. * @param key - Key of the tag + * @returns Tag value */ - deleteTag(key: ShaderTag): void; + getTagValue(key: ShaderTag): T; - deleteTag(keyOrKeyName: ShaderTag | string): void { - delete this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId - ]; + getTagValue(keyOrKeyName: ShaderTag | string): T { + return ( + this._tagsMap[ + typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + ] + ); } /** - * Get tag by key name. - * @param keyName - Key name of the tag - * @returns Tag value + * Delete a tag by key name. + * @param KeyName - Key name of the tag */ - getTagValue(keyName: string): number | string | boolean; + deleteTag(KeyName: string): void; /** - * Get tag value by key. + * Delete a tag by key. * @param key - Key of the tag - * @returns Tag value */ - getTagValue(key: ShaderTag): number | string | boolean; + deleteTag(key: ShaderTag): void; - getTagValue(keyOrKeyName: ShaderTag | string): number | string | boolean { - return this._tagsMap[ + deleteTag(keyOrKeyName: ShaderTag | string): void { + delete this._tagsMap[ typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId ]; } diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index 568ff6c3e0..e28818da03 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -38,7 +38,7 @@ export class ShaderPass extends ShaderPart { this._fragmentSource = fragmentSource; for (const key in tags) { - this.setTag(key, tags[key]); + this.setTagValue(key, tags[key]); } } diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 38f401c7cc..41073e22d7 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -28,7 +28,7 @@ export class SubShader extends ShaderPart { this._passes = passes.slice(); for (const key in tags) { - this.setTag(key, tags[key]); + this.setTagValue(key, tags[key]); } } } From 9aa10735bb9b2a95a41929cde91efb70fc18dfa6 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 15:27:57 +0800 Subject: [PATCH 55/62] refactor: opt code --- packages/core/src/Camera.ts | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index f59bac9251..a8e141a04b 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -479,15 +479,29 @@ export class Camera extends Component { /** * Set the replacement shader. * @param shader - Replacement shader - * @param replacementTagKey - Sub shader tag key + * @param replacementTagName - Sub shader tag name * * @remarks - * If replacementTagKey is not specified, the first sub shader will be replaced. - * If replacementTagKey is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. + * If replacementTagName is not specified, the first sub shader will be replaced. + * If replacementTagName is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. */ - setReplacementShader(shader: Shader, replacementTagKey?: ShaderTag): void { + setReplacementShader(shader: Shader, replacementTagName?: string); + + /** + * Set the replacement shader. + * @param shader - Replacement shader + * @param replacementTag - Sub shader tag + * + * @remarks + * If replacementTag is not specified, the first sub shader will be replaced. + * If replacementTag is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. + */ + setReplacementShader(shader: Shader, replacementTag?: ShaderTag); + + setReplacementShader(shader: Shader, replacementTag?: string | ShaderTag): void { this._replacementShader = shader; - this._replacementSubShaderTag = replacementTagKey; + this._replacementSubShaderTag = + typeof replacementTag === "string" ? ShaderTag.getByName(replacementTag) : replacementTag; } /** From b36f1967af88aeca80708450455e4cf27d41952d Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 15:43:01 +0800 Subject: [PATCH 56/62] refactor: opt code --- packages/core/src/shader/ShaderPart.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 1ed0c250da..ae8c1a5c0c 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -45,11 +45,9 @@ export abstract class ShaderPart { getTagValue(key: ShaderTag): T; getTagValue(keyOrKeyName: ShaderTag | string): T { - return ( - this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId - ] - ); + return this._tagsMap[ + typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + ] as T; } /** From 05262563be26ac3d715d5da590c741940cc994fb Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 15:46:10 +0800 Subject: [PATCH 57/62] refactor: opt code --- packages/core/src/shader/ShaderPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index ae8c1a5c0c..19d46d8d62 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -64,7 +64,7 @@ export abstract class ShaderPart { deleteTag(keyOrKeyName: ShaderTag | string): void { delete this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + (typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName)._uniqueId ]; } } From 35e22d3f32ddb9f013098a122ce28df258293ec0 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Fri, 10 Mar 2023 17:19:34 +0800 Subject: [PATCH 58/62] refactor: opt code --- tests/src/core/Shader.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index b303d8f5a8..1accfda650 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -53,9 +53,9 @@ describe("Shader", () => { const subShader = customShader.subShaders[0]; // Add tag by name - subShader.setTag("customTagKey", "customTagValue"); + subShader.setTagValue("customTagKey", "customTagValue"); let getTag = subShader.getTagValue("customTagKey"); - expect(getTag.name).to.equal("customTagValue"); + expect(getTag).to.equal("customTagValue"); // Delete tag by name subShader.deleteTag("customTagKey"); @@ -63,7 +63,7 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - subShader.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); + subShader.setTagValue(ShaderTag.getByName("customTagKey"), "customTagValue"); getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); @@ -78,7 +78,7 @@ describe("Shader", () => { const shaderPass = customShader.subShaders[0].passes[0]; // Add tag by name - shaderPass.setTag("customTagKey", "customTagValue"); + shaderPass.setTagValue("customTagKey", "customTagValue"); let getTag = shaderPass.getTagValue("customTagKey"); expect(getTag).to.equal("customTagValue"); @@ -88,7 +88,7 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - shaderPass.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); + shaderPass.setTagValue(ShaderTag.getByName("customTagKey"), "customTagValue"); getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); From cb4c9afc0289b5df6d7f07c52f05c6bcf969e838 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sat, 11 Mar 2023 14:41:54 +0800 Subject: [PATCH 59/62] refactor: opt code --- packages/core/src/Camera.ts | 10 ++-- .../core/src/RenderPipeline/Basic2DBatcher.ts | 4 +- .../core/src/RenderPipeline/RenderContext.ts | 6 +-- packages/core/src/shader/ShaderPart.ts | 50 +++++++++---------- packages/core/src/shader/ShaderPass.ts | 2 +- .../shader/{ShaderTag.ts => ShaderTagKey.ts} | 14 +++--- packages/core/src/shader/SubShader.ts | 2 +- packages/core/src/shader/index.ts | 2 +- tests/src/core/Shader.test.ts | 8 +-- 9 files changed, 49 insertions(+), 49 deletions(-) rename packages/core/src/shader/{ShaderTag.ts => ShaderTagKey.ts} (51%) diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index a8e141a04b..7de3a5a13b 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -13,7 +13,7 @@ import { Shader } from "./shader/Shader"; import { ShaderData } from "./shader/ShaderData"; import { ShaderMacroCollection } from "./shader/ShaderMacroCollection"; import { ShaderProperty } from "./shader/ShaderProperty"; -import { ShaderTag } from "./shader/ShaderTag"; +import { ShaderTagKey } from "./shader/ShaderTagKey"; import { TextureCubeFace } from "./texture/enums/TextureCubeFace"; import { RenderTarget } from "./texture/RenderTarget"; import { Transform } from "./Transform"; @@ -71,7 +71,7 @@ export class Camera extends Component { /** @internal */ _replacementShader: Shader = null; /** @internal */ - _replacementSubShaderTag: ShaderTag = null; + _replacementSubShaderTag: ShaderTagKey = null; private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; @@ -496,12 +496,12 @@ export class Camera extends Component { * If replacementTag is not specified, the first sub shader will be replaced. * If replacementTag is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. */ - setReplacementShader(shader: Shader, replacementTag?: ShaderTag); + setReplacementShader(shader: Shader, replacementTag?: ShaderTagKey); - setReplacementShader(shader: Shader, replacementTag?: string | ShaderTag): void { + setReplacementShader(shader: Shader, replacementTag?: string | ShaderTagKey): void { this._replacementShader = shader; this._replacementSubShaderTag = - typeof replacementTag === "string" ? ShaderTag.getByName(replacementTag) : replacementTag; + typeof replacementTag === "string" ? ShaderTagKey.getByName(replacementTag) : replacementTag; } /** diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index ad136ca70e..1d8885162c 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -2,7 +2,7 @@ import { Camera } from "../Camera"; import { Engine } from "../Engine"; import { Buffer, BufferBindFlag, BufferUsage, IndexFormat, MeshTopology, SubMesh, VertexElement } from "../graphic"; import { BufferMesh } from "../mesh"; -import { ShaderTag } from "../shader/ShaderTag"; +import { ShaderTagKey } from "../shader/ShaderTagKey"; import { ClassPool } from "./ClassPool"; import { RenderElement } from "./RenderElement"; import { SpriteMaskRenderData } from "./SpriteMaskRenderData"; @@ -12,7 +12,7 @@ import { TextRenderData } from "./TextRenderData"; type SpriteData = SpriteRenderData | SpriteMaskRenderData; export abstract class Basic2DBatcher { - protected static _disableBatchTag: ShaderTag = ShaderTag.getByName("spriteDisableBatching"); + protected static _disableBatchTag: ShaderTagKey = ShaderTagKey.getByName("spriteDisableBatching"); /** The maximum number of vertex. */ static MAX_VERTEX_COUNT: number = 4096; diff --git a/packages/core/src/RenderPipeline/RenderContext.ts b/packages/core/src/RenderPipeline/RenderContext.ts index cabc943328..d4220147d9 100644 --- a/packages/core/src/RenderPipeline/RenderContext.ts +++ b/packages/core/src/RenderPipeline/RenderContext.ts @@ -1,6 +1,6 @@ import { Camera } from "../Camera"; import { Shader, ShaderProperty } from "../shader"; -import { ShaderTag } from "../shader/ShaderTag"; +import { ShaderTagKey } from "../shader/ShaderTagKey"; import { VirtualCamera } from "../VirtualCamera"; /** @@ -9,7 +9,7 @@ import { VirtualCamera } from "../VirtualCamera"; */ export class RenderContext { static vpMatrixProperty = ShaderProperty.getByName("u_VPMat"); - static pipelineStageKey: ShaderTag = ShaderTag.getByName("pipelineStage"); + static pipelineStageKey: ShaderTagKey = ShaderTagKey.getByName("pipelineStage"); private static _viewMatrixProperty = ShaderProperty.getByName("u_viewMat"); private static _projectionMatrixProperty = ShaderProperty.getByName("u_projMat"); @@ -18,7 +18,7 @@ export class RenderContext { virtualCamera: VirtualCamera; replacementShader: Shader; - replacementTag: ShaderTag; + replacementTag: ShaderTagKey; pipelineStageTagValue: string; applyVirtualCamera(virtualCamera: VirtualCamera): void { diff --git a/packages/core/src/shader/ShaderPart.ts b/packages/core/src/shader/ShaderPart.ts index 19d46d8d62..9cb62f357c 100644 --- a/packages/core/src/shader/ShaderPart.ts +++ b/packages/core/src/shader/ShaderPart.ts @@ -1,4 +1,4 @@ -import { ShaderTag } from "./ShaderTag"; +import { ShaderTagKey } from "./ShaderTagKey"; /** * Base class for shader structure. @@ -11,17 +11,17 @@ export abstract class ShaderPart { * @param keyName - Key name of the tag * @param value - Tag value */ - setTagValue(keyName: string, value: T): void; + setTag(keyName: string, value: T): void; /** * Set tag. * @param key - Key of the tag * @param value - Tag value */ - setTagValue(key: ShaderTag, value: T): void; + setTag(key: ShaderTagKey, value: T): void; - setTagValue(keyOrKeyName: ShaderTag | string, value: T): void { - const key = typeof keyOrKeyName === "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName; + setTag(keyOrKeyName: ShaderTagKey | string, value: T): void { + const key = typeof keyOrKeyName === "string" ? ShaderTagKey.getByName(keyOrKeyName) : keyOrKeyName; const tags = this._tagsMap; if (tags[key._uniqueId]) { @@ -31,40 +31,40 @@ export abstract class ShaderPart { } /** - * Get tag by key name. - * @param keyName - Key name of the tag - * @returns Tag value + * Delete a tag by key name. + * @param KeyName - Key name of the tag */ - getTagValue(keyName: string): T; + deleteTag(KeyName: string): void; /** - * Get tag value by key. + * Delete a tag by key. * @param key - Key of the tag - * @returns Tag value */ - getTagValue(key: ShaderTag): T; + deleteTag(key: ShaderTagKey): void; - getTagValue(keyOrKeyName: ShaderTag | string): T { - return this._tagsMap[ - typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId - ] as T; + deleteTag(keyOrKeyName: ShaderTagKey | string): void { + delete this._tagsMap[ + (typeof keyOrKeyName == "string" ? ShaderTagKey.getByName(keyOrKeyName) : keyOrKeyName)._uniqueId + ]; } /** - * Delete a tag by key name. - * @param KeyName - Key name of the tag + * Get tag by key name. + * @param keyName - Key name of the tag + * @returns Tag value */ - deleteTag(KeyName: string): void; + getTagValue(keyName: string): T; /** - * Delete a tag by key. + * Get tag value by key. * @param key - Key of the tag + * @returns Tag value */ - deleteTag(key: ShaderTag): void; + getTagValue(key: ShaderTagKey): T; - deleteTag(keyOrKeyName: ShaderTag | string): void { - delete this._tagsMap[ - (typeof keyOrKeyName == "string" ? ShaderTag.getByName(keyOrKeyName) : keyOrKeyName)._uniqueId - ]; + getTagValue(keyOrKeyName: ShaderTagKey | string): T { + return this._tagsMap[ + typeof keyOrKeyName == "string" ? ShaderTagKey.getByName(keyOrKeyName)._uniqueId : keyOrKeyName._uniqueId + ] as T; } } diff --git a/packages/core/src/shader/ShaderPass.ts b/packages/core/src/shader/ShaderPass.ts index e28818da03..568ff6c3e0 100644 --- a/packages/core/src/shader/ShaderPass.ts +++ b/packages/core/src/shader/ShaderPass.ts @@ -38,7 +38,7 @@ export class ShaderPass extends ShaderPart { this._fragmentSource = fragmentSource; for (const key in tags) { - this.setTagValue(key, tags[key]); + this.setTag(key, tags[key]); } } diff --git a/packages/core/src/shader/ShaderTag.ts b/packages/core/src/shader/ShaderTagKey.ts similarity index 51% rename from packages/core/src/shader/ShaderTag.ts rename to packages/core/src/shader/ShaderTagKey.ts index 88f5b04972..938a87a50a 100644 --- a/packages/core/src/shader/ShaderTag.ts +++ b/packages/core/src/shader/ShaderTagKey.ts @@ -1,18 +1,18 @@ /** - * Shader tag. + * Shader tag key. */ -export class ShaderTag { +export class ShaderTagKey { private static _nameCounter: number = 0; - private static _nameMap: Record = Object.create(null); + private static _nameMap: Record = Object.create(null); /** * Get shader property by name. * @param name - Name of the shader property * @returns Shader property */ - static getByName(name: string): ShaderTag { - const nameMap = ShaderTag._nameMap; - return (nameMap[name] ||= new ShaderTag(name)); + static getByName(name: string): ShaderTagKey { + const nameMap = ShaderTagKey._nameMap; + return (nameMap[name] ||= new ShaderTagKey(name)); } /** Shader tag property name. */ @@ -23,6 +23,6 @@ export class ShaderTag { private constructor(name: string) { this.name = name; - this._uniqueId = ShaderTag._nameCounter++; + this._uniqueId = ShaderTagKey._nameCounter++; } } diff --git a/packages/core/src/shader/SubShader.ts b/packages/core/src/shader/SubShader.ts index 41073e22d7..38f401c7cc 100644 --- a/packages/core/src/shader/SubShader.ts +++ b/packages/core/src/shader/SubShader.ts @@ -28,7 +28,7 @@ export class SubShader extends ShaderPart { this._passes = passes.slice(); for (const key in tags) { - this.setTagValue(key, tags[key]); + this.setTag(key, tags[key]); } } } diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index f57096ce10..f82422601a 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -11,6 +11,6 @@ export { ShaderData } from "./ShaderData"; export { ShaderMacro } from "./ShaderMacro"; export { ShaderPass } from "./ShaderPass"; export { ShaderProperty } from "./ShaderProperty"; -export { ShaderTag } from "./ShaderTag"; +export { ShaderTagKey } from "./ShaderTagKey"; export { SubShader } from "./SubShader"; diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index 1accfda650..dedb3a447a 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -53,7 +53,7 @@ describe("Shader", () => { const subShader = customShader.subShaders[0]; // Add tag by name - subShader.setTagValue("customTagKey", "customTagValue"); + subShader.setTag("customTagKey", "customTagValue"); let getTag = subShader.getTagValue("customTagKey"); expect(getTag).to.equal("customTagValue"); @@ -63,7 +63,7 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - subShader.setTagValue(ShaderTag.getByName("customTagKey"), "customTagValue"); + subShader.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); @@ -78,7 +78,7 @@ describe("Shader", () => { const shaderPass = customShader.subShaders[0].passes[0]; // Add tag by name - shaderPass.setTagValue("customTagKey", "customTagValue"); + shaderPass.setTag("customTagKey", "customTagValue"); let getTag = shaderPass.getTagValue("customTagKey"); expect(getTag).to.equal("customTagValue"); @@ -88,7 +88,7 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - shaderPass.setTagValue(ShaderTag.getByName("customTagKey"), "customTagValue"); + shaderPass.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); From 3b48e809b6dc0947043b127c4b90ba971ce7a654 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sat, 11 Mar 2023 14:43:30 +0800 Subject: [PATCH 60/62] refactor: opt code --- tests/src/core/Shader.test.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index dedb3a447a..e35e726aa6 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -8,7 +8,7 @@ import { ShaderMacro, ShaderPass, ShaderProperty, - ShaderTag, + ShaderTagKey, SubShader } from "@oasis-engine/core"; import { WebGLEngine } from "@oasis-engine/rhi-webgl"; @@ -63,13 +63,13 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - subShader.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); - getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); + subShader.setTag(ShaderTagKey.getByName("customTagKey"), "customTagValue"); + getTag = subShader.getTagValue(ShaderTagKey.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTagKey.getByName("customTagValue")); // Delete tag - subShader.deleteTag(ShaderTag.getByName("customTagKey")); - getTag = subShader.getTagValue(ShaderTag.getByName("customTagKey")); + subShader.deleteTag(ShaderTagKey.getByName("customTagKey")); + getTag = subShader.getTagValue(ShaderTagKey.getByName("customTagKey")); expect(getTag).to.undefined; }); @@ -88,13 +88,13 @@ describe("Shader", () => { expect(getTag).to.undefined; // Add tag - shaderPass.setTag(ShaderTag.getByName("customTagKey"), "customTagValue"); - getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTag.getByName("customTagValue")); + shaderPass.setTag(ShaderTagKey.getByName("customTagKey"), "customTagValue"); + getTag = shaderPass.getTagValue(ShaderTagKey.getByName("customTagKey")); + expect(getTag).to.equal(ShaderTagKey.getByName("customTagValue")); // Delete tag - shaderPass.deleteTag(ShaderTag.getByName("customTagKey")); - getTag = shaderPass.getTagValue(ShaderTag.getByName("customTagKey")); + shaderPass.deleteTag(ShaderTagKey.getByName("customTagKey")); + getTag = shaderPass.getTagValue(ShaderTagKey.getByName("customTagKey")); expect(getTag).to.undefined; }); From 9b83f1e96a3d0abef0d74f91aaa710c2927eb713 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sat, 11 Mar 2023 14:45:55 +0800 Subject: [PATCH 61/62] refactor: opt code --- tests/src/core/Shader.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/core/Shader.test.ts b/tests/src/core/Shader.test.ts index e35e726aa6..c41c20d66c 100644 --- a/tests/src/core/Shader.test.ts +++ b/tests/src/core/Shader.test.ts @@ -65,7 +65,7 @@ describe("Shader", () => { // Add tag subShader.setTag(ShaderTagKey.getByName("customTagKey"), "customTagValue"); getTag = subShader.getTagValue(ShaderTagKey.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTagKey.getByName("customTagValue")); + expect(getTag).to.equal("customTagValue"); // Delete tag subShader.deleteTag(ShaderTagKey.getByName("customTagKey")); @@ -90,7 +90,7 @@ describe("Shader", () => { // Add tag shaderPass.setTag(ShaderTagKey.getByName("customTagKey"), "customTagValue"); getTag = shaderPass.getTagValue(ShaderTagKey.getByName("customTagKey")); - expect(getTag).to.equal(ShaderTagKey.getByName("customTagValue")); + expect(getTag).to.equal("customTagValue"); // Delete tag shaderPass.deleteTag(ShaderTagKey.getByName("customTagKey")); From 16809bc435dd4356f328b952f4692d6cc5eb8c19 Mon Sep 17 00:00:00 2001 From: singlecoder Date: Mon, 13 Mar 2023 15:10:56 +0800 Subject: [PATCH 62/62] Refactor model matrix for 2d (#11) * refactor(2d): refactor model matrix for 2d --- packages/core/src/2d/sprite/SpriteRenderer.ts | 10 +++++++++- packages/core/src/2d/text/TextRenderer.ts | 10 +++++++++- packages/core/src/shaderlib/extra/sprite.vs.glsl | 8 -------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/core/src/2d/sprite/SpriteRenderer.ts b/packages/core/src/2d/sprite/SpriteRenderer.ts index 24afdbefa8..16f60dcd0a 100644 --- a/packages/core/src/2d/sprite/SpriteRenderer.ts +++ b/packages/core/src/2d/sprite/SpriteRenderer.ts @@ -1,4 +1,4 @@ -import { BoundingBox, Color } from "@oasis-engine/math"; +import { BoundingBox, Color, Matrix } from "@oasis-engine/math"; import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManager"; import { ICustomClone } from "../../clone/ComponentCloner"; import { Entity } from "../../Entity"; @@ -230,6 +230,14 @@ export class SpriteRenderer extends Renderer implements ICustomClone { super._onDestroy(); } + /** + * @override + */ + protected _updateShaderData(context: RenderContext): void { + // @ts-ignore + this._updateTransformShaderData(context, Matrix._identity); + } + /** * @override */ diff --git a/packages/core/src/2d/text/TextRenderer.ts b/packages/core/src/2d/text/TextRenderer.ts index c94f7f6488..b71ecc1a59 100644 --- a/packages/core/src/2d/text/TextRenderer.ts +++ b/packages/core/src/2d/text/TextRenderer.ts @@ -1,4 +1,4 @@ -import { BoundingBox, Color, Vector3 } from "@oasis-engine/math"; +import { BoundingBox, Color, Vector3, Matrix } from "@oasis-engine/math"; import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManager"; import { ICustomClone } from "../../clone/ComponentCloner"; import { Engine } from "../../Engine"; @@ -340,6 +340,14 @@ export class TextRenderer extends Renderer implements ICustomClone { this._dirtyFlag &= ~type; } + /** + * @override + */ + protected _updateShaderData(context: RenderContext): void { + // @ts-ignore + this._updateTransformShaderData(context, Matrix._identity); + } + /** * @override */ diff --git a/packages/core/src/shaderlib/extra/sprite.vs.glsl b/packages/core/src/shaderlib/extra/sprite.vs.glsl index 02c1928af3..2fde5996e9 100644 --- a/packages/core/src/shaderlib/extra/sprite.vs.glsl +++ b/packages/core/src/shaderlib/extra/sprite.vs.glsl @@ -1,8 +1,4 @@ -#ifdef USE_MODEL_MATRIX uniform mat4 u_MVPMat; -#else -uniform mat4 u_VPMat; -#endif attribute vec3 POSITION; attribute vec2 TEXCOORD_0; @@ -13,11 +9,7 @@ varying vec4 v_color; void main() { - #ifdef USE_MODEL_MATRIX gl_Position = u_MVPMat * vec4(POSITION, 1.0); - #else - gl_Position = u_VPMat * vec4(POSITION, 1.0); - #endif v_uv = TEXCOORD_0; v_color = COLOR_0;