import { Material, Matrix, MeshRenderer, MeshTopology, ModelMesh, Script, Texture2D, Vector2, Vector3 } from "oasis-engine"; import { PaladinAdapter } from "../adapter/PaladinAdapter"; import { BgMaterialAndroid } from "./Android/BgMaterialAndroid"; import { ARManager } from "./ARManager"; import { BgMaterialIos } from "./IOS/BgMaterialIos"; /** * 使用时再重写,性能可以得到提升 */ export class ARBackground extends Script { private _material: Material; private _textureY: Texture2D; private _textureUV: Texture2D; private _textureProject: Matrix; onAwake() { const { entity, engine } = this; // MeshRenderer const renderer = entity.addComponent(MeshRenderer); renderer.mesh = this._createPlane(); const material = PaladinAdapter.isIOS ? new BgMaterialIos(engine) : new BgMaterialAndroid(engine); renderer.setMaterial(material); this._material = material; } /** * 更新相机背景 * @param curARFrame - AR 帧数据 */ onUpdate(deltaTime: number): void { const { textureY, textureUV, textureProject } = ARManager.ins; if (textureY && textureY != this._textureY) { this._material.shaderData.setTexture("u_frameY", textureY); this._textureY = textureY; if (PaladinAdapter.isIOS) { const scaleMatrix = this._material.shaderData.getMatrix("u_scaleMatrix"); const screenWidth = this.engine.canvas.width; const screenHeight = this.engine.canvas.height; const frameWidth = textureY.height; const frameHeight = textureY.width; const screenRatio = screenWidth / screenHeight; const frameRatio = frameWidth / frameHeight; const ratio = screenRatio / frameRatio; if (ratio > 1) { scaleMatrix.elements[0] = 1; scaleMatrix.elements[5] = ratio; } else { scaleMatrix.elements[0] = 1 / ratio; scaleMatrix.elements[5] = 1; } } } if (textureUV && textureUV != this._textureUV) { this._material.shaderData.setTexture("u_frameUV", textureUV); this._textureUV = textureUV; } if (textureProject != this._textureProject) { this._material.shaderData.setMatrix("u_proMatrix", textureProject); this._textureProject = textureProject; } } /** * 创建相机背景平面 * @returns */ private _createPlane(): ModelMesh { const mesh = new ModelMesh(this.engine); mesh.setPositions([new Vector3(-1, -1, 1), new Vector3(1, -1, 1), new Vector3(1, 1, 1), new Vector3(-1, 1, 1)]); mesh.setUVs([new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0), new Vector2(0, 0)]); mesh.uploadData(true); mesh.addSubMesh(0, 4, MeshTopology.TriangleFan); return mesh; } }