/// import { Color, Mesh, Node, PerspectiveCamera, PointLight, Quaternion, Scene, Submesh, Vector3 } from "../src/data/index"; import { Renderer, degToRad } from "../src/oktaeder"; import "./style.css"; new EventSource("/esbuild").addEventListener("change", () => location.reload()); const canvas = document.createElement("canvas"); window.addEventListener("resize", onResize); onResize.call(window); const renderer = await Renderer.init(canvas); const camera = new PerspectiveCamera({ verticalFovRad: degToRad(50), nearPlane: 0.001, farPlane: Infinity, }); const vertexBuffer = renderer.createVertexBuffer({ vertexCount: 12, texCoord: true }); vertexBuffer.writeTypedArray(0, { position: new Float32Array([ 0, 0, 1, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 1, ]), texCoord: new Float32Array([ 0.5, 0.7113, 0.333333, 1, 0.166666, 0.7113, 0.333333, 0.4226, 0, 0.4226, 0, 1, 1, 1, 0.666666, 1, 0.833333, 0.7113, 0.666666, 0.4226, 1, 0.4226, 0.5, 0.7113, ]), }); const indexBuffer = renderer.createIndexBuffer({ indexCount: 24, indexFormat: "uint16" }); indexBuffer.writeArray(0, [ 0, 2, 1, 3, 4, 2, 5, 1, 2, 2, 0, 3, 6, 8, 7, 9, 8, 10, 7, 8, 11, 11, 8, 9, ]); const submesh: Submesh = { start: 0, length: 24 }; const mesh = new Mesh({ vertexBuffer, indexBuffer, submeshes: [submesh] }); const imageBitmap = await loadImageBitmap("/uvmap.png"); const texture = renderer.createTexture({ format: "srgb", width: imageBitmap.width, height: imageBitmap.height, usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, }); renderer._device.queue.copyExternalImageToTexture( { source: imageBitmap, flipY: false }, { texture: texture._texture }, { width: imageBitmap.width, height: imageBitmap.height }, ); const material = renderer.createMaterial({ baseColor: Color.white(), baseColorPartialCoverageTexture: texture, roughness: 0.5, metallic: 0, }); const node = new Node({ mesh, materials: [material] }); const scene = new Scene({ nodes: [ node, new Node({ translation: new Vector3(0, 1, -1), light: new PointLight({ color: new Color(1, 1, 1) }), }), new Node({ translation: new Vector3(0, -1, -1), light: new PointLight({ color: new Color(1, 1, 1) }), }), new Node({ translation: new Vector3(0, 0.8, -3), rotation: Quaternion.fromRotationYZ(degToRad(15)), camera, }), ], ambientLight: new Color(0.01, 0.01, 0.01), }); function onResize(this: Window) { canvas.width = this.innerWidth; canvas.height = this.innerHeight; } const _quaternion = Quaternion.identity(); async function loadImageBitmap(url: string) { const res = await fetch(url); const blob = await res.blob(); const imageBitmap = await createImageBitmap(blob, { colorSpaceConversion: "none" }); return imageBitmap; } function draw(timeMs: number) { const time = 0.001 * timeMs; node.setRotation(_quaternion.setRotationZX(-0.5 * time)); renderer.render(scene, camera); requestAnimationFrame(draw); } requestAnimationFrame(draw); document.body.appendChild(canvas);