Utilizing a vertex shader to rotate a geometry within threejs

Having trouble rotating a box using vertex shader, it's getting sheared but I can't pinpoint the issue. Can someone help me troubleshoot? Check out the code snippet below:

uniform float delta;
void main()
{
    vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
      gl_Position = (projectionMatrix * modelViewPosition);
      float new_x = gl_Position.x*cos(delta) - gl_Position.y*sin(delta);
      float new_y = gl_Position.y*cos(delta) + gl_Position.x*sin(delta);
      gl_Position.x = new_x;
      gl_Position.y = new_y;
}

https://jsfiddle.net/co4vbhye/

Answer №1

When dealing with a rectangular viewport, the projection matrix comes into play to make necessary adjustments. The final transformation required for vertex coordinates involves applying the projection matrix:

clip_position = projection * view * model * position

To introduce rotation to the vertex coordinate position, you'll first perform the rotation calculation and then apply the view matrix followed by the projection matrix:

uniform float delta;
void main()
{
    vec3 p = position.xyz;
    float new_x = p.x*cos(delta) - p.y*sin(delta);
    float new_y = p.y*cos(delta) + p.x*sin(delta);

    gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}

It's important to ensure that the aspect ratio defined in the projection matrix (PerspectiveCamera) matches the aspect ratio of the viewport (canvas):

Choose one of the following options:

//RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

//CAMERA
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);

or

//RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);

//CAMERA
camera = new THREE.PerspectiveCamera(75, CANVAS_WIDTH / CANVAS_HEIGHT, 0.01, 10000);

Take a look at the provided example:

var renderer,
    scene,
    camera,
    container = document.getElementById('Canvas_3');

//RENDERER
renderer = new THREE.WebGLRenderer();
//renderer.setClearColor(0xffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

//CAMERA
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);

//SCENE
scene = new THREE.Scene();

var customUniforms = {
    delta: {
        value: 0
    }
};
var material = new THREE.ShaderMaterial({
    uniforms: customUniforms,
    vertexShader: document.getElementById('vertexShader').textContent,
    fragmentShader: document.getElementById('fragmentShader').textContent
});

var geometry = new THREE.BoxBufferGeometry(1, 1, 1, 0, 0, 0);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.z = -5;
mesh.position.x = 0;
scene.add(mesh);

window.onresize = function() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
}

//RENDER LOOP
render();

var delta = 0;

function render() {

    delta += 0.006;
    if (delta > 1.57) delta = 0;

    mesh.material.uniforms.delta.value = delta;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
<div id="Canvas_3"></div>

<script type="x-shader/x-vertex" id="vertexShader">
uniform float delta;
void main()
{
    vec3 p = position.xyz;
    float new_x = p.x*cos(delta) - p.y*sin(delta);
    float new_y = p.y*cos(delta) + p.x*sin(delta);
    
    gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}
</script>

<script type="x-shader/x-fragment" id="fragmentShader">
uniform float delta;
void main() {
    gl_FragColor = vec4(delta, 0.0, 1.0-delta, 1.0);
}
</script>

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 is the best way to shorten a tweet that goes over 140 characters?

I have an algorithm for tweeting that eliminates @-mentions and will not post tweets under the following conditions: 1) if the question is different from the answer, 2) if the composed tweet exceeds 140 characters, and 3) if the tweet is potentially sensit ...

Struggling to make a click event work in aframe

Attempting to develop an inventory system for a game using the AFrame library has been quite challenging. I have a specific custom component in place that should make the item I am picking up invisible while making the in-hand item visible. However, for so ...

AJAX Showdown: Comparing jQuery's AJAX API to JavaScript's XHR

tl;dr: I have two different scripts that appear to be identical, but one works while the other does not. Why is this? Let me provide some context for this post. I am working on creating an image uploading form that utilizes AJAX requests to generate a dyn ...

Combining an array of intricate data models to create

Currently, my setup involves using Entity Framework 7 in conjunction with ASP.NET MVC 5. In my application, I have various forms that resemble the design showcased in this image. By clicking on the "new" button within these forms, a Bootstrap modal like t ...

Step-by-step guide on integrating a custom JS file into an Angular component

Trying to grasp Angular, I embarked on adding some JavaScript logic to one of my components from a separate JS file. While following advice from a similar query (How to add custom js file to angular component like css file), it seems I missed something cru ...

retrieving data from array elements

{ "success": true, "users": [ { "photo": { "id": "users/m1ul7palf4iqelyfhvyv", "secure_url": "https://res.cloudinary.com/dpbdw6lxh/image/upload/v1665251810 ...

Exporting JavaScript formatting in Netbeans is a breeze

Does anyone know how to preserve the formatting for JavaScript in Netbeans 8.1 when exporting? After clicking on the export button and expanding Formatting, I couldn't find any option specifically for JavaScript. I've thought about locating the ...

Submitting a form is disabled when there are multiple React form inputs

I have a simple code example that is working correctly as expected. You can check it out here: https://jsfiddle.net/x1suxu9h/ var Hello = React.createClass({ getInitialState: function() { return { msg: '' } }, onSubmit: function(e) { ...

if considering an integer value of 0 as equivalent to null

I am struggling with using axios to send data to an API in react. Despite the server successfully receiving the values, my code is not entering the if block as expected. Interestingly, when I make the same request from a rest client, it works perfectly. He ...

Step-by-step guide on visually comparing two iframes for differences

Scenario : In my project, I am dealing with 2 iframes that contain a significant number of divs and other controls, making both iframes similar in size to complete HTML websites. My goal is to compare these two iframes and identify any differences. Consi ...

Attempting to streamline the process of verifying the truthfulness of an object key and subsequently adding it to a different

In the process of creating a form to interact with a remote API, I aim to construct a GET request query string depending on which checkboxes the user chooses. Initially, I considered using a series of if/else statements to check whether the model object k ...

Dispatching a personalized jQuery validation form

I have been working on a simple custom validation script. Despite it meeting my needs, I am struggling to figure out how to properly submit the form after validation. Initially, I thought using 'return true' would do the trick, but unfortunately, ...

Display picture on webpage in 10 seconds

Hi, I'm working on a website project and I've run into an issue where I need to use JavaScript, but I haven't mastered it yet. I have a background image slideshow set up where a new image appears every 6 seconds. My idea is to have the sec ...

Variable within a JSON response encapsulated in a JavaScript object

I am attempting to include a PHP variable within a JavaScript script that is stored in a result variable and will be processed with JSON, but I am struggling to make it work. I believe the issue lies with the use of double and single quotes, but I cannot d ...

The issue arises when attempting to render an SVG with JavaScript embedded inside using the img, object, or

Issue with the title ... please follow these steps: (view codes below) Create an svg + open it separately (name it keysaway.svg) Create html + open it individually When you observe, the svg displays a simple up and down animation but fails to work when l ...

The brush functionality does not display rotated x-axis labels

I am experiencing issues with my D3 area chart that includes brush functionality on a rotated x-axis at a 45-degree angle. Initially, the x-axis labels are displayed properly but when I apply the brush to the chart, the labels disappear and do not reappe ...

The Model.function method is not a valid function that can be used within a router

Currently facing a challenge with my router setup. I have exported the function as shown in the code snippet below. This is the Model I am using: "use strict"; var mongoose = require('mongoose'); var bcrypt = require("bcryptjs"); var Schema = m ...

Utilizing Angular to nest a simple component within another component and display it exclusively on a targeted page or parent component

Currently, I am developing a mobile app using Ionic 3 and have created 2 components - Dumb or presentation components. The first component is the <ion-navbar>, which contains another component called <header-wallet-badge></header-wallet-badg ...

Vue is having trouble loading dynamic src files, and the require function isn't functioning properly

I'm facing an issue with displaying a dynamic image. When I use the following code: <img :src="src" alt="img"> It doesn't seem to work. However, it works perfectly fine when I use: <img src="../assets/img/banana ...

Guide on importing a JS file into the main JS file using Three.js

I'm fairly new to Threejs and I am trying to organize my code by putting some of my threejs code in a separate JS file and then using it in my main.js file. Here is a simplified version of what I am trying to do: main.js import * as THREE from &ap ...