我对threejs有一定的经验,并已使用它来正确渲染以等边矩形投影形式存储的360x360图像-网络上有很多示例可以做到这一点。
但是我想使用threejs渲染我的圆形图像,可能作为球体内部的纹理。我看了一些示例(例如https://threejs.org/examples/#webgl_panorama_dualfisheye和Mapping image onto a sphere in Three.js),这些示例似乎为我指明了正确的方向,但我想我只是对threejs如何工作分解的认识不足在一起。
第二个(眼球)似乎使我靠近,但是遵循眼球代码恰好意味着我的图像显示了两次(我想这是有道理的,因为我的图像是正方形的,纹理必须覆盖整个球体。
因此,我尝试使用SphereGeometry的长版本构造函数制作部分球体(360 * 235),但是更改phi会给我带来看起来像橙色缺失切片的东西。改变theta可以给我正确的形状,但是纹理不能正确放置在上面。
所以我的总体问题是如何进行这项工作,但我认为困扰我的主要因素是:
由什么控制如何将纹理绘制到网格上? (这样我就可以只一次绘制纹理,并且只能绘制到我需要的球体部分上)
我看到设置UV是必要的(geometry.faceVertexUvs?),我读了https://en.wikipedia.org/wiki/UV_mapping,所以我有点理解这是什么意思,但我不知道从哪里着手。纠正我的图像的紫外线(仍然像数字1一样,如何阻止它显示在球体的“背面”)
答案 0 :(得分:0)
好的,所以我继续阅读了一些关于UV的知识,并做了很多实验。这是我主要理解的工作代码(仅是相关位):
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 );
答案 1 :(得分:0)
如您所知,您的源图片不完整,因为它覆盖了 360x235。您必须“扩展”它以覆盖整个 360x360 球体。
我也有一台可以创建相同图像的相机;到目前为止,我无法找到一个完整的 javascript 源代码来获取这些原始图像、转换为正确的格式并在球体上变形,所以我不得不找到另一个解决方案:提前转换图像。
为此我使用 ffmpeg。
使用此命令行:
ffmpeg -i C:\Users\luca\Downloads\qNfrX.jpg -vf v360=fisheye:e:ih_fov=235:iv_fov=235 test.jpg
你得到这张图片:
改用这个命令行:
ffmpeg -i C:\Users\luca\Downloads\qNfrX.jpg -vf v360=fisheye:e:ih_fov=235:iv_fov=235:pitch=-90 test2.jpg
使用不同的俯仰角,你会得到这个图像:
然后您可以使用一个这些等距柱状图来包裹一个球体,但在这方面我无法直接提供帮助;可能这个来源可以提供帮助,但我仍在研究它: