diff --git a/src/babylon/animation-benchmark.ts b/src/babylon/animation-benchmark.ts new file mode 100644 index 0000000..908a80e --- /dev/null +++ b/src/babylon/animation-benchmark.ts @@ -0,0 +1,102 @@ +/** + * @title Animation + * @category Benchmark + */ + +import { + DirectionalLight, + Engine, + Scene, + SceneLoader, + UniversalCamera, + Vector3 +} from "@babylonjs/core"; +import "@babylonjs/loaders"; + +// ... YOUR SCENE CREATION + +// 创建画布元素 +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 createScene = (): Scene => { + const scene = new Scene(engine); + const camera = new UniversalCamera( + "UniversalCamera", + new Vector3(-6.5 * 1.5, 6.58 * 1.5, 8.5 * 1.5), + scene + ); + + // Targets the camera to a particular position. In this case the scene origin + camera.setTarget(Vector3.Zero()); + + const light2 = new DirectionalLight( + "dir01", + new Vector3(0, -0.5, -1.0), + scene + ); + light2.position = new Vector3(0, 5, 5); + + console.time("load"); + + SceneLoader.LoadAssetContainer( + "https://mdn.alipayobjects.com/rms/afts/file/A*DVfMRKjm6bMAAAAAAAAAAAAAARQnAQ/", + "HVGirl.glb", + scene, + function (container) { + container.meshes[0].scaling.scaleInPlace(0.05); + container.addAllToScene(); + + container.animationGroups[1].start(); + container.animationGroups[1].loopAnimation = true; + + for (let i = 0; i < 15; i++) { + for (let j = 0; j < 15; j++) { + const plane2Entries = container.instantiateModelsToScene( + undefined, + false, + { + doNotInstantiate: true, + } + ); + + plane2Entries.rootNodes[0].position.x = -2.4 * 1.8 + i * 0.6; + plane2Entries.rootNodes[0].position.z = -2.4 * 2 + j * 0.6; + const animationGroup = plane2Entries.animationGroups[1]; + animationGroup.start( + true, + 1.0, + animationGroup.from + Math.random() * 1000, + animationGroup.to, + false + ); + animationGroup.loopAnimation = true; + } + } + + console.timeEnd("load"); + } + ); + + return scene; +}; + +// 调用创建场景函数 +const scene = createScene(); + +// 渲染循环 +engine.runRenderLoop(() => { + scene.render(); +}); + +// 响应窗口大小变化 +window.addEventListener("resize", () => { + engine.resize(); +}); diff --git a/src/babylon/flipY.ts b/src/babylon/flipY.ts deleted file mode 100644 index 8eb1ba5..0000000 --- a/src/babylon/flipY.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @title FlipY - * @category Basic - */ -import * as BABYLON from "babylonjs"; - -// 获取 canvas 元素 -const canvas = document.getElementById("canvas") as HTMLCanvasElement; - -// 创建渲染器 -const engine = new BABYLON.Engine(canvas, true); - -// 创建场景 -const scene = new BABYLON.Scene(engine); - -// 创建相机 -const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2, 5, BABYLON.Vector3.Zero(), scene); -camera.attachControl(canvas, true); - -// 创建平面 -const plane = BABYLON.MeshBuilder.CreatePlane("plane", { width: 2, height: 2 }, scene); - -// 创建材质 -const material = new BABYLON.StandardMaterial("material", scene); -const texture = new BABYLON.Texture( - "https://mdn.alipayobjects.com/huamei_dmxymu/afts/img/A*z81hQ5sRQ0kAAAAAAAAAAAAADuuHAQ/original", - scene -); -material.emissiveTexture = texture; -console.log(texture.invertY) - -// 应用材质到平面 -plane.material = material; - -// 渲染循环 -engine.runRenderLoop(() => { - scene.render(); -}); diff --git a/src/galacean/ambient-light.ts b/src/galacean/ambient-light.ts deleted file mode 100644 index e2367bc..0000000 --- a/src/galacean/ambient-light.ts +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @title AmbientLight - * @category Light - */ -import { - AmbientLight, - AssetType, - BackgroundMode, - Camera, - DiffuseMode, - DirectLight, - Logger, - MeshRenderer, - PBRMaterial, - PrimitiveMesh, - SkyBoxMaterial, - Vector3, - WebGLEngine -} from "@galacean/engine"; -import { OrbitControl } from "@galacean/engine-toolkit"; -import * as dat from "dat.gui"; - -Logger.enable(); -WebGLEngine.create({ canvas: "canvas" }).then((engine) => { - engine.canvas.resizeByClientSize(); - - const scene = engine.sceneManager.activeScene; - const rootEntity = scene.createRootEntity(); - const gui = new dat.GUI(); - - // Create camera - const cameraNode = rootEntity.createChild("camera_node"); - cameraNode.transform.position = new Vector3(-3, 0, 3); - cameraNode.addComponent(Camera); - cameraNode.addComponent(OrbitControl); - - // Create sky - const sky = scene.background.sky; - const skyMaterial = new SkyBoxMaterial(engine); - scene.background.mode = BackgroundMode.Sky; - sky.material = skyMaterial; - sky.mesh = PrimitiveMesh.createCuboid(engine, 1, 1, 1); - - const lightEntity = rootEntity.createChild(); - lightEntity.addComponent(DirectLight).intensity = 0.5; - lightEntity.transform.setPosition(-5, 5, 5); - lightEntity.transform.lookAt(new Vector3(0, 0, 0)); - - // material ball - const ball = rootEntity.createChild("ball"); - const ballRender = ball.addComponent(MeshRenderer); - const material = new PBRMaterial(engine); - material.metallic = 0; - material.roughness = 0; - ballRender.mesh = PrimitiveMesh.createSphere(engine, 1, 64); - ballRender.setMaterial(material); - - engine.resourceManager - .load({ - type: AssetType.Env, - url: "https://gw.alipayobjects.com/os/bmw-prod/6470ea5e-094b-4a77-a05f-4945bf81e318.bin" - }) - .then((ambientLight) => { - scene.ambientLight = ambientLight; - skyMaterial.texture = ambientLight.specularTexture; - skyMaterial.textureDecodeRGBM = true; - openDebug(ambientLight.specularTexture); - engine.run(); - }); - - function openDebug(specularTexture) { - const info = { - diffuseMode: "SphericalHarmonics", - diffuseSolidColor: [0.212 * 255, 0.227 * 255, 0.259 * 255], - specularTexture: true - }; - - gui.add(info, "diffuseMode", ["SolidColor", "SphericalHarmonics"]).onChange((v) => { - if (v === "SphericalHarmonics") { - scene.ambientLight.diffuseMode = DiffuseMode.SphericalHarmonics; - } else if (v === "SolidColor") { - scene.ambientLight.diffuseMode = DiffuseMode.SolidColor; - } - }); - - gui.addColor(info, "diffuseSolidColor").onChange((v) => { - scene.ambientLight.diffuseSolidColor.set(v[0] / 255, v[1] / 255, v[2] / 255, 1); - }); - - gui.add(info, "specularTexture").onChange((v) => { - if (v) { - scene.ambientLight.specularTexture = specularTexture; - } else { - scene.ambientLight.specularTexture = null; - } - }); - - // env light debug - gui.add(scene.ambientLight, "specularIntensity", 0, 1); - gui.add(scene.ambientLight, "diffuseIntensity", 0, 1); - } -}); diff --git a/src/galacean/animation-benchmark.ts b/src/galacean/animation-benchmark.ts index 2a056bb..7a4bb07 100644 --- a/src/galacean/animation-benchmark.ts +++ b/src/galacean/animation-benchmark.ts @@ -7,64 +7,63 @@ import { Animator, AssetType, Camera, + DirectLight, GLTFResource, - PBRMaterial, - Texture2D, + Vector3, WebGLEngine, } from "@galacean/engine"; -import { Stats } from "@galacean/engine-toolkit"; // Create engine object -WebGLEngine.create({ canvas: "canvas" }).then((engine) => { +WebGLEngine.create({ + canvas: "canvas", + graphicDeviceOptions: { powerPreference: "high-performance" }, +}).then((engine) => { engine.canvas.resizeByClientSize(); // Create root entity and get scene const scene = engine.sceneManager.activeScene; const rootEntity = scene.createRootEntity(); scene.ambientLight.diffuseSolidColor.set(1, 1, 1, 1); + scene.ambientLight.diffuseIntensity = 0; // Create camera. const cameraEntity = rootEntity.createChild("Camera"); - cameraEntity.transform.setPosition(0, 5, 20); - cameraEntity.addComponent(Camera); - cameraEntity.addComponent(Stats); + // cameraEntity.addComponent(OrbitControl); + cameraEntity.transform.setPosition(6.5 * 1.5, 6.58 * 1.5, 8.5 * 1.5); + const camera = cameraEntity.addComponent(Camera); + cameraEntity.transform.lookAt(new Vector3(0, 0, 0)); + camera.farClipPlane = 1000; + const lightEntity = scene.createRootEntity("light"); + const directLight = lightEntity.addComponent(DirectLight); + directLight.intensity = 0.6; + directLight.direction.set(0, -0.5, -1.0); + + console.time("load"); // Load resources and add models. engine.resourceManager - .load([ - { - url: "https://gw.alipayobjects.com/os/loanprod/bf055064-3eec-4d40-bce0-ddf11dfbb88a/5d78db60f211d21a43834e23/4f5e6bb277dd2fab8e2097d7a418c5bc.gltf", - // url: "https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb", - type: AssetType.GLTF, - }, - { - url: "https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*OStMT63k5o8AAAAAAAAAAAAAARQnAQ", - type: AssetType.Texture2D, - }, - ]) - .then((resources: Object[]) => { - const glTF = resources[0]; - const baseTexture = resources[1]; - const model = glTF.defaultSceneRoot; - - glTF.materials.forEach((material: PBRMaterial) => { - material.baseTexture = baseTexture; - material.baseColor.set(1, 1, 1, 1); - }); + .load({ + url: "https://mdn.alipayobjects.com/rms/afts/file/A*DVfMRKjm6bMAAAAAAAAAAAAAARQnAQ/HVGirl.glb", + type: AssetType.GLTF, + }) + .then((glTF) => { + const model = glTF.instantiateSceneRoot(); + model.transform.setScale(0.0005, 0.0005, 0.0005); - for (let i = 0; i < 30; i++) { - for (let j = 0; j < 18; j++) { + for (let i = 0; i < 15; i++) { + for (let j = 0; j < 15; j++) { const modelClone = model.clone(); rootEntity.addChild(modelClone); const { transform } = modelClone; - transform.setRotation(0, -90, 0); - transform.setScale(0.5, 0.5, 0.5); - transform.setPosition(i * 1.0 - 15.0, j * 1.2, -j * 3.5); + transform.position.x = -2.4 * 1.8 + i * 0.6; + transform.position.z = -2.4 * 2 + j * 0.6; - modelClone.getComponent(Animator).play(glTF.animations[3].name); + modelClone.getComponent(Animator).play(glTF.animations[1].name,undefined,Math.random()); } } + + console.timeEnd("load"); }); // Run engine diff --git a/src/three/animation-benchmark.ts b/src/three/animation-benchmark.ts index d29e70c..27a51d2 100644 --- a/src/three/animation-benchmark.ts +++ b/src/three/animation-benchmark.ts @@ -14,8 +14,8 @@ const camera = new THREE.PerspectiveCamera( 0.1, 100 ); -camera.position.y = 5; -camera.position.z = 20; +camera.position.set(6.5 * 1.5, 6.58 * 1.5, 8.5 * 1.5); +camera.lookAt(new THREE.Vector3(0, 0, 0)); const scene = new THREE.Scene(); @@ -23,53 +23,35 @@ var ambientLight = new THREE.AmbientLight(0xffffff); ambientLight.color.set(new THREE.Color(1, 1, 1)); scene.add(ambientLight); -// 创建一个TextureLoader对象 -const textureLoader = new THREE.TextureLoader(); - let mixers = []; -textureLoader.load( - "https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*OStMT63k5o8AAAAAAAAAAAAAARQnAQ", - function (texture) { - texture.flipY = false; - const loader = new GLTFLoader(); - loader.load( - "https://gw.alipayobjects.com/os/loanprod/bf055064-3eec-4d40-bce0-ddf11dfbb88a/5d78db60f211d21a43834e23/4f5e6bb277dd2fab8e2097d7a418c5bc.gltf", - // "https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb", - function (glTF) { - const model = glTF.scene; - - // 遍历场景中的所有对象 - model.traverse(function (child) { - // 检查对象是否具有材质 - if (child.isMesh) { - // 遍历材质并修改纹理 - child.material.map = texture; - child.material.color = new THREE.Color(1, 1, 1); - } - }); +const loader = new GLTFLoader(); +console.time("load"); +loader.load( + "https://mdn.alipayobjects.com/rms/afts/file/A*DVfMRKjm6bMAAAAAAAAAAAAAARQnAQ/HVGirl.glb", + function (glTF) { + const model = glTF.scene; - for (let i = 0; i < 30; i++) { - for (let j = 0; j < 18; j++) { - const cloneModel = clone(model); - cloneModel.position.set(i * 1.0 - 15.0, j * 1.2, -j * 3.5); - cloneModel.scale.set(0.5, 0.5, 0.5); + for (let i = 0; i < 15; i++) { + for (let j = 0; j < 15; j++) { + const cloneModel = clone(model); + cloneModel.position.x = -2.4 * 1.8 + i * 0.6; + cloneModel.position.z = -2.4 * 2 + j * 0.6; + cloneModel.scale.set(0.05, 0.05, 0.05); - cloneModel.rotation.set(0, -90, 0); + scene.add(cloneModel); - scene.add(cloneModel); - - const mixer = new THREE.AnimationMixer(cloneModel); - mixers.push(mixer); - const animationAction = mixer.clipAction(glTF.animations[3]); - animationAction.play(); - } - } - }, - undefined, - function (error) { - console.error(error); + const mixer = new THREE.AnimationMixer(cloneModel); + mixers.push(mixer); + const animationAction = mixer.clipAction(glTF.animations[1]); + animationAction.play(); } - ); + } + + console.timeEnd("load"); + }, + undefined, + function (error) { + console.error(error); } ); diff --git a/src/three/basic.ts b/src/three/basic.ts deleted file mode 100644 index c4300f7..0000000 --- a/src/three/basic.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @title Basic - * @category Basic - */ -import * as THREE from "three"; - -// init - -const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10); -camera.position.z = 1; - -const scene = new THREE.Scene(); - -const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2); -const material = new THREE.MeshNormalMaterial(); - -const mesh = new THREE.Mesh(geometry, material); -scene.add(mesh); - -const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("canvas"), antialias: true }); -renderer.setSize(window.innerWidth, window.innerHeight); -renderer.setAnimationLoop(animation); - -// animation - -function animation(time) { - mesh.rotation.x = time / 2000; - mesh.rotation.y = time / 1000; - - renderer.render(scene, camera); - requestAnimationFrame(animation); -} -requestAnimationFrame(animation); diff --git a/template/index.html b/template/index.html index e83d9b4..108370a 100644 --- a/template/index.html +++ b/template/index.html @@ -34,6 +34,20 @@ background-color: #45a049; box-shadow: 2px 2px 12px rgba(0, 0, 0, 0.2); } + + .open { + position: absolute; + top: 0; + right: 0; + background-color: aliceblue; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + font-size: 24px; + cursor: pointer; + } @@ -49,6 +63,12 @@