Transforming a THREE.js shader into a PIXI.js shader

I am currently exploring the world of PIXI.js and custom Shaders, and I must admit, it's a bit overwhelming for me. I came across a GLSL Shader (created by DonKarlssonSan) that I would like to convert to PIXI.js in order to compare performance. Any assistance on this matter would be greatly appreciated!

var container;
var camera, scene, renderer;
var uniforms;
var startTime;

init();
animate();

function init() {
  container = document.getElementById('container');

  startTime = Date.now();
  camera = new THREE.Camera();
  camera.position.z = 1;

  scene = new THREE.Scene();

  var geometry = new THREE.PlaneBufferGeometry(16, 9);

  // Rest of the JavaScript code
}

// Further JavaScript functions and shaders

JSFiddle: https://jsfiddle.net/9t0ayrmh/1/

*I have made progress with a PIXI.js template and everything is functioning as intended. However, I am struggling with connecting the shaders to the filters. I can share my current attempts if necessary.

Thank you!

Answer №1

Converting the GLSL code is unnecessary. You can utilize the same shader by creating a PIXI.Filter and setting the values of the uniforms iResolution and iGlobalTime. Apply the filter to the PIXI.Container. For example:

let app = new PIXI.Application({width : window.innerWidth, height : window.innerHeight});
app.resizeTo = window;

let fragmentShader = document.getElementById('fragmentShader').textContent;

let filter = new PIXI.Filter(null, fragmentShader);
filter.uniforms.iResolution = [app.screen.width, app.screen.height];
filter.uniforms.iGlobalTime = 0.0;

let container = new PIXI.Container();
container.filterArea = app.screen;
container.filters = [filter];

app.stage.addChild(container);
document.body.appendChild(app.view);

It's worth noting that the vertex shader can be omitted, as the default vertex shader of the filter is sufficient.

The process of animating and updating the time uniform (iGlobalTime) closely resembles the approach in THREE.js. For instance:

startTime = Date.now();
app.ticker.add(function(delta) {
    var currentTime = Date.now();
    filter.uniforms.iGlobalTime = (currentTime - startTime) * 0.0005;
});

Refer to the example in Pixi v5.1.5:

var app = new PIXI.Application({width : window.innerWidth, height : window.innerHeight});
app.resizeTo = window;

let fragmentShader = document.getElementById('fragmentShader').textContent;

let filter = new PIXI.Filter(null, fragmentShader);
filter.uniforms.iResolution = [app.screen.width, app.screen.height];
filter.uniforms.iGlobalTime = 0.0;

let container = new PIXI.Container();
container.filterArea = app.screen;
container.filters = [filter];

app.stage.addChild(container);
document.getElementById('container').appendChild(app.view);

function onresize(event) {
    if (app.resize)
        app.resize();
    container.filterArea = app.screen;
    filter.uniforms.iResolution = [app.screen.width, app.screen.height];
}
window.addEventListener('resize', onresize, false);

startTime = Date.now();
app.ticker.add(function(delta) {
    var currentTime = Date.now();
    filter.uniforms.iGlobalTime = (currentTime - startTime) * 0.0005;
});
html, body { margin: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
<div id="container"></div>

<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec2 iResolution;
uniform float iGlobalTime;
vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

// Remaining shader code
...
// End of shader code

</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's the best way to mount a file on a field?

Can you assist in resolving this issue by utilizing a form on JSFiddle? If a user fills out the following fields: name, email, phone, message The data should be output to the console. However, if a user adds a file to the field attachment No output ...

creating an interactive table with the help of the useState hook

I'm new to JavaScipt and ReactJS, so I have a question that may seem obvious but I can't seem to figure it out. I am attempting to display my array in a table using useState, but currently I can only show the header. Additionally, if anyone know ...

Rendering data from an API using v-if

Could you help me change the tag that currently displays true or false? I want it to show "FREE" if the event is free and "PAID" if it's not. Check out the Eventbrite API here The response I'm receiving from data.events.is_free is in boolean fo ...

Angular displays X items in each row and column

I've been struggling with this task for the past 2 hours. My goal is to display a set of buttons on the screen, but I'm facing some challenges. The current layout of the buttons doesn't look quite right as they appear cluttered and unevenly ...

Is it possible to change the background color of a MUI theme in ReactJS by using Css

Currently, I am utilizing Material UI to create a theme that is functioning correctly. However, upon adding <CssBaseline/> to the App.js file, it unexpectedly changes the background color to white instead of the intended #1f262a specified in the inde ...

Can context be passed into a component that is created using ReactDOM.render()?

TL;DR In this given example code: ReactDOM.render(<MyComponent prop1={someVar} />, someDomNode); Can one manually provide React context to the instance of MyComponent? This might seem like an unusual question considering React's usual behavio ...

Issue with CSS styles not linking correctly to ejs templates

I'm having trouble linking my CSS stylesheet in my project. I have the CSS file stored in a public folder with a css subfolder within it. Despite trying various methods, I can't seem to get the stylesheet to connect properly. Below is a snippet f ...

What is the best way to display items within a table using React?

I'm just starting to learn React. Can someone show me how to use the "map" function to list elements from two different arrays in two columns? state = { dates: ["2000", "2001", "2002"], cases: ["1", "2", "3"] } render() { return ( <thea ...

What is the method for determining if parsing is necessary or unnecessary?

Let's talk JSON: var datat= {"Model": "Model A", "Datase": [ { "Id": "DatchikSveta11", "Group": 2, "State": "on", "Dat ...

Steps for adding information to an AngularJS scope

I am facing an issue with setting the data inside the scope once it becomes active. On my HTML page, I have a show/hide menu that displays data when a button is clicked. I need to store this data within the scope correctly. Please advise on any corrections ...

Here is a way to prevent a null input value from being accepted in a JavaScript function

Hey there, I have a function that looks like this: class Fun { pem_Files_Checker_And_Adder_Server_Id_Adder(id , serverType , hostname) { //do something }; }; } In order for this function to work properly, I need to give it some values. For exam ...

The functionality of jQuery's .hide method is not effective in this specific scenario

HTML section <div class="navigation-bar"></div> Jquery & JavaScript section function hideUserDiv(){ $('.ask-user').hide(); } var ask = '<div id="ask-user" style="block;position:absolute;height:auto;bottom:0;top ...

Disable, Hide, or Remove Specific Options in a Single Dropdown Selection

A challenge I am facing involves creating a form with multiple select options that need to be ranked by the user from 1-8. However, I am encountering some difficulties in hiding, removing, or disabling certain select options. Below is an excerpt from my f ...

What is the best way to adjust the size of a Div slideshow using

I need help with creating a slideshow that covers my webpage width 100% and height 500px. The image resolution is 1200*575. Can someone assist me with this? CSS #slide{ width : 100%; height: 500px; } HTML <!DOCTYPE html> <html> ...

The SVG image does not display in browsers other than Internet Explorer (IE)

I am encountering an issue with adding a menu toggle image in SVG format to my HTML. Unfortunately, the image is not displaying as expected. Here are screenshots for comparison between Explorer and Chrome: https://i.stack.imgur.com/74sqh.png https://i. ...

Discord.js: AbortError: The request was cancelled by the user

Recently, while working on my ticket system and the process for logging transcripts, I encountered an unexpected error that caused transcripts to fail sending. This issue never occurred before. The error message displayed was: [Error Handling System] Multi ...

Issue with AWS SDK client-S3 upload: Chrome freezes after reaching 8 GB upload limit

Whenever I try to upload a 17 GB file from my browser, Chrome crashes after reaching 8 GB due to memory exhaustion. import { PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'; import { Progress, Upload } from "@aws-sdk/lib-storage& ...

Tips for maintaining an updated array's consistency on page refresh in Vue.js?

HelloWorld.vue Dynamic routing in Vuejs: <template> <div> <b>Vuejs dynamic routing</b> <div v-for="item in items" :key="item.id"> <b>{{ item.id }}.</b> &nbsp;&nbsp;&nbsp; <rou ...

Guide on integrating next-images with rewrite in next.config.js

I'm currently facing a dilemma with my next.config.js file. I've successfully added a proxy to my requests using rewrite, but now I want to incorporate next-images to load svg files as well. However, I'm unsure of how to combine both functio ...