如何捕获使用 WebXR API 创建增强现实 (AR) 体验的 Three.js 场景的屏幕截图?

问题描述 投票:0回答:1

我正在使用 Three.js、WebXR 和 Vue.js 第 3 版开发增强现实应用程序。我的目标是添加一个按钮,按下该按钮时,会捕获当前场景的快照。但是,我在尝试拍摄快照时遇到了问题。在移动设备上,捕获的图像是空白的,而在桌面上的WebXR环境中(我使用firefox和chrome以及webxrapi扩展来模拟galax s8手机),我只能看到白色背景的3D模型。

这是我的 Vue 组件模板的代码:

<template>
    <canvas ref="canvas" id="canvas"></canvas>
    <div ref="overlay" id="overlay">
        <button  ref="picture" class="picture-button" v-show="arSessionStarted">
        TA BILD
        </button>
        <button ref="rotate" class="rotation-button" v-show="arSessionStarted">
        ROTERA 
        </button>
    </div>
</template>

这是主要功能:

init() {
    // Create a THREE scene
    this.scene = new THREE.Scene()
    this.camera = new THREE.PerspectiveCamera(
        70,
        window.innerWidth / window.innerHeight,
        0.1,
        20
    );
    this.camera.position.z = 1;
   // CreatE a THREE WebGLRenderer
    this.canvas = this.$refs.canvas;
    this.gl = this.canvas.getContext('webgl', {xrCompatible: true});
    this.renderer = new THREE.WebGLRenderer({
        canvas: this.canvas,
        context: this.gl,
        antialias: true,
        alpha: true,
        powerPreference: 'high-performance', 
        xrCompatible: true,
        preserveDrawingBuffer: true
    });
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.xr.enabled = true;

    // Create a THREE light object
    const light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 1);
    light.position.set(0.5, 1, 0.25);
    this.scene.add(light);
    
    // Load the model and reticle to the scene
    this.addReticleToScene();
    this.addModelToScene(); 
    // Create THREE controller to place the container
    this.controller = this.renderer.xr.getController(0);
    this.controller.addEventListener("select", this.onSelect);
    this.scene.add(this.controller);
    
    // Create a button to enter  a AR session 
    this.overlay = this.$refs.overlay;
    const button = ARButton.createButton(this.renderer, {
        requiredFeatures: ["hit-test"],
        optionalFeatures: [
            "dom-overlay",
            "dom-overlay-for-handheld-ar",
        ],
        domOverlay: {
            root: this.overlay,
        },
    });
    this.overlay.appendChild(button);
    // Add an id to the ar button
    button.id = "my-id";
    //Initiate the event listeners for the rotate and take picture buttons
    this.rotationButton = this.$refs.rotate;
    this.takePictureButton = this.$refs.picture;
    this.rotationButton.addEventListener('beforexrselect', ev => ev.preventDefault());
    this.takePictureButton.addEventListener('beforexrselect', ev => ev.preventDefault());
    
    this.rotationButton.addEventListener('click', () => {
        this.rotate();
    });
    
    this.takePictureButton.addEventListener('click', () => {
        this.takePicture();
    });
    // Add event listener to adjust the size of the window
    window.addEventListener("resize", this.onWindowResize, false);
}

这是takePicture函数:

takePicture() {
    //Take Picture
    this.screenshoot = this.renderer.domElement.toDataURL();
    console.log(this.screenshoot);
    alert("Work in Progress!");
},

这是渲染器:

render(timestamp, frame) {
    if (frame) {
        if (!this.hitTestSourceInitialized) {
            this.initializeHitTestSource();
        }
        if (this.hitTestSourceInitialized) {
            const hitTestResults = frame.getHitTestResults(
                this.hitTestSource
            );
            if (hitTestResults.length > 0) {
                const hit = hitTestResults[0];
                const pose = hit.getPose(this.localSpace);
                this.reticle.visible = true;
                this.reticle.matrix.fromArray(pose.transform.matrix);
            } else {
                this.reticle.visible = false;
            }
        }
        this.renderer.render(this.scene, this.camera);
    }
}
animate() {
    this.renderer.setAnimationLoop(this.render);
}

我尝试过以下方法:

takePicture() {
    //Take Picture
    this.screenshoot = this.renderer.domElement.toDataURL();
    console.log(this.screenshoot);
    alert("Work in Progress!");
},

来自 stackoverflow 的线程: 如何使用 THREE.PerspectiveCamera 捕捉 THREE.Scene 的图像?

来自 stackoverflow 的线程: Three.js:如何将场景的 2D 快照制作为 JPG 图像?

three.js 3d vuejs3 augmented-reality webxr
1个回答
0
投票

我们有一个使用 MindAR 进行屏幕捕获的解决方案。它涉及为 AR 源的副本创建一个额外的画布,获取大小适合渲染画布的渲染画布,捕获复制的画布 WebGL 2D 上下文,然后获取视频源和渲染画布并将它们绘制到复制的画布上。通过 2D WebGL 上下文绘制画布。然后使用

toDataURL
保存复制画布。请参阅此处的代码示例:

https://github.com/dvbridges/ar-projects/blob/main/mind-ar- Threejs-image-tracker/script.js

© www.soinside.com 2019 - 2024. All rights reserved.