如何使用threejs渲染360 x 235度FOV图像?

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

我有一个摄像头拍摄声称代表235度视野的圆形图像,如下所示:enter image description here

我有三个经验,并用它来正确渲染360x360图像存储为equirectangular投影 - 网上有大量的样本来做到这一点。

但我想使用threejs渲染我的圆形图像,可能是一个球体内的纹理。我看了一些例子(例如https://threejs.org/examples/#webgl_panorama_dualfisheyeMapping image onto a sphere in Three.js),这些例子似乎指向了我正确的方向,但我想我还不太了解trijs如何将各个部分放在一起。

第二个(眼球)似乎让我接近,但遵循眼球代码确切意味着我的图像显示两次(我想这是有道理的,因为我的图像是方形的,纹理必须覆盖整个球体。

所以我尝试使用长版SphereGeometry的构造函数来制作一个部分球体(360 * 235)但是改变phi给了我一个看起来像橙色缺失切片的东西。改变theta给了我正确的形状,但纹理没有正确地放置它。

所以我的整体问题是如何使这项工作,但我认为主要的事情是:

  1. 什么控制纹理如何绘制到网格上? (这样我只能在一次上绘制纹理,而且只能在我需要的球体部分上绘制)
  2. 我看到设置UV是必要的(geometry.faceVertexUvs?),我读了https://en.wikipedia.org/wiki/UV_mapping所以我有点理解这意味着什么,但我不知道从哪里开始为我的图像找出正确的UV(仍然,像数字1,如何阻止它显示在球体的“背面”)
javascript three.js texture-mapping
1个回答
0
投票

好的,所以我去了解更多有关紫外线的信息并进行了大量的实验。这是工作代码(只是相关位),我大多理解:

var geometry = new THREE.SphereGeometry( 30, 256, 128, 0, Math.PI * 2, 0, Math.PI );
geometry.scale( - 1, 1, 1 );//inside out

var imgWidth = 0.8;//I thought this should be 235/360, but used trial and error for less fisheye distortion

var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
for ( i = 0; i < faceVertexUvs.length; i ++ ) {

    var uvs = faceVertexUvs[ i ];
    var face = geometry.faces[ i ];
    //y is top to bottom
    //z is in-out?
    //x is side-side? positive x is front, negative is back

    for ( var j = 0; j < 3; j ++ ) {
        var fvNj = face.vertexNormals[j];
        var yaw = Math.atan2(fvNj.z, fvNj.x)/(Math.PI); //around, -1 to 1
        var pitch = Math.asin(fvNj.y)/Math.PI; //height, -0.5 to 0.5
        pitch = pitch * -1 + 0.5;//flip and make zero to one
        pitch *= imgWidth;

        if(pitch < 0.5){
            //how to do fisheye correction??
            //var correction = (fvNj.x == 0 && fvNj.z == 0) ? 1 : (Math.acos(fvNj.y) / Math.sqrt(fvNj.x * fvNj.x + fvNj.z * fvNj.z)) * (2 / Math.PI);
            var x = Math.cos(yaw * Math.PI);// -1 to 1
            var y = Math.sin(yaw * Math.PI);// -1 to 1
            var u = 0.5 + x*pitch;
            var v = 0.5 + y*pitch;  

            uvs[ j ].x = u;
            uvs[ j ].y = v;
        }else{
            uvs[j].x = 0;
            uvs[j].y = 0;
        }
    }
}

mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
© www.soinside.com 2019 - 2024. All rights reserved.