用AR增强电商体验:移动应用中的3D产品预览指南

1. AR产品预览在电商应用中的目的与优势

  • 提升客户体验:AR产品预览可以让客户在购买前查看和体验产品,从而减轻购买决策时的不确定性。
  • 增加参与度与购买率:通过AR可视化产品在用户空间中的实际效果,使客户更倾向于下单,并提高应用的用户互动率。

2. 所需的库

  • Three.js:用于在应用中渲染和显示3D模型的库。
  • JSARToolkit:用于基于标记的AR功能的库,可以通过摄像头实时检测特定标记。
  • THREEx.AR:辅助库,简化了Three.js和JSARToolkit的集成,为设置标记检测和3D对象显示提供了现成的功能。

3. 在应用中设置AR空间

  • 使用Three.js创建3D场景:利用Three.js创建3D场景,用于渲染产品模型。
  • 摄像头与渲染器设置:设置摄像头视图以便在真实物体上渲染AR元素,并将渲染器集成到应用屏幕上。
  • 照明与效果设置:添加环境光和点光源以照亮产品,增强AR体验的真实感。

    var scene, camera, renderer;
    scene = new THREE.Scene();
    camera = new THREE.Camera();
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

4. 为产品显示集成标记检测

  • 标记源设置:初始化arToolkitSource以从设备摄像头获取视频输入,从而实现实时标记检测。
  • 标记上下文设置:使用arToolkitContext处理标记数据并将其与3D产品预览集成,确保正确的对齐和比例。

    arToolkitSource = new THREEx.ArToolkitSource({ sourceType: 'webcam' });
    arToolkitContext = new THREEx.ArToolkitContext({
       cameraParametersUrl: 'data/camera_para.dat',
       detectionMode: 'mono'
    });

5. 将3D模型放置在标记上

  • 初始化标记:使用Hiro标记或自定义标记作为锚点。当应用检测到标记时,它会触发显示3D模型(例如客户感兴趣的产品)。
  • 加载产品模型:使用Three.js的TextureLoaderGLTFLoader加载产品模型(如家具、饰品)。通过纹理自定义模型外观,并根据产品的实际尺寸调整比例。

    let geometry = new THREE.SphereGeometry(1, 32, 32);
    let loader = new THREE.TextureLoader();
    let texture = loader.load('images/product-texture.jpg');
    let material = new THREE.MeshLambertMaterial({ map: texture });
    let mesh = new THREE.Mesh(geometry, material);
    markerRoot.add(mesh);

6. 与AR产品的交互

  • 旋转与缩放:添加交互选项,使用户可以旋转、缩放产品,以从不同角度查看细节。
  • 动态标记识别:启用多个产品的动态标记识别,允许用户通过切换不同标记来查看不同商品。
  • 自定义选项:允许用户在AR预览中更改产品的颜色或样式,例如选择家具的面料颜色或饰面。

7. 将AR无缝集成到应用流程中

  • AR模式触发:在每个产品页面上添加“AR预览”按钮,点击后切换到AR模式,启动摄像头并开始标记识别。
  • 从AR直接添加到购物车:在AR预览中直接集成“添加到购物车”功能,方便用户在预览后立即购买。
  • 特殊优惠的推送通知:使用通知鼓励用户尝试AR预览,以查看打折商品或新商品的独特AR体验。

8. AR优化的附加提示

  • 优化模型质量:保持模型轻量化以缩短加载时间,同时保留必要的细节。
  • 调整照明效果:应用与实际照明相匹配的AR照明,使产品看起来更加自然。
  • 最小化电量消耗:在不需要时卸载AR组件,避免设备的电池过度消耗。

9. 测试与部署

  • 跨设备测试:确保在Android和iOS设备上兼容,并测试摄像头访问权限。
  • 用户指导:为首次使用的用户提供简短的教程,解释如何使用AR功能、找到标记以及如何与产品互动。

10. AR在电商中的实际优势

  • 提升产品理解:通过提前查看产品的尺寸和外观,客户在选择商品时更有信心。
  • 减少退货率:在购买前看到真实的产品后,客户的满意度更高,退货率更低。
  • 提高购买率:AR预览提供的沉浸式体验有助于促进客户的购买决策,从而提升转化率。

通过在您的电商应用中集成AR产品预览,您不仅可以使应用脱颖而出,还可以为客户提供更具吸引力和满意度的购物体验。

full source code

<!DOCTYPE html>
<head>
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <title>Hello, world!</title>
    <!-- include three.js library -->
    <script src='js/three.js'></script>
    <!-- include jsartookit -->
    <script src="jsartoolkit5/artoolkit.min.js"></script>
    <script src="jsartoolkit5/artoolkit.api.js"></script>
    <!-- include threex.artoolkit -->
    <script src="threex/threex-artoolkitsource.js"></script>
    <script src="threex/threex-artoolkitcontext.js"></script>
    <script src="threex/threex-arbasecontrols.js"></script>
    <script src="threex/threex-armarkercontrols.js"></script>
</head>

<body style='margin : 0px; overflow: hidden; font-family: Monospace;'>

<!-- 
  Example created by Lee Stemkoski: https://github.com/stemkoski
  Based on the AR.js library and examples created by Jerome Etienne: https://github.com/jeromeetienne/AR.js/
-->

<script>

var scene, camera, renderer, clock, deltaTime, totalTime;

var arToolkitSource, arToolkitContext;

var markerRoot1;

var mesh1;

initialize();
animate();

function initialize()
{
    scene = new THREE.Scene();

    let ambientLight = new THREE.AmbientLight( 0xcccccc, 0.5 );
    scene.add( ambientLight );

    camera = new THREE.Camera();
    scene.add(camera);

    renderer = new THREE.WebGLRenderer({
        antialias : true,
        alpha: true
    });
    renderer.setClearColor(new THREE.Color('lightgrey'), 0)
    renderer.setSize( 640, 480 );
    renderer.domElement.style.position = 'absolute'
    renderer.domElement.style.top = '0px'
    renderer.domElement.style.left = '0px'
    document.body.appendChild( renderer.domElement );

    clock = new THREE.Clock();
    deltaTime = 0;
    totalTime = 0;

    ////////////////////////////////////////////////////////////
    // setup arToolkitSource
    ////////////////////////////////////////////////////////////

    arToolkitSource = new THREEx.ArToolkitSource({
        sourceType : 'webcam',
    });

    function onResize()
    {
        arToolkitSource.onResize()  
        arToolkitSource.copySizeTo(renderer.domElement) 
        if ( arToolkitContext.arController !== null )
        {
            arToolkitSource.copySizeTo(arToolkitContext.arController.canvas)    
        }   
    }

    arToolkitSource.init(function onReady(){
        onResize()
    });

    // handle resize event
    window.addEventListener('resize', function(){
        onResize()
    });

    ////////////////////////////////////////////////////////////
    // setup arToolkitContext
    ////////////////////////////////////////////////////////////    

    // create atToolkitContext
    arToolkitContext = new THREEx.ArToolkitContext({
        cameraParametersUrl: 'data/camera_para.dat',
        detectionMode: 'mono'
    });

    // copy projection matrix to camera when initialization complete
    arToolkitContext.init( function onCompleted(){
        camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
    });

    ////////////////////////////////////////////////////////////
    // setup markerRoots
    ////////////////////////////////////////////////////////////

    // build markerControls
    markerRoot1 = new THREE.Group();
    scene.add(markerRoot1);
    let markerControls1 = new THREEx.ArMarkerControls(arToolkitContext, markerRoot1, {
        type: 'pattern', patternUrl: "data/hiro.patt",
    })

    let geometry1 = new THREE.SphereGeometry(1, 32,32);

    let loader = new THREE.TextureLoader();
    let texture = loader.load( 'images/earth-sphere.jpg', render );
    let material1 = new THREE.MeshLambertMaterial( { map: texture, opacity: 0.8 } );

    mesh1 = new THREE.Mesh( geometry1, material1 );
    mesh1.position.y = 1;

    markerRoot1.add( mesh1 );

    let pointLight = new THREE.PointLight( 0xffffff, 1, 100 );
    pointLight.position.set(0.5,3,2);
    // create a mesh to help visualize the position of the light
    pointLight.add( 
        new THREE.Mesh( 
            new THREE.SphereBufferGeometry( 0.05, 16,8 ), 
            new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0.8 }) 
        ) 
    );
    markerRoot1.add( pointLight );
}

function update()
{
    if ( markerRoot1.visible )
        mesh1.rotation.y += 0.01;
    // update artoolkit on every frame
    if ( arToolkitSource.ready !== false )
        arToolkitContext.update( arToolkitSource.domElement );
}

function render()
{
    renderer.render( scene, camera );
}

function animate()
{
    requestAnimationFrame(animate);
    deltaTime = clock.getDelta();
    totalTime += deltaTime;
    update();
    render();
}

</script>

</body>
</html>

Articles

Our Products


Articles

Our Products


Get in Touch with us

Speak to Us or Whatsapp(+66) 83001 0222

Chat with Us on LINEiiitum1984

Our HeadquartersChanthaburi, Thailand