在WebVR/WebXR中,使用three.js锁定摄像机位置的最佳方法是什么?
用户仍然需要能够旋转他们的头部,但是他们的头部移动不应该改变相机的位置(x,y,z)。
发布于 2021-04-29 19:51:31
参见简单解决方案的更新
这种能力是错误的,而且是明确的从WebXR规范中删除。
他们对位置数据示例的“琐碎”剥离是在他们的360-photos.html示例中,是skyboxMaterial类的顶点着色器被他们复杂的渲染器所吞噬。
具体而言:
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视图时执行以下操作:
//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:您将希望优化变量的使用,以避免不必要的分配。我把它们留在这里是为了更好地想象每一种计算所使用的内容。
发布于 2020-01-02 18:20:42
您可以将相机的位置xyz值设置为零在每一个帧,以锁定它的位置。然而,请注意,这是不舒服的许多用户时,看到实际的3D场景。它基本上只适用于180/360度视频观看者,在这种情况下,源素材不支持空间移动,但即使在这种情况下,如果有任何浮动的UI元素进行交互,也应该使用头部位置。
https://stackoverflow.com/questions/59562580
复制相似问题