diff --git a/.gitignore b/.gitignore index 229c3ea39a6..7ba394514c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -/lib +lib/ +.turbo/ /bin /web.config .idea diff --git a/cc.config.json b/cc.config.json index 7b51e5dd86e..cb74327075f 100644 --- a/cc.config.json +++ b/cc.config.json @@ -678,6 +678,12 @@ "type": "boolean", "value": false, "internal": true + }, + "CULL_MESHOPT": { + "comment": "An internal constant to indicate whether we cull the meshopt wasm module and asm.js module.", + "type": "boolean", + "value": true, + "internal": true } }, diff --git a/cocos/2d/components/mask.ts b/cocos/2d/components/mask.ts index a01247055d4..4cb13d13d42 100644 --- a/cocos/2d/components/mask.ts +++ b/cocos/2d/components/mask.ts @@ -456,11 +456,9 @@ export class Mask extends Component { protected _removeMaskNode (): void { if (this._sprite) { - this._sprite.destroy(); this._sprite = null; } if (this._graphics) { - this._graphics.destroy(); this._graphics = null; } } diff --git a/cocos/3d/assets/mesh.ts b/cocos/3d/assets/mesh.ts index d064d93ddb0..5011a6e09d8 100644 --- a/cocos/3d/assets/mesh.ts +++ b/cocos/3d/assets/mesh.ts @@ -28,11 +28,11 @@ import { Asset } from '../../asset/assets/asset'; import { IDynamicGeometry } from '../../primitive/define'; import { BufferBlob } from '../misc/buffer-blob'; import { Skeleton } from './skeleton'; -import { geometry, cclegacy, sys, warnID, Mat4, Quat, Vec3, assertIsTrue, murmurhash2_32_gc, errorID } from '../../core'; +import { geometry, cclegacy, sys, warnID, Mat4, Quat, Vec3, assertIsTrue, murmurhash2_32_gc, errorID, halfToFloat } from '../../core'; import { RenderingSubMesh } from '../../asset/assets'; import { Attribute, Device, Buffer, BufferInfo, AttributeName, BufferUsageBit, Feature, Format, - FormatInfos, FormatType, MemoryUsageBit, PrimitiveMode, getTypedArrayConstructor, DrawInfo, FormatInfo, deviceManager, + FormatInfos, FormatType, MemoryUsageBit, PrimitiveMode, getTypedArrayConstructor, DrawInfo, FormatInfo, deviceManager, FormatFeatureBit, } from '../../gfx'; import { Morph } from './morph'; import { MorphRendering, createMorphRendering } from './morph-rendering'; @@ -409,6 +409,11 @@ export class Mesh extends Asset { if (this.struct.encoded) { // decode mesh data info = decodeMesh(info); } + if (this.struct.quantized + && !(deviceManager.gfxDevice.getFormatFeatures(Format.RGB16F) & FormatFeatureBit.VERTEX_ATTRIBUTE)) { + // dequantize mesh data + info = dequantizeMesh(info); + } this._struct = info.struct; this._data = info.data; @@ -1507,11 +1512,6 @@ export function decodeMesh (mesh: Mesh.ICreateInfo): Mesh.ICreateInfo { return mesh; } - // decode the mesh - if (!MeshoptDecoder.supported) { - return mesh; - } - const res_checker = (res: number): void => { if (res < 0) { errorID(14204, res); @@ -1581,4 +1581,150 @@ export function inflateMesh (mesh: Mesh.ICreateInfo): Mesh.ICreateInfo { return mesh; } +export function dequantizeMesh (mesh: Mesh.ICreateInfo): Mesh.ICreateInfo { + const struct = JSON.parse(JSON.stringify(mesh.struct)) as Mesh.IStruct; + + const bufferBlob = new BufferBlob(); + bufferBlob.setNextAlignment(0); + + function transformVertex ( + reader: ((offset: number) => number), + writer: ((offset: number, value: number) => void), + count: number, + components: number, + componentSize: number, + readerStride: number, + writerStride: number, + ): void { + for (let i = 0; i < count; i++) { + for (let j = 0; j < components; j++) { + const inputOffset = readerStride * i + componentSize * j; + const outputOffset = writerStride * i + componentSize * j; + writer(outputOffset, reader(inputOffset)); + } + } + } + + function dequantizeHalf ( + reader: ((offset: number) => number), + writer: ((offset: number, value: number) => void), + count: number, + components: number, + readerStride: number, + writerStride: number, + ): void { + for (let i = 0; i < count; i++) { + for (let j = 0; j < components; j++) { + const inputOffset = readerStride * i + 2 * j; + const outputOffset = writerStride * i + 4 * j; + const value = halfToFloat(reader(inputOffset)); + writer(outputOffset, value); + } + } + } + + for (let i = 0; i < struct.vertexBundles.length; ++i) { + const bundle = struct.vertexBundles[i]; + const view = bundle.view; + const attributes = bundle.attributes; + const oldAttributes = mesh.struct.vertexBundles[i].attributes; + const strides: number[] = []; + const dequantizes: boolean[] = []; + const readers: ((offset: number) => number)[] = []; + for (let j = 0; j < attributes.length; ++j) { + const attr = attributes[j]; + const inputView = new DataView(mesh.data.buffer, view.offset + getOffset(oldAttributes, j)); + const reader = getReader(inputView, attr.format); + let dequantize = true; + switch (attr.format) { + case Format.R16F: + attr.format = Format.R32F; + break; + case Format.RG16F: + attr.format = Format.RG32F; + break; + case Format.RGB16F: + attr.format = Format.RGB32F; + break; + case Format.RGBA16F: + attr.format = Format.RGBA32F; + break; + default: + dequantize = false; + break; + } + strides.push(FormatInfos[attr.format].size); + dequantizes.push(dequantize); + readers.push(reader!); + } + const netStride = strides.reduce((acc, cur) => acc + cur, 0); + const newBuffer = new Uint8Array(netStride * view.count); + for (let j = 0; j < attributes.length; ++j) { + const attribute = attributes[j]; + const reader = readers[j]; + const outputView = new DataView(newBuffer.buffer, getOffset(attributes, j)); + const writer = getWriter(outputView, attribute.format)!; + const dequantize = dequantizes[j]; + const formatInfo = FormatInfos[attribute.format]; + if (dequantize) { + dequantizeHalf( + reader, + writer, + view.count, + formatInfo.count, + view.stride, + netStride, + ); + } else { + transformVertex( + reader, + writer, + view.count, + formatInfo.count, + formatInfo.size / formatInfo.count, + view.stride, + netStride, + ); + } + } + + bufferBlob.setNextAlignment(netStride); + const newView: Mesh.IBufferView = { + offset: bufferBlob.getLength(), + length: newBuffer.byteLength, + count: view.count, + stride: netStride, + }; + bundle.view = newView; + bufferBlob.addBuffer(newBuffer); + } + + // dump index buffer + for (const primitive of struct.primitives) { + if (primitive.indexView === undefined) { + continue; + } + const view = primitive.indexView; + const buffer = new Uint8Array(mesh.data.buffer, view.offset, view.length); + bufferBlob.setNextAlignment(view.stride); + const newView: Mesh.IBufferView = { + offset: bufferBlob.getLength(), + length: buffer.byteLength, + count: view.count, + stride: view.stride, + }; + primitive.indexView = newView; + bufferBlob.addBuffer(buffer); + } + + const data = new Uint8Array(bufferBlob.getCombined()); + + struct.quantized = false; + + return { + struct, + data, + }; +} + // function get diff --git a/cocos/3d/framework/mesh-renderer.ts b/cocos/3d/framework/mesh-renderer.ts index 9869186e7d1..8c4543f3182 100644 --- a/cocos/3d/framework/mesh-renderer.ts +++ b/cocos/3d/framework/mesh-renderer.ts @@ -899,6 +899,7 @@ export class MeshRenderer extends ModelRenderer { if (this._mesh) { const meshStruct = this._mesh.struct; this._model.createBoundingShape(meshStruct.minPosition, meshStruct.maxPosition); + this._model.updateWorldBound(); } // Initialize lighting map before model initializing // because the lighting map will influence the model's shader diff --git a/cocos/3d/misc/mesh-codec.ts b/cocos/3d/misc/mesh-codec.ts index ba9f5088c9d..f875a7a0571 100644 --- a/cocos/3d/misc/mesh-codec.ts +++ b/cocos/3d/misc/mesh-codec.ts @@ -21,7 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { WASM_SUPPORT_MODE } from 'internal:constants'; +import { CULL_MESHOPT, WASM_SUPPORT_MODE } from 'internal:constants'; import { ensureWasmModuleReady, instantiateWasm } from 'pal/wasm'; import { sys, logID } from '../../core'; @@ -90,4 +90,6 @@ export function InitDecoder (): Promise { })); } -game.onPostInfrastructureInitDelegate.add(InitDecoder); +if (!CULL_MESHOPT) { + game.onPostInfrastructureInitDelegate.add(InitDecoder); +} diff --git a/cocos/misc/camera-component.ts b/cocos/misc/camera-component.ts index e4201ecfcbd..2c2067e5d5e 100644 --- a/cocos/misc/camera-component.ts +++ b/cocos/misc/camera-component.ts @@ -313,7 +313,7 @@ export class Camera extends Component { */ @type(FOVAxis) @displayOrder(7) - @visible(function (this: Camera): boolean { + @visible(function visible (this: Camera): boolean { return this._projection === ProjectionType.PERSPECTIVE; }) @tooltip('i18n:camera.fov_axis') @@ -354,10 +354,10 @@ export class Camera extends Component { * @zh 正交模式下的相机视角高度。 */ @displayOrder(9) - @visible(function (this: Camera): boolean { + @visible(function visible (this: Camera): boolean { return this._projection === ProjectionType.ORTHO; }) - @rangeMin(1) + @rangeMin(1e-6) @tooltip('i18n:camera.ortho_height') get orthoHeight (): number { return this._orthoHeight; diff --git a/cocos/physics-2d/box2d-wasm/instantiated.ts b/cocos/physics-2d/box2d-wasm/instantiated.ts index 5156374fd49..023cb80afe1 100644 --- a/cocos/physics-2d/box2d-wasm/instantiated.ts +++ b/cocos/physics-2d/box2d-wasm/instantiated.ts @@ -35,7 +35,8 @@ export const B2 = {} as any; export function getImplPtr (wasmObject: any): number { // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return (wasmObject).$$.ptr; + if (!wasmObject) return 0; + return (wasmObject).$$.ptr as number; } /** diff --git a/cocos/physics-2d/box2d-wasm/joints/joint-2d.ts b/cocos/physics-2d/box2d-wasm/joints/joint-2d.ts index 2f0990e0d6b..0f4c964861b 100644 --- a/cocos/physics-2d/box2d-wasm/joints/joint-2d.ts +++ b/cocos/physics-2d/box2d-wasm/joints/joint-2d.ts @@ -22,7 +22,7 @@ THE SOFTWARE. */ -import { B2, addImplPtrReference, addImplPtrReferenceWASM, getImplPtr } from '../instantiated'; +import { B2, addImplPtrReference, addImplPtrReferenceWASM, getImplPtr, removeImplPtrReference, removeImplPtrReferenceWASM } from '../instantiated'; import { IJoint2D } from '../../spec/i-physics-joint'; import { Joint2D, PhysicsSystem2D, RigidBody2D } from '../../framework'; import { B2PhysicsWorld } from '../physics-world'; @@ -54,7 +54,7 @@ export class B2Joint implements IJoint2D { } onDisable (): void { - PhysicsSystem2D.instance._callAfterStep(this, this._destroy); + PhysicsSystem2D.instance._callAfterStep(this, this.destroy); } // need init after body and connected body init @@ -106,9 +106,11 @@ export class B2Joint implements IJoint2D { this._inited = true; } - _destroy (): void { + destroy (): void { if (!this._inited) return; + removeImplPtrReference(getImplPtr(this._b2joint)); + removeImplPtrReferenceWASM(getImplPtr(this._b2joint)); (PhysicsSystem2D.instance.physicsWorld as B2PhysicsWorld).impl.DestroyJoint(this._b2joint!); this._b2joint = null; diff --git a/cocos/physics-2d/box2d-wasm/joints/mouse-joint.ts b/cocos/physics-2d/box2d-wasm/joints/mouse-joint.ts index f5d359056da..51f73a9cfd2 100644 --- a/cocos/physics-2d/box2d-wasm/joints/mouse-joint.ts +++ b/cocos/physics-2d/box2d-wasm/joints/mouse-joint.ts @@ -118,7 +118,7 @@ export class B2MouseJoint extends B2Joint implements IMouseJoint { } onTouchEnd (event: Touch): void { - this._destroy(); + this.destroy(); this._isTouched = false; } diff --git a/cocos/physics-2d/box2d-wasm/rigid-body.ts b/cocos/physics-2d/box2d-wasm/rigid-body.ts index feb13037e4c..a92e0533863 100644 --- a/cocos/physics-2d/box2d-wasm/rigid-body.ts +++ b/cocos/physics-2d/box2d-wasm/rigid-body.ts @@ -22,7 +22,7 @@ THE SOFTWARE. */ -import { B2 } from './instantiated'; +import { B2, getTSObjectFromWASMObject, getTSObjectFromWASMObjectPtr } from './instantiated'; import { IRigidBody2D } from '../spec/i-rigid-body'; import { RigidBody2D } from '../framework/components/rigid-body-2d'; import { PhysicsSystem2D } from '../framework/physics-system'; @@ -31,8 +31,10 @@ import { Vec2, toRadian, Vec3, Quat, IVec2Like, toDegree, TWO_PI, HALF_PI } from import { PHYSICS_2D_PTM_RATIO, ERigidBody2DType } from '../framework/physics-types'; import { Node } from '../../scene-graph/node'; -import { Collider2D } from '../framework'; +import { Collider2D, Joint2D } from '../framework'; import { NodeEventType } from '../../scene-graph/node-event'; +import { B2Shape2D } from './shapes/shape-2d'; +import { B2Joint } from './joints/joint-2d'; const tempVec3 = new Vec3(); const tempVec2_1 = { x: 0, y: 0 };//new B2.Vec2(0, 0); @@ -114,6 +116,29 @@ export class B2RigidBody2D implements IRigidBody2D { _destroy (): void { if (!this._inited) return; + //collect all fixtures attached to this rigid body and process them + const fixtureList = this.impl?.GetFixtureList(); + if (fixtureList) { + let shapeTSObj = getTSObjectFromWASMObject(fixtureList); + while (shapeTSObj && shapeTSObj.impl) { + shapeTSObj.destroy(); + const nextFixture = fixtureList.GetNext(); + shapeTSObj = getTSObjectFromWASMObject(nextFixture); + } + } + + //collect all joints attached to this rigid body and process them + const jointListPtr = this.impl?.GetJointList(); + if (jointListPtr) { + let jointWASMPtr = B2.JointEdgeGetJoint(jointListPtr) as number; + let jointTSObj = getTSObjectFromWASMObjectPtr(jointWASMPtr); + while (jointTSObj) { + jointTSObj.destroy(); + jointWASMPtr = B2.JointEdgeGetNext(jointListPtr) as number; + jointTSObj = getTSObjectFromWASMObjectPtr(jointWASMPtr); + } + } + (PhysicsSystem2D.instance.physicsWorld as B2PhysicsWorld).removeBody(this); this._inited = false; diff --git a/cocos/physics-2d/box2d-wasm/shapes/shape-2d.ts b/cocos/physics-2d/box2d-wasm/shapes/shape-2d.ts index 5f102e03580..84ab4a5881b 100644 --- a/cocos/physics-2d/box2d-wasm/shapes/shape-2d.ts +++ b/cocos/physics-2d/box2d-wasm/shapes/shape-2d.ts @@ -77,7 +77,7 @@ export class B2Shape2D implements IBaseShape { } onDisable (): void { - PhysicsSystem2D.instance._callAfterStep(this, this._destroy); + PhysicsSystem2D.instance._callAfterStep(this, this.destroy); } start (): void { @@ -92,7 +92,7 @@ export class B2Shape2D implements IBaseShape { } apply (): void { - this._destroy(); + this.destroy(); if (this.collider.enabledInHierarchy) { this._init(); } @@ -200,7 +200,7 @@ export class B2Shape2D implements IBaseShape { this._inited = true; } - _destroy (): void { + destroy (): void { if (!this._inited) return; const fixtures = this._fixtures; diff --git a/cocos/render-scene/scene/submodel.ts b/cocos/render-scene/scene/submodel.ts index a1e51f42617..66a026c2fb8 100644 --- a/cocos/render-scene/scene/submodel.ts +++ b/cocos/render-scene/scene/submodel.ts @@ -333,10 +333,12 @@ export class SubModel { if (!this._globalPatches && pipelinePatches.length === 0) { return; } else if (pipelinePatches.length) { - if (this._globalPatches && pipelinePatches.length === this._globalPatches.length) { + if (this._globalPatches) { const globalPatches = Object.entries(this._globalPatches); - const patchesStateUnchanged = JSON.stringify(pipelinePatches.sort()) === JSON.stringify(globalPatches.sort()); - if (patchesStateUnchanged) return; + if (pipelinePatches.length === globalPatches.length) { + const patchesStateUnchanged = JSON.stringify(pipelinePatches.sort()) === JSON.stringify(globalPatches.sort()); + if (patchesStateUnchanged) return; + } } } this._globalPatches = pipeline.macros; diff --git a/cocos/rendering/post-process/passes/forward-pass.ts b/cocos/rendering/post-process/passes/forward-pass.ts index fb73550de00..4fa9f366640 100644 --- a/cocos/rendering/post-process/passes/forward-pass.ts +++ b/cocos/rendering/post-process/passes/forward-pass.ts @@ -17,10 +17,11 @@ export class ForwardPass extends BasePass { depthBufferShadingScale = 1; calcDepthSlot (camera: Camera): void { - let canUsePrevDepth = !!passContext.depthSlotName; - canUsePrevDepth = !(camera.clearFlag & ClearFlagBit.DEPTH_STENCIL); + const depthSlotName = !!passContext.depthSlotName; + let canUsePrevDepth = !(camera.clearFlag & ClearFlagBit.DEPTH_STENCIL); canUsePrevDepth = canUsePrevDepth && passContext.shadingScale === this.depthBufferShadingScale; if (canUsePrevDepth) { + if (!depthSlotName) passContext.depthSlotName = super.slotName(camera, 1); return; } this.depthBufferShadingScale = passContext.shadingScale; diff --git a/cocos/rendering/post-process/post-process-builder.ts b/cocos/rendering/post-process/post-process-builder.ts index fa656a459b1..eb56eb6baa1 100644 --- a/cocos/rendering/post-process/post-process-builder.ts +++ b/cocos/rendering/post-process/post-process-builder.ts @@ -237,7 +237,9 @@ export class PostProcessBuilder implements PipelineBuilder { } if (pass.name === 'BloomPass') { - (pass as BloomPass).hdrInputName = floatOutputPass.getHDRInputName(); + // for override post-process builder + (pass as BloomPass).hdrInputName = (floatOutputPass === undefined || floatOutputPass === null) + ? '' : floatOutputPass.getHDRInputName(); } pass.lastPass = lastPass; diff --git a/cocos/spine/lib/spine-define.ts b/cocos/spine/lib/spine-define.ts index 28d53f939f2..f267bf1c1fe 100644 --- a/cocos/spine/lib/spine-define.ts +++ b/cocos/spine/lib/spine-define.ts @@ -524,7 +524,6 @@ function overrideProperty_VertexAttachment (): void { proto: prototype, property: 'id', getter: prototype.getId, - setter: prototype.setId, }, { proto: prototype, @@ -727,15 +726,12 @@ function overrideProperty_RegionAttachment (): void { property: 'rendererObject', getter: prototype.getRendererObject, }, - { - proto: prototype, - property: 'offset', - getter: prototype.getOffset, - }, ]; propertyPolyfills.forEach((prop): void => { js.getset(prop.proto, prop.property, prop.getter, prop.setter); }); + + overrideDefineArrayProp(prototype, prototype.getOffset, 'offset'); overrideDefineArrayPropGetSet(prototype, prototype.getUVs, prototype.setUVs, spine.wasmUtil.wasm.VectorFloat, 'uvs'); } @@ -766,6 +762,11 @@ function overrideProperty_SlotData (): void { property: 'index', getter: prototype.getIndex, }, + { + proto: prototype, + property: 'boneData', + getter: prototype.getBoneData, + }, { proto: prototype, property: 'name', @@ -791,8 +792,6 @@ function overrideProperty_SlotData (): void { propertyPolyfills.forEach((prop): void => { js.getset(prop.proto, prop.property, prop.getter, prop.setter); }); - overrideDefineArrayProp(prototype, prototype.getBoneData, 'boneData'); - overrideDefineArrayProp(prototype, prototype.getDeform, 'deform'); } function overrideProperty_IkConstraint (): void { @@ -1226,13 +1225,14 @@ function overrideProperty_Slot (): void { }, { proto: prototype, - property: 'deform', - getter: prototype.getDeform, + property: 'skeleton', + getter: prototype.getSkeleton, }, ]; propertyPolyfills.forEach((prop): void => { js.getset(prop.proto, prop.property, prop.getter); }); + overrideDefineArrayProp(prototype, prototype.getDeform, 'deform'); } function overrideProperty_Skin (): void { diff --git a/cocos/ui/editbox/edit-box-impl-base.ts b/cocos/ui/editbox/edit-box-impl-base.ts index 7b742034370..9ce78026dc9 100644 --- a/cocos/ui/editbox/edit-box-impl-base.ts +++ b/cocos/ui/editbox/edit-box-impl-base.ts @@ -37,11 +37,22 @@ export class EditBoxImplBase { */ public _delegate: EditBox | null = null; - public init (delegate: EditBox): void {} + /** + * @engineInternal dirty flag to update the matrix + */ + public _dirtyFlag: boolean | null = false; - public onEnable (): void {} + public init (delegate: EditBox): void { + // To be overrode + } + + public onEnable (): void { + // To be overrode + } - public update (): void { } + public update (): void { + // To be overrode + } public onDisable (): void { if (this._editing) { @@ -53,9 +64,13 @@ export class EditBoxImplBase { this._delegate = null; } - public setTabIndex (index: number): void {} + public setTabIndex (index: number): void { + // To be overrode + } - public setSize (width: number, height: number): void {} + public setSize (width: number, height: number): void { + // To be overrode + } public setFocus (value): void { if (value) { @@ -69,7 +84,11 @@ export class EditBoxImplBase { return this._editing; } - public beginEditing (): void {} + public beginEditing (): void { + // To be overrode + } - public endEditing (): void {} + public endEditing (): void { + // To be overrode + } } diff --git a/cocos/ui/editbox/edit-box-impl.ts b/cocos/ui/editbox/edit-box-impl.ts index 14e1bb11270..f6a36d25700 100644 --- a/cocos/ui/editbox/edit-box-impl.ts +++ b/cocos/ui/editbox/edit-box-impl.ts @@ -137,6 +137,7 @@ export class EditBoxImpl extends EditBoxImplBase { } public update (): void { + if (!this._dirtyFlag) return; this._updateMatrix(); } @@ -625,12 +626,12 @@ export class EditBoxImpl extends EditBoxImplBase { this._delegate!._editBoxEditingDidEnded(); }; - elem.addEventListener('compositionstart', cbs.compositionStart); - elem.addEventListener('compositionend', cbs.compositionEnd); - elem.addEventListener('input', cbs.onInput); - elem.addEventListener('keydown', cbs.onKeydown); - elem.addEventListener('blur', cbs.onBlur); - elem.addEventListener('touchstart', cbs.onClick); + elem.addEventListener('compositionstart', cbs.compositionStart as EventListenerOrEventListenerObject); + elem.addEventListener('compositionend', cbs.compositionEnd as EventListenerOrEventListenerObject); + elem.addEventListener('input', cbs.onInput as EventListenerOrEventListenerObject); + elem.addEventListener('keydown', cbs.onKeydown as EventListenerOrEventListenerObject); + elem.addEventListener('blur', cbs.onBlur as EventListenerOrEventListenerObject); + elem.addEventListener('touchstart', cbs.onClick as EventListenerOrEventListenerObject); } private _removeEventListeners (): void { if (!this._edTxt) { @@ -640,12 +641,12 @@ export class EditBoxImpl extends EditBoxImplBase { const elem = this._edTxt; const cbs = this.__eventListeners; - elem.removeEventListener('compositionstart', cbs.compositionStart); - elem.removeEventListener('compositionend', cbs.compositionEnd); - elem.removeEventListener('input', cbs.onInput); - elem.removeEventListener('keydown', cbs.onKeydown); - elem.removeEventListener('blur', cbs.onBlur); - elem.removeEventListener('touchstart', cbs.onClick); + elem.removeEventListener('compositionstart', cbs.compositionStart as EventListenerOrEventListenerObject); + elem.removeEventListener('compositionend', cbs.compositionEnd as EventListenerOrEventListenerObject); + elem.removeEventListener('input', cbs.onInput as EventListenerOrEventListenerObject); + elem.removeEventListener('keydown', cbs.onKeydown as EventListenerOrEventListenerObject); + elem.removeEventListener('blur', cbs.onBlur as EventListenerOrEventListenerObject); + elem.removeEventListener('touchstart', cbs.onClick as EventListenerOrEventListenerObject); cbs.compositionStart = null; cbs.compositionEnd = null; diff --git a/cocos/ui/editbox/edit-box.ts b/cocos/ui/editbox/edit-box.ts index 4bca693cdc7..63846eeb9cb 100644 --- a/cocos/ui/editbox/edit-box.ts +++ b/cocos/ui/editbox/edit-box.ts @@ -492,6 +492,9 @@ export class EditBox extends Component { public _editBoxEditingDidBegan (): void { ComponentEventHandler.emitEvents(this.editingDidBegan, this); this.node.emit(EventType.EDITING_DID_BEGAN, this); + if (this._impl) { + this._impl._dirtyFlag = true; + } } /** @@ -503,6 +506,9 @@ export class EditBox extends Component { public _editBoxEditingDidEnded (text?: string): void { ComponentEventHandler.emitEvents(this.editingDidEnded, this); this.node.emit(EventType.EDITING_DID_ENDED, this, text); + if (this._impl) { + this._impl._dirtyFlag = false; + } } /** diff --git a/editor/assets/chunks/common/color/tone-mapping.chunk b/editor/assets/chunks/common/color/tone-mapping.chunk index 5f35af77b09..6808b806772 100644 --- a/editor/assets/chunks/common/color/tone-mapping.chunk +++ b/editor/assets/chunks/common/color/tone-mapping.chunk @@ -8,10 +8,12 @@ vec3 HDRToLDR(vec3 color) #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC && CC_SURFACES_ENABLE_DEBUG_VIEW if (IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING) #endif + { // linear exposure has already applied to light intensity #if CC_TONE_MAPPING_TYPE == HDR_TONE_MAPPING_ACES color.rgb = ACESToneMap(color.rgb); #endif + } #endif return color; diff --git a/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk b/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk index bf3553519f8..c038209b091 100644 --- a/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk +++ b/editor/assets/chunks/shading-entries/data-structures/fs-input.chunk @@ -31,7 +31,7 @@ void CCSurfacesGetFragmentInput(out SurfacesStandardFragmentInput fsInput) #define FSInput_worldTangent v_tangent.xyz // unnormalized #define FSInput_mirrorNormal v_tangent.w #else - #define FSInput_worldTangent vec3(0.0, 0.0, 0.0) + #define FSInput_worldTangent vec3(1.0, 1.0, 1.0) // normalize zero vector may crash on webgpu, use 1 instead #define FSInput_mirrorNormal 1.0 #endif diff --git a/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk b/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk index cd1e3391a55..4b19e669c80 100644 --- a/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/misc/sky-fs.chunk @@ -15,6 +15,14 @@ void main() { vec4 color = SurfacesFragmentModifyBaseColorAndTransparency(); color.a = 1.0; + // HDR Fog + // todo: apply fogColorBrightness to linear fogColor for supporting scatter lighting with HDR + #if CC_USE_FOG != CC_FOG_NONE + float fogFactor = 1.0; + CC_TRANSFER_FOG_BASE(vec4(FSInput_worldPos, 1.0), fogFactor); + CC_APPLY_FOG_BASE(color, fogFactor); + #endif + #if CC_USE_RGBE_OUTPUT color = packRGBE(color.rgb); #else//todo: change to #elif !CC_USE_FLOAT_OUTPUT when sky render queue has been fixed with custom pipeline @@ -22,12 +30,5 @@ void main() { color.rgb = LinearToSRGB(color.rgb); #endif - //todo: LDR fogging in gamma space, HDR fogging should move before tone mapping - #if CC_USE_FOG != CC_FOG_NONE - float fogFactor = 1.0; - CC_TRANSFER_FOG_BASE(vec4(FSInput_worldPos, 1.0), fogFactor); - CC_APPLY_FOG_BASE(color, fogFactor); - #endif - fragColorX = color; } diff --git a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk index 17565ac6f50..386daaf0908 100644 --- a/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk +++ b/editor/assets/chunks/shading-entries/main-functions/render-to-scene/pipeline/forward-fs.chunk @@ -128,6 +128,18 @@ void main() { #endif #endif + // Fog, rgbe and gamma output can't apply fog with forward-add pass + // todo: apply fogColorBrightness to linear fogColor for supporting scatter lighting with HDR + #if CC_USE_FOG != CC_FOG_NONE && (!CC_USE_FLOAT_OUTPUT || CC_IS_TRANSPARENCY_PASS) + #if !CC_FORWARD_ADD + #ifdef CC_SURFACES_LIGHTING_MODIFY_FOG + color.rgb = CCSurfacesLightingModifyFog(fogFactor, color.rgb, surfaceData, lightingResult); + #else + CC_APPLY_FOG_BASE(color, fogFactor); + #endif + #endif + #endif + // Color output #if CC_USE_RGBE_OUTPUT color = packRGBE(color.rgb); // for reflection-map @@ -139,16 +151,5 @@ void main() { #endif #endif - // Fog, rgbe and gamma output can't apply fog with forward-add pass - // todo: apply fogColorBrightness to fogColor for supporting scatter lighting with HDR - #if CC_USE_FOG != CC_FOG_NONE && (!CC_USE_FLOAT_OUTPUT || CC_IS_TRANSPARENCY_PASS) - #if !CC_FORWARD_ADD - #ifdef CC_SURFACES_LIGHTING_MODIFY_FOG - color.rgb = CCSurfacesLightingModifyFog(fogFactor, color.rgb, surfaceData, lightingResult); - #else - CC_APPLY_FOG_BASE(color, fogFactor); - #endif - #endif - #endif fragColorX = color; } diff --git a/editor/assets/effects/advanced/fabric.effect.meta b/editor/assets/effects/advanced/fabric.effect.meta index 8a62097c4df..8940a2567de 100644 --- a/editor/assets/effects/advanced/fabric.effect.meta +++ b/editor/assets/effects/advanced/fabric.effect.meta @@ -1,5 +1,5 @@ { - "ver": "1.7.0", + "ver": "1.7.1", "importer": "effect", "imported": true, "uuid": "b25c7601-1d07-4a56-86c5-62e83ea7c61e", diff --git a/editor/assets/effects/advanced/leaf.effect b/editor/assets/effects/advanced/leaf.effect index aa690844804..f43c3248f56 100644 --- a/editor/assets/effects/advanced/leaf.effect +++ b/editor/assets/effects/advanced/leaf.effect @@ -113,7 +113,7 @@ CCProgram macro-remapping %{ // ui displayed macros #pragma define-meta HAS_SECOND_UV #pragma define-meta USE_TWOSIDE - //use FSInput_faceSideSign for materials #pragma define-meta USE_TWOSIDE_MATERIAL + //use FSInput_faceSideSign for different textures #pragma define-meta USE_TWOSIDE_MATERIAL #pragma define-meta USE_VERTEX_COLOR #pragma define-meta USE_DITHERED_ALPHA_TEST diff --git a/editor/assets/effects/pipeline/float-output-process.effect b/editor/assets/effects/pipeline/float-output-process.effect index de8f2d61d44..153ce534f7d 100644 --- a/editor/assets/effects/pipeline/float-output-process.effect +++ b/editor/assets/effects/pipeline/float-output-process.effect @@ -42,14 +42,15 @@ CCProgram copy-fs %{ CCProgram tonemap-fs %{ precision highp float; + #define CC_SURFACES_ENABLE_DEBUG_VIEW 1 #include #include - #include - #include + #include #include + #include + #include #include #include - #include in vec2 v_uv; @@ -60,16 +61,7 @@ CCProgram tonemap-fs %{ layout(location = 0) out vec4 fragColor; - vec3 HDR2LDR_PostProcess(vec3 color) { - #if CC_USE_HDR && CC_TONE_MAPPING_TYPE == TONE_MAPPING_ACES - return ACESToneMap(color.rgb); - #else - return color.rgb; - #endif - } - vec4 CCFragOutput_PostProcess(vec4 color) { - // fog related vec4 worldPos = vec4(0.0); #if CC_USE_FOG != CC_FOG_NONE @@ -79,22 +71,23 @@ CCProgram tonemap-fs %{ worldPos = GetWorldPosFromNDCPosRH(posHS, cc_matProj, cc_matViewProjInv); #endif - // todo: apply fogColorBrightness to fogColor for supporting scatter lighting with HDR + // HDR fog + // todo: apply fogColorBrightness to linear fogColor for supporting scatter lighting with HDR + #if CC_USE_FOG != CC_FOG_NONE + float fogFactor = 1.0; + CC_TRANSFER_FOG_BASE(worldPos, fogFactor); + CC_APPLY_FOG_BASE(color, fogFactor); + #endif // tone mapping if (!DebugViewNeedDisplayOriginalData()) { #if CC_USE_FLOAT_OUTPUT - color.rgb = HDR2LDR_PostProcess(color.rgb); + color.rgb = HDRToLDR(color.rgb); color.rgb = LinearToSRGB(color.rgb); #endif } // LDR fog - #if CC_USE_FOG != CC_FOG_NONE - float fogFactor = 1.0; - CC_TRANSFER_FOG_BASE(worldPos, fogFactor); - CC_APPLY_FOG_BASE(color, fogFactor); - #endif return color; } diff --git a/editor/assets/effects/pipeline/post-process/post-final.effect b/editor/assets/effects/pipeline/post-process/post-final.effect index a1c6e08c4d2..3d8aa313f37 100644 --- a/editor/assets/effects/pipeline/post-process/post-final.effect +++ b/editor/assets/effects/pipeline/post-process/post-final.effect @@ -33,7 +33,7 @@ CCProgram fs %{ layout(location = 0) out vec4 fragColor; void main () { - fragColor = vec4(texture(inputTexture, v_uv).rgb, 1.0); + fragColor = texture(inputTexture, v_uv); } }% diff --git a/editor/assets/primitives.fbx b/editor/assets/primitives.fbx index f93a097616a..1ddad73bd08 100755 Binary files a/editor/assets/primitives.fbx and b/editor/assets/primitives.fbx differ diff --git a/editor/i18n/en/assets.js b/editor/i18n/en/assets.js index d2393bfd1bc..84943ce0549 100644 --- a/editor/i18n/en/assets.js +++ b/editor/i18n/en/assets.js @@ -93,7 +93,7 @@ module.exports = { propertyTips: { // macros USE_DITHERED_ALPHA_TEST: 'Make transparency using opaque dithered alpha clip with TAA.', - USE_TWOSIDE: 'Two sided material for single-face objects, normal get inverse on back-face. Cull mode should set to None.', + USE_TWOSIDE: 'Two sided lighting for single-face objects, normal get inverse on back-face automatically. Cull mode should set to None.', IS_ANISOTROPY: 'Anisotropic materials, such as hair, disc, metal with micro-wires.', USE_VERTEX_COLOR: 'Use vertex color, will become darker if mesh does not contain vertex color data.', FIX_ANISOTROPIC_ROTATION_MAP: 'Fix the anomalous seam at the black-white joint of the anisotropic rotation map, turn it on if you encounter this problem.', diff --git a/editor/i18n/en/localization.js b/editor/i18n/en/localization.js index 0b1adaa5577..236afc74403 100755 --- a/editor/i18n/en/localization.js +++ b/editor/i18n/en/localization.js @@ -1034,6 +1034,10 @@ module.exports = link(mixin({ label: "Box2D Based 2D Physics System", description: "2D Physics system that based on Box2D.", }, + physics_2d_box2d_wasm: { + label: "Box2D-wasm Based 2D Physics System", + description: "2D Physics system that based on Box2D-wasm.", + }, intersection_2d: { label: "2D Intersection Algorithms", description: "Include 2D intersection algorithms.", diff --git a/editor/i18n/zh/assets.js b/editor/i18n/zh/assets.js index edf9f8acf94..e02c185354e 100644 --- a/editor/i18n/zh/assets.js +++ b/editor/i18n/zh/assets.js @@ -93,7 +93,7 @@ module.exports = { propertyTips: { // macros USE_DITHERED_ALPHA_TEST: '使用抖动透贴的方式来实现半透明效果,最好同时开启 TAA', - USE_TWOSIDE: '双面材质,通常用于单面物体,正面和背面的法线相反。还需将 Cull Mode 设为 None', + USE_TWOSIDE: '双面材质,仅影响光照,通常用于单面物体,正面和背面的法线会自动取反。还需将 Cull Mode 设为 None', IS_ANISOTROPY: '各向异性材质,通常用于头发、光碟、拉丝金属等', USE_VERTEX_COLOR: '使用顶点色,如果模型本身没有顶点色可能会发黑', FIX_ANISOTROPIC_ROTATION_MAP: '修复各向异性旋转图黑白相接处的异常接缝,遇到此问题再开启', @@ -325,84 +325,65 @@ module.exports = { name: '填充顶点色', title: '如果模型没有顶点颜色属性,添加颜色属性,填充为白色。', }, + meshOptimize: { + name: '网格优化', + title: '是否优化网格数据。', + vertexCache: { + name: '顶点缓存', + title: '优化顶点缓冲区以提高顶点缓存命中率。
建议对顶点数较高的模型启用此选项。', + }, + vertexFetch: { + name: '顶点提取', + title: '优化顶点缓冲区以提高顶点提取效率。
建议对顶点数较高的模型启用此选项。', + }, + overdraw: { + name: '过度绘制', + title: '优化顶点缓冲区以减少过度绘制。
建议对顶点数较高的模型启用此选项。', + }, + }, meshSimplify: { - name: 'Mesh 简化', - title: 'Mesh 简化可以被用来简化导入的模型,可以在需要模型减面时使用。
在一些少数情况下减面后的模型可能会出现显示异常,如发生这种情况请尝试调整参数并重试。', - simplification: { - name: 'Simplification', - title: 'Simplification', - si: { - name: 'Achieve The Ratio R', - title: 'Achieve The Ratio R', - }, - sa: { - name: 'Aggressively Simplify', - title: 'Aggressively Simplify', - }, + name: '网格简化', + title: '是否简化网格数据。', + targetRatio: { + name: '目标比率', + title: '简化网格数据的目标顶点数的比例。
建议将此值设置为 0.5。', }, - scene: { - name: 'Scene', - title: 'Scene', - kn: { - name: 'Keep Nodes Transform', - title: 'Keep Nodes Transform', - }, - ke: { - name: 'Keep Extras Data', - title: 'Keep Extras Data', - }, + autoErrorRate: { + name: '自动误差率', + title: '是否自动计算简化网格数据的误差率。', }, - miscellaneous: { - name: 'Miscellaneous', - title: 'Miscellaneous', - noq: { - name: 'Disable Quantization', - title: 'Disable Quantization', - }, - v: { - name: 'Verbose Output', - title: 'Verbose Output', - }, + errorRate: { + name: '误差率', + title: '简化网格数据的最大误差率。
此值还会影响结果大小。
建议调整直到获得良好的结果。', }, - algorithm: { - name: '减面算法', - simplify: 'simplify', - gltfpack: 'gltfpack (已废弃)', + lockBoundary: { + name: '锁定边界', + title: '是否锁定简化网格数据的边界。', }, - simplify: { - targetRatio: { - name: 'LOD 压缩比例', - title: '减面之后的目标面数比例,0 代表减面至最少,1 代表没有减面的原模型。', - }, - preserveSurfaceCurvature: { - name: '保留表面曲率', - title: 'Preserve Surface Curvature', - }, - preserveBorderEdges: { - name: '保留边界边', - title: 'Preserve Border Edges', - }, - preserveUVSeamEdges: { - name: '保留 UV 缝合边', - title: 'Preserve UV Seam Edges', - }, - preserveUVFoldoverEdges: { - name: '保留 UV 折叠边', - title: 'Preserve UV Foldover Edges', - }, - agressiveness: { - name: '误差距离', - title: '模型减面算法的激进程度。
当设置数值越高时,算法的减面策略会越激进,但是过于激进的策略更有可能导致结果错误。', - }, - maxIterationCount: { - name: '计算迭代次数', - title: '最大重复计数代表减面算法运行的重复次数。
高数值可以使算法运行结果更接近目标,但也会增加运行时间和结果错误的概率。', - }, + }, + meshCluster: { + name: '网格切块', + title: '是否分割网格数据。', + generateBounding: { + name: '生成包围体', + title: '是否为聚类的网格数据生成包围球和法线锥。', + }, + }, + meshCompress:{ + name: '网格压缩', + title: '是否压缩网格数据。', + encode: { + name: '编码', + title: '对网格数据进行编码以减少数据大小。', + }, + compress: { + name: '压缩', + title: '对网格数据进行压缩以减少数据大小。', }, - gltfpack: { - warn: '当前资源使用的减面算法 gltfpack 已被废弃,请选用新的 simplify 减面算法。', + quantize: { + name: '量化', + title: '对网格数据进行量化以减少数据大小。', }, - warn: '警告:优化后,网格资源的数量和名称会发生改变,这将会造成组件引用的资源丢失,请及时手动更新;(另外,对于模型资源中预生成的预制体,资源同步机制会自动更新)', }, animationBakeRate: { name: '动画烘焙速率', diff --git a/editor/i18n/zh/localization.js b/editor/i18n/zh/localization.js index b1047daed39..87c24c16973 100755 --- a/editor/i18n/zh/localization.js +++ b/editor/i18n/zh/localization.js @@ -1008,6 +1008,10 @@ module.exports = link(mixin({ label: "基于 Box2D 的 2D 物理系统", description: "基于 Box2D 的 2D 物理系统支持。", }, + physics_2d_box2d_wasm: { + label: "基于 Box2D-wasm 的 2D 物理系统", + description: "基于 Box2D-wasm 的 2D 物理系统支持。", + }, intersection_2d: { label: "2D 相交检测算法", description: "包含用于二维相交检测的算法。", diff --git a/editor/inspector/components.js b/editor/inspector/components.js index 37fd3598924..1dd378709ac 100644 --- a/editor/inspector/components.js +++ b/editor/inspector/components.js @@ -15,8 +15,6 @@ module.exports = { 'cc.SkeletalAnimation': join(__dirname, './components/skeletal-animation.js'), 'cc.SphereLight': join(__dirname, './components/sphere-light.js'), 'cc.SpotLight': join(__dirname, './components/spot-light.js'), - 'cc.PointLight': join(__dirname, './components/point-light.js'), - 'cc.RangedDirectionalLight': join(__dirname, './components/ranged-directional-light.js'), 'cc.Sprite': join(__dirname, './components/sprite.js'), 'cc.Terrain': join(__dirname, './components/terrain.js'), 'cc.VideoPlayer': join(__dirname, './components/video-player.js'), diff --git a/editor/inspector/components/widget.js b/editor/inspector/components/widget.js index a4b52964acd..85e97d536a5 100644 --- a/editor/inspector/components/widget.js +++ b/editor/inspector/components/widget.js @@ -8,6 +8,7 @@ const Vue = require('vue/dist/vue.min.js'); const propUtils = require('../utils/prop'); const cssMediaWidth = 340; +let layout = 'vertical'; exports.template = `