There are some options to use Shaders with javascript/typescript.
I just saw an npm package that allows me to use fragment shader easily.
I'm using typescript, but in this case I don't really use ts lol.
REACT-VFX exports VFXSpan, VFXImg and VFXVideo
These components works just like <span>, <img> and <video> - accepts all properties they have, but they are rendered in WebGL world with shader effects!
import*asVFXfrom'react-vfx';exportdefault()=>(<VFX.VFXProvider>{/* Render text as image, then apply the shader effect! */}<VFX.VFXSpanshader="rainbow">Hithere!</VFX.VFXSpan>
{/* Render image with shader */}<VFX.VFXImgsrc="cat.png"alt="image"shader="rgbShift"/>{/* It also supports animated GIFs! */}<VFX.VFXImgsrc="doge.gif"shader="pixelate"/>{/* and videos! */}<VFX.VFXVideosrc="mind_blown.mp4"autoplayplaysinline
In this post, I will show you how to use react-vfx for displaying FragmentShaders.
Steps
Step1. Create a new react app by create-react-app
Step2. Install react-vfx
Step3. Create a new component for FragmentShader
Step4. Run the app
Step1 Create react app
In this case, we will use create-react-app. If you have a template, you can use it.
Here is one thing you should know about create-react-app
If you've previously installed create-react-app globally via npm install -g create-react-app, we recommend you uninstall the package using npm uninstall -g create-react-app to ensure that npx always uses the latest version.
Global installs of create-react-app are no longer supported.
If you install react-create-app globally, I recommend you to uninstall it since it may prevent you to create a new react app(Actually my case didn't create an app properly just generate package.json and a couple of files)
$ npx create-react-app myshader --template typescript
# or I used yarn since I have switched a package manager from npm to yarn$ yarn create react-app myshader --template typescript
If you don't want to use Typescript try the following.
This isn't necessary, but I prefer to run before adding a component.
$ yarn start
You will see this.
Step2 Install react-vfx
# using styled-components
$ yarn add react-vfx styled-components
$ yarn add -D @types/styled-components <-- if you use typescript
# or
$ npm install react-vfx styled-components
$ npm install -D @types/styled-components <-- if you use typescript
Step3 Create component
In this case, I created a new file, MyShader.tsx under src. If you are using js, the file's extension should be .jsx
importReactfrom"react";import*asVFXfrom"react-vfx";importstyledfrom"styled-components";constContent=styled.div`
width: 100vw;
height: 100vh;
`;constmetal=`
uniform vec2 resolution;
uniform float time;
void main()
{
vec2 coord = gl_FragCoord.xy / resolution.xy;
vec2 st = coord;
vec3 line = vec3(0.0);
coord *= 4.;
float len;
for (int i = 0; i < 15; i++) {
len = length(vec2(coord.x, coord.y));
coord.x += cos(coord.y + sin(len)) + cos(time * .07) * 0.2;
coord.y += sin(coord.x + cos(len)) + sin(time * 0.1);
}
len *= cos(len * 0.4);
len -= 10.;
for (float i = 0.0; i < 5.0; i++) {
len += 0.11 / abs(mod(st.x, 1.09 * i) * 200.) * 1.;
}
vec3 color = vec3(cos(len + 0.2) * 1.15, cos(len + 0.1), cos(len - 0.05));
gl_FragColor = vec4(color, 1.0);
}
`;constMyShader:React.FC=()=>{return (<><VFX.VFXProvider><VFX.VFXSpanshader={metal}><Content></Content>
</VFX.VFXSpan>
</VFX.VFXProvider>
</>
);}exportdefaultMyShader;
As you can see the code is very simple except Fragment shader.
Import packages and create a styled tag, Content and write a Fragment Shader, metal. Then add react-vfx.
Actually, I tried the following. But it didn't render the content properly. Haven't checked the exact issue lol.
If everything works well, you will see the following. (Actually, what you will see is an animation.)
I use threejs to use fragment shader which is pretty good since threejs has nice samples so I just need to modify shader part and threejs input's part. However, with typescript the setup is a little bit troublesome to me. But, react-vfx is very handy since it is written in typescript so I don't need to install any @type file for it. I will use this for updating my portfolio site.