diff --git a/package.json b/package.json index 6d20405..4644e83 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@types/three": "^0.164.0", "babylonjs": "^7.6.0", "dat.gui": "^0.7.9", + "pixi.js": "^8.1.8", "stats.js": "^0.17.0", "three": "^0.164.1", "three-nebula": "^10.0.3", diff --git a/src/babylon/sprite-benchmark.ts b/src/babylon/sprite-benchmark.ts deleted file mode 100644 index e99e684..0000000 --- a/src/babylon/sprite-benchmark.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @title Sprite - * @category Benchmark - */ - -import { - Sprite, - SpriteManager, - Vector3, - Engine, - Scene, - UniversalCamera, -} from "@babylonjs/core"; - -// 创建画布元素 -const canvas = document.getElementById("canvas") as HTMLCanvasElement; -document.body.appendChild(canvas); - -// 初始化引擎 -const engine = new Engine(canvas, true); - -canvas.width = canvas.clientWidth * window.devicePixelRatio; -canvas.height = canvas.clientHeight * window.devicePixelRatio; -const scene = new Scene(engine); - -var camera = new UniversalCamera( - "UniversalCamera", - new Vector3(0, 0, -180), - scene -); -camera.setTarget(Vector3.Zero()); - -const col = 22; -const row = 90; -// 创建精灵纹理 -var spriteManager = new SpriteManager( - "spriteManager", - "https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*YwyMRq8_O-4AAAAAAAAAAAAADjCHAQ/original", - col * row, - { width: 407, height: 401 }, - scene -); - -const offsetX = 3.2; -const offsetY = 2.5; -// 中心点所在行列 -const centerX = col * 0.5; -const centerY = row * 0.5; -const sprites = []; -for (let i = 0; i < row; ++i) { - for (let j = 0; j < col; ++j) { - var sprite = new Sprite(`sprite_${i}_${j}`, spriteManager); - sprite.position.x = (j - centerX) * offsetX; - sprite.position.y = (i - centerY) * offsetY; - sprite.size = 8; // 设置精灵大小 - sprites.push(sprite); - } -} - -// 帧更新函数 -const speed = Math.PI / 360; -scene.onBeforeRenderObservable.add(function () { - // 遍历所有精灵,每帧更新它们的旋转角度 - sprites.forEach(function (sprite) { - sprite.angle += speed; // 每帧旋转一个角度 - }); -}); - -// 渲染循环 -engine.runRenderLoop(function () { - scene.render(); -}); diff --git a/src/babylon/text-benchmark.ts b/src/babylon/text-benchmark.ts deleted file mode 100644 index 2b376cd..0000000 --- a/src/babylon/text-benchmark.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @title Text - * @category Benchmark - */ - -import { Vector3, Engine, Scene, UniversalCamera } from "@babylonjs/core"; -import { AdvancedDynamicTexture, TextBlock } from "@babylonjs/gui"; - -// 创建画布元素 -const canvas = document.getElementById("canvas") as HTMLCanvasElement; -document.body.appendChild(canvas); - -// 初始化引擎 -const engine = new Engine(canvas, true); - -canvas.width = canvas.clientWidth * window.devicePixelRatio; -canvas.height = canvas.clientHeight * window.devicePixelRatio; -const scene = new Scene(engine); - -var camera = new UniversalCamera( - "UniversalCamera", - new Vector3(0, 0, -180), - scene -); -camera.setTarget(Vector3.Zero()); - -const col = 22; -const row = 90; -const offsetX = 37; -const offsetY = 20; -// 中心点所在行列 -const centerX = col * 0.5; -const centerY = row * 0.5; -const texts = []; -const advancedTexture = AdvancedDynamicTexture.CreateFullscreenUI("UI", false, scene); -for (let i = 0; i < row; ++i) { - for (let j = 0; j < col; ++j) { - const textBlock = new TextBlock(); - textBlock.text = "hello"; - textBlock.color = "white"; - textBlock.fontSize = 36; - advancedTexture.addControl(textBlock); - textBlock.scaleX = 0.6; - textBlock.scaleY = 0.6; - textBlock.left = `${(j - centerX) * offsetX + 20}px`; - textBlock.top = `${(i - centerY) * offsetY}px`; - texts.push(textBlock); - } -} - -// 帧更新函数 -const speed = Math.PI / 360; -scene.onBeforeRenderObservable.add(function () { - // 遍历所有精灵,每帧更新它们的旋转角度 - texts.forEach(function (text) { - text.rotation += speed; // 每帧旋转一个角度 - }); -}); - -// 渲染循环 -engine.runRenderLoop(function () { - scene.render(); -}); diff --git a/src/galacean/sprite-benchmark.ts b/src/galacean/sprite-benchmark.ts index 95d4d5d..0ea5aef 100644 --- a/src/galacean/sprite-benchmark.ts +++ b/src/galacean/sprite-benchmark.ts @@ -8,13 +8,14 @@ import { Camera, Script, Sprite, + SpriteAtlas, SpriteRenderer, Texture2D, WebGLEngine, } from "@galacean/engine"; class Rotate extends Script { - speed = 30; + speed = 60; onUpdate(dt: number): void { this.entity.transform.rotation.z += this.speed * dt; } @@ -35,16 +36,17 @@ WebGLEngine.create({ camera.orthographicSize = (engine.canvas.height * 0.5) / 100; engine.resourceManager - .load({ - url: "https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*YwyMRq8_O-4AAAAAAAAAAAAADjCHAQ/original", - type: AssetType.Texture2D, + .load({ + url: "https://mdn.alipayobjects.com/oasis_be/afts/file/A*s_FUSawb0sgAAAAAAAAAAAAADkp5AQ/SpriteAtlas.json", + type: AssetType.SpriteAtlas, }) - .then((texture: Texture2D) => { - const sprite = new Sprite(engine, texture); + .then((atlas: SpriteAtlas) => { + const sprite1 = atlas.getSprite("/tex1-spr.png"); + const sprite2 = atlas.getSprite("/tex2-spr.png"); - const col = 22; + const col = 88; const row = 90; - const offsetX = 0.38; + const offsetX = 0.1; const offsetY = 0.2; // 中心点所在行列 const centerX = col * 0.5; @@ -55,10 +57,11 @@ WebGLEngine.create({ const entity = rootEntity.createChild(`sprite-${i}`); const sr = entity.addComponent(SpriteRenderer); entity.addComponent(Rotate); - sr.sprite = sprite; + sr.sprite = i % 2 === 0 ? sprite1 : sprite2; sr && (sr.priority = index++); const transform = entity.transform; - transform.setScale(0.2, 0.2, 0.2); + const scale = 0.075; + transform.setScale(scale, scale, scale); transform.setPosition( (j - centerX) * offsetX, (i - centerY) * offsetY, diff --git a/src/pixi/sprite-benchmark.ts b/src/pixi/sprite-benchmark.ts new file mode 100644 index 0000000..9895371 --- /dev/null +++ b/src/pixi/sprite-benchmark.ts @@ -0,0 +1,63 @@ +/** + * @title Sprite + * @category Benchmark + */ + +import * as PIXI from "pixi.js"; + +const canvas = document.getElementById("canvas") as HTMLCanvasElement; +const app = new PIXI.Application(); +app + .init({ + canvas: canvas, + resizeTo: window, + width: canvas.width, + height: canvas.height, + }) + .then(() => { + PIXI.Assets.load([ + { + src: "https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*YwyMRq8_O-4AAAAAAAAAAAAADjCHAQ/original", + loadParser: "loadTextures", + }, + { + src: "https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*ClJLS6U4HtsAAAAAAAAAAAAADjCHAQ/original", + loadParser: "loadTextures", + }, + ]).then((textureRecord) => { + const col = 88; + const row = 90; + const offsetX = 5; + const offsetY = 10; + // 中心点所在行列 + const centerX = col * 0.5; + const centerY = row * 0.5; + // 屏幕宽高 + const screen = app.screen; + const halfWidth = screen.width * 0.5; + const halfHeight = screen.height * 0.5; + const sprites = []; + const texture1 = + textureRecord[ + "https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*YwyMRq8_O-4AAAAAAAAAAAAADjCHAQ/original" + ]; + const texture2 = textureRecord['https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*ClJLS6U4HtsAAAAAAAAAAAAADjCHAQ/original']; + for (let i = 0; i < row; ++i) { + for (let j = 0; j < col; ++j) { + const sprite = new PIXI.Sprite(i % 2 === 0 ? texture1 : texture2); + app.stage.addChild(sprite); + sprite.scale = 0.045; + sprite.anchor.set(0.5, 0.5); + sprite.x = halfWidth + (j - centerX) * offsetX + 5; + sprite.y = halfHeight + (i - centerY) * offsetY + 10; + sprites.push(sprite); + } + } + + app.ticker.add((time) => { + for (let i = 0, n = sprites.length; i < n; ++i) { + sprites[i].rotation += 0.01 * time.deltaTime; + } + }); + }); + }); diff --git a/src/pixi/text-benchmark.ts b/src/pixi/text-benchmark.ts new file mode 100644 index 0000000..9a3449b --- /dev/null +++ b/src/pixi/text-benchmark.ts @@ -0,0 +1,55 @@ +/** + * @title Text + * @category Benchmark + */ + +import * as PIXI from "pixi.js"; + +const canvas = document.getElementById("canvas") as HTMLCanvasElement; +const app = new PIXI.Application(); +app + .init({ + canvas: canvas, + resizeTo: window, + width: canvas.width, + height: canvas.height, + }) + .then(() => { + const col = 22; + const row = 90; + const offsetX = 20; + const offsetY = 10; + // 中心点所在行列 + const centerX = col * 0.5; + const centerY = row * 0.5; + // 屏幕宽高 + const screen = app.screen; + const halfWidth = screen.width * 0.5; + const halfHeight = screen.height * 0.5; + const texts = []; + const style = new PIXI.TextStyle({ + fontFamily: "Arial", + fontSize: 20, + fill: 0xffffff, + }); + for (let i = 0; i < row; ++i) { + for (let j = 0; j < col; ++j) { + const text = new PIXI.Text({ + text: "hello", + style, + }); + app.stage.addChild(text); + text.anchor.set(0.5, 0.5); + text.scale = 0.8; + text.x = halfWidth + (j - centerX) * offsetX + 10; + text.y = halfHeight + (i - centerY) * offsetY + 10; + texts.push(text); + } + } + + app.ticker.add((time) => { + for (let i = 0, n = texts.length; i < n; ++i) { + texts[i].rotation += 0.01 * time.deltaTime; + } + }); + }); diff --git a/src/three/sprite-benchmark.ts b/src/three/sprite-benchmark.ts deleted file mode 100644 index d6f8e4e..0000000 --- a/src/three/sprite-benchmark.ts +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @title Sprite - * @category Benchmark - */ -import * as THREE from "three"; - -const scene = new THREE.Scene(); - -// 创建正交相机 -const width = window.innerWidth * window.devicePixelRatio; -const height = window.innerHeight * window.devicePixelRatio; -const aspectRatio = width / height; -const camera = new THREE.OrthographicCamera( - -aspectRatio, - aspectRatio, - 1, - -1, - 0.1, - 1000 -); -camera.position.z = 5; - -// 创建渲染器,并指定 canvas 元素作为渲染目标 -const canvas = document.getElementById("canvas") as HTMLCanvasElement; -canvas.width = canvas.clientWidth * window.devicePixelRatio; -canvas.height = canvas.clientHeight * window.devicePixelRatio; -const renderer = new THREE.WebGLRenderer({ - canvas, -}); -renderer.setSize(width, height); - -// 创建精灵纹理,传入图片的 URL -const spriteMap = new THREE.TextureLoader().load( - "https://mdn.alipayobjects.com/huamei_w6ifet/afts/img/A*YwyMRq8_O-4AAAAAAAAAAAAADjCHAQ/original" -); -const spriteMaterial = new THREE.SpriteMaterial({ map: spriteMap }); - -const col = 22; -const row = 90; -const offsetX = 0.023; -const offsetY = 0.015; -// 中心点所在行列 -const centerX = col * 0.5; -const centerY = row * 0.5; -const sprites = []; -for (let i = 0; i < row; ++i) { - for (let j = 0; j < col; ++j) { - const sprite = new THREE.Sprite(spriteMaterial); - sprite.scale.set(0.05, 0.05, 0.05); // 设置精灵大小 - scene.add(sprite); - sprite.position.set((j - centerX) * offsetX - 0.2, (i - centerY) * offsetY + 0.5, 0); - sprites.push(sprite); - } -} - -let rotationAngle = 0; -const map = spriteMaterial.map; -map.center.set(0.5, 0.5); -const speed = Math.PI / 360; -function updateSpriteRotation() { - rotationAngle += speed; - for (let i = 0, l = sprites.length; i < l; ++i) { - map.rotation = rotationAngle; - } -} - -// 渲染循环 -function animate() { - requestAnimationFrame(animate); - updateSpriteRotation(); - renderer.render(scene, camera); -} -animate(); diff --git a/src/three/text-benchmark.ts b/src/three/text-benchmark.ts deleted file mode 100644 index 461a584..0000000 --- a/src/three/text-benchmark.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @title Text - * @category Benchmark - */ - -import * as THREE from "three"; -import SpriteText from "three-spritetext"; - -const scene = new THREE.Scene(); - -// 创建正交相机 -const width = window.innerWidth * window.devicePixelRatio; -const height = window.innerHeight * window.devicePixelRatio; -const aspectRatio = width / height; -const camera = new THREE.OrthographicCamera( - -aspectRatio, - aspectRatio, - 1, - -1, - 0.1, - 1000 -); -camera.position.z = 5; - -// 创建渲染器,并指定 canvas 元素作为渲染目标 -const canvas = document.getElementById("canvas") as HTMLCanvasElement; -canvas.width = canvas.clientWidth * window.devicePixelRatio; -canvas.height = canvas.clientHeight * window.devicePixelRatio; -const renderer = new THREE.WebGLRenderer({ - canvas, -}); -renderer.setSize(width, height); - -const col = 22; -const row = 90; -const offsetX = 0.023; -const offsetY = 0.015; -// 中心点所在行列 -const centerX = col * 0.5; -const centerY = row * 0.5; -const maps = []; -for (let i = 0; i < row; ++i) { - for (let j = 0; j < col; ++j) { - const text = new SpriteText("hello"); - text.scale.set(0.025, 0.025, 0.025); - text.position.set((j - centerX) * offsetX - 0.21, (i - centerY) * offsetY + 0.5, 0); - const map = text.material.map; - map.center.set(0.5, 0.5); - scene.add(text); - maps.push(map); - } -} - -let rotationAngle = 0; -const speed = Math.PI / 360; -function updateSpriteRotation() { - rotationAngle += speed; - for (let i = 0, l = maps.length; i < l; ++i) { - maps[i].rotation = rotationAngle; - } -} - -// 渲染循环 -function animate() { - requestAnimationFrame(animate); - updateSpriteRotation(); - renderer.render(scene, camera); -} -animate(); diff --git a/template/index.html b/template/index.html index 108370a..a39a4f6 100644 --- a/template/index.html +++ b/template/index.html @@ -73,6 +73,7 @@
+
diff --git a/template/index.js b/template/index.js index 51ff5c2..1580020 100644 --- a/template/index.js +++ b/template/index.js @@ -4,7 +4,7 @@ const searchBarDOM = document.getElementById("searchBar"); const iframe = document.getElementById("iframe"); const items = []; // itemDOM,label -const platforms = ["galacean", "three", "babylon"]; +const platforms = ["galacean", "three", "babylon", "pixi"]; let url = new URL(window.location.href); const platform = url.searchParams.get("platform") ?? "galacean"; @@ -13,8 +13,10 @@ platforms.splice(platforms.indexOf(platform), 1); const button1 = document.getElementById("button1"); const button2 = document.getElementById("button2"); +const button3 = document.getElementById("button3"); button1.innerText = platforms[0]; button2.innerText = platforms[1]; +button3.innerText = platforms[2]; button1.addEventListener("click", () => { url.searchParams.set("platform", platforms[0]); window.location.href = url.toString(); @@ -23,6 +25,10 @@ button2.addEventListener("click", () => { url.searchParams.set("platform", platforms[1]); window.location.href = url.toString(); }); +button3.addEventListener("click", () => { + url.searchParams.set("platform", platforms[2]); + window.location.href = url.toString(); +}); import(`./mpa/${platform}/.demoList.json`).then(({ default: demoList }) => { Object.keys(demoList).forEach((group) => { @@ -74,7 +80,7 @@ import(`./mpa/${platform}/.demoList.json`).then(({ default: demoList }) => { } function clickItem(itemDOM) { - console.log('on hash change') + console.log("on hash change"); window.location.hash = `#mpa/${itemDOM.title}`; url = new URL(window.location.href); }