Tips for creating a 360 x 235 degree FOV image using three.js

My camera captures round images with a 235-degree field of view, like this one: https://i.sstatic.net/qNfrX.jpg

I am familiar with threejs and have successfully rendered 360x360 images as equirectangular projections. However, I want to use threejs to render my round image within a sphere. I have reviewed some examples (here and here) that point me in the right direction, but I need help putting all the pieces together.

The example with the eyeball gets me close, but copying its code results in my image appearing twice on the sphere. I attempted creating a partial sphere by adjusting SphereGeometry's constructor, but encountered issues with texture mapping.

My main question is how to achieve this, specifically regarding:

  1. How to control the texture painting onto the mesh (to apply it once and only where needed)

  2. Understanding UV mapping and determining the correct UVs for my image to prevent it from being displayed on the back of the sphere

Answer №1

After delving into UVs and conducting various experiments, I have come up with a refined code snippet that I am beginning to grasp. Here is the relevant portion of the working code:

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;//Initially calculated as 235/360, but adjusted through trial and error for reduced fisheye distortion

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

    var uvs = faceVertexUvs[ i ];
    var face = geometry.faces[ i ];
    //y represents top to bottom
    //z denotes in-out direction
    //x indicates side-to-side orientation; positive x signifies front, while negative denotes back

    for ( var j = 0; j < 3; j ++ ) {
        var fvNj = face.vertexNormals[j];
        var yaw = Math.atan2(fvNj.z, fvNj.x)/(Math.PI); //rotation around axis, ranging from -1 to 1
        var pitch = Math.asin(fvNj.y)/Math.PI; //elevation angle, ranges from -0.5 to 0.5
        pitch = pitch * -1 + 0.5;//invert and normalize to range from zero to one
        pitch *= imgWidth;

        if(pitch < 0.5){
            //considering 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);//range from -1 to 1
            var y = Math.sin(yaw * Math.PI);//range from -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 );

Answer №2

It's important to note that the source image is incomplete, only covering 360x235. To fully cover the 360x360 sphere, it needs to be "extended".

While I also have a camera producing similar images, I haven't found a complete JavaScript solution for handling these raw images yet. That's why I turned to an alternative method: pre-converting the image.

I rely on ffmpeg for this task.

By using the following command line:

ffmpeg -i qNfrX.jpg -vf v360=fisheye:e:ih_fov=235:iv_fov=235 test.jpg 

You'll obtain this resulting image:

https://i.sstatic.net/DMKqb.png

If you instead use this command line:

ffmpeg -i qNfrX.jpg -vf v360=fisheye:e:ih_fov=235:iv_fov=235:pitch=-90 test2.jpg

Adjusting the pitch angle will give you this new image:

https://i.sstatic.net/Ic4ET.png

You can then utilize one of these equirectangular images to wrap around a sphere, but I cannot offer direct assistance with this process. This resource may be helpful, although I'm still exploring its capabilities:

https://github.com/legokichi/three-fisheye

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What causes images to be omitted from a PDF file when using mywindow.print()?

Here is the scenario I am dealing with: On a particular webpage, there is a print button. The page contains various information, including receipts. When the user clicks on "print", I want only the receipts to be printed: https://i.sstatic.net/WobKK.png ...

Transform an array containing arrays into an array of individual objects

After spending a considerable amount of time trying various solutions, I am still unable to achieve the desired result. The issue lies in getting an array of objects from service calls and organizing them into a single array for data loading purposes. The ...

Live AJAX inquiries in progress

Is there a way to track the number of active AJAX requests in jQuery, Mootools, or another library similar to Prototype's Ajax.activeRequestCount? I am looking for a method that can be used across different libraries or directly through XMLHttpRequest ...

Having trouble with NextJS when trying to add an item to an element and render it in a Tailwind select

Struggling with displaying dynamic values in a select box using NextJS After fetching data from an API endpoint, I aim to populate a select box. However, my goal is to prepend a new element to the 'teams' array and ensure it appears first upon p ...

Zingchart encounters issues when attempting to plot a CSV file containing over 10 columns

Situation: I want to create a Zingchart graph from a CSV file containing 37 columns. The header in the CSV file will be used as the legend for the graph. Issue: When I define less than 10 elements in the header (including the X-axis name), everything wo ...

Update the second dropdown automatically based on the selection in the first dropdown menu

I need assistance with creating two dropdown menus that are linked, so when an option is selected in the first menu, it automatically changes the options available in the second menu. Both menus should be visible at all times. I have set up a fiddle to pr ...

When res.write is called before res.send, an error occurs

I'm struggling to figure out why I am getting an error with the following code. app.get("/", (req, res) => { res.write("Hello"); res.send(" World!"); }) // Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers afte ...

Storing knockout view model data in a database and fetching it back

I am currently working on a web form that utilizes knockout, and I need to add a new feature that allows users to save the form as a draft in the database. Later on, they should be able to load it again to make modifications or submit it. Is there a built ...

Tips for applying multiple colors to text within an option tag

I am currently struggling with adding a drop-down list to my form that displays 2 values, with the second value having a different text color (light gray). After some research, it seems like I need to use JavaScript for this customization. However, as I am ...

webpack is encountering difficulty resolving the node_modules material-icons directory

Encountering an Error ERROR in ./node_modules/material-icons/iconfont/material-icons.css (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[5].use[2]!./node_mod ...

Transform a date string into a date entity

Collecting the user's input for the date and saving it as a string variable. The format of the value is Fri Aug 27 2021 00:00:00 GMT+0530 (India Standard Time) My goal is to convert this string back into a new Date() object in order to make additiona ...

Issue with react-router-dom: <Route> elements are strictly meant for configuring the router and should not be rendered on their own

I've been grappling with this issue for quite some time now, but none of my attempts have succeeded and I keep encountering the same error: < Route> elements are for router configuration only and should not be rendered Here's the snippet ...

When scrolling back to the top of the page, the data-spy feature does not re-highlight the "Home" anchor

After experimenting with Data-spy to change the active anchor while scrolling, I encountered an issue. Upon scrolling back up to the top of the page from the about section, the "Home" anchor failed to re-activate. How can this be fixed? I attempted to rem ...

Discover the method for concealing a button using ng-show and ng-hide directives

<div> <div class="pull-right"> <button type="button" data-ng-click="editFigure()" id="EditFigure">Edit Figure </button> <button type="button" data-ng-click="figurePreview()" id="PreviewFigure">Figure Previ ...

Guide on how to verify if a component with a specific name is registered within the Composition API of Vue 3

My current situation involves a template that loads dynamic components based on their names: <template> <div> <div> <div> <component :is="getFormRenderer" &g ...

CORS problem in Chrome when using AngularJS and Symfony 3

I've been dealing with a bug on my backend and frontend for the past week. I created a REST API (php/symfony) to manage books and authors. Initially, I had trouble with cross-origin requests on DELETE, which has been resolved. However, now I am facin ...

What is the process for editing a JSON file and preserving the modifications?

I have a JSON file with a key (food_image) and I am looking to dynamically assign the index value in a loop to it, such as food_image0, food_image1 ... food_image{loop index}. After that, I aim to save this modified JSON file under a new name. All values ...

Protractor: What is the best way to retrieve the baseUrl from the command line input?

How can I retrieve the baseUrl that was passed through the command line in Protractor? For example: protractor conf.js --baseUrl=http://myawesomesite.com I attempted to use browser.baseUrl to access the baseUrl set in my conf.js file, but it does not see ...

Node.js: Attempting to arrange ISO dates based on their time span

I am currently working on creating a line chart using the chart.js library. In order to do this, I have an array that contains ISO dates and my goal is to determine which ISO dates belong to the same hour and day. This information will then be used to gene ...

Error message encountered when attempting to rotate an object in three.js: "Object is undefined"

Experiencing an "Undefined Object" error while attempting to rotate an object using three.js. Here is a snippet of the code in question: var object; function render() { renderer.render(scene, camera); } function animate() { object.rotation.x + ...