首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锁定相机在WebVR / WebXR中的位置

锁定相机在WebVR / WebXR中的位置
EN

Stack Overflow用户
提问于 2020-01-02 11:29:17
回答 2查看 545关注 0票数 2

在WebVR/WebXR中,使用three.js锁定摄像机位置的最佳方法是什么?

用户仍然需要能够旋转他们的头部,但是他们的头部移动不应该改变相机的位置(x,y,z)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-29 19:51:31

参见简单解决方案的更新

这种能力是错误的,而且是明确的从WebXR规范中删除

他们对位置数据示例的“琐碎”剥离是在他们的360-photos.html示例中,是skyboxMaterial类的顶点着色器被他们复杂的渲染器所吞噬。

具体而言:

代码语言:javascript
复制
get vertexSource() {
    return `
    uniform int EYE_INDEX;
    uniform vec4 texCoordScaleOffset[2];
    attribute vec3 POSITION;
    attribute vec2 TEXCOORD_0;
    varying vec2 vTexCoord;

    vec4 vertex_main(mat4 proj, mat4 view, mat4 model) {
      vec4 scaleOffset = texCoordScaleOffset[EYE_INDEX];
      vTexCoord = (TEXCOORD_0 * scaleOffset.xy) + scaleOffset.zw;
      // Drop the translation portion of the view matrix
      view[3].xyz = vec3(0.0, 0.0, 0.0);
      vec4 out_vec = proj * view * model * vec4(POSITION, 1.0);

      // Returning the W component for both Z and W forces the geometry depth to
      // the far plane. When combined with a depth func of LEQUAL this makes the
      // sky write to any depth fragment that has not been written to yet.
      return out_vec.xyww;
    }`;
  }

又好又小..。/s

希望这会有所帮助,我目前正在处理相同的问题,如果/当我克服了这个问题,我将更新这个答案。

更新2:承诺,而不是修改每个着色器,以支持这一能力。在处理每个xrPose视图时执行以下操作:

代码语言:javascript
复制
    //NOTE: Uses the gl-matrix.js library, albeit slightly modified
    //to add vec3.multiplyBy. Which is used to multiply a vector
    //by a single value.
    
    let dist;
    let poseMaxDist = 0.4; //0.4M or 1.2ft
    
    let calculatedViewPos;
    let viewRotAsQuat;
    let vector;

    let origin = vec3.create();
    let framePose = vec3.create();
    let poseToBounds = vec3.create();
    let elasticTransformMatrix = mat4.create();

    let view = pose.views[viewIdx];
    //If positionDisabled, negate headset position changes, while maintaining
    //eye offset which allows for limited translation as users head does
    //move laterally when looking around.
    if(_positionDisabled){
        //DOMPoint to vec3 easier calculations.
        framePose = vec3.fromValues(
            pose.transform.position.x,
            pose.transform.position.y,
            pose.transform.position.z);

        //Distance from the origin
        dist = vec3.distance(origin, framePose);

        if(dist >= poseMaxDist){
            //calculation 'origin' == A
            //framePose == B
            let AB = vec3.create();
            let AC = vec3.create();
            let C = vec3.create();
            let CB = vec3.create();

            //Vector from origin to pose
            vec3.subtract(AB, framePose, origin);

            //Unit vector from origin to pose
            vec3.normalize(AB, AB);

            //Max allowed vector from origin to pose
            vec3.multiplyBy(AC, AB, poseMaxDist);

            //Limit point from origin to pose using max allowed vector  
            vec3.add(C, origin, AC);
      
            //vector from pose to limit point, use to shift view
            vec3.subtract(poseToBounds, C, framePose);

            //vector from limit point to pose, use to shift origin
            vec3.subtract(CB, framePose, C);

            //Shift calculation 'origin'
            vec3.add(origin, origin, CB);

            //adjust view matrix using the caluclated origin,
            //and the vector from the pose to the limit point.
            calculatedViewPos = vec4.fromValues(
                view.transform.position.x - origin[0] + poseToBounds[0],
                view.transform.position.y - origin[1] + poseToBounds[1],
                view.transform.position.z - origin[2] + poseToBounds[2],
                view.transform.position.w);

        }else{
            //adjust view matrix using the caluclated origin
            calculatedViewPos = vec4.fromValues(
                view.transform.position.x - origin[0],
                view.transform.position.y - origin[1],
                view.transform.position.z - origin[2],
                view.transform.position.w);
        }

        //Changing the DOMPoint to a quat for easier matrix calculation.
        viewRotAsQuat = quat.fromValues(
            view.transform.orientation.x,
            view.transform.orientation.y,
            view.transform.orientation.z,
            view.transform.orientation.w
        );

        mat4.fromRotationTranslation(elasticTransformMatrix, viewRotAsQuat, calculatedViewPos)

        mat4.invert(elasticTransformMatrix, elasticTransformMatrix);
            
        mat4.multiply(modelViewMatrix, elasticTransformMatrix, entity.transformMatrix);

    }else{
        mat4.multiply(modelViewMatrix, view.transform.inverse.matrix, entity.transformMatrix);
    }

FYI:您将希望优化变量的使用,以避免不必要的分配。我把它们留在这里是为了更好地想象每一种计算所使用的内容。

票数 1
EN

Stack Overflow用户

发布于 2020-01-02 18:20:42

您可以将相机的位置xyz值设置为零在每一个帧,以锁定它的位置。然而,请注意,这是不舒服的许多用户时,看到实际的3D场景。它基本上只适用于180/360度视频观看者,在这种情况下,源素材不支持空间移动,但即使在这种情况下,如果有任何浮动的UI元素进行交互,也应该使用头部位置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59562580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档