I am seeking to transform an elongated image into a two-dimensional circle using WebGL. This process will involve intentional distortion of the image

Trying to figure out how to take a high-resolution image and wrap it into a circle has been a challenge. It's like bending a steel bar until it forms a perfect circle with both ends touching.

I've been grappling with threejs for the past 8 hours, attempting to apply the image as a texture on a circle geometry. However, I'm stuck on how to apply the texture to a long mesh and then properly warp that mesh. The transformation doesn't need to be animated, but we essentially have a 360 panoramic image that needs to be "flattened" into a top-down view.

Instead of sharing my code (since it's not drastically different), I've been experimenting with this tutorial:

At this point, I believe I grasp the general concept.

I've also tried using just canvas to divide the image into strips and warp each strip individually, but this method was incredibly slow and I couldn't get it to function properly either!

Any help or suggestions would be greatly appreciated.

Answer №1

Here's an alternative shader version for you to check out: Shadertoy - Circle Distortion

Below is the code snippet:

#define dPI 6.28318530718   // 2*PI
#define sR 0.3              // small radius
#define bR 1.0              // big radius

void main(void)
{
// calculate coordinates on the canvas
    vec2 uv = gl_FragCoord.xy / iResolution.xy*2.-vec2(1.);
    uv.x *= iResolution.x/iResolution.y;

// check if it's within the ring area
    float k = 0.0;
    float d = length(uv);
    if(d>sR && d<bR)
        k = 1.0;

// calculate the texture UV
    vec2 tUV = vec2(0.0,0.0);

    // Determine x coordinate for the texture UV
    tUV.x = atan(uv.y/uv.x)/dPI+0.5*(1.-clamp(uv.x,0.0,1.0)/uv.x);

    // Calculate y coordinate for the texture UV
    tUV.y = (d-sR)/(bR-sR);

// output the pixel
    vec3 col = texture2D(iChannel0, tUV).rgb;
    gl_FragColor = vec4(col*k,1.);
}

You can draw a rectangle on the canvas and apply this shader code to see the effect.

I trust this information proves beneficial to you.

Answer №2

Here is a function utilizing the canvas's context2d to achieve the desired outcome.

The concept involves iterating around the circle with a small angular increment and drawing a thin section of 'texture' along the radius of the circle.

To optimize performance, a potential approach is to manually calculate the transformation required for a single setTransform operation instead of multiple steps.
The optimal step count is determined by step = atan(1, radius)
(visualized: moving one unit upward when at a distance of radius from the center yields tan = 1/radius => step angle = atan(1, radius).)

Find the fiddle link here: http://jsfiddle.net/gamealchemist/hto1s6fy/

Here's a brief example featuring a cloudy landscape:

// draw the part of img defined by the rect (startX, startY, endX, endY) inside 
// the circle of center (cx,cy) between radius (innerRadius -> outerRadius) 
// - no check performed -
function drawRectInCircle(img, cx, cy, innerRadius, outerRadius, startX, startY, endX, endY) {
    var angle = 0;

    var step = 1 * Math.atan2(1, outerRadius);
    var limit = 2 * Math.PI;

    ctx.save();
    ctx.translate(cx, cy);
    while (angle < limit) {
        ctx.save();
        ctx.rotate(angle);
        ctx.translate(innerRadius, 0);
        ctx.rotate(-Math.PI / 2);
        var ratio = angle / limit;
        var x = startX + ratio * (endX - startX);
        ctx.drawImage(img, x, startY, 1, (endY - startY), 0, 0, 1, (outerRadius - innerRadius));
        ctx.restore();
        angle += step;
    }
    ctx.restore();
}

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

React state variable resetting to its initial value unexpectedly

I have encountered a puzzling issue with the React useState hook. After setting the state of a value, it gets reset to null unexpectedly. The main problem lies in the click event that should update the startDate value to the current date and time. This cli ...

Sending numerous array values from datatables

I am currently working with datatables that allow for multiple selections. When I select 3 rows from top to bottom (as shown in this picture), the console.log returns this specific value for each row selected. The value that needs to be passed to the next ...

Incorporate React Components into a traditional HTML, CSS, and JavaScript project

Can I incorporate a React Native Component (https://www.npmjs.com/package/react-native-gifted-chat) into my vanilla JavaScript project? Is it feasible to embed a React Native component within a vanilla JavaScript project? If yes, then what is the process ...

I am encountering difficulty in printing multiple documents from FireStore

I am facing an issue where I can successfully retrieve and print all documents from a Firestore collection one by one using console.log(). However, when attempting to display these documents on the screen, only the most recent document is showing up. Here ...

Protect database entries from cross-site scripting attacks

I have a project in progress where I am developing an application that extracts text from tweets, saves it to the database, and then presents it on the browser. I am currently concerned about potential security risks if the text contains PHP or HTML tags. ...

the reason behind the peculiar behavior of angularjs ng-include

I am attempting to utilize an ng-template to iterate through my args in order to create an indented menu content. Unfortunately, I have encountered issues with ng-include not working as expected. I have tried adding a quote but it still does not work. For ...

The specified instant cannot be located in 'moment' while attempting to import {Moment} from 'moment' module

Struggling in a reactJS project with typescript to bring in moment alongside the type Moment Attempted using import moment, { Moment } from 'moment' This approach triggers ESLint warnings: ESLint: Moment not found in 'moment'(import/n ...

rotation of mesh without moving geometry or changing pivot point (THREEJS)

Currently, I am trying to implement a "local rotation" on a mesh in THREEJS. My goal is to have the rotation centered around the geometry center, but instead, it is centered around the geometry "origin" (0, 0, 0). Here's the situation: It is n ...

Populating a ListBox without the need to constantly scroll upwards

I'm currently facing an issue with a ListBox that displays online users fetched from a MySQL database. Every second, the ListBox is updated with new users. The problem arises when adding an item to the ListBox causes it to scroll up, which I want to a ...

What is the process for integrating three.js code manually into an iframe?

I recently posted a question on Stack Overflow inquiring about how to input code into an iframe without using a file or URL. While I was successful with simple cases like <h1>Hello World</h1>, my ultimate goal is to integrate three.js into thes ...

Having difficulty in dynamically loading an image from an API's URL in Angular

In the title, I mentioned that I am utilizing a free API to display cryptocurrency news for my practice project. Everything seems to be working fine except for displaying the images in card view. I will share my code here, so if you have any suggestions on ...

What are the steps to store and access state variables using session storage in a React application?

I am currently utilizing React version 18.2.0. In my application, I have a component called BodyComponent that stores the data retrieved from an API call in its state as results, along with some filter information in filters. The BodyComponent fetches the ...

Attempting to send JSX as a prop value

IMPORTANT UPDATE: Good news - the code is actually functioning correctly! The issue was caused by a header element obstructing the content, leading to confusion. Apologies for any misunderstandings! I am attempting to pass a simple <p> JSX tag as a ...

Angular app sends a JSON request and receives no data in response

It seems like Angular may be loading the page before fully receiving all the information from JSONP. There are times when refreshing the page multiple times eventually displays the information, but it's not consistent. Interestingly, the code used on ...

Using jQuery, you can create and add an element to the page when a user clicks

Currently, my webpage contains numerous anchor tags that link to various video files, along with a single div element: <a href="http://www.example.com/example-1.mkv" class="video">1</a> <a href="http://www.example.com/example-2.mkv" class=" ...

How can I update the color scheme in styled components based on the active state of the component?

I'm currently working on a react accordion component that requires changing styles based on the active and inactive states. I have successfully set the state and added two props for color and active color. The goal is to change colors when the user cl ...

Three-dimensional.js and components of the design

Looking for advice on how to manipulate individual parts of a 3D model in Three.js. My model is made up of various components that I need to control separately. Any tips or suggestions would be greatly appreciated. Thank you! ...

There seems to be an issue with the .html() function in one of my

I'm currently in the process of transitioning my code to Angular and I could use some assistance with creating a directive. Here's what I'm trying to convert: jQuery(document).ready(function ($) { "use strict"; $('#cool-naviga ...

Experience seamless navigation with Highstock's fluid panning feature

I'm attempting to achieve seamless panning on a basic highstock chart by clicking and dragging within the plot area. Interestingly, I have found that this works flawlessly when my data is not based on timestamps: data: [-25.1,-23.8,-19.9,-19.1,-19.1 ...

Enhance Vaadin 14: Automatically adjust TextArea size when window is resized

Using Vaadin 14.1.19 in a project called "My Starter Project," I attempted to create a TextArea that supports multiple lines. Initially, everything seemed fine, but upon resizing the TextArea, it failed to adjust the number of visible lines. Here is the co ...